Skip to content

Commit 19ef37c

Browse files
committed
Merge branch 'ds/commit-graph-format-v2' into pu
Introduce version 2 of the commit-graph format to correct deficiency in the initial version. cf. <[email protected]> (v2) * ds/commit-graph-format-v2: commit-graph: implement file format version 2 commit-graph: add --version=<n> option commit-graph: create new version flags commit-graph: collapse parameters into flags commit-graph: return with errors during write
2 parents 00cd7fb + c94278d commit 19ef37c

File tree

8 files changed

+254
-70
lines changed

8 files changed

+254
-70
lines changed

Documentation/git-commit-graph.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ or `--stdin-packs`.)
5151
+
5252
With the `--append` option, include all commits that are present in the
5353
existing commit-graph file.
54+
+
55+
With the `--version=<n>` option, specify the file format version. Used
56+
only for testing.
5457

5558
'read'::
5659

Documentation/technical/commit-graph-format.txt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,22 @@ and hash type.
3131

3232
All 4-byte numbers are in network order.
3333

34+
There are two versions available, 1 and 2. These currently differ only in
35+
the header.
36+
3437
HEADER:
3538

39+
All commit-graph files use the first five bytes for the same purpose.
40+
3641
4-byte signature:
3742
The signature is: {'C', 'G', 'P', 'H'}
3843

3944
1-byte version number:
40-
Currently, the only valid version is 1.
45+
Currently, the valid version numbers are 1 and 2.
46+
47+
The remainder of the header changes depending on the version.
48+
49+
Version 1:
4150

4251
1-byte Hash Version (1 = SHA-1)
4352
We infer the hash length (H) from this value.
@@ -47,6 +56,21 @@ HEADER:
4756
1-byte (reserved for later use)
4857
Current clients should ignore this value.
4958

59+
Version 2:
60+
61+
1-byte number (C) of "chunks"
62+
63+
1-byte reachability index version number:
64+
Currently, the only valid number is 1.
65+
66+
1-byte (reserved for later use)
67+
Current clients expect this value to be zero, and will not
68+
try to read the commit-graph file if it is non-zero.
69+
70+
4-byte format identifier for the hash algorithm:
71+
If this identifier does not agree with the repository's current
72+
hash algorithm, then the client will not read the commit graph.
73+
5074
CHUNK LOOKUP:
5175

5276
(C + 1) * 12 bytes listing the table of contents for the chunks:

builtin/commit-graph.c

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ static char const * const builtin_commit_graph_usage[] = {
1010
N_("git commit-graph [--object-dir <objdir>]"),
1111
N_("git commit-graph read [--object-dir <objdir>]"),
1212
N_("git commit-graph verify [--object-dir <objdir>]"),
13-
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
13+
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits] [--version=<n>]"),
1414
NULL
1515
};
1616

@@ -25,7 +25,7 @@ static const char * const builtin_commit_graph_read_usage[] = {
2525
};
2626

2727
static const char * const builtin_commit_graph_write_usage[] = {
28-
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
28+
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits] [--version=<n>]"),
2929
NULL
3030
};
3131

@@ -35,6 +35,7 @@ static struct opts_commit_graph {
3535
int stdin_packs;
3636
int stdin_commits;
3737
int append;
38+
int version;
3839
} opts;
3940

4041

@@ -116,6 +117,11 @@ static int graph_read(int argc, const char **argv)
116117
*(unsigned char*)(graph->data + 5),
117118
*(unsigned char*)(graph->data + 6),
118119
*(unsigned char*)(graph->data + 7));
120+
121+
if (*(unsigned char *)(graph->data + 4) == 2)
122+
printf("hash algorithm: %X\n",
123+
get_be32(graph->data + 8));
124+
119125
printf("num_commits: %u\n", graph->num_commits);
120126
printf("chunks:");
121127

@@ -141,6 +147,8 @@ static int graph_write(int argc, const char **argv)
141147
struct string_list *pack_indexes = NULL;
142148
struct string_list *commit_hex = NULL;
143149
struct string_list lines;
150+
int result;
151+
int flags = COMMIT_GRAPH_PROGRESS;
144152

145153
static struct option builtin_commit_graph_write_options[] = {
146154
OPT_STRING(0, "object-dir", &opts.obj_dir,
@@ -154,6 +162,8 @@ static int graph_write(int argc, const char **argv)
154162
N_("start walk at commits listed by stdin")),
155163
OPT_BOOL(0, "append", &opts.append,
156164
N_("include all commits already in the commit-graph file")),
165+
OPT_INTEGER(0, "version", &opts.version,
166+
N_("specify the file format version")),
157167
OPT_END(),
158168
};
159169

@@ -165,14 +175,24 @@ static int graph_write(int argc, const char **argv)
165175
die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
166176
if (!opts.obj_dir)
167177
opts.obj_dir = get_object_directory();
178+
if (opts.append)
179+
flags |= COMMIT_GRAPH_APPEND;
168180

169-
read_replace_refs = 0;
181+
switch (opts.version) {
182+
case 1:
183+
flags |= COMMIT_GRAPH_VERSION_1;
184+
break;
170185

171-
if (opts.reachable) {
172-
write_commit_graph_reachable(opts.obj_dir, opts.append, 1);
173-
return 0;
186+
case 2:
187+
flags |= COMMIT_GRAPH_VERSION_2;
188+
break;
174189
}
175190

191+
read_replace_refs = 0;
192+
193+
if (opts.reachable)
194+
return write_commit_graph_reachable(opts.obj_dir, flags);
195+
176196
string_list_init(&lines, 0);
177197
if (opts.stdin_packs || opts.stdin_commits) {
178198
struct strbuf buf = STRBUF_INIT;
@@ -188,14 +208,13 @@ static int graph_write(int argc, const char **argv)
188208
UNLEAK(buf);
189209
}
190210

191-
write_commit_graph(opts.obj_dir,
192-
pack_indexes,
193-
commit_hex,
194-
opts.append,
195-
1);
211+
result = write_commit_graph(opts.obj_dir,
212+
pack_indexes,
213+
commit_hex,
214+
flags);
196215

197216
UNLEAK(lines);
198-
return 0;
217+
return result;
199218
}
200219

201220
int cmd_commit_graph(int argc, const char **argv, const char *prefix)

builtin/commit.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,8 +1669,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
16691669
"new_index file. Check that disk is not full and quota is\n"
16701670
"not exceeded, and then \"git restore --staged :/\" to recover."));
16711671

1672-
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
1673-
write_commit_graph_reachable(get_object_directory(), 0, 0);
1672+
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
1673+
write_commit_graph_reachable(get_object_directory(), 0))
1674+
return 1;
16741675

16751676
repo_rerere(the_repository, 0);
16761677
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);

builtin/gc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
685685
clean_pack_garbage();
686686
}
687687

688-
if (gc_write_commit_graph)
689-
write_commit_graph_reachable(get_object_directory(), 0,
690-
!quiet && !daemonized);
688+
if (gc_write_commit_graph &&
689+
write_commit_graph_reachable(get_object_directory(),
690+
!quiet && !daemonized ? COMMIT_GRAPH_PROGRESS : 0))
691+
return 1;
691692

692693
if (auto_gc && too_many_loose_objects())
693694
warning(_("There are too many unreachable loose objects; "

0 commit comments

Comments
 (0)