gc: automatically write commit-graph files

The commit-graph file is a very helpful feature for speeding up git operations. In order to make it more useful, make it possible to write the commit-graph file during standard garbage collection operations. Add a 'gc.commitGraph' config setting that triggers writing a commit-graph file after any non-trivial 'git gc' command. Defaults to false while the commit-graph feature matures. We specifically do not want to have this on by default until the commit-graph feature is fully integrated with history-modifying features like shallow clones. Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Jun 27, 2018 at 09:24 UTC d5d5d7b64131a23a13698242797f11f6479e39e8
4 files changed +30 -3
Documentation/config.txt
+6 -3
@@ -904,9 +904,12 @@ core.notesRef::
904 This setting defaults to "refs/notes/commits", and it can be overridden by
905 the `GIT_NOTES_REF` environment variable. See linkgit:git-notes[1].
906
907 -core.commitGraph::
908 - Enable git commit graph feature. Allows reading from the
909 - commit-graph file.
907 +gc.commitGraph::
908 + If true, then gc will rewrite the commit-graph file when
909 + linkgit:git-gc[1] is run. When using linkgit:git-gc[1]
910 + '--auto' the commit-graph will be updated if housekeeping is
911 + required. Default is false. See linkgit:git-commit-graph[1]
912 + for details.
913
914 core.sparseCheckout::
915 Enable "sparse checkout" feature. See section "Sparse checkout" in
Documentation/git-gc.txt
+4
@@ -136,6 +136,10 @@ The optional configuration variable `gc.packRefs` determines if
136 it within all non-bare repos or it can be set to a boolean value.
137 This defaults to true.
138
139 +The optional configuration variable `gc.commitGraph` determines if
140 +'git gc' should run 'git commit-graph write'. This can be set to a
141 +boolean value. This defaults to false.
142 +
143 The optional configuration variable `gc.aggressiveWindow` controls how
144 much time is spent optimizing the delta compression of the objects in
145 the repository when the --aggressive option is specified. The larger
builtin/gc.c
+6
@@ -20,6 +20,7 @@
20 #include "sigchain.h"
21 #include "argv-array.h"
22 #include "commit.h"
23 +#include "commit-graph.h"
24 #include "packfile.h"
25 #include "object-store.h"
26 #include "pack.h"
@@ -40,6 +41,7 @@ static int aggressive_depth = 50;
41 static int aggressive_window = 250;
42 static int gc_auto_threshold = 6700;
43 static int gc_auto_pack_limit = 50;
44 +static int gc_write_commit_graph;
45 static int detach_auto = 1;
46 static timestamp_t gc_log_expire_time;
47 static const char *gc_log_expire = "1.day.ago";
@@ -129,6 +131,7 @@ static void gc_config(void)
131 git_config_get_int("gc.aggressivedepth", &aggressive_depth);
132 git_config_get_int("gc.auto", &gc_auto_threshold);
133 git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
134 + git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph);
135 git_config_get_bool("gc.autodetach", &detach_auto);
136 git_config_get_expiry("gc.pruneexpire", &prune_expire);
137 git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
@@ -641,6 +644,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
644 if (pack_garbage.nr > 0)
645 clean_pack_garbage();
646
647 + if (gc_write_commit_graph)
648 + write_commit_graph_reachable(get_object_directory(), 0);
649 +
650 if (auto_gc && too_many_loose_objects())
651 warning(_("There are too many unreachable loose objects; "
652 "run 'git prune' to remove them."));
t/t5318-commit-graph.sh
+14
@@ -245,6 +245,20 @@ test_expect_success 'perform fast-forward merge in full repo' '
245 test_cmp expect output
246 '
247
248 +test_expect_success 'check that gc computes commit-graph' '
249 + cd "$TRASH_DIRECTORY/full" &&
250 + git commit --allow-empty -m "blank" &&
251 + git commit-graph write --reachable &&
252 + cp $objdir/info/commit-graph commit-graph-before-gc &&
253 + git reset --hard HEAD~1 &&
254 + git config gc.writeCommitGraph true &&
255 + git gc &&
256 + cp $objdir/info/commit-graph commit-graph-after-gc &&
257 + ! test_cmp commit-graph-before-gc commit-graph-after-gc &&
258 + git commit-graph write --reachable &&
259 + test_cmp commit-graph-after-gc $objdir/info/commit-graph
260 +'
261 +
262 # the verify tests below expect the commit-graph to contain
263 # exactly the commits reachable from the commits/8 branch.
264 # If the file changes the set of commits in the list, then the