From 61c1ad542cd0e33417f409444f2037eefb6d2117 Mon Sep 17 00:00:00 2001 From: Emily Yang Date: Mon, 6 Oct 2025 16:15:02 -0700 Subject: [PATCH] Commitgraph: add new config for changed-paths and recommend it in scalar Changed-path bloom filters has been a stable feature for a few years and it significantly improves performance of file history computation for large repos. Currently it can be turned on by 'git commit-graph write --changed-paths'. As one of the large repos, Microsoft Office MonoRepo would like to get this feature on for repo developers with minimal effort. In this commit, we're proposing a new config option 'commitGraph.changedPaths', which acts like '--changed-paths' and always respects command line precedence. We then add this new config as recommended in scalar to benefit large repos. This commit also adds corresponding doc and unit tests for the new config. Signed-off-by: Emily Yang Mentored-by: Derrick Stolee --- Documentation/config/commitgraph.adoc | 8 ++++ builtin/commit-graph.c | 5 +++ scalar.c | 1 + t/t5318-commit-graph.sh | 65 +++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) diff --git a/Documentation/config/commitgraph.adoc b/Documentation/config/commitgraph.adoc index 7f8c9d6638f1a1..c540e8a43dbba7 100644 --- a/Documentation/config/commitgraph.adoc +++ b/Documentation/config/commitgraph.adoc @@ -8,6 +8,14 @@ commitGraph.maxNewFilters:: Specifies the default value for the `--max-new-filters` option of `git commit-graph write` (c.f., linkgit:git-commit-graph[1]). +commitGraph.changedPaths:: + If true, then `git commit-graph write` will compute and write + changed-path Bloom filters by default, equivalent to passing + `--changed-paths`. If false or unset, changed-path Bloom filters + will only be written when explicitly requested via `--changed-paths`. + Command-line options always take precedence over this configuration. + Defaults to unset. + commitGraph.readChangedPaths:: Deprecated. Equivalent to commitGraph.changedPathsVersion=-1 if true, and commitGraph.changedPathsVersion=0 if false. (If commitGraph.changedPathVersion diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index fe3ebaadadadb6..3e2c4461cd6cbf 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -210,6 +210,11 @@ static int git_commit_graph_write_config(const char *var, const char *value, { if (!strcmp(var, "commitgraph.maxnewfilters")) write_opts.max_new_filters = git_config_int(var, value, ctx->kvi); + else if (!strcmp(var, "commitgraph.changedpaths")) { + /* Only set to 1 if config is true and not already overridden by command line */ + if (opts.enable_changed_paths == -1 && git_config_bool(var, value)) + opts.enable_changed_paths = 1; + } /* * No need to fall-back to 'git_default_config', since this was already * called in 'cmd_commit_graph()'. diff --git a/scalar.c b/scalar.c index 4a373c133d8562..f7543116272b77 100644 --- a/scalar.c +++ b/scalar.c @@ -166,6 +166,7 @@ static int set_recommended_config(int reconfigure) #endif /* Optional */ { "status.aheadBehind", "false" }, + { "commitGraph.changedPaths", "true" }, { "commitGraph.generationVersion", "1" }, { "core.autoCRLF", "false" }, { "core.safeCRLF", "false" }, diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 0b3404f58fe5f9..4ddd49d4cd97e1 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -946,4 +946,69 @@ test_expect_success 'stale commit cannot be parsed when traversing graph' ' ) ' +test_expect_success 'commitGraph.changedPaths=true acts like --changed-paths' ' + git init config-changed-paths-true && + ( + cd config-changed-paths-true && + test_commit initial && + test_commit second && + test_commit third && + + # set commitGraph.changedPaths to true and it should write bloom filters + git config commitGraph.changedPaths true && + GIT_PROGRESS_DELAY=0 git commit-graph write --reachable --progress 2>error && + grep -i "bloom filters" error && + + # --no-changed-paths should take precedence over the config and erase bloom filters + GIT_PROGRESS_DELAY=0 git commit-graph write --no-changed-paths --reachable --progress 2>error && + ! grep -i "bloom filters" error && + + # --changed-paths should take precedence over the config and add bloom filters + GIT_PROGRESS_DELAY=0 git commit-graph write --changed-paths --reachable --progress 2>error && + grep -i "bloom filters" error + + ) +' + +test_expect_success 'commitGraph.changedPaths=false respects command line options' ' + git init config-changed-paths-false && + ( + cd config-changed-paths-false && + test_commit initial && + test_commit second && + test_commit third && + + # set commitGraph.changedPaths to false and it should not write bloom filters + git config commitGraph.changedPaths false && + GIT_PROGRESS_DELAY=0 git commit-graph write --reachable --progress 2>error && + ! grep -i "bloom filters" error && + + # --changed-paths should take precedence over the config and add bloom filters + GIT_PROGRESS_DELAY=0 git commit-graph write --changed-paths --reachable --progress 2>error && + grep -i "bloom filters" error && + + # --no-changed-paths should take precedence over the config and erase bloom filters + GIT_PROGRESS_DELAY=0 git commit-graph write --no-changed-paths --reachable --progress 2>error && + ! grep -i "bloom filters" error + ) +' + +test_expect_success 'commitGraph.changedPaths=unset respects command line options' ' + git init config-changed-paths-unset && + ( + cd config-changed-paths-unset && + test_commit initial && + test_commit second && + test_commit third && + + # commitGraph.changedPaths is not set and it should always respect command line options + GIT_PROGRESS_DELAY=0 git commit-graph write --reachable --progress 2>error && + ! grep -i "bloom filters" error && + GIT_PROGRESS_DELAY=0 git commit-graph write --changed-paths --reachable --progress 2>error && + grep -i "bloom filters" error && + GIT_PROGRESS_DELAY=0 git commit-graph write --no-changed-paths --reachable --progress 2>error && + ! grep -i "bloom filters" error + ) +' + test_done