@@ -41,21 +41,21 @@ COMMANDS
Write a commit-graph file based on the commits found in packfiles.
+
-With the `--stdin-packs` option, generate the new commit graph by
+With the `--input=stdin-packs` option, generate the new commit graph by
walking objects only in the specified pack-indexes. (Cannot be combined
-with `--stdin-commits` or `--reachable`.)
+with `--input=stdin-commits` or `--input=reachable`.)
+
-With the `--stdin-commits` option, generate the new commit graph by
-walking commits starting at the commits specified in stdin as a list
+With the `--input=stdin-commits` option, generate the new commit graph
+by walking commits starting at the commits specified in stdin as a list
of OIDs in hex, one OID per line. (Cannot be combined with
-`--stdin-packs` or `--reachable`.)
+`--input=stdin-packs` or `--input=reachable`.)
+
-With the `--reachable` option, generate the new commit graph by walking
-commits starting at all refs. (Cannot be combined with `--stdin-commits`
-or `--stdin-packs`.)
+With the `--input=reachable` option, generate the new commit graph by
+walking commits starting at all refs. (Cannot be combined with
+`--input=stdin-commits` or `--input=stdin-packs`.)
+
-With the `--append` option, include all commits that are present in the
-existing commit-graph file.
+With the `--input=append` option, include all commits that are present
+in the existing commit-graph file.
+
With the `--split[=<strategy>]` option, write the commit-graph as a
chain of multiple commit-graph files stored in
@@ -105,20 +105,20 @@ $ git commit-graph write
using commits in `<pack-index>`.
+
------------------------------------------------
-$ echo <pack-index> | git commit-graph write --stdin-packs
+$ echo <pack-index> | git commit-graph write --input=stdin-packs
------------------------------------------------
* Write a commit-graph file containing all reachable commits.
+
------------------------------------------------
-$ git show-ref -s | git commit-graph write --stdin-commits
+$ git show-ref -s | git commit-graph write --input=stdin-commits
------------------------------------------------
* Write a commit-graph file containing all commits in the current
commit-graph file along with those reachable from `HEAD`.
+
------------------------------------------------
-$ git rev-parse HEAD | git commit-graph write --stdin-commits --append
+$ git rev-parse HEAD | git commit-graph write --input=stdin-commits --input=append
------------------------------------------------
@@ -9,8 +9,9 @@
static char const * const builtin_commit_graph_usage[] = {
N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
- N_("git commit-graph write [--object-dir <objdir>] [--append] "
- "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
+ N_("git commit-graph write [--object-dir <objdir>] "
+ "[--split[=<strategy>]] "
+ "[--input=<reachable|stdin-packs|stdin-commits|append>] "
"[--[no-]progress] <split options>"),
NULL
};
@@ -21,18 +22,23 @@ static const char * const builtin_commit_graph_verify_usage[] = {
};
static const char * const builtin_commit_graph_write_usage[] = {
- N_("git commit-graph write [--object-dir <objdir>] [--append] "
- "[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
+ N_("git commit-graph write [--object-dir <objdir>] "
+ "[--split[=<strategy>]] "
+ "[--input=<reachable|stdin-packs|stdin-commits|append>] "
"[--[no-]progress] <split options>"),
NULL
};
+enum commit_graph_input {
+ COMMIT_GRAPH_INPUT_REACHABLE = (1 << 1),
+ COMMIT_GRAPH_INPUT_STDIN_PACKS = (1 << 2),
+ COMMIT_GRAPH_INPUT_STDIN_COMMITS = (1 << 3),
+ COMMIT_GRAPH_INPUT_APPEND = (1 << 4)
+};
+
static struct opts_commit_graph {
const char *obj_dir;
- int reachable;
- int stdin_packs;
- int stdin_commits;
- int append;
+ enum commit_graph_input input;
int split;
int shallow;
int progress;
@@ -57,6 +63,28 @@ static struct object_directory *find_odb(struct repository *r,
return odb;
}
+static int option_parse_input(const struct option *opt, const char *arg,
+ int unset)
+{
+ enum commit_graph_input *to = opt->value;
+ if (unset || !strcmp(arg, "packs")) {
+ *to = 0;
+ return 0;
+ }
+
+ if (!strcmp(arg, "reachable"))
+ *to |= COMMIT_GRAPH_INPUT_REACHABLE;
+ else if (!strcmp(arg, "stdin-packs"))
+ *to |= COMMIT_GRAPH_INPUT_STDIN_PACKS;
+ else if (!strcmp(arg, "stdin-commits"))
+ *to |= COMMIT_GRAPH_INPUT_STDIN_COMMITS;
+ else if (!strcmp(arg, "append"))
+ *to |= COMMIT_GRAPH_INPUT_APPEND;
+ else
+ die(_("unrecognized --input source, %s"), arg);
+ return 0;
+}
+
static int graph_verify(int argc, const char **argv)
{
struct commit_graph *graph = NULL;
@@ -149,14 +177,21 @@ static int graph_write(int argc, const char **argv)
OPT_STRING(0, "object-dir", &opts.obj_dir,
N_("dir"),
N_("The object directory to store the graph")),
- OPT_BOOL(0, "reachable", &opts.reachable,
- N_("start walk at all refs")),
- OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
- N_("scan pack-indexes listed by stdin for commits")),
- OPT_BOOL(0, "stdin-commits", &opts.stdin_commits,
- N_("start walk at commits listed by stdin")),
- OPT_BOOL(0, "append", &opts.append,
- N_("include all commits already in the commit-graph file")),
+ OPT_CALLBACK(0, "input", &opts.input, NULL,
+ N_("include commits from this source in the graph"),
+ option_parse_input),
+ OPT_BIT(0, "reachable", &opts.input,
+ N_("start walk at all refs"),
+ COMMIT_GRAPH_INPUT_REACHABLE),
+ OPT_BIT(0, "stdin-packs", &opts.input,
+ N_("scan pack-indexes listed by stdin for commits"),
+ COMMIT_GRAPH_INPUT_STDIN_PACKS),
+ OPT_BIT(0, "stdin-commits", &opts.input,
+ N_("start walk at commits listed by stdin"),
+ COMMIT_GRAPH_INPUT_STDIN_COMMITS),
+ OPT_BIT(0, "append", &opts.input,
+ N_("include all commits already in the commit-graph file"),
+ COMMIT_GRAPH_INPUT_APPEND),
OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
OPT_CALLBACK_F(0, "split", &split_opts.flags, NULL,
N_("allow writing an incremental commit-graph file"),
@@ -182,11 +217,13 @@ static int graph_write(int argc, const char **argv)
builtin_commit_graph_write_options,
builtin_commit_graph_write_usage, 0);
- if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1)
- die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
+ if ((!!(opts.input & COMMIT_GRAPH_INPUT_REACHABLE) +
+ !!(opts.input & COMMIT_GRAPH_INPUT_STDIN_PACKS) +
+ !!(opts.input & COMMIT_GRAPH_INPUT_STDIN_COMMITS)) > 1)
+ die(_("use at most one of --input=reachable, --input=stdin-commits, or --input=stdin-packs"));
if (!opts.obj_dir)
opts.obj_dir = get_object_directory();
- if (opts.append)
+ if (opts.input & COMMIT_GRAPH_INPUT_APPEND)
flags |= COMMIT_GRAPH_WRITE_APPEND;
if (opts.split)
flags |= COMMIT_GRAPH_WRITE_SPLIT;
@@ -196,22 +233,22 @@ static int graph_write(int argc, const char **argv)
read_replace_refs = 0;
odb = find_odb(the_repository, opts.obj_dir);
- if (opts.reachable) {
+ if (opts.input & COMMIT_GRAPH_INPUT_REACHABLE) {
if (write_commit_graph_reachable(odb, flags, &split_opts))
return 1;
return 0;
}
string_list_init(&lines, 0);
- if (opts.stdin_packs || opts.stdin_commits) {
+ if (opts.input & (COMMIT_GRAPH_INPUT_STDIN_PACKS | COMMIT_GRAPH_INPUT_STDIN_COMMITS)) {
struct strbuf buf = STRBUF_INIT;
while (strbuf_getline(&buf, stdin) != EOF)
string_list_append(&lines, strbuf_detach(&buf, NULL));
- if (opts.stdin_packs)
+ if (opts.input & COMMIT_GRAPH_INPUT_STDIN_PACKS)
pack_indexes = &lines;
- if (opts.stdin_commits) {
+ if (opts.input & COMMIT_GRAPH_INPUT_STDIN_COMMITS) {
commit_hex = &lines;
flags |= COMMIT_GRAPH_WRITE_CHECK_OIDS;
}
@@ -227,7 +227,7 @@ graph_git_behavior 'cleared graph, commit 8 vs merge 2' full commits/8 merge/2
test_expect_success 'build graph from latest pack with closure' '
cd "$TRASH_DIRECTORY/full" &&
- cat new-idx | git commit-graph write --stdin-packs &&
+ cat new-idx | git commit-graph write --input=stdin-packs &&
test_path_is_file $objdir/info/commit-graph &&
graph_read_expect "9" "extra_edges"
'
@@ -240,7 +240,7 @@ test_expect_success 'build graph from commits with closure' '
git tag -a -m "merge" tag/merge merge/2 &&
git rev-parse tag/merge >commits-in &&
git rev-parse merge/1 >>commits-in &&
- cat commits-in | git commit-graph write --stdin-commits &&
+ cat commits-in | git commit-graph write --input=stdin-commits &&
test_path_is_file $objdir/info/commit-graph &&
graph_read_expect "6"
'
@@ -35,7 +35,7 @@ test_expect_success 'create commits and write commit-graph' '
test_commit $i &&
git branch commits/$i || return 1
done &&
- git commit-graph write --reachable &&
+ git commit-graph write --input=reachable &&
test_path_is_file $infodir/commit-graph &&
graph_read_expect 3
'
The 'write' mode of the 'commit-graph' supports input from a number of different sources: pack indexes over stdin, commits over stdin, commits reachable from all references, and so on. Each of these options are specified with a unique option: '--stdin-packs', '--stdin-commits', etc. Similar to our replacement of 'git config [--<type>]' with 'git config [--type=<type>]' (c.f., fb0dc3bac1 (builtin/config.c: support `--type=<type>` as preferred alias for `--<type>`, 2018-04-18)), softly deprecate '[--<input>]' in favor of '[--input=<source>]'. This makes it more clear to implement new options that are combinations of other options (such as, for example, "none", a combination of the old "--append" and a new sentinel to specify to _not_ look in other packs, which we will implement in a future patch). Unfortunately, the new enumerated type is a bitfield, even though it makes much more sense as '0, 1, 2, ...'. Even though *almost* all options are pairwise exclusive, '--stdin-{packs,commits}' *is* compatible with '--append'. For this reason, use a bitfield. Signed-off-by: Taylor Blau <me@ttaylorr.com> --- Documentation/git-commit-graph.txt | 26 +++++----- builtin/commit-graph.c | 83 +++++++++++++++++++++--------- t/t5318-commit-graph.sh | 4 +- t/t5324-split-commit-graph.sh | 2 +- 4 files changed, 76 insertions(+), 39 deletions(-)