diff options
-rw-r--r-- | Documentation/git-commit-graph.txt | 4 | ||||
-rw-r--r-- | commit-graph.c | 21 | ||||
-rwxr-xr-x | t/t5324-split-commit-graph.sh | 13 |
3 files changed, 34 insertions, 4 deletions
diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt index de6b6de230..e1f48c95b3 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.txt @@ -39,7 +39,9 @@ COMMANDS -------- 'write':: -Write a commit-graph file based on the commits found in packfiles. +Write a commit-graph file based on the commits found in packfiles. If +the config option `core.commitGraph` is disabled, then this command will +output a warning, then return success without writing a commit-graph file. + With the `--stdin-packs` option, generate the new commit graph by walking objects only in the specified pack-indexes. (Cannot be combined diff --git a/commit-graph.c b/commit-graph.c index cb042bdba8..6f62a07313 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -2008,7 +2008,7 @@ static int commit_compare(const void *_a, const void *_b) static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) { - uint32_t i; + uint32_t i, dedup_i = 0; if (ctx->report_progress) ctx->progress = start_delayed_progress( @@ -2023,17 +2023,27 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) if (i && oideq(&ctx->commits.list[i - 1]->object.oid, &ctx->commits.list[i]->object.oid)) { - die(_("unexpected duplicate commit id %s"), - oid_to_hex(&ctx->commits.list[i]->object.oid)); + /* + * Silently ignore duplicates. These were likely + * created due to a commit appearing in multiple + * layers of the chain, which is unexpected but + * not invalid. We should make sure there is a + * unique copy in the new layer. + */ } else { unsigned int num_parents; + ctx->commits.list[dedup_i] = ctx->commits.list[i]; + dedup_i++; + num_parents = commit_list_count(ctx->commits.list[i]->parents); if (num_parents > 2) ctx->num_extra_edges += num_parents - 1; } } + ctx->commits.nr = dedup_i; + stop_progress(&ctx->progress); } @@ -2150,6 +2160,11 @@ int write_commit_graph(struct object_directory *odb, int replace = 0; struct bloom_filter_settings bloom_settings = DEFAULT_BLOOM_FILTER_SETTINGS; + prepare_repo_settings(the_repository); + if (!the_repository->settings.core_commit_graph) { + warning(_("attempting to write a commit-graph, but 'core.commitGraph' is disabled")); + return 0; + } if (!commit_graph_compatible(the_repository)) return 0; diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index c334ee9155..4d3842b83b 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -440,4 +440,17 @@ test_expect_success '--split=replace with partial Bloom data' ' verify_chain_files_exist $graphdir ' +test_expect_success 'prevent regression for duplicate commits across layers' ' + git init dup && + git -C dup commit --allow-empty -m one && + git -C dup -c core.commitGraph=false commit-graph write --split=no-merge --reachable 2>err && + test_i18ngrep "attempting to write a commit-graph" err && + git -C dup commit-graph write --split=no-merge --reachable && + git -C dup commit --allow-empty -m two && + git -C dup commit-graph write --split=no-merge --reachable && + git -C dup commit --allow-empty -m three && + git -C dup commit-graph write --split --reachable && + git -C dup commit-graph verify +' + test_done |