commit-graph: add '--reachable' option
When writing commit-graph files, it can be convenient to ask for all reachable commits (starting at the ref set) in the resulting file. This is particularly helpful when writing to stdin is complicated, such as a future integration with 'git gc'. 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
59fb87701ff68eb114e54ce6834e91c4ae8f60a7
5 files changed
+49
-6
Documentation/git-commit-graph.txt
+6
-2
@@ -38,12 +38,16 @@ Write a commit graph file based on the commits found in packfiles.
38
+
39
With the `--stdin-packs` option, generate the new commit graph by
40
walking objects only in the specified pack-indexes. (Cannot be combined
41
-with --stdin-commits.)
41
+with `--stdin-commits` or `--reachable`.)
42
+
43
With the `--stdin-commits` option, generate the new commit graph by
44
walking commits starting at the commits specified in stdin as a list
45
of OIDs in hex, one OID per line. (Cannot be combined with
46
---stdin-packs.)
46
+`--stdin-packs` or `--reachable`.)
47
++
48
+With the `--reachable` option, generate the new commit graph by walking
49
+commits starting at all refs. (Cannot be combined with `--stdin-commits`
50
+or `--stdin-packs`.)
51
+
52
With the `--append` option, include all commits that are present in the
53
existing commit-graph file.
builtin/commit-graph.c
+12
-4
@@ -10,7 +10,7 @@ static char const * const builtin_commit_graph_usage[] = {
10
N_("git commit-graph [--object-dir <objdir>]"),
11
N_("git commit-graph read [--object-dir <objdir>]"),
12
N_("git commit-graph verify [--object-dir <objdir>]"),
13
- N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
13
+ N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
14
NULL
15
};
16
@@ -25,12 +25,13 @@ static const char * const builtin_commit_graph_read_usage[] = {
25
};
26
27
static const char * const builtin_commit_graph_write_usage[] = {
28
- N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
28
+ N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
29
NULL
30
};
31
32
static struct opts_commit_graph {
33
const char *obj_dir;
34
+ int reachable;
35
int stdin_packs;
36
int stdin_commits;
37
int append;
@@ -127,6 +128,8 @@ static int graph_write(int argc, const char **argv)
128
OPT_STRING(0, "object-dir", &opts.obj_dir,
129
N_("dir"),
130
N_("The object directory to store the graph")),
131
+ OPT_BOOL(0, "reachable", &opts.reachable,
132
+ N_("start walk at all refs")),
133
OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
134
N_("scan pack-indexes listed by stdin for commits")),
135
OPT_BOOL(0, "stdin-commits", &opts.stdin_commits,
@@ -140,11 +143,16 @@ static int graph_write(int argc, const char **argv)
143
builtin_commit_graph_write_options,
144
builtin_commit_graph_write_usage, 0);
145
143
- if (opts.stdin_packs && opts.stdin_commits)
144
- die(_("cannot use both --stdin-commits and --stdin-packs"));
146
+ if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1)
147
+ die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
148
if (!opts.obj_dir)
149
opts.obj_dir = get_object_directory();
150
151
+ if (opts.reachable) {
152
+ write_commit_graph_reachable(opts.obj_dir, opts.append);
153
+ return 0;
154
+ }
155
+
156
string_list_init(&lines, 0);
157
if (opts.stdin_packs || opts.stdin_commits) {
158
struct strbuf buf = STRBUF_INIT;
commit-graph.c
+20
@@ -7,6 +7,7 @@
7
#include "packfile.h"
8
#include "commit.h"
9
#include "object.h"
10
+#include "refs.h"
11
#include "revision.h"
12
#include "sha1-lookup.h"
13
#include "commit-graph.h"
@@ -656,6 +657,25 @@ static void compute_generation_numbers(struct packed_commit_list* commits)
657
}
658
}
659
660
+static int add_ref_to_list(const char *refname,
661
+ const struct object_id *oid,
662
+ int flags, void *cb_data)
663
+{
664
+ struct string_list *list = (struct string_list *)cb_data;
665
+
666
+ string_list_append(list, oid_to_hex(oid));
667
+ return 0;
668
+}
669
+
670
+void write_commit_graph_reachable(const char *obj_dir, int append)
671
+{
672
+ struct string_list list;
673
+
674
+ string_list_init(&list, 1);
675
+ for_each_ref(add_ref_to_list, &list);
676
+ write_commit_graph(obj_dir, NULL, &list, append);
677
+}
678
+
679
void write_commit_graph(const char *obj_dir,
680
struct string_list *pack_indexes,
681
struct string_list *commit_hex,
commit-graph.h
+1
@@ -48,6 +48,7 @@ struct commit_graph {
48
49
struct commit_graph *load_commit_graph_one(const char *graph_file);
50
51
+void write_commit_graph_reachable(const char *obj_dir, int append);
52
void write_commit_graph(const char *obj_dir,
53
struct string_list *pack_indexes,
54
struct string_list *commit_hex,
t/t5318-commit-graph.sh
+10
@@ -205,6 +205,16 @@ test_expect_success 'build graph from commits with append' '
205
graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
206
graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2
207
208
+test_expect_success 'build graph using --reachable' '
209
+ cd "$TRASH_DIRECTORY/full" &&
210
+ git commit-graph write --reachable &&
211
+ test_path_is_file $objdir/info/commit-graph &&
212
+ graph_read_expect "11" "large_edges"
213
+'
214
+
215
+graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
216
+graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2
217
+
218
test_expect_success 'setup bare repo' '
219
cd "$TRASH_DIRECTORY" &&
220
git clone --bare --no-local full bare &&