From patchwork Tue Oct 29 10:00:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217529 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79198139A for ; Tue, 29 Oct 2019 10:00:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 418792083E for ; Tue, 29 Oct 2019 10:00:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b6Ny4ibV" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726636AbfJ2KAy (ORCPT ); Tue, 29 Oct 2019 06:00:54 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:37702 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725840AbfJ2KAx (ORCPT ); Tue, 29 Oct 2019 06:00:53 -0400 Received: by mail-wm1-f65.google.com with SMTP id q130so1692576wme.2 for ; Tue, 29 Oct 2019 03:00:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=8ItaMLWPuiDh0xwOy8VHn052gcTcGh76NSKNNuJiI7E=; b=b6Ny4ibVBr4HI6Tq6a8uF2+8ScwdB+B6T6Riat5bS9IIO42eJUxGUzXJtIsFlQkomU +Nu4XnheV+u3VtCCx2iiNRXnL3S+NskBNydr7w6+OFaaDh9QojOs0q8b3RmZb+zh79iY hJBd86J/CAipOospJkbrxf7b1/9wTVtq2urjalJ/ai1p708tCPY+3AeqAFI4MgvyTUdw xpKXjYVYK565IK/Zq5gCeF5aru9ZqDOBAEojrFBfGz1txvSwhWWhxtNFlccyGDmKM5Cw vkui3DvZVx8WNu161Knb1Yyoy/qfvKj68J2JCliNswQixoVKPK2kNA1i080wtKhEHehq qBXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=8ItaMLWPuiDh0xwOy8VHn052gcTcGh76NSKNNuJiI7E=; b=YA19Cc59eiMO8WA80RYQ+e/iEwbWgUR2vgnZZXnF5u6/fHjHjpgrp4Lqf+NoIOUwq8 IyrPqa3VS9gMtiQfE8+PZ7ii2YeQfBo0ufRYDwmvxyPQKmggny8ZKQwmsfT1OA/IEcAS lIKr0EcJO17k4NSnrxafOcu263dyOLDUuIzQ98N3Vtzh7hoGOU5gOcVSro98pNVeIjOG xYkWVHHZe8rHECEP6E73ckvId4JEgYDvW+l1yvddiHBV9oYekQBakGJknOOrIjslGXaK rU1sx3jYIegRq6nlx9D7Pz2QaEMiPexUIsnHhXI6muHwnHlKTu+3LaeumUlSozfm8thE KMfg== X-Gm-Message-State: APjAAAX1FRHYa4WDe0E0BH6FKWd6D1tybUmeiz/gvENcRtT/rL6pqm0r 8hYgE3SQ1ezCDUB1hWAghQfGEunc X-Google-Smtp-Source: APXvYqwLiyaWToOQKG5deu3menA6Cy/11OK1WNww8ZMN0ED5kXavqlsI2Zca6Gmgh0Y9a5MZw66deQ== X-Received: by 2002:a1c:f208:: with SMTP id s8mr1904432wmc.82.1572343249230; Tue, 29 Oct 2019 03:00:49 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r81sm2522320wme.16.2019.10.29.03.00.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:48 -0700 (PDT) Message-Id: <1796c119be0be2e707685b423fdb23c6f6675a28.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:37 +0000 Subject: [PATCH 01/10] diff: move doc to diff.h and diffcore.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-diff.txt to both diff.h and diffcore.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-diff.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header files. There are three members documented in the doc file that weren't found in the header files, assuming the doc wasn't up to date and the members no longer exist: touched_flags, COLOR_DIFF_WORDS and QUIET. Signed-off-by: Heba Waly --- Documentation/technical/api-diff.txt | 174 --------------------------- diff.h | 127 +++++++++++++++++++ diffcore.h | 32 +++++ 3 files changed, 159 insertions(+), 174 deletions(-) delete mode 100644 Documentation/technical/api-diff.txt diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt deleted file mode 100644 index 30fc0e9c93..0000000000 --- a/Documentation/technical/api-diff.txt +++ /dev/null @@ -1,174 +0,0 @@ -diff API -======== - -The diff API is for programs that compare two sets of files (e.g. two -trees, one tree and the index) and present the found difference in -various ways. The calling program is responsible for feeding the API -pairs of files, one from the "old" set and the corresponding one from -"new" set, that are different. The library called through this API is -called diffcore, and is responsible for two things. - -* finding total rewrites (`-B`), renames (`-M`) and copies (`-C`), and - changes that touch a string (`-S`), as specified by the caller. - -* outputting the differences in various formats, as specified by the - caller. - -Calling sequence ----------------- - -* Prepare `struct diff_options` to record the set of diff options, and - then call `repo_diff_setup()` to initialize this structure. This - sets up the vanilla default. - -* Fill in the options structure to specify desired output format, rename - detection, etc. `diff_opt_parse()` can be used to parse options given - from the command line in a way consistent with existing git-diff - family of programs. - -* Call `diff_setup_done()`; this inspects the options set up so far for - internal consistency and make necessary tweaking to it (e.g. if - textual patch output was asked, recursive behaviour is turned on); - the callback set_default in diff_options can be used to tweak this more. - -* As you find different pairs of files, call `diff_change()` to feed - modified files, `diff_addremove()` to feed created or deleted files, - or `diff_unmerge()` to feed a file whose state is 'unmerged' to the - API. These are thin wrappers to a lower-level `diff_queue()` function - that is flexible enough to record any of these kinds of changes. - -* Once you finish feeding the pairs of files, call `diffcore_std()`. - This will tell the diffcore library to go ahead and do its work. - -* Calling `diff_flush()` will produce the output. - - -Data structures ---------------- - -* `struct diff_filespec` - -This is the internal representation for a single file (blob). It -records the blob object name (if known -- for a work tree file it -typically is a NUL SHA-1), filemode and pathname. This is what the -`diff_addremove()`, `diff_change()` and `diff_unmerge()` synthesize and -feed `diff_queue()` function with. - -* `struct diff_filepair` - -This records a pair of `struct diff_filespec`; the filespec for a file -in the "old" set (i.e. preimage) is called `one`, and the filespec for a -file in the "new" set (i.e. postimage) is called `two`. A change that -represents file creation has NULL in `one`, and file deletion has NULL -in `two`. - -A `filepair` starts pointing at `one` and `two` that are from the same -filename, but `diffcore_std()` can break pairs and match component -filespecs with other filespecs from a different filepair to form new -filepair. This is called 'rename detection'. - -* `struct diff_queue` - -This is a collection of filepairs. Notable members are: - -`queue`:: - - An array of pointers to `struct diff_filepair`. This - dynamically grows as you add filepairs; - -`alloc`:: - - The allocated size of the `queue` array; - -`nr`:: - - The number of elements in the `queue` array. - - -* `struct diff_options` - -This describes the set of options the calling program wants to affect -the operation of diffcore library with. - -Notable members are: - -`output_format`:: - The output format used when `diff_flush()` is run. - -`context`:: - Number of context lines to generate in patch output. - -`break_opt`, `detect_rename`, `rename-score`, `rename_limit`:: - Affects the way detection logic for complete rewrites, renames - and copies. - -`abbrev`:: - Number of hexdigits to abbreviate raw format output to. - -`pickaxe`:: - A constant string (can and typically does contain newlines to - look for a block of text, not just a single line) to filter out - the filepairs that do not change the number of strings contained - in its preimage and postimage of the diff_queue. - -`flags`:: - This is mostly a collection of boolean options that affects the - operation, but some do not have anything to do with the diffcore - library. - -`touched_flags`:: - Records whether a flag has been changed due to user request - (rather than just set/unset by default). - -`set_default`:: - Callback which allows tweaking the options in diff_setup_done(). - -BINARY, TEXT;; - Affects the way how a file that is seemingly binary is treated. - -FULL_INDEX;; - Tells the patch output format not to use abbreviated object - names on the "index" lines. - -FIND_COPIES_HARDER;; - Tells the diffcore library that the caller is feeding unchanged - filepairs to allow copies from unmodified files be detected. - -COLOR_DIFF;; - Output should be colored. - -COLOR_DIFF_WORDS;; - Output is a colored word-diff. - -NO_INDEX;; - Tells diff-files that the input is not tracked files but files - in random locations on the filesystem. - -ALLOW_EXTERNAL;; - Tells output routine that it is Ok to call user specified patch - output routine. Plumbing disables this to ensure stable output. - -QUIET;; - Do not show any output. - -REVERSE_DIFF;; - Tells the library that the calling program is feeding the - filepairs reversed; `one` is two, and `two` is one. - -EXIT_WITH_STATUS;; - For communication between the calling program and the options - parser; tell the calling program to signal the presence of - difference using program exit code. - -HAS_CHANGES;; - Internal; used for optimization to see if there is any change. - -SILENT_ON_REMOVE;; - Affects if diff-files shows removed files. - -RECURSIVE, TREE_IN_RECURSIVE;; - Tells if tree traversal done by tree-diff should recursively - descend into a tree object pair that are different in preimage - and postimage set. - -(JC) diff --git a/diff.h b/diff.h index 7f8f024feb..86d7871618 100644 --- a/diff.h +++ b/diff.h @@ -9,6 +9,49 @@ #include "object.h" #include "oidset.h" +/** + * The diff API is for programs that compare two sets of files (e.g. two trees, + * one tree and the index) and present the found difference in various ways. + * The calling program is responsible for feeding the API pairs of files, one + * from the "old" set and the corresponding one from "new" set, that are + * different. + * The library called through this API is called diffcore, and is responsible + * for two things. + * + * - finding total rewrites (`-B`), renames (`-M`) and copies (`-C`), and + * changes that touch a string (`-S`), as specified by the caller. + * + * - outputting the differences in various formats, as specified by the caller. + * + * Calling sequence + * ---------------- + * + * - Prepare `struct diff_options` to record the set of diff options, and then + * call `repo_diff_setup()` to initialize this structure. This sets up the + * vanilla default. + * + * - Fill in the options structure to specify desired output format, rename + * detection, etc. `diff_opt_parse()` can be used to parse options given + * from the command line in a way consistent with existing git-diff family + * of programs. + * + * - Call `diff_setup_done()`; this inspects the options set up so far for + * internal consistency and make necessary tweaking to it (e.g. if textual + * patch output was asked, recursive behaviour is turned on); the callback + * set_default in diff_options can be used to tweak this more. + * + * - As you find different pairs of files, call `diff_change()` to feed + * modified files, `diff_addremove()` to feed created or deleted files, or + * `diff_unmerge()` to feed a file whose state is 'unmerged' to the API. + * These are thin wrappers to a lower-level `diff_queue()` function that is + * flexible enough to record any of these kinds of changes. + * + * - Once you finish feeding the pairs of files, call `diffcore_std()`. + * This will tell the diffcore library to go ahead and do its work. + * + * - Calling `diff_flush()` will produce the output. + */ + struct combine_diff_path; struct commit; struct diff_filespec; @@ -65,21 +108,66 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data) #define DIFF_FLAGS_INIT { 0 } struct diff_flags { + + /** + * Tells if tree traversal done by tree-diff should recursively descend + * into a tree object pair that are different in preimage and postimage set. + */ unsigned recursive; unsigned tree_in_recursive; + + /* Affects the way how a file that is seemingly binary is treated. */ unsigned binary; unsigned text; + + /** + * Tells the patch output format not to use abbreviated object names on the + * "index" lines. + */ unsigned full_index; + + /* Affects if diff-files shows removed files. */ unsigned silent_on_remove; + + /** + * Tells the diffcore library that the caller is feeding unchanged + * filepairs to allow copies from unmodified files be detected. + */ unsigned find_copies_harder; + unsigned follow_renames; unsigned rename_empty; + + /* Internal; used for optimization to see if there is any change. */ unsigned has_changes; + unsigned quick; + + /** + * Tells diff-files that the input is not tracked files but files in random + * locations on the filesystem. + */ unsigned no_index; + + /** + * Tells output routine that it is Ok to call user specified patch output + * routine. Plumbing disables this to ensure stable output. + */ unsigned allow_external; + + /** + * For communication between the calling program and the options parser; + * tell the calling program to signal the presence of difference using + * program exit code. + */ unsigned exit_with_status; + + /** + * Tells the library that the calling program is feeding the filepairs + * reversed; `one` is two, and `two` is one. + */ unsigned reverse_diff; + unsigned check_failed; unsigned relative_name; unsigned ignore_submodules; @@ -131,36 +219,72 @@ enum diff_submodule_format { DIFF_SUBMODULE_INLINE_DIFF }; +/** + * the set of options the calling program wants to affect the operation of + * diffcore library with. + */ struct diff_options { const char *orderfile; + + /** + * A constant string (can and typically does contain newlines to look for + * a block of text, not just a single line) to filter out the filepairs + * that do not change the number of strings contained in its preimage and + * postimage of the diff_queue. + */ const char *pickaxe; + const char *single_follow; const char *a_prefix, *b_prefix; const char *line_prefix; size_t line_prefix_length; + + /** + * collection of boolean options that affects the operation, but some do + * not have anything to do with the diffcore library. + */ struct diff_flags flags; /* diff-filter bits */ unsigned int filter; int use_color; + + /* Number of context lines to generate in patch output. */ int context; + int interhunkcontext; + + /* Affects the way detection logic for complete rewrites, renames and + * copies. + */ int break_opt; int detect_rename; + int irreversible_delete; int skip_stat_unmatch; int line_termination; + + /* The output format used when `diff_flush()` is run. */ int output_format; + unsigned pickaxe_opts; + + /* Affects the way detection logic for complete rewrites, renames and + * copies. + */ int rename_score; int rename_limit; + int needed_rename_limit; int degraded_cc_to_c; int show_rename_progress; int dirstat_permille; int setup; + + /* Number of hexdigits to abbreviate raw format output to. */ int abbrev; + int ita_invisible_in_index; /* white-space error highlighting */ #define WSEH_NEW (1<<12) @@ -192,6 +316,7 @@ struct diff_options { /* to support internal diff recursion by --follow hack*/ int found_follow; + /* Callback which allows tweaking the options in diff_setup_done(). */ void (*set_default)(struct diff_options *); FILE *file; @@ -245,6 +370,7 @@ void diff_emit_submodule_error(struct diff_options *o, const char *err); void diff_emit_submodule_pipethrough(struct diff_options *o, const char *line, int len); +/* Output should be colored. */ enum color_diff { DIFF_RESET = 0, DIFF_CONTEXT = 1, @@ -270,6 +396,7 @@ enum color_diff { DIFF_FILE_OLD_BOLD = 21, DIFF_FILE_NEW_BOLD = 22, }; + const char *diff_get_color(int diff_use_color, enum color_diff ix); #define diff_get_color_opt(o, ix) \ diff_get_color((o)->use_color, ix) diff --git a/diffcore.h b/diffcore.h index b651061c0e..7c07347e42 100644 --- a/diffcore.h +++ b/diffcore.h @@ -28,6 +28,12 @@ struct userdiff_driver; #define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */ +/** + * the internal representation for a single file (blob). It records the blob + * object name (if known -- for a work tree file it typically is a NUL SHA-1), + * filemode and pathname. This is what the `diff_addremove()`, `diff_change()` + * and `diff_unmerge()` synthesize and feed `diff_queue()` function with. + */ struct diff_filespec { struct object_id oid; char *path; @@ -66,6 +72,17 @@ void diff_free_filespec_data(struct diff_filespec *); void diff_free_filespec_blob(struct diff_filespec *); int diff_filespec_is_binary(struct repository *, struct diff_filespec *); +/** + * This records a pair of `struct diff_filespec`; the filespec for a file in + * the "old" set (i.e. preimage) is called `one`, and the filespec for a file + * in the "new" set (i.e. postimage) is called `two`. A change that represents + * file creation has NULL in `one`, and file deletion has NULL in `two`. + * + * A `filepair` starts pointing at `one` and `two` that are from the same + * filename, but `diffcore_std()` can break pairs and match component filespecs + * with other filespecs from a different filepair to form new filepair. This is + * called 'rename detection'. + */ struct diff_filepair { struct diff_filespec *one; struct diff_filespec *two; @@ -77,6 +94,7 @@ struct diff_filepair { unsigned done_skip_stat_unmatch : 1; unsigned skip_stat_unmatch_result : 1; }; + #define DIFF_PAIR_UNMERGED(p) ((p)->is_unmerged) #define DIFF_PAIR_RENAME(p) ((p)->renamed_pair) @@ -94,11 +112,25 @@ void diff_free_filepair(struct diff_filepair *); int diff_unmodified_pair(struct diff_filepair *); +/** + * This is a collection of filepairs. Notable members are: + * + * - `queue`: + * An array of pointers to `struct diff_filepair`. This dynamically grows as + * you add filepairs; + * + * - `alloc`: + * The allocated size of the `queue` array; + * + * - `nr`: + * The number of elements in the `queue` array. + */ struct diff_queue_struct { struct diff_filepair **queue; int alloc; int nr; }; + #define DIFF_QUEUE_CLEAR(q) \ do { \ (q)->queue = NULL; \ From patchwork Tue Oct 29 10:00:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217547 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 67ABB1390 for ; Tue, 29 Oct 2019 10:01:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3AE312083E for ; Tue, 29 Oct 2019 10:01:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qh+fkHZM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726463AbfJ2KAx (ORCPT ); Tue, 29 Oct 2019 06:00:53 -0400 Received: from mail-wr1-f48.google.com ([209.85.221.48]:36039 "EHLO mail-wr1-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726109AbfJ2KAx (ORCPT ); Tue, 29 Oct 2019 06:00:53 -0400 Received: by mail-wr1-f48.google.com with SMTP id w18so12932679wrt.3 for ; Tue, 29 Oct 2019 03:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=C4tdvHrsbIUd/BqwlbGvevZdwEQqmIVmLeZz7+YyZvE=; b=qh+fkHZMnNhzRuV2xE7C+Gsy4tSauMSohO22diDeATcr+HWM9TNE0WGVJyTDkLxIKl m1fzQg8fBSmtMM/oDTw8PRV8+Mzq5YvbJmDIU8jvASR4GeHNdFpfdNidTmXEL4dNLvsm EsquirSeYT7qbi7sQh1vITQPCP5SHgD2A+krGic1E61nxrNiEi/LKHA+ES3Uo7sSqMc0 c3mgUqfUje2GXDEzjykxc8eNxKbTjKIncMuA/UR1r+qlakthJggPe8wW1JQsIWwkZMD3 RuIHii312Tj/IRYUXoA09JMlES4of4mlYPVeG3jBHzXNpiMlH01diC8YMOuJ/1Ieqkau D1jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=C4tdvHrsbIUd/BqwlbGvevZdwEQqmIVmLeZz7+YyZvE=; b=IdL9GdwvD6tEuk/6Bao8njVkQ3Ya+E/0SjB+rP+v5Foar+0oj0ZNij7lWGNdeyjLHg w/H4lv4HwQ/SAMPaZn/JuKCVfjabaH3lKvcL8pXoy88nlyFuQYV90PT/VCZ+UHh2DqaH 53YMPYLKm0L3axA1zzaGDoN3pZqde9MECgOog25M/lkA8H5uHyjqVAKbv0XLOz/LKK27 CZ8TjDC9jlq5NZ2yuJK1l71q6qrvFAsKXKfhyb2JRPxuEafom/b4RXUxPjjTHB3exr8t 4SXK+O0aeyYwWMFNJPFwkSgISxaiM1u47MAuuaolQURAfVWX4IYxBRS/dmwztjxsLWgf awLw== X-Gm-Message-State: APjAAAWeYSnk41LSiRZAYPX62YVT+MDS+5EjBfDzP0g6ZrQkSGkDdNmk Gz5qt/tejZmzLiUKt9om0ECsuF9q X-Google-Smtp-Source: APXvYqy8Qdm5kvPYrrAC5B/aw3OPHT9H9TPDLcdlZq3hmHlGy+2+WFW6X5lSbSz5YENTrpmYCiXijw== X-Received: by 2002:adf:e9c7:: with SMTP id l7mr2566163wrn.57.1572343249893; Tue, 29 Oct 2019 03:00:49 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r13sm18509297wra.74.2019.10.29.03.00.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:49 -0700 (PDT) Message-Id: <290935e846f6e1758bdf0eb1518bfa01662764ca.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:38 +0000 Subject: [PATCH 02/10] dir: move doc to dir.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-directory-listing.txt to dir.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-directory-listing.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header files. Signed-off-by: Heba Waly --- .../technical/api-directory-listing.txt | 130 ------------------ dir.h | 118 +++++++++++++++- 2 files changed, 113 insertions(+), 135 deletions(-) delete mode 100644 Documentation/technical/api-directory-listing.txt diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt deleted file mode 100644 index 76b6e4f71b..0000000000 --- a/Documentation/technical/api-directory-listing.txt +++ /dev/null @@ -1,130 +0,0 @@ -directory listing API -===================== - -The directory listing API is used to enumerate paths in the work tree, -optionally taking `.git/info/exclude` and `.gitignore` files per -directory into account. - -Data structure --------------- - -`struct dir_struct` structure is used to pass directory traversal -options to the library and to record the paths discovered. A single -`struct dir_struct` is used regardless of whether or not the traversal -recursively descends into subdirectories. - -The notable options are: - -`exclude_per_dir`:: - - The name of the file to be read in each directory for excluded - files (typically `.gitignore`). - -`flags`:: - - A bit-field of options: - -`DIR_SHOW_IGNORED`::: - - Return just ignored files in `entries[]`, not untracked - files. This flag is mutually exclusive with - `DIR_SHOW_IGNORED_TOO`. - -`DIR_SHOW_IGNORED_TOO`::: - - Similar to `DIR_SHOW_IGNORED`, but return ignored files in - `ignored[]` in addition to untracked files in - `entries[]`. This flag is mutually exclusive with - `DIR_SHOW_IGNORED`. - -`DIR_KEEP_UNTRACKED_CONTENTS`::: - - Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is set, the - untracked contents of untracked directories are also returned in - `entries[]`. - -`DIR_SHOW_IGNORED_TOO_MODE_MATCHING`::: - - Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if - this is set, returns ignored files and directories that match - an exclude pattern. If a directory matches an exclude pattern, - then the directory is returned and the contained paths are - not. A directory that does not match an exclude pattern will - not be returned even if all of its contents are ignored. In - this case, the contents are returned as individual entries. -+ -If this is set, files and directories that explicitly match an ignore -pattern are reported. Implicitly ignored directories (directories that -do not match an ignore pattern, but whose contents are all ignored) -are not reported, instead all of the contents are reported. - -`DIR_COLLECT_IGNORED`::: - - Special mode for git-add. Return ignored files in `ignored[]` and - untracked files in `entries[]`. Only returns ignored files that match - pathspec exactly (no wildcards). Does not recurse into ignored - directories. - -`DIR_SHOW_OTHER_DIRECTORIES`::: - - Include a directory that is not tracked. - -`DIR_HIDE_EMPTY_DIRECTORIES`::: - - Do not include a directory that is not tracked and is empty. - -`DIR_NO_GITLINKS`::: - - If set, recurse into a directory that looks like a Git - directory. Otherwise it is shown as a directory. - -The result of the enumeration is left in these fields: - -`entries[]`:: - - An array of `struct dir_entry`, each element of which describes - a path. - -`nr`:: - - The number of members in `entries[]` array. - -`alloc`:: - - Internal use; keeps track of allocation of `entries[]` array. - -`ignored[]`:: - - An array of `struct dir_entry`, used for ignored paths with the - `DIR_SHOW_IGNORED_TOO` and `DIR_COLLECT_IGNORED` flags. - -`ignored_nr`:: - - The number of members in `ignored[]` array. - -Calling sequence ----------------- - -Note: index may be looked at for .gitignore files that are CE_SKIP_WORKTREE -marked. If you to exclude files, make sure you have loaded index first. - -* Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0, - sizeof(dir))`. - -* To add single exclude pattern, call `add_pattern_list()` and then - `add_pattern()`. - -* To add patterns from a file (e.g. `.git/info/exclude`), call - `add_patterns_from_file()` , and/or set `dir.exclude_per_dir`. A - short-hand function `setup_standard_excludes()` can be used to set - up the standard set of exclude settings. - -* Set options described in the Data Structure section above. - -* Call `read_directory()`. - -* Use `dir.entries[]`. - -* Call `clear_directory()` when none of the contained elements are no longer in use. - -(JC) diff --git a/dir.h b/dir.h index 2fbdef014f..1b41d29c07 100644 --- a/dir.h +++ b/dir.h @@ -1,11 +1,43 @@ #ifndef DIR_H #define DIR_H -/* See Documentation/technical/api-directory-listing.txt */ - #include "cache.h" #include "strbuf.h" +/** + * The directory listing API is used to enumerate paths in the work tree, + * optionally taking `.git/info/exclude` and `.gitignore` files per directory + * into account. + */ + +/** + * Calling sequence + * ---------------- + * + * Note: index may be looked at for .gitignore files that are CE_SKIP_WORKTREE + * marked. If you to exclude files, make sure you have loaded index first. + * + * - Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0, + * sizeof(dir))`. + * + * - To add single exclude pattern, call `add_pattern_list()` and then + * `add_pattern()`. + * + * - To add patterns from a file (e.g. `.git/info/exclude`), call + * `add_patterns_from_file()` , and/or set `dir.exclude_per_dir`. A + * short-hand function `setup_standard_excludes()` can be used to set + * up the standard set of exclude settings. + * + * - Set options described in the Data Structure section above. + * + * - Call `read_directory()`. + * + * - Use `dir.entries[]`. + * + * - Call `clear_directory()` when none of the contained elements are no longer in use. + * + */ + struct dir_entry { unsigned int len; char name[FLEX_ARRAY]; /* more */ @@ -144,25 +176,101 @@ struct untracked_cache { unsigned int use_fsmonitor : 1; }; +/** + * pass directory traversal options to the library and to record the paths + * discovered. A single `struct dir_struct` is used regardless of whether or + * not the traversal recursively descends into subdirectories. + */ struct dir_struct { - int nr, alloc; - int ignored_nr, ignored_alloc; + + /* The number of members in `entries[]` array. */ + int nr; + + /* Internal use; keeps track of allocation of `entries[]` array.*/ + int alloc; + + /* The number of members in `ignored[]` array. */ + int ignored_nr; + + int ignored_alloc; + + /* bit-field of options */ enum { + + /** + * Return just ignored files in `entries[]`, not untracked files. + * This flag is mutually exclusive with `DIR_SHOW_IGNORED_TOO`. + */ DIR_SHOW_IGNORED = 1<<0, + + /* Include a directory that is not tracked. */ DIR_SHOW_OTHER_DIRECTORIES = 1<<1, + + /* Do not include a directory that is not tracked and is empty. */ DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, + + /** + * If set, recurse into a directory that looks like a Git directory. + * Otherwise it is shown as a directory. + */ DIR_NO_GITLINKS = 1<<3, + + /** + * Special mode for git-add. Return ignored files in `ignored[]` and + * untracked files in `entries[]`. Only returns ignored files that match + * pathspec exactly (no wildcards). Does not recurse into ignored + * directories. + */ DIR_COLLECT_IGNORED = 1<<4, + + /** + * Similar to `DIR_SHOW_IGNORED`, but return ignored files in + * `ignored[]` in addition to untracked files in `entries[]`. + * This flag is mutually exclusive with `DIR_SHOW_IGNORED`. + */ DIR_SHOW_IGNORED_TOO = 1<<5, + DIR_COLLECT_KILLED_ONLY = 1<<6, + + /** + * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is + * set, the untracked contents of untracked directories are also + * returned in `entries[]`. + */ DIR_KEEP_UNTRACKED_CONTENTS = 1<<7, + + /** + * Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is + * set, returns ignored files and directories that match an exclude + * pattern. If a directory matches an exclude pattern, then the + * directory is returned and the contained paths are not. A directory + * that does not match an exclude pattern will not be returned even if + * all of its contents are ignored. In this case, the contents are + * returned as individual entries. + * + * If this is set, files and directories that explicitly match an ignore + * pattern are reported. Implicitly ignored directories (directories that + * do not match an ignore pattern, but whose contents are all ignored) + * are not reported, instead all of the contents are reported. + */ DIR_SHOW_IGNORED_TOO_MODE_MATCHING = 1<<8, + DIR_SKIP_NESTED_GIT = 1<<9 } flags; + + /* An array of `struct dir_entry`, each element of which describes a path. */ struct dir_entry **entries; + + /** + * used for ignored paths with the `DIR_SHOW_IGNORED_TOO` and + * `DIR_COLLECT_IGNORED` flags. + */ struct dir_entry **ignored; - /* Exclude info */ + /** + * The name of the file to be read in each directory for excluded files + * (typically `.gitignore`). + */ const char *exclude_per_dir; /* From patchwork Tue Oct 29 10:00:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217531 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DB88315AB for ; Tue, 29 Oct 2019 10:00:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AC5E12087F for ; Tue, 29 Oct 2019 10:00:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="siwJhSBu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726538AbfJ2KAy (ORCPT ); Tue, 29 Oct 2019 06:00:54 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:42211 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726166AbfJ2KAx (ORCPT ); Tue, 29 Oct 2019 06:00:53 -0400 Received: by mail-wr1-f68.google.com with SMTP id a15so622755wrf.9 for ; Tue, 29 Oct 2019 03:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=maRAJuup5abJ1hJXrBJ5YMG/weYvOZoneGLFTTC2A8E=; b=siwJhSBuoexoIVXAicEMGhpgHIfnOku9+4YkQq4Ga1H51rqC9P4kHrTgbiKXCEJ0OU IbIASrmW6nnKqOF6C+oDnfDrQLTrS8w9lurLfiFnulVReEMzaGVnI2ak4sOo0GqYL/He 2D3UnmG53u/HmKaAnfrcE3w4K8hOsoWn+nGnLkihE10XCPS/BIJ8JoN/rqlekXtn1C/K pYjCqj+BPtvbdqzuiLDWEM0TlC+6tsxQPjobPGA1Kaxg41oE/RKB/tt4SzDNH2HAbcIo gYmkrvaT4IFUxvEBkRzoqK0ypIy61wTrCQWJQ8po7h6p9LR8H9y7rhvyM4OocfJNfsw2 3LKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=maRAJuup5abJ1hJXrBJ5YMG/weYvOZoneGLFTTC2A8E=; b=SprlxZhZdwErRt3COZmGtoU0eZDGBoE1KPo5h3RqxrOsjEr0x3HpkXWcIEl7cJRkzr w8uy+Pu3uCUIEsgc/NXMgzi02nM/58VIDvPLH1PhCzfE12bznybImN+7tJu8/pHl2NDp t56foG0GD4fOl7vZ7Rl8JcOxnXp9QpH9injc+dc/d/4aoiK2NwItchh6FmFnG4Udxh1R ODAneq8CPmiJjtwNbGWoQ3k/FGn2Sh+6JdDi/3si4XzvznfLqEBYU30dOPohTWjsmmYM G6pqmNWkwQ/G64Z4IOd1as+gPCzjh+uxOdq6vGyHfaIjEuGsPhNGyCPuwjE0TP0anKLZ CkZw== X-Gm-Message-State: APjAAAVGiGIobQK5aYhNHtOXDLEABXEV0FMKMGuMFrZMalLRi9HVtmbt HE0AAB5alsmagLMwkUNOQYQckVIJ X-Google-Smtp-Source: APXvYqz0i+pjNZ4G9kWxTAUfGbaK5OT7B7f52PiSdCOxs9XLAgDUHeUlXs63b7yIC3BtDdpuWvBBQA== X-Received: by 2002:adf:fcc7:: with SMTP id f7mr19462767wrs.345.1572343250563; Tue, 29 Oct 2019 03:00:50 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 11sm1657747wmb.34.2019.10.29.03.00.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:50 -0700 (PDT) Message-Id: In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:39 +0000 Subject: [PATCH 03/10] graph: move doc to graph.h and graph.c Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-history-graph.txt to graph.h and graph.c as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. The graph library was already well documented, so few comments were added to both graph.h and graph.c Also documentation/technical/api-history-graph.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-history-graph.txt | 173 ------------------ graph.c | 1 + graph.h | 121 ++++++++++++ 3 files changed, 122 insertions(+), 173 deletions(-) delete mode 100644 Documentation/technical/api-history-graph.txt diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt deleted file mode 100644 index d0d1707c8c..0000000000 --- a/Documentation/technical/api-history-graph.txt +++ /dev/null @@ -1,173 +0,0 @@ -history graph API -================= - -The graph API is used to draw a text-based representation of the commit -history. The API generates the graph in a line-by-line fashion. - -Functions ---------- - -Core functions: - -* `graph_init()` creates a new `struct git_graph` - -* `graph_update()` moves the graph to a new commit. - -* `graph_next_line()` outputs the next line of the graph into a strbuf. It - does not add a terminating newline. - -* `graph_padding_line()` outputs a line of vertical padding in the graph. It - is similar to `graph_next_line()`, but is guaranteed to never print the line - containing the current commit. Where `graph_next_line()` would print the - commit line next, `graph_padding_line()` prints a line that simply extends - all branch lines downwards one row, leaving their positions unchanged. - -* `graph_is_commit_finished()` determines if the graph has output all lines - necessary for the current commit. If `graph_update()` is called before all - lines for the current commit have been printed, the next call to - `graph_next_line()` will output an ellipsis, to indicate that a portion of - the graph was omitted. - -The following utility functions are wrappers around `graph_next_line()` and -`graph_is_commit_finished()`. They always print the output to stdout. -They can all be called with a NULL graph argument, in which case no graph -output will be printed. - -* `graph_show_commit()` calls `graph_next_line()` and - `graph_is_commit_finished()` until one of them return non-zero. This prints - all graph lines up to, and including, the line containing this commit. - Output is printed to stdout. The last line printed does not contain a - terminating newline. - -* `graph_show_oneline()` calls `graph_next_line()` and prints the result to - stdout. The line printed does not contain a terminating newline. - -* `graph_show_padding()` calls `graph_padding_line()` and prints the result to - stdout. The line printed does not contain a terminating newline. - -* `graph_show_remainder()` calls `graph_next_line()` until - `graph_is_commit_finished()` returns non-zero. Output is printed to stdout. - The last line printed does not contain a terminating newline. Returns 1 if - output was printed, and 0 if no output was necessary. - -* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all - lines but the first with a graph line. The caller is responsible for - ensuring graph output for the first line has already been printed to stdout. - (This can be done with `graph_show_commit()` or `graph_show_oneline()`.) If - a NULL graph is supplied, the strbuf is printed as-is. - -* `graph_show_commit_msg()` is similar to `graph_show_strbuf()`, but it also - prints the remainder of the graph, if more lines are needed after the strbuf - ends. It is better than directly calling `graph_show_strbuf()` followed by - `graph_show_remainder()` since it properly handles buffers that do not end in - a terminating newline. The output printed by `graph_show_commit_msg()` will - end in a newline if and only if the strbuf ends in a newline. - -Data structure --------------- -`struct git_graph` is an opaque data type used to store the current graph -state. - -Calling sequence ----------------- - -* Create a `struct git_graph` by calling `graph_init()`. When using the - revision walking API, this is done automatically by `setup_revisions()` if - the '--graph' option is supplied. - -* Use the revision walking API to walk through a group of contiguous commits. - The `get_revision()` function automatically calls `graph_update()` each time - it is invoked. - -* For each commit, call `graph_next_line()` repeatedly, until - `graph_is_commit_finished()` returns non-zero. Each call to - `graph_next_line()` will output a single line of the graph. The resulting - lines will not contain any newlines. `graph_next_line()` returns 1 if the - resulting line contains the current commit, or 0 if this is merely a line - needed to adjust the graph before or after the current commit. This return - value can be used to determine where to print the commit summary information - alongside the graph output. - -Limitations ------------ - -* `graph_update()` must be called with commits in topological order. It should - not be called on a commit if it has already been invoked with an ancestor of - that commit, or the graph output will be incorrect. - -* `graph_update()` must be called on a contiguous group of commits. If - `graph_update()` is called on a particular commit, it should later be called - on all parents of that commit. Parents must not be skipped, or the graph - output will appear incorrect. -+ -`graph_update()` may be used on a pruned set of commits only if the parent list -has been rewritten so as to include only ancestors from the pruned set. - -* The graph API does not currently support reverse commit ordering. In - order to implement reverse ordering, the graphing API needs an - (efficient) mechanism to find the children of a commit. - -Sample usage ------------- - ------------- -struct commit *commit; -struct git_graph *graph = graph_init(opts); - -while ((commit = get_revision(opts)) != NULL) { - while (!graph_is_commit_finished(graph)) - { - struct strbuf sb; - int is_commit_line; - - strbuf_init(&sb, 0); - is_commit_line = graph_next_line(graph, &sb); - fputs(sb.buf, stdout); - - if (is_commit_line) - log_tree_commit(opts, commit); - else - putchar(opts->diffopt.line_termination); - } -} ------------- - -Sample output -------------- - -The following is an example of the output from the graph API. This output does -not include any commit summary information--callers are responsible for -outputting that information, if desired. - ------------- -* -* -* -|\ -* | -| | * -| \ \ -| \ \ -*-. \ \ -|\ \ \ \ -| | * | | -| | | | | * -| | | | | * -| | | | | * -| | | | | |\ -| | | | | | * -| * | | | | | -| | | | | * \ -| | | | | |\ | -| | | | * | | | -| | | | * | | | -* | | | | | | | -| |/ / / / / / -|/| / / / / / -* | | | | | | -|/ / / / / / -* | | | | | -| | | | | * -| | | | |/ -| | | | * ------------- diff --git a/graph.c b/graph.c index f53135485f..eab3af1dc7 100644 --- a/graph.c +++ b/graph.c @@ -34,6 +34,7 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb); * handle directly. It is assumed that this is the same file handle as the * file specified by the graph diff options. This is necessary so that * graph_show_strbuf can be called even with a NULL graph. + * If a NULL graph is supplied, the strbuf is printed as-is. */ static void graph_show_strbuf(struct git_graph *graph, FILE *file, diff --git a/graph.h b/graph.h index af623390b6..8313e293c7 100644 --- a/graph.h +++ b/graph.h @@ -2,6 +2,103 @@ #define GRAPH_H #include "diff.h" +/** + * The graph API is used to draw a text-based representation of the commit + * history. The API generates the graph in a line-by-line fashion. + * + * Calling sequence + * ---------------- + * + * - Create a `struct git_graph` by calling `graph_init()`. When using the + * revision walking API, this is done automatically by `setup_revisions()` if + * the '--graph' option is supplied. + * + * - Use the revision walking API to walk through a group of contiguous commits. + * The `get_revision()` function automatically calls `graph_update()` each time + * it is invoked. + * + * - For each commit, call `graph_next_line()` repeatedly, until + * `graph_is_commit_finished()` returns non-zero. Each call to + * `graph_next_line()` will output a single line of the graph. The resulting + * lines will not contain any newlines. `graph_next_line()` returns 1 if the + * resulting line contains the current commit, or 0 if this is merely a line + * needed to adjust the graph before or after the current commit. This return + * value can be used to determine where to print the commit summary information + * alongside the graph output. + * + * Limitations + * ----------- + * - Check the graph_update() function for its limitations. + * + * - The graph API does not currently support reverse commit ordering. In + * order to implement reverse ordering, the graphing API needs an + * (efficient) mechanism to find the children of a commit. + * + * Sample usage + * ------------ + * + * ------------ + * struct commit *commit; + * struct git_graph *graph = graph_init(opts); + * + * while ((commit = get_revision(opts)) != NULL) { + * while (!graph_is_commit_finished(graph)) + * { + * struct strbuf sb; + * int is_commit_line; + * + * strbuf_init(&sb, 0); + * is_commit_line = graph_next_line(graph, &sb); + * fputs(sb.buf, stdout); + * + * if (is_commit_line) + * log_tree_commit(opts, commit); + * else + * putchar(opts->diffopt.line_termination); + * } + * } + * ------------ + * Sample output + * ------------- + * + * The following is an example of the output from the graph API. This output does + * not include any commit summary information--callers are responsible for + * outputting that information, if desired. + * ------------ + * * + * * + * * + * |\ + * * | + * | | * + * | \ \ + * | \ \ + * *-. \ \ + * |\ \ \ \ + * | | * | | + * | | | | | * + * | | | | | * + * | | | | | * + * | | | | | |\ + * | | | | | | * + * | * | | | | | + * | | | | | * \ + * | | | | | |\ | + * | | | | * | | | + * | | | | * | | | + * * | | | | | | | + * | |/ / / / / / + * |/| / / / / / + * * | | | | | | + * |/ / / / / / + * * | | | | | + * | | | | | * + * | | | | |/ + * | | | | * + * ------------ + * + */ + /* A graph is a pointer to this opaque structure */ struct git_graph; @@ -50,6 +147,21 @@ struct git_graph *graph_init(struct rev_info *opt); * If graph_update() is called before graph_is_commit_finished() returns 1, * the next call to graph_next_line() will output an ellipsis ("...") * to indicate that a portion of the graph is missing. + * + * Limitations: + * ----------- + * + * - `graph_update()` must be called with commits in topological order. It should + * not be called on a commit if it has already been invoked with an ancestor of + * that commit, or the graph output will be incorrect. + * + * - `graph_update()` must be called on a contiguous group of commits. If + * `graph_update()` is called on a particular commit, it should later be called + * on all parents of that commit. Parents must not be skipped, or the graph + * output will appear incorrect. + * + * - `graph_update()` may be used on a pruned set of commits only if the parent list + * has been rewritten so as to include only ancestors from the pruned set. */ void graph_update(struct git_graph *graph, struct commit *commit); @@ -62,6 +174,10 @@ void graph_update(struct git_graph *graph, struct commit *commit); * for this commit. If 0 is returned, graph_next_line() may still be * called without calling graph_update(), and it will merely output * appropriate "vertical padding" in the graph. + * + * If `graph_update()` is called before all lines for the current commit have + * been printed, the next call to `graph_next_line()` will output an ellipsis, + * to indicate that a portion of the graph was omitted. */ int graph_is_commit_finished(struct git_graph const *graph); @@ -112,6 +228,7 @@ void graph_show_padding(struct git_graph *graph); /* * If the graph is non-NULL, print the rest of the history graph for this * commit to stdout. Does not print a terminating newline on the last line. + * Returns 1 if output was printed, and 0 if no output was necessary. */ int graph_show_remainder(struct git_graph *graph); @@ -121,6 +238,10 @@ int graph_show_remainder(struct git_graph *graph); * This is similar to graph_show_strbuf(), but it always prints the * remainder of the graph. * + * It is better than directly calling `graph_show_strbuf()` followed by + * `graph_show_remainder()` since it properly handles buffers that do not end in + * a terminating newline. + * * If the strbuf ends with a newline, the output printed by * graph_show_commit_msg() will end with a newline. If the strbuf is * missing a terminating newline (including if it is empty), the output From patchwork Tue Oct 29 10:00:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217535 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 86BE61390 for ; Tue, 29 Oct 2019 10:00:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5A8622087F for ; Tue, 29 Oct 2019 10:00:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VjKpDafG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726979AbfJ2KA5 (ORCPT ); Tue, 29 Oct 2019 06:00:57 -0400 Received: from mail-wr1-f49.google.com ([209.85.221.49]:38494 "EHLO mail-wr1-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726287AbfJ2KAz (ORCPT ); Tue, 29 Oct 2019 06:00:55 -0400 Received: by mail-wr1-f49.google.com with SMTP id v9so12907572wrq.5 for ; Tue, 29 Oct 2019 03:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ZjbU42ohlXG4SEU8alLZNOejEwGyPxddDj3hVXSK4Wg=; b=VjKpDafG8SZ4REGmnKpCBvdMiLa19bSoJeP5HN48QfykEfFbhlcipCzcyH4+g3zhyb Q0ofvHFpIAtodmA9VK5G8xBsH88IDZWwMdP1TE8tMi8lKr0PPjd45g58i54OLzeCrTD8 +Xq78gkKP/EMVMlpImjCmapFKGFIFvCyjpxSuH4GITgeDTGjMKj6qbn5HVMQV4c64Dq0 /3mBZ9mTSzFq9gVNIj7+2h//zXWvHcOj8tgovV25pW+UZbx+yYjyuc6Jp1En65ulr4gt DJJhrpt7I9A0HcTNSBXeAXylkRc0nZm1ZDb/lH+wtwo6awlHVi4vYfkx2D00KdADCgcW WUQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ZjbU42ohlXG4SEU8alLZNOejEwGyPxddDj3hVXSK4Wg=; b=PzE6R3khycbOxzNx6V0IefVgGU6S0qpq0Wc+6Mq80pQFE/4rQwDtUlAaM7XPm4HFIg cjIpSiqPfIx/Spk7CRI/vJt/8HiAymHhyVNy9YzxpfKQxxZIG423Usln/51uqGC6YsgB xBACEb/+PBCreL5Kpqk/txdc9QO/yJQxpU2Ppj2RGcD5tMNveD0ozso7Fl5eSQp9DBJz GfI1To8L4Cbvr0n1tI/YXG2kJcDzjzrX+yN7PKZg+VblOfxEpwu/oZc+gYENU/A9ZQtp F4k74OyD36LTAMQEBLOcSHcn2O8ZxLgigJoXhoT0JfwQJSxeOVfnL1Ax5g9VUPsDK0NB yOTg== X-Gm-Message-State: APjAAAXdJA9XjczU3MZfn3Tq/mhAYVQVeLsvTjOxPEdjUh0Y17V8NEnN visSxutrF5wsJbqoJFjo3XH4nz2i X-Google-Smtp-Source: APXvYqwHfyLjZdFf/HXVu0VRDb7Dv9EAJEUwY6OEDo6Za4gxHTDwDoMIWqfXo1Yv++oUHMdUgOdlLg== X-Received: by 2002:adf:f684:: with SMTP id v4mr17905696wrp.336.1572343251257; Tue, 29 Oct 2019 03:00:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 74sm17133519wrm.92.2019.10.29.03.00.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:50 -0700 (PDT) Message-Id: <504f1f7c892c8bfc4774ac5fec912855e74e38a5.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:40 +0000 Subject: [PATCH 04/10] merge: move doc to ll-merge.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-merge.txt to ll-merge.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-merge.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-merge.txt | 104 -------------------------- ll-merge.h | 80 +++++++++++++++++++- 2 files changed, 79 insertions(+), 105 deletions(-) delete mode 100644 Documentation/technical/api-merge.txt diff --git a/Documentation/technical/api-merge.txt b/Documentation/technical/api-merge.txt deleted file mode 100644 index 9dc1bed768..0000000000 --- a/Documentation/technical/api-merge.txt +++ /dev/null @@ -1,104 +0,0 @@ -merge API -========= - -The merge API helps a program to reconcile two competing sets of -improvements to some files (e.g., unregistered changes from the work -tree versus changes involved in switching to a new branch), reporting -conflicts if found. The library called through this API is -responsible for a few things. - - * determining which trees to merge (recursive ancestor consolidation); - - * lining up corresponding files in the trees to be merged (rename - detection, subtree shifting), reporting edge cases like add/add - and rename/rename conflicts to the user; - - * performing a three-way merge of corresponding files, taking - path-specific merge drivers (specified in `.gitattributes`) - into account. - -Data structures ---------------- - -* `mmbuffer_t`, `mmfile_t` - -These store data usable for use by the xdiff backend, for writing and -for reading, respectively. See `xdiff/xdiff.h` for the definitions -and `diff.c` for examples. - -* `struct ll_merge_options` - -This describes the set of options the calling program wants to affect -the operation of a low-level (single file) merge. Some options: - -`virtual_ancestor`:: - Behave as though this were part of a merge between common - ancestors in a recursive merge. - If a helper program is specified by the - `[merge ""] recursive` configuration, it will - be used (see linkgit:gitattributes[5]). - -`variant`:: - Resolve local conflicts automatically in favor - of one side or the other (as in 'git merge-file' - `--ours`/`--theirs`/`--union`). Can be `0`, - `XDL_MERGE_FAVOR_OURS`, `XDL_MERGE_FAVOR_THEIRS`, or - `XDL_MERGE_FAVOR_UNION`. - -`renormalize`:: - Resmudge and clean the "base", "theirs" and "ours" files - before merging. Use this when the merge is likely to have - overlapped with a change in smudge/clean or end-of-line - normalization rules. - -Low-level (single file) merge ------------------------------ - -`ll_merge`:: - - Perform a three-way single-file merge in core. This is - a thin wrapper around `xdl_merge` that takes the path and - any merge backend specified in `.gitattributes` or - `.git/info/attributes` into account. Returns 0 for a - clean merge. - -Calling sequence: - -* Prepare a `struct ll_merge_options` to record options. - If you have no special requests, skip this and pass `NULL` - as the `opts` parameter to use the default options. - -* Allocate an mmbuffer_t variable for the result. - -* Allocate and fill variables with the file's original content - and two modified versions (using `read_mmfile`, for example). - -* Call `ll_merge()`. - -* Read the merged content from `result_buf.ptr` and `result_buf.size`. - -* Release buffers when finished. A simple - `free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); - free(result_buf.ptr);` will do. - -If the modifications do not merge cleanly, `ll_merge` will return a -nonzero value and `result_buf` will generally include a description of -the conflict bracketed by markers such as the traditional `<<<<<<<` -and `>>>>>>>`. - -The `ancestor_label`, `our_label`, and `their_label` parameters are -used to label the different sides of a conflict if the merge driver -supports this. - -Everything else ---------------- - -Talk about and merge_file(): - - - merge_trees() to merge with rename detection - - merge_recursive() for ancestor consolidation - - try_merge_command() for other strategies - - conflict format - - merge options - -(Daniel, Miklos, Stephan, JC) diff --git a/ll-merge.h b/ll-merge.h index e78973dd55..ec3617c627 100644 --- a/ll-merge.h +++ b/ll-merge.h @@ -7,16 +7,94 @@ #include "xdiff/xdiff.h" +/** + * The merge API helps a program to reconcile two competing sets of + * improvements to some files (e.g., unregistered changes from the work + * tree versus changes involved in switching to a new branch), reporting + * conflicts if found. The library called through this API is + * responsible for a few things. + * + * - determining which trees to merge (recursive ancestor consolidation); + * + * - lining up corresponding files in the trees to be merged (rename + * detection, subtree shifting), reporting edge cases like add/add + * and rename/rename conflicts to the user; + * + * - performing a three-way merge of corresponding files, taking + * path-specific merge drivers (specified in `.gitattributes`) + * into account. + * + * Calling sequence: + * ---------------- + * + * - Prepare a `struct ll_merge_options` to record options. + * If you have no special requests, skip this and pass `NULL` + * as the `opts` parameter to use the default options. + * + * - Allocate an mmbuffer_t variable for the result. + * + * - Allocate and fill variables with the file's original content + * and two modified versions (using `read_mmfile`, for example). + * + * - Call `ll_merge()`. + * + * - Read the merged content from `result_buf.ptr` and `result_buf.size`. + * + * - Release buffers when finished. A simple + * `free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); + * free(result_buf.ptr);` will do. + * + * If the modifications do not merge cleanly, `ll_merge` will return a + * nonzero value and `result_buf` will generally include a description of + * the conflict bracketed by markers such as the traditional `<<<<<<<` + * and `>>>>>>>`. + * + * The `ancestor_label`, `our_label`, and `their_label` parameters are + * used to label the different sides of a conflict if the merge driver + * supports this. + */ + + struct index_state; +/** + * This describes the set of options the calling program wants to affect + * the operation of a low-level (single file) merge. + */ struct ll_merge_options { + + /** + * Behave as though this were part of a merge between common ancestors in + * a recursive merge. If a helper program is specified by the + * `[merge ""] recursive` configuration, it will be used. + */ unsigned virtual_ancestor : 1; - unsigned variant : 2; /* favor ours, favor theirs, or union merge */ + + /** + * Resolve local conflicts automatically in favor of one side or the other + * (as in 'git merge-file' `--ours`/`--theirs`/`--union`). Can be `0`, + * `XDL_MERGE_FAVOR_OURS`, `XDL_MERGE_FAVOR_THEIRS`, + * or `XDL_MERGE_FAVOR_UNION`. + */ + unsigned variant : 2; + + /** + * Resmudge and clean the "base", "theirs" and "ours" files before merging. + * Use this when the merge is likely to have overlapped with a change in + * smudge/clean or end-of-line normalization rules. + */ unsigned renormalize : 1; + unsigned extra_marker_size; long xdl_opts; }; +/** + * Perform a three-way single-file merge in core. This is a thin wrapper + * around `xdl_merge` that takes the path and any merge backend specified in + * `.gitattributes` or `.git/info/attributes` into account. + * Returns 0 for a clean merge. + */ int ll_merge(mmbuffer_t *result_buf, const char *path, mmfile_t *ancestor, const char *ancestor_label, From patchwork Tue Oct 29 10:00:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217533 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3EDDC1390 for ; Tue, 29 Oct 2019 10:00:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C0CC2083E for ; Tue, 29 Oct 2019 10:00:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OIERy2im" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726708AbfJ2KAz (ORCPT ); Tue, 29 Oct 2019 06:00:55 -0400 Received: from mail-wr1-f52.google.com ([209.85.221.52]:36049 "EHLO mail-wr1-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726099AbfJ2KAy (ORCPT ); Tue, 29 Oct 2019 06:00:54 -0400 Received: by mail-wr1-f52.google.com with SMTP id w18so12932826wrt.3 for ; Tue, 29 Oct 2019 03:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=xXawFyU7upXqvr/vbNOTWiN1EjDFS8qw9umHTjSIxS0=; b=OIERy2immGmj7l3nrj81nAfixMZcIzxIC3d2ZssEnSc+XfBJsUd3BtNg7x6acKajL+ KkFyvGGShFPxewOrzxmNnwBv54TFS5fntuhzLlBA8slURde5xrXZUL1t7lwIriS7Z34C ortVMZeSR08qFG2KhucNtQeU5h3gVkcqVidRYRuu82kN1pr0hk16K6sSmdvwIdA7eQ73 32qEDcp44wwXl0IH9jCGr0EF4WgoJ08u6QuOTIjBYZUFPb00q14xlRjdGeJsUm7JuqId qW16mwi1tx0afeS6PFmFWw4mniOtscWmzyLf4JTlxQYmg536T+5XnxGonGPOJTjLjb8V Yx8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=xXawFyU7upXqvr/vbNOTWiN1EjDFS8qw9umHTjSIxS0=; b=Ww1Yre38C3cKiofacgwT4SSwaOw5Fiy6PXrmc7QGelJIhQTxvymFJVbB9hIJrUUIW7 YjoYMCjOvvcWXKbl5iwv4tH8TuACn4Kct6DmC2Oa9p1ur6pfm3MB5uj9/ojLTeQ0S1OB xGVlZCIZrID0JLe/RBUHVUugUZc2t90BIEotKWFot0i1irhXOehJbo1jtg7No6F7JGO6 0tg5HWyuqiGewgqiORkv4ZXg7HTQrs0iQTPz++nRc7LvXMAZIoBoPdQoO8jgxdEh3I3+ cJ4H/Dsq+IbqaMf6TaGLH08MFLEdAOBXfjQUMPgUD1KmAD6h8WQ+3YZ8MotqhBX5v8hU Di0Q== X-Gm-Message-State: APjAAAWYEofDGxyEa/urUyDmPPfKITEMBE3ba5MNkCXEzvZsojaXVVEZ VML+qJnxBADGG1lBttNhMUxiFF5Y X-Google-Smtp-Source: APXvYqx5xx224VsFQd8I0M9gAt9LLLsjn7Uhv81XhFLHTwp/9wk7iAZ8iIb3gtn/YCeEXXeA4vuMUQ== X-Received: by 2002:adf:e850:: with SMTP id d16mr18275837wrn.251.1572343251963; Tue, 29 Oct 2019 03:00:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p13sm2362804wma.41.2019.10.29.03.00.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:51 -0700 (PDT) Message-Id: <4302bdd13fcd5e6108c54c983397b0fa4949e2fa.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:41 +0000 Subject: [PATCH 05/10] sha1-array: move doc to sha1-array.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-oid-array.txt to sha1-array.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-oid-array.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-oid-array.txt | 90 ----------------------- sha1-array.h | 80 ++++++++++++++++++++ 2 files changed, 80 insertions(+), 90 deletions(-) delete mode 100644 Documentation/technical/api-oid-array.txt diff --git a/Documentation/technical/api-oid-array.txt b/Documentation/technical/api-oid-array.txt deleted file mode 100644 index c97428c2c3..0000000000 --- a/Documentation/technical/api-oid-array.txt +++ /dev/null @@ -1,90 +0,0 @@ -oid-array API -============== - -The oid-array API provides storage and manipulation of sets of object -identifiers. The emphasis is on storage and processing efficiency, -making them suitable for large lists. Note that the ordering of items is -not preserved over some operations. - -Data Structures ---------------- - -`struct oid_array`:: - - A single array of object IDs. This should be initialized by - assignment from `OID_ARRAY_INIT`. The `oid` member contains - the actual data. The `nr` member contains the number of items in - the set. The `alloc` and `sorted` members are used internally, - and should not be needed by API callers. - -Functions ---------- - -`oid_array_append`:: - Add an item to the set. The object ID will be placed at the end of - the array (but note that some operations below may lose this - ordering). - -`oid_array_lookup`:: - Perform a binary search of the array for a specific object ID. - If found, returns the offset (in number of elements) of the - object ID. If not found, returns a negative integer. If the array - is not sorted, this function has the side effect of sorting it. - -`oid_array_clear`:: - Free all memory associated with the array and return it to the - initial, empty state. - -`oid_array_for_each`:: - Iterate over each element of the list, executing the callback - function for each one. Does not sort the list, so any custom - hash order is retained. If the callback returns a non-zero - value, the iteration ends immediately and the callback's - return is propagated; otherwise, 0 is returned. - -`oid_array_for_each_unique`:: - Iterate over each unique element of the list in sorted order, - but otherwise behave like `oid_array_for_each`. If the array - is not sorted, this function has the side effect of sorting - it. - -`oid_array_filter`:: - Apply the callback function `want` to each entry in the array, - retaining only the entries for which the function returns true. - Preserve the order of the entries that are retained. - -Examples --------- - ------------------------------------------ -int print_callback(const struct object_id *oid, - void *data) -{ - printf("%s\n", oid_to_hex(oid)); - return 0; /* always continue */ -} - -void some_func(void) -{ - struct sha1_array hashes = OID_ARRAY_INIT; - struct object_id oid; - - /* Read objects into our set */ - while (read_object_from_stdin(oid.hash)) - oid_array_append(&hashes, &oid); - - /* Check if some objects are in our set */ - while (read_object_from_stdin(oid.hash)) { - if (oid_array_lookup(&hashes, &oid) >= 0) - printf("it's in there!\n"); - - /* - * Print the unique set of objects. We could also have - * avoided adding duplicate objects in the first place, - * but we would end up re-sorting the array repeatedly. - * Instead, this will sort once and then skip duplicates - * in linear time. - */ - oid_array_for_each_unique(&hashes, print_callback, NULL); -} ------------------------------------------ diff --git a/sha1-array.h b/sha1-array.h index 55d016c4bf..dc1bca9c9a 100644 --- a/sha1-array.h +++ b/sha1-array.h @@ -1,6 +1,52 @@ #ifndef SHA1_ARRAY_H #define SHA1_ARRAY_H +/** + * The API provides storage and manipulation of sets of object identifiers. + * The emphasis is on storage and processing efficiency, making them suitable + * for large lists. Note that the ordering of items is not preserved over some + * operations. + * + * Examples + * -------- + * ----------------------------------------- + * int print_callback(const struct object_id *oid, + * void *data) + * { + * printf("%s\n", oid_to_hex(oid)); + * return 0; // always continue + * } + * + * void some_func(void) + * { + * struct sha1_array hashes = OID_ARRAY_INIT; + * struct object_id oid; + * + * // Read objects into our set + * while (read_object_from_stdin(oid.hash)) + * oid_array_append(&hashes, &oid); + * + * // Check if some objects are in our set + * while (read_object_from_stdin(oid.hash)) { + * if (oid_array_lookup(&hashes, &oid) >= 0) + * printf("it's in there!\n"); + * + * // Print the unique set of objects. We could also have + * // avoided adding duplicate objects in the first place, + * // but we would end up re-sorting the array repeatedly. + * // Instead, this will sort once and then skip duplicates + * // in linear time. + * + * oid_array_for_each_unique(&hashes, print_callback, NULL); + * } + */ + +/** + * A single array of object IDs. This should be initialized by assignment from + * `OID_ARRAY_INIT`. The `oid` member contains the actual data. The `nr` member + * contains the number of items in the set. The `alloc` and `sorted` members + * are used internally, and should not be needed by API callers. + */ struct oid_array { struct object_id *oid; int nr; @@ -10,18 +56,52 @@ struct oid_array { #define OID_ARRAY_INIT { NULL, 0, 0, 0 } +/** + * Add an item to the set. The object ID will be placed at the end of the array + * (but note that some operations below may lose this ordering). + */ void oid_array_append(struct oid_array *array, const struct object_id *oid); + +/** + * Perform a binary search of the array for a specific object ID. If found, + * returns the offset (in number of elements) of the object ID. If not found, + * returns a negative integer. If the array is not sorted, this function has + * the side effect of sorting it. + */ int oid_array_lookup(struct oid_array *array, const struct object_id *oid); + +/** + * Free all memory associated with the array and return it to the initial, + * empty state. + */ void oid_array_clear(struct oid_array *array); typedef int (*for_each_oid_fn)(const struct object_id *oid, void *data); +/** + * Iterate over each element of the list, executing the callback function for + * each one. Does not sort the list, so any custom hash order is retained. + * If the callback returns a non-zero value, the iteration ends immediately + * and the callback's return is propagated; otherwise, 0 is returned. + */ int oid_array_for_each(struct oid_array *array, for_each_oid_fn fn, void *data); + +/** + * Iterate over each unique element of the list in sorted order, but otherwise + * behave like `oid_array_for_each`. If the array is not sorted, this function + * has the side effect of sorting it. + */ int oid_array_for_each_unique(struct oid_array *array, for_each_oid_fn fn, void *data); + +/** + * Apply the callback function `want` to each entry in the array, retaining + * only the entries for which the function returns true. Preserve the order + * of the entries that are retained. + */ void oid_array_filter(struct oid_array *array, for_each_oid_fn want, void *cbdata); From patchwork Tue Oct 29 10:00:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217543 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4838E1747 for ; Tue, 29 Oct 2019 10:01:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1AECB2083E for ; Tue, 29 Oct 2019 10:01:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Q9XGrqy+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726757AbfJ2KAz (ORCPT ); Tue, 29 Oct 2019 06:00:55 -0400 Received: from mail-wm1-f54.google.com ([209.85.128.54]:36895 "EHLO mail-wm1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726342AbfJ2KAy (ORCPT ); Tue, 29 Oct 2019 06:00:54 -0400 Received: by mail-wm1-f54.google.com with SMTP id q130so1692757wme.2 for ; Tue, 29 Oct 2019 03:00:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=12WZXDvSSSFUqF+tPHhMpooqo/fLyKCbw1DKsKakPTE=; b=Q9XGrqy+mfsGTSo+JUxfLPZjZZ5QkUiWlGOn/ISerB/r4+jxYOGKfx2n/5Y+a12NIJ DwJiJHWr8dAkNzo9eTKIcf7qdus/nAaLaW2a2A0aPKxjq9/UheP58CKWrd4MtnscDFAC TQJib0670N4USbZsXiiAZAjAnBuNZ9EXemmWW0Svvhlee8M54SJ99jJxatKqdHYUXMah UQjlFAmUaNChQJLIV75ZQ64qDwFqCfATWHXKKd90GR+WuA2beWosIKrbTpDMPMqG6QOw +UcQYo26obfCzPiNuL9wQWuup6nYW0/1DAo7p2D/Li1FFzEO/51yb/bc3XoG9JVE8oL/ JYvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=12WZXDvSSSFUqF+tPHhMpooqo/fLyKCbw1DKsKakPTE=; b=A1nb0C5uHj4XRHJhxjy6g5QckjBHLGdkU9GrUfwUYbUSU68DbXf4XZZy27aOuLdig0 ekcYT49eK25ndjYZj5u6+IAxTA8eWyJzk5gH7jXy+rutCtfITaHlz8P2dZ58BOVVwuaU q+Y49pNIm02fg6wQXpgE71YH7+sf18eiOeasnW1JNdf2Btj5eX1qqVZej+YHM3nQwNgt EhPo0tlrgH9P+IP1Ghvo6q6LfDTqfafJus/Uqh8VtJgi3MwHvVlwvgs2WpFA24Czz1fW ehBLtovE/pqnn/eAnmyVURuy5mjnN3fwSlugXpYkNkNMoDGWz7zWDXd7/GsumlW+lI1I UDUQ== X-Gm-Message-State: APjAAAW1RBw04zvJbtRenPxphP5tTt8JoHEE/vOcxPKCj9uBgaaAYN6r 8CIrCgBX3UX937Pp4UNlTU+eGnX3 X-Google-Smtp-Source: APXvYqwfskp/slbRr430h94OJD6CzhwEO1mjrcjz0Ekntxp/Pcw7QW2EAXed0++7H+0aLZvKsPGHfg== X-Received: by 2002:a1c:49d5:: with SMTP id w204mr3331589wma.111.1572343252560; Tue, 29 Oct 2019 03:00:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id p18sm2558212wmi.42.2019.10.29.03.00.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:52 -0700 (PDT) Message-Id: In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:42 +0000 Subject: [PATCH 06/10] remote: move doc to remote.h and refspec.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-remote.txt to remote.h and refspec.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. N.B. The doc for both push and fetch members of the remote struct aren't moved because they are out of date, as the members were changed from arrays of rspecs to struct refspec 2 years ago. Also documentation/technical/api-remote.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-remote.txt | 127 ------------------------- refspec.h | 16 ++++ remote.h | 57 ++++++++++- 3 files changed, 70 insertions(+), 130 deletions(-) delete mode 100644 Documentation/technical/api-remote.txt diff --git a/Documentation/technical/api-remote.txt b/Documentation/technical/api-remote.txt deleted file mode 100644 index f10941b2e8..0000000000 --- a/Documentation/technical/api-remote.txt +++ /dev/null @@ -1,127 +0,0 @@ -Remotes configuration API -========================= - -The API in remote.h gives access to the configuration related to -remotes. It handles all three configuration mechanisms historically -and currently used by Git, and presents the information in a uniform -fashion. Note that the code also handles plain URLs without any -configuration, giving them just the default information. - -struct remote -------------- - -`name`:: - - The user's nickname for the remote - -`url`:: - - An array of all of the url_nr URLs configured for the remote - -`pushurl`:: - - An array of all of the pushurl_nr push URLs configured for the remote - -`push`:: - - An array of refspecs configured for pushing, with - push_refspec being the literal strings, and push_refspec_nr - being the quantity. - -`fetch`:: - - An array of refspecs configured for fetching, with - fetch_refspec being the literal strings, and fetch_refspec_nr - being the quantity. - -`fetch_tags`:: - - The setting for whether to fetch tags (as a separate rule from - the configured refspecs); -1 means never to fetch tags, 0 - means to auto-follow tags based on the default heuristic, 1 - means to always auto-follow tags, and 2 means to fetch all - tags. - -`receivepack`, `uploadpack`:: - - The configured helper programs to run on the remote side, for - Git-native protocols. - -`http_proxy`:: - - The proxy to use for curl (http, https, ftp, etc.) URLs. - -`http_proxy_authmethod`:: - - The method used for authenticating against `http_proxy`. - -struct remotes can be found by name with remote_get(), and iterated -through with for_each_remote(). remote_get(NULL) will return the -default remote, given the current branch and configuration. - -struct refspec --------------- - -A struct refspec holds the parsed interpretation of a refspec. If it -will force updates (starts with a '+'), force is true. If it is a -pattern (sides end with '*') pattern is true. src and dest are the -two sides (including '*' characters if present); if there is only one -side, it is src, and dst is NULL; if sides exist but are empty (i.e., -the refspec either starts or ends with ':'), the corresponding side is -"". - -An array of strings can be parsed into an array of struct refspecs -using parse_fetch_refspec() or parse_push_refspec(). - -remote_find_tracking(), given a remote and a struct refspec with -either src or dst filled out, will fill out the other such that the -result is in the "fetch" specification for the remote (note that this -evaluates patterns and returns a single result). - -struct branch -------------- - -Note that this may end up moving to branch.h - -struct branch holds the configuration for a branch. It can be looked -up with branch_get(name) for "refs/heads/{name}", or with -branch_get(NULL) for HEAD. - -It contains: - -`name`:: - - The short name of the branch. - -`refname`:: - - The full path for the branch ref. - -`remote_name`:: - - The name of the remote listed in the configuration. - -`merge_name`:: - - An array of the "merge" lines in the configuration. - -`merge`:: - - An array of the struct refspecs used for the merge lines. That - is, merge[i]->dst is a local tracking ref which should be - merged into this branch by default. - -`merge_nr`:: - - The number of merge configurations - -branch_has_merge_config() returns true if the given branch has merge -configuration given. - -Other stuff ------------ - -There is other stuff in remote.h that is related, in general, to the -process of interacting with remotes. - -(Daniel Barkalow) diff --git a/refspec.h b/refspec.h index 9b6e64a824..3f2bd4aaa5 100644 --- a/refspec.h +++ b/refspec.h @@ -20,6 +20,22 @@ struct refspec_item { #define REFSPEC_INIT_FETCH { .fetch = REFSPEC_FETCH } #define REFSPEC_INIT_PUSH { .fetch = REFSPEC_PUSH } +/** + * A struct refspec holds the parsed interpretation of a refspec. If it will + * force updates (starts with a '+'), force is true. If it is a pattern + * (sides end with '*') pattern is true. src and dest are the two sides + * (including '*' characters if present); if there is only one side, it is src, + * and dst is NULL; if sides exist but are empty (i.e., the refspec either + * starts or ends with ':'), the corresponding side is "". + * + * An array of strings can be parsed into an array of struct refspecs using + * parse_fetch_refspec() or parse_push_refspec(). + * + * remote_find_tracking(), given a remote and a struct refspec with either src + * or dst filled out, will fill out the other such that the result is in the + * "fetch" specification for the remote (note that this evaluates patterns and + * returns a single result). + */ struct refspec { struct refspec_item *items; int alloc; diff --git a/remote.h b/remote.h index 0e1d2b245b..2277426199 100644 --- a/remote.h +++ b/remote.h @@ -6,6 +6,14 @@ #include "hashmap.h" #include "refspec.h" +/** + * The API gives access to the configuration related to remotes. It handles + * all three configuration mechanisms historically and currently used by Git, + * and presents the information in a uniform fashion. Note that the code also + * handles plain URLs without any configuration, giving them just the default + * information. + */ + enum { REMOTE_UNCONFIGURED = 0, REMOTE_CONFIG, @@ -16,16 +24,22 @@ enum { struct remote { struct hashmap_entry ent; + /* The user's nickname for the remote */ const char *name; + int origin, configured_in_repo; const char *foreign_vcs; + /* An array of all of the url_nr URLs configured for the remote */ const char **url; + int url_nr; int url_alloc; + /* An array of all of the pushurl_nr push URLs configured for the remote */ const char **pushurl; + int pushurl_nr; int pushurl_alloc; @@ -34,32 +48,47 @@ struct remote { struct refspec fetch; /* + * The setting for whether to fetch tags (as a separate rule from the + * configured refspecs); * -1 to never fetch tags * 0 to auto-follow tags on heuristic (default) * 1 to always auto-follow tags * 2 to always fetch tags */ int fetch_tags; + int skip_default_update; int mirror; int prune; int prune_tags; + /** + * The configured helper programs to run on the remote side, for + * Git-native protocols. + */ const char *receivepack; const char *uploadpack; - /* - * for curl remotes only - */ + /* The proxy to use for curl (http, https, ftp, etc.) URLs. */ char *http_proxy; + + /* The method used for authenticating against `http_proxy`. */ char *http_proxy_authmethod; }; +/** + * struct remotes can be found by name with remote_get(). + * remote_get(NULL) will return the default remote, given the current branch + * and configuration. + */ struct remote *remote_get(const char *name); + struct remote *pushremote_get(const char *name); int remote_is_configured(struct remote *remote, int in_repo); typedef int each_remote_fn(struct remote *remote, void *priv); + +/* iterate through struct remotes */ int for_each_remote(each_remote_fn fn, void *priv); int remote_has_url(struct remote *remote, const char *url); @@ -194,16 +223,36 @@ struct ref *get_remote_ref(const struct ref *remote_refs, const char *name); */ int remote_find_tracking(struct remote *remote, struct refspec_item *refspec); +/** + * struct branch holds the configuration for a branch. It can be looked up with + * branch_get(name) for "refs/heads/{name}", or with branch_get(NULL) for HEAD. + */ struct branch { + + /* The short name of the branch. */ const char *name; + + /* The full path for the branch ref. */ const char *refname; + /* The name of the remote listed in the configuration. */ const char *remote_name; + const char *pushremote_name; + /* An array of the "merge" lines in the configuration. */ const char **merge_name; + + /** + * An array of the struct refspecs used for the merge lines. That is, + * merge[i]->dst is a local tracking ref which should be merged into this + * branch by default. + */ struct refspec_item **merge; + + /* The number of merge configurations */ int merge_nr; + int merge_alloc; const char *push_tracking_ref; @@ -215,7 +264,9 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit); const char *remote_ref_for_branch(struct branch *branch, int for_push, int *explicit); +/* returns true if the given branch has merge configuration given. */ int branch_has_merge_config(struct branch *branch); + int branch_merge_matches(struct branch *, int n, const char *); /** From patchwork Tue Oct 29 10:00:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217541 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD5481390 for ; Tue, 29 Oct 2019 10:01:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A09482083E for ; Tue, 29 Oct 2019 10:01:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IsrexNd7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726851AbfJ2KA5 (ORCPT ); Tue, 29 Oct 2019 06:00:57 -0400 Received: from mail-wr1-f50.google.com ([209.85.221.50]:40935 "EHLO mail-wr1-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726510AbfJ2KAz (ORCPT ); Tue, 29 Oct 2019 06:00:55 -0400 Received: by mail-wr1-f50.google.com with SMTP id o28so12904686wro.7 for ; Tue, 29 Oct 2019 03:00:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=bIQFN7Giyzj0Cp3ZhrwOhNDIUw+bJ062AZKqqcec2l0=; b=IsrexNd73vqmX5joNlytDq2F4BC+T7uC/lJ6DtxhQc23h7YVCUVr4wgyBvY6DT/GYD jXI2/LVysLkSwDDBIY1n9a4Cg2kUV4Zf+z6aeLcEKkCDiQEm+BmShm47BhaMDKLCUdvQ bLDR3xJxkhihsiZBLfbHwDh3fBjYT38RWSOzCPI6SkUMW0cA6TDYO7c/+upUrCqJK9V7 3UYXVJgTjkfkZFa7xU4IbfFacXIzuDgqFtIt/QtVVoSWeZALVaPq7YUWO59ZMpxKKZJC Mlx3KrPpzi98t6X/DCbLYaqqCrnkesW96L8x30AHZ0q4egM7jCUOREwQswfFn2E0/OUC uljQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=bIQFN7Giyzj0Cp3ZhrwOhNDIUw+bJ062AZKqqcec2l0=; b=Umm9dGYeLbOEAyYVhx9SX1JD6b2mm97FttBTnaKrvtK+ib4V2SVvryexZJh0+kPMsa NjxvqfTDC3RddrMrG1xhRr9nhQibhcsb90RzjZ4oE5AuD3ZVevlk/WivPTFQO/Atj/oZ 5V6Jpev+mxbO5M/fYmsR1kr/F4s5b/oWn4tUB1aJU36KBCJN7K1DKASMDiE+nWZwLS7s cEOzv4r+GWJqYEbf/CWAWobuq4EFH+TEnZU/VCiqtSbl31mlWUkh84KUky6QnOHcjKDj sF4OwJc3Fa34Xio47niDMr4WnXVcLLRta6R+TeYAHYdXX4MTS2kWHEJxJ1261NZLgH6K t2Sg== X-Gm-Message-State: APjAAAUi2DTV/O3ItYzsrvrsYAitzTvwkAi7c6m2yS985MCswoSNfHZ2 NULie7xqE5ZfTwzWWfMvIljvc6z1 X-Google-Smtp-Source: APXvYqxZdWc9eCLntMqviB5iuAGUY6ZUeHWjuhCqgiDEbsBLRaemHSQUKmsKa6Y0bvka78BgTjJcmw== X-Received: by 2002:a5d:6a42:: with SMTP id t2mr18509830wrw.155.1572343253118; Tue, 29 Oct 2019 03:00:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id j14sm17155317wrj.35.2019.10.29.03.00.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:52 -0700 (PDT) Message-Id: <9c900c58a20de7b14c5944f0c09372697634f0dd.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:43 +0000 Subject: [PATCH 07/10] refs: move doc to refs.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-ref-iteration.txt to refs.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-ref-iteration.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-ref-iteration.txt | 78 ------------------- refs.h | 51 ++++++++++++ 2 files changed, 51 insertions(+), 78 deletions(-) delete mode 100644 Documentation/technical/api-ref-iteration.txt diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt deleted file mode 100644 index ad9d019ff9..0000000000 --- a/Documentation/technical/api-ref-iteration.txt +++ /dev/null @@ -1,78 +0,0 @@ -ref iteration API -================= - - -Iteration of refs is done by using an iterate function which will call a -callback function for every ref. The callback function has this -signature: - - int handle_one_ref(const char *refname, const struct object_id *oid, - int flags, void *cb_data); - -There are different kinds of iterate functions which all take a -callback of this type. The callback is then called for each found ref -until the callback returns nonzero. The returned value is then also -returned by the iterate function. - -Iteration functions -------------------- - -* `head_ref()` just iterates the head ref. - -* `for_each_ref()` iterates all refs. - -* `for_each_ref_in()` iterates all refs which have a defined prefix and - strips that prefix from the passed variable refname. - -* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`, - `for_each_replace_ref()` iterate refs from the respective area. - -* `for_each_glob_ref()` iterates all refs that match the specified glob - pattern. - -* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined. - -* Use `refs_` API for accessing submodules. The submodule ref store could - be obtained with `get_submodule_ref_store()`. - -* `for_each_rawref()` can be used to learn about broken ref and symref. - -* `for_each_reflog()` iterates each reflog file. - -Submodules ----------- - -If you want to iterate the refs of a submodule you first need to add the -submodules object database. You can do this by a code-snippet like -this: - - const char *path = "path/to/submodule" - if (add_submodule_odb(path)) - die("Error submodule '%s' not populated.", path); - -`add_submodule_odb()` will return zero on success. If you -do not do this you will get an error for each ref that it does not point -to a valid object. - -Note: As a side-effect of this you cannot safely assume that all -objects you lookup are available in superproject. All submodule objects -will be available the same way as the superprojects objects. - -Example: --------- - ----- -static int handle_remote_ref(const char *refname, - const unsigned char *sha1, int flags, void *cb_data) -{ - struct strbuf *output = cb_data; - strbuf_addf(output, "%s\n", refname); - return 0; -} - -... - - struct strbuf output = STRBUF_INIT; - for_each_remote_ref(handle_remote_ref, &output); - printf("%s", output.buf); ----- diff --git a/refs.h b/refs.h index 730d05ad91..545029c6d8 100644 --- a/refs.h +++ b/refs.h @@ -310,19 +310,35 @@ int refs_for_each_branch_ref(struct ref_store *refs, int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data); +/* just iterates the head ref. */ int head_ref(each_ref_fn fn, void *cb_data); + +/* iterates all refs. */ int for_each_ref(each_ref_fn fn, void *cb_data); + +/** + * iterates all refs which have a defined prefix and strips that prefix from + * the passed variable refname. + */ int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data); + int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken); int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken); + +/** + * iterate refs from the respective area. + */ int for_each_tag_ref(each_ref_fn fn, void *cb_data); int for_each_branch_ref(each_ref_fn fn, void *cb_data); int for_each_remote_ref(each_ref_fn fn, void *cb_data); int for_each_replace_ref(struct repository *r, each_repo_ref_fn fn, void *cb_data); + +/* iterates all refs that match the specified glob pattern. */ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data); + int for_each_glob_ref_in(each_ref_fn fn, const char *pattern, const char *prefix, void *cb_data); @@ -791,6 +807,41 @@ int reflog_expire(const char *refname, const struct object_id *oid, int ref_storage_backend_exists(const char *name); struct ref_store *get_main_ref_store(struct repository *r); + +/** + * Submodules + * ---------- + * + * If you want to iterate the refs of a submodule you first need to add the + * submodules object database. You can do this by a code-snippet like + * this: + * + * const char *path = "path/to/submodule" + * if (add_submodule_odb(path)) + * die("Error submodule '%s' not populated.", path); + * + * `add_submodule_odb()` will return zero on success. If you + * do not do this you will get an error for each ref that it does not point + * to a valid object. + * + * Note: As a side-effect of this you cannot safely assume that all + * objects you lookup are available in superproject. All submodule objects + * will be available the same way as the superprojects objects. + * + * Example: + * -------- + * + * ---- + * static int handle_remote_ref(const char *refname, + * const unsigned char *sha1, int flags, void *cb_data) + * { + * struct strbuf *output = cb_data; + * strbuf_addf(output, "%s\n", refname); + * return 0; + * } + * + */ + /* * Return the ref_store instance for the specified submodule. For the * main repository, use submodule==NULL; such a call cannot fail. For From patchwork Tue Oct 29 10:00:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217537 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EACF015AB for ; Tue, 29 Oct 2019 10:00:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BDE102083E for ; Tue, 29 Oct 2019 10:00:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="D+jva+FF" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726985AbfJ2KA5 (ORCPT ); Tue, 29 Oct 2019 06:00:57 -0400 Received: from mail-wr1-f51.google.com ([209.85.221.51]:36053 "EHLO mail-wr1-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725840AbfJ2KA4 (ORCPT ); Tue, 29 Oct 2019 06:00:56 -0400 Received: by mail-wr1-f51.google.com with SMTP id w18so12932961wrt.3 for ; Tue, 29 Oct 2019 03:00:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=CIlb7vhgvVx3vjpkNksrPt/9jqhoDqOBOGxQUnA8eKA=; b=D+jva+FFTWN3YcvjtGIc4AijeoBGopfzoM3/Y/ikCrDcXW8h0n1VAlvqtEsmaOl5ug gILpFI+fIVbdbsLfYoQ1SzGA6EOnwIgtmBFBo+hNxFeBtgCevTK9W3fmU5CBkdh9tgG3 jzmV4gfo0EzZ2qRMlIwfKoTcjrGrAouLynd6GLVHgV4MGw2nFqRA2bPZubTcn3TQXEo8 Xx3UCem/v8WZS9xMYFES+gwU3Gn7IHMLjrl39F0gOH4zIs8Qf6HChu6M1RZxXvIj3SAm DWNqfvFMCMKOy9bgcIwE+VzBvrjJaG2V+vmW8GF0UxxS4ANono+M7er3lUN+umkcCwNa SSng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=CIlb7vhgvVx3vjpkNksrPt/9jqhoDqOBOGxQUnA8eKA=; b=YCCncJUDaenlp3u5Gwt4pK6cUHJK/E4PQivLXiASWNkUg1EUW/jNrgsGTJyEkTgf3l +e2Ofe8vcKtaDniiULdbO0tXuoaDJb+9sYgbrm72kpdP5qWgi/4auDDooICNvpDIvjsS gVRTrihYTgjlEm0Qmwl2SF2M3vJDLfEgLbUiEIn+eaRw+Ukqiz+30Ee7HkiTjxkoaHF3 d8yU5x+kxtMS0H7xdxUvutbhfhjUioqQs5ABWB1filApoFSIjCP40uRFsrbbxlSOimJb WSVjQJmcwU9ZxUb3AYLIJGswjmYI3VrUwzrLAjGtSTj8fPDUhMdk4GsIrVWeO2YY1hwX bAKA== X-Gm-Message-State: APjAAAWz2LxDeEUPo30DfCaKN7nlNxaySqdDM4WIqDkCHj42JfLLjBot xjF/LvimcCnKHustPLS0IKOPm9Gc X-Google-Smtp-Source: APXvYqxGKDheyLu/NAEMfp2vm1CiAGuivLPrqmUnLlcOhpcoFpheUIlhs3ycE0bhb6F2TWexUCN3cw== X-Received: by 2002:a5d:63c1:: with SMTP id c1mr18135518wrw.332.1572343253914; Tue, 29 Oct 2019 03:00:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c8sm1936620wml.44.2019.10.29.03.00.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:53 -0700 (PDT) Message-Id: <052d4e5e56ae7b7d672579efc540d191a101bb2b.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:44 +0000 Subject: [PATCH 08/10] attr: move doc to attr.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-gitattributes.txt to attr.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-gitattributes.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-gitattributes.txt | 154 ------------------ attr.h | 141 +++++++++++++++- 2 files changed, 134 insertions(+), 161 deletions(-) delete mode 100644 Documentation/technical/api-gitattributes.txt diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt deleted file mode 100644 index 45f0df600f..0000000000 --- a/Documentation/technical/api-gitattributes.txt +++ /dev/null @@ -1,154 +0,0 @@ -gitattributes API -================= - -gitattributes mechanism gives a uniform way to associate various -attributes to set of paths. - - -Data Structure --------------- - -`struct git_attr`:: - - An attribute is an opaque object that is identified by its name. - Pass the name to `git_attr()` function to obtain the object of - this type. The internal representation of this structure is - of no interest to the calling programs. The name of the - attribute can be retrieved by calling `git_attr_name()`. - -`struct attr_check_item`:: - - This structure represents one attribute and its value. - -`struct attr_check`:: - - This structure represents a collection of `attr_check_item`. - It is passed to `git_check_attr()` function, specifying the - attributes to check, and receives their values. - - -Attribute Values ----------------- - -An attribute for a path can be in one of four states: Set, Unset, -Unspecified or set to a string, and `.value` member of `struct -attr_check_item` records it. There are three macros to check these: - -`ATTR_TRUE()`:: - - Returns true if the attribute is Set for the path. - -`ATTR_FALSE()`:: - - Returns true if the attribute is Unset for the path. - -`ATTR_UNSET()`:: - - Returns true if the attribute is Unspecified for the path. - -If none of the above returns true, `.value` member points at a string -value of the attribute for the path. - - -Querying Specific Attributes ----------------------------- - -* Prepare `struct attr_check` using attr_check_initl() - function, enumerating the names of attributes whose values you are - interested in, terminated with a NULL pointer. Alternatively, an - empty `struct attr_check` can be prepared by calling - `attr_check_alloc()` function and then attributes you want to - ask about can be added to it with `attr_check_append()` - function. - -* Call `git_check_attr()` to check the attributes for the path. - -* Inspect `attr_check` structure to see how each of the - attribute in the array is defined for the path. - - -Example -------- - -To see how attributes "crlf" and "ident" are set for different paths. - -. Prepare a `struct attr_check` with two elements (because - we are checking two attributes): - ------------- -static struct attr_check *check; -static void setup_check(void) -{ - if (check) - return; /* already done */ - check = attr_check_initl("crlf", "ident", NULL); -} ------------- - -. Call `git_check_attr()` with the prepared `struct attr_check`: - ------------- - const char *path; - - setup_check(); - git_check_attr(path, check); ------------- - -. Act on `.value` member of the result, left in `check->items[]`: - ------------- - const char *value = check->items[0].value; - - if (ATTR_TRUE(value)) { - The attribute is Set, by listing only the name of the - attribute in the gitattributes file for the path. - } else if (ATTR_FALSE(value)) { - The attribute is Unset, by listing the name of the - attribute prefixed with a dash - for the path. - } else if (ATTR_UNSET(value)) { - The attribute is neither set nor unset for the path. - } else if (!strcmp(value, "input")) { - If none of ATTR_TRUE(), ATTR_FALSE(), or ATTR_UNSET() is - true, the value is a string set in the gitattributes - file for the path by saying "attr=value". - } else if (... other check using value as string ...) { - ... - } ------------- - -To see how attributes in argv[] are set for different paths, only -the first step in the above would be different. - ------------- -static struct attr_check *check; -static void setup_check(const char **argv) -{ - check = attr_check_alloc(); - while (*argv) { - struct git_attr *attr = git_attr(*argv); - attr_check_append(check, attr); - argv++; - } -} ------------- - - -Querying All Attributes ------------------------ - -To get the values of all attributes associated with a file: - -* Prepare an empty `attr_check` structure by calling - `attr_check_alloc()`. - -* Call `git_all_attrs()`, which populates the `attr_check` - with the attributes attached to the path. - -* Iterate over the `attr_check.items[]` array to examine - the attribute names and values. The name of the attribute - described by an `attr_check.items[]` object can be retrieved via - `git_attr_name(check->items[i].attr)`. (Please note that no items - will be returned for unset attributes, so `ATTR_UNSET()` will return - false for all returned `attr_check.items[]` objects.) - -* Free the `attr_check` struct by calling `attr_check_free()`. diff --git a/attr.h b/attr.h index b0378bfe5f..404548f028 100644 --- a/attr.h +++ b/attr.h @@ -1,9 +1,121 @@ #ifndef ATTR_H #define ATTR_H +/** + * gitattributes mechanism gives a uniform way to associate various attributes + * to set of paths. + * + * + * Querying Specific Attributes + * ---------------------------- + * + * - Prepare `struct attr_check` using attr_check_initl() function, enumerating + * the names of attributes whose values you are interested in, terminated with + * a NULL pointer. Alternatively, an empty `struct attr_check` can be + * prepared by calling `attr_check_alloc()` function and then attributes you + * want to ask about can be added to it with `attr_check_append()` function. + * + * - Call `git_check_attr()` to check the attributes for the path. + * + * - Inspect `attr_check` structure to see how each of the attribute in the + * array is defined for the path. + * + * + * Example + * ------- + * + * To see how attributes "crlf" and "ident" are set for different paths. + * + * - Prepare a `struct attr_check` with two elements (because we are checking + * two attributes): + * + * ------------ + * static struct attr_check *check; + * static void setup_check(void) + * { + * if (check) + * return; // already done + * check = attr_check_initl("crlf", "ident", NULL); + * } + * ------------ + * + * - Call `git_check_attr()` with the prepared `struct attr_check`: + * + * ------------ + * const char *path; + * + * setup_check(); + * git_check_attr(path, check); + * ------------ + * + * - Act on `.value` member of the result, left in `check->items[]`: + * + * ------------ + * const char *value = check->items[0].value; + * + * if (ATTR_TRUE(value)) { + * The attribute is Set, by listing only the name of the + * attribute in the gitattributes file for the path. + * } else if (ATTR_FALSE(value)) { + * The attribute is Unset, by listing the name of the + * attribute prefixed with a dash - for the path. + * } else if (ATTR_UNSET(value)) { + * The attribute is neither set nor unset for the path. + * } else if (!strcmp(value, "input")) { + * If none of ATTR_TRUE(), ATTR_FALSE(), or ATTR_UNSET() is + * true, the value is a string set in the gitattributes + * file for the path by saying "attr=value". + * } else if (... other check using value as string ...) { + * ... + * } + * ------------ + * + * To see how attributes in argv[] are set for different paths, only + * the first step in the above would be different. + * + * ------------ + * static struct attr_check *check; + * static void setup_check(const char **argv) + * { + * check = attr_check_alloc(); + * while (*argv) { + * struct git_attr *attr = git_attr(*argv); + * attr_check_append(check, attr); + * argv++; + * } + * } + * ------------ + * + * + * Querying All Attributes + * ----------------------- + * + * To get the values of all attributes associated with a file: + * + * - Prepare an empty `attr_check` structure by calling `attr_check_alloc()`. + * + * - Call `git_all_attrs()`, which populates the `attr_check` with the + * attributes attached to the path. + * + * - Iterate over the `attr_check.items[]` array to examine the attribute + * names and values. The name of the attribute described by an + * `attr_check.items[]` object can be retrieved via + * `git_attr_name(check->items[i].attr)`. (Please note that no items will be + * returned for unset attributes, so `ATTR_UNSET()` will return false for all + * returned `attr_check.items[]` objects.) + * + * - Free the `attr_check` struct by calling `attr_check_free()`. + */ + struct index_state; -/* An attribute is a pointer to this opaque structure */ +/** + * An attribute is an opaque object that is identified by its name. Pass the + * name to `git_attr()` function to obtain the object of this type. + * The internal representation of this structure is of no interest to the + * calling programs. The name of the attribute can be retrieved by calling + * `git_attr_name()`. + */ struct git_attr; /* opaque structures used internally for attribute collection */ @@ -21,21 +133,36 @@ const struct git_attr *git_attr(const char *); extern const char git_attr__true[]; extern const char git_attr__false[]; -/* For public to check git_attr_check results */ +/** + * Attribute Values + * ---------------- + * + * An attribute for a path can be in one of four states: Set, Unset, Unspecified + * or set to a string, and `.value` member of `struct attr_check_item` records + * it. The three macros check these, if none of them returns true, `.value` + * member points at a string value of the attribute for the path. + */ + +/* Returns true if the attribute is Set for the path. */ #define ATTR_TRUE(v) ((v) == git_attr__true) + +/* Returns true if the attribute is Unset for the path. */ #define ATTR_FALSE(v) ((v) == git_attr__false) + +/* Returns true if the attribute is Unspecified for the path. */ #define ATTR_UNSET(v) ((v) == NULL) -/* - * Send one or more git_attr_check to git_check_attrs(), and - * each 'value' member tells what its value is. - * Unset one is returned as NULL. - */ +/* This structure represents one attribute and its value. */ struct attr_check_item { const struct git_attr *attr; const char *value; }; +/** + * This structure represents a collection of `attr_check_item`. It is passed to + * `git_check_attr()` function, specifying the attributes to check, and + * receives their values. + */ struct attr_check { int nr; int alloc; From patchwork Tue Oct 29 10:00:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217545 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5FD0D139A for ; Tue, 29 Oct 2019 10:01:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 323CB2083E for ; Tue, 29 Oct 2019 10:01:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="m5+2/Vdy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727060AbfJ2KBB (ORCPT ); Tue, 29 Oct 2019 06:01:01 -0400 Received: from mail-wr1-f50.google.com ([209.85.221.50]:34528 "EHLO mail-wr1-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726099AbfJ2KA4 (ORCPT ); Tue, 29 Oct 2019 06:00:56 -0400 Received: by mail-wr1-f50.google.com with SMTP id t16so12931275wrr.1 for ; Tue, 29 Oct 2019 03:00:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=/r3LV3ig26h2jE3K96c9klAmXlWRTCzKv5xNU6JF0nQ=; b=m5+2/Vdy7WWnMQDMiDVM+CKGDNxGg8U0tBEWyMRDRyAH2ymDk7ISGAZTcB2uvSQ8+E orVQIWET7SD8SMZX1IqlyxLZ8o843xzzC1GBitWZ1zAUrhxc4aVoGloP0mfv/N+DYJrt n/V5HfRK1cq4dxPfi+KUBQW/I2lV5m+EV3Ml5hefqShmVTP9aAgyG9nfYaKmvI0Y2aoY vV36XAu+VFDAWpkkMUhtuvZxbPAYlK6fkm0nKIdLi9aZjxEbTI4teHYAtLMFbXBexNJr RBzO1QbYXbi9zQlAhVVzBOK2W/qFjrvcRH+f9KJYmB60wI/OQjzGJJ1Jlzhlyuu7A1zK WHNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=/r3LV3ig26h2jE3K96c9klAmXlWRTCzKv5xNU6JF0nQ=; b=innX2ywCz1hmszrIkszgXcyjgFCshMcJl6YlzWuyA0SHr1UDAaJjrwkd3cBkJmroQf oxWGQzwHfzSFLrfbIFWJVx6bhFHDdDSYmKjvDWBnfmcz8IP1dSuWwaIFbHT6mHuSyPyG fxHjIkRAlmEs8u+vMDmZULJvj0CxTi/a9sIIjEH/gdkfJZTlV2g2+zFdK+gyrltS0rdh gIdWUKUKE6tMZ4oVMzVeYkSDibnvG3P1k0c1yF1g5yNOUDmLSAuZ7GUQxkeugfcoo2iy PunwaEOypZwpDTDRePjuhmEkW8MxkluQHrZBFTcVkLBGAr6bc1jUI4n58jM2C27PuoZ8 Ht1w== X-Gm-Message-State: APjAAAVQQ5SiIjHkK5KF75GNIQCuLEmvcfYZHqTP4s4VklS7Fjc5Pv/c pv+lvYZqmjSF2zcajrn67s5kAQnU X-Google-Smtp-Source: APXvYqyZoG3YQGixeRDS2YeSAKiPUmBRhzQW+cwaIVjZ+0PkLJVmqc9LIkEX0irYOU6mDkZHqiHy6Q== X-Received: by 2002:a5d:614b:: with SMTP id y11mr1524759wrt.374.1572343254555; Tue, 29 Oct 2019 03:00:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x8sm14795758wrr.43.2019.10.29.03.00.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:54 -0700 (PDT) Message-Id: In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:45 +0000 Subject: [PATCH 09/10] revision: move doc to revision.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-revision-walking.txt to revision.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-revision-walking.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly Reviewed-by: Emily Shaffer --- .../technical/api-revision-walking.txt | 72 ------------------- revision.h | 59 +++++++++++++++ 2 files changed, 59 insertions(+), 72 deletions(-) delete mode 100644 Documentation/technical/api-revision-walking.txt diff --git a/Documentation/technical/api-revision-walking.txt b/Documentation/technical/api-revision-walking.txt deleted file mode 100644 index 03f9ea6ac4..0000000000 --- a/Documentation/technical/api-revision-walking.txt +++ /dev/null @@ -1,72 +0,0 @@ -revision walking API -==================== - -The revision walking API offers functions to build a list of revisions -and then iterate over that list. - -Calling sequence ----------------- - -The walking API has a given calling sequence: first you need to -initialize a rev_info structure, then add revisions to control what kind -of revision list do you want to get, finally you can iterate over the -revision list. - -Functions ---------- - -`repo_init_revisions`:: - - Initialize a rev_info structure with default values. The third - parameter may be NULL or can be prefix path, and then the `.prefix` - variable will be set to it. This is typically the first function you - want to call when you want to deal with a revision list. After calling - this function, you are free to customize options, like set - `.ignore_merges` to 0 if you don't want to ignore merges, and so on. See - `revision.h` for a complete list of available options. - -`add_pending_object`:: - - This function can be used if you want to add commit objects as revision - information. You can use the `UNINTERESTING` object flag to indicate if - you want to include or exclude the given commit (and commits reachable - from the given commit) from the revision list. -+ -NOTE: If you have the commits as a string list then you probably want to -use setup_revisions(), instead of parsing each string and using this -function. - -`setup_revisions`:: - - Parse revision information, filling in the `rev_info` structure, and - removing the used arguments from the argument list. Returns the number - of arguments left that weren't recognized, which are also moved to the - head of the argument list. The last parameter is used in case no - parameter given by the first two arguments. - -`prepare_revision_walk`:: - - Prepares the rev_info structure for a walk. You should check if it - returns any error (non-zero return code) and if it does not, you can - start using get_revision() to do the iteration. - -`get_revision`:: - - Takes a pointer to a `rev_info` structure and iterates over it, - returning a `struct commit *` each time you call it. The end of the - revision list is indicated by returning a NULL pointer. - -`reset_revision_walk`:: - - Reset the flags used by the revision walking api. You can use - this to do multiple sequential revision walks. - -Data structures ---------------- - -Talk about , things like: - -* two diff_options, one for path limiting, another for output; -* remaining functions; - -(Linus, JC, Dscho) diff --git a/revision.h b/revision.h index 4134dc6029..983ffc0f12 100644 --- a/revision.h +++ b/revision.h @@ -9,6 +9,19 @@ #include "diff.h" #include "commit-slab-decl.h" +/** + * The revision walking API offers functions to build a list of revisions + * and then iterate over that list. + * + * Calling sequence + * ---------------- + * + * The walking API has a given calling sequence: first you need to initialize + * a rev_info structure, then add revisions to control what kind of revision + * list do you want to get, finally you can iterate over the revision list. + * + */ + /* Remember to update object flag allocation in object.h */ #define SEEN (1u<<0) #define UNINTERESTING (1u<<1) @@ -306,11 +319,29 @@ struct setup_revision_opt { #ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS #define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix) #endif + +/** + * Initialize a rev_info structure with default values. The third parameter may + * be NULL or can be prefix path, and then the `.prefix` variable will be set + * to it. This is typically the first function you want to call when you want + * to deal with a revision list. After calling this function, you are free to + * customize options, like set `.ignore_merges` to 0 if you don't want to + * ignore merges, and so on. + */ void repo_init_revisions(struct repository *r, struct rev_info *revs, const char *prefix); + +/** + * Parse revision information, filling in the `rev_info` structure, and + * removing the used arguments from the argument list. Returns the number + * of arguments left that weren't recognized, which are also moved to the + * head of the argument list. The last parameter is used in case no + * parameter given by the first two arguments. + */ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *); + void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, const struct option *options, const char * const usagestr[]); @@ -319,9 +350,26 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt); +/** + * Reset the flags used by the revision walking api. You can use this to do + * multiple sequential revision walks. + */ void reset_revision_walk(void); + +/** + * Prepares the rev_info structure for a walk. You should check if it returns + * any error (non-zero return code) and if it does not, you can start using + * get_revision() to do the iteration. + */ int prepare_revision_walk(struct rev_info *revs); + +/** + * Takes a pointer to a `rev_info` structure and iterates over it, returning a + * `struct commit *` each time you call it. The end of the revision list is + * indicated by returning a NULL pointer. + */ struct commit *get_revision(struct rev_info *revs); + char *get_revision_mark(const struct rev_info *revs, const struct commit *commit); void put_revision_mark(const struct rev_info *revs, @@ -333,8 +381,19 @@ void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees) void show_object_with_name(FILE *, struct object *, const char *); +/** + * This function can be used if you want to add commit objects as revision + * information. You can use the `UNINTERESTING` object flag to indicate if + * you want to include or exclude the given commit (and commits reachable + * from the given commit) from the revision list. + * + * NOTE: If you have the commits as a string list then you probably want to + * use setup_revisions(), instead of parsing each string and using this + * function. + */ void add_pending_object(struct rev_info *revs, struct object *obj, const char *name); + void add_pending_oid(struct rev_info *revs, const char *name, const struct object_id *oid, unsigned int flags); From patchwork Tue Oct 29 10:00:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11217539 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 78F5A1390 for ; Tue, 29 Oct 2019 10:00:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 562E72087F for ; Tue, 29 Oct 2019 10:00:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Bq/X2gag" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727021AbfJ2KA6 (ORCPT ); Tue, 29 Oct 2019 06:00:58 -0400 Received: from mail-wm1-f53.google.com ([209.85.128.53]:36900 "EHLO mail-wm1-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726833AbfJ2KA5 (ORCPT ); Tue, 29 Oct 2019 06:00:57 -0400 Received: by mail-wm1-f53.google.com with SMTP id q130so1692917wme.2 for ; Tue, 29 Oct 2019 03:00:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=WlammgDF0L+1RNwpwU1Hv0Eo8cOXgnk5/hW7BCWo5IU=; b=Bq/X2gagwmD7IDCmU6s0RkveJZzRtftZGcz87nmC7CxonMt9v+OoAmj/MMdaD84S/6 znCsgljukqUy3h70zyXTyG+DpWGIrJX/AnneJW+H42odKJRIzej1QtRdCswJPGdZxPwv H0wvH419ZkTusS6RH1VlmedGo/8hptyIWVjVBdstZqB7a+O+jYGc97H0TtyiMUD9P48H JXA+E6xWMNzJ2Rvm1In52qoPUzkcD1kpbW9k/yqjZJCi3OMovgiQ3oAfZzA8Bc0z088K j1EjovdJ4amBXcOQN7lG+oXxLjGXcx1TAVWJ2b+RF/T1nMkZkMlobpaRXAGLuicqm8ZT VBcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=WlammgDF0L+1RNwpwU1Hv0Eo8cOXgnk5/hW7BCWo5IU=; b=JyvQNnI2bKq8PyHnhZCqVdWYYCu4JqEMYXBVCJ043lEzXG35gOmJVfW8zz/umweOf9 oaLA0nM0R/ezJJD29prc9KtIz2LMaZtgGcBgOSKXT6435MVi3P8MsocNpiNCZWjvhL6/ IEI6Ho3qHOLWzFbpXyYtDHGyH3A6NG+FPg6TRZcn3gpYX2oNXKrg5E5uvdJF0o+r/qhd KIhZ1AFGm6UtUPn46KTrQYTvfl9Kwqc9nmNXQwQEqAuGDAyBySLE06DhhZeUIECo0cuG wPw7IM3e3Hd+f6DzAVKK4wofS7RNkUKeHFhOBmoC3bp0tbwuFy13lkrro8zB7PhZM9Ug 7CCQ== X-Gm-Message-State: APjAAAUVQqCQ6hkN1866/JuNKxbroo+u/tU1NJUKYMY/w00UbOqVt1Wc eqWtfQOrt9RQFewk8HipW6Tcw8mi X-Google-Smtp-Source: APXvYqyZgiemWxWkKhXd/S3GZO+Aokx9apLpoEFdih8YqC4r0h9Lm2MPx6rkt/ZLQIpLVRG3QFle7w== X-Received: by 2002:a1c:7dd8:: with SMTP id y207mr2050234wmc.12.1572343255342; Tue, 29 Oct 2019 03:00:55 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 6sm2745580wmd.36.2019.10.29.03.00.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Oct 2019 03:00:54 -0700 (PDT) Message-Id: <575721694957bc7532147573f4f3cac4443257b3.1572343246.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Heba Waly via GitGitGadget" Date: Tue, 29 Oct 2019 10:00:46 +0000 Subject: [PATCH 10/10] pathspec: move doc to pathspec.h Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Heba Waly , Junio C Hamano , Heba Waly Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Heba Waly Move the documentation from Documentation/technical/api-setup.txt to pathspec.h as it's easier for the developers to find the usage information beside the code instead of looking for it in another doc file. Also documentation/technical/api-setup.txt is removed because the information it has is now redundant and it'll be hard to keep it up to date and synchronized with the documentation in the header file. Signed-off-by: Heba Waly --- Documentation/technical/api-setup.txt | 47 --------------------------- pathspec.h | 34 ++++++++++++++++++- 2 files changed, 33 insertions(+), 48 deletions(-) delete mode 100644 Documentation/technical/api-setup.txt diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt deleted file mode 100644 index eb1fa9853e..0000000000 --- a/Documentation/technical/api-setup.txt +++ /dev/null @@ -1,47 +0,0 @@ -setup API -========= - -Talk about - -* setup_git_directory() -* setup_git_directory_gently() -* is_inside_git_dir() -* is_inside_work_tree() -* setup_work_tree() - -(Dscho) - -Pathspec --------- - -See glossary-context.txt for the syntax of pathspec. In memory, a -pathspec set is represented by "struct pathspec" and is prepared by -parse_pathspec(). This function takes several arguments: - -- magic_mask specifies what features that are NOT supported by the - following code. If a user attempts to use such a feature, - parse_pathspec() can reject it early. - -- flags specifies other things that the caller wants parse_pathspec to - perform. - -- prefix and args come from cmd_* functions - -parse_pathspec() helps catch unsupported features and reject them -politely. At a lower level, different pathspec-related functions may -not support the same set of features. Such pathspec-sensitive -functions are guarded with GUARD_PATHSPEC(), which will die in an -unfriendly way when an unsupported feature is requested. - -The command designers are supposed to make sure that GUARD_PATHSPEC() -never dies. They have to make sure all unsupported features are caught -by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC() -should give the designers all pathspec-sensitive codepaths and what -features they support. - -A similar process is applied when a new pathspec magic is added. The -designer lifts the GUARD_PATHSPEC restriction in the functions that -support the new magic. At the same time (s)he has to make sure this -new feature will be caught at parse_pathspec() in commands that cannot -handle the new magic in some cases. grepping parse_pathspec() should -help. diff --git a/pathspec.h b/pathspec.h index 1c18a2c90c..0fbd7a051d 100644 --- a/pathspec.h +++ b/pathspec.h @@ -22,6 +22,10 @@ struct index_state; #define PATHSPEC_ONESTAR 1 /* the pathspec pattern satisfies GFNM_ONESTAR */ +/** + * In memory, a pathspec set is represented by "struct pathspec" and is + * prepared by parse_pathspec(). + */ struct pathspec { int nr; unsigned int has_wildcard:1; @@ -73,18 +77,46 @@ struct pathspec { */ #define PATHSPEC_LITERAL_PATH (1<<6) -/* +/** * Given command line arguments and a prefix, convert the input to * pathspec. die() if any magic in magic_mask is used. * * Any arguments used are copied. It is safe for the caller to modify * or free 'prefix' and 'args' after calling this function. + * + * - magic_mask specifies what features that are NOT supported by the following + * code. If a user attempts to use such a feature, parse_pathspec() can reject + * it early. + * + * - flags specifies other things that the caller wants parse_pathspec to + * perform. + * + * - prefix and args come from cmd_* functions + * + * parse_pathspec() helps catch unsupported features and reject them politely. + * At a lower level, different pathspec-related functions may not support the + * same set of features. Such pathspec-sensitive functions are guarded with + * GUARD_PATHSPEC(), which will die in an unfriendly way when an unsupported + * feature is requested. + * + * The command designers are supposed to make sure that GUARD_PATHSPEC() never + * dies. They have to make sure all unsupported features are caught by + * parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC() should + * give the designers all pathspec-sensitive codepaths and what features they + * support. + * + * A similar process is applied when a new pathspec magic is added. The designer + * lifts the GUARD_PATHSPEC restriction in the functions that support the new + * magic. At the same time (s)he has to make sure this new feature will be + * caught at parse_pathspec() in commands that cannot handle the new magic in + * some cases. grepping parse_pathspec() should help. */ void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask, unsigned flags, const char *prefix, const char **args); + void copy_pathspec(struct pathspec *dst, const struct pathspec *src); void clear_pathspec(struct pathspec *);