commit-graph: not compatible with replace objects

Create new method commit_graph_compatible(r) to check if a given repository r is compatible with the commit-graph feature. Fill the method with a check to see if replace-objects exist. Test this interaction succeeds, including ignoring an existing commit-graph and failing to write a new commit-graph. However, we do ensure that we write a new commit-graph by setting read_replace_refs to 0, thereby ignoring the replace refs. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Aug 20, 2018 at 18:24 UTC d6538246d3d4edbfbc9b0af6a2aa38552d35f7f1
5 files changed +50 -1
builtin/commit-graph.c
+4
@@ -120,6 +120,8 @@ static int graph_read(int argc, const char **argv)
120 return 0;
121 }
122
123 +extern int read_replace_refs;
124 +
125 static int graph_write(int argc, const char **argv)
126 {
127 struct string_list *pack_indexes = NULL;
@@ -150,6 +152,8 @@ static int graph_write(int argc, const char **argv)
152 if (!opts.obj_dir)
153 opts.obj_dir = get_object_directory();
154
155 + read_replace_refs = 0;
156 +
157 if (opts.reachable) {
158 write_commit_graph_reachable(opts.obj_dir, opts.append);
159 return 0;
commit-graph.c
+21
@@ -13,6 +13,8 @@
13 #include "commit-graph.h"
14 #include "object-store.h"
15 #include "alloc.h"
16 +#include "hashmap.h"
17 +#include "replace-object.h"
18
19 #define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
20 #define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
@@ -56,6 +58,19 @@ static struct commit_graph *alloc_commit_graph(void)
58 return g;
59 }
60
61 +extern int read_replace_refs;
62 +
63 +static int commit_graph_compatible(struct repository *r)
64 +{
65 + if (read_replace_refs) {
66 + prepare_replace_object(r);
67 + if (hashmap_get_size(&r->objects->replace_map->map))
68 + return 0;
69 + }
70 +
71 + return 1;
72 +}
73 +
74 struct commit_graph *load_commit_graph_one(const char *graph_file)
75 {
76 void *graph_map;
@@ -223,6 +238,9 @@ static int prepare_commit_graph(struct repository *r)
238 */
239 return 0;
240
241 + if (!commit_graph_compatible(r))
242 + return 0;
243 +
244 obj_dir = r->objects->objectdir;
245 prepare_commit_graph_one(r, obj_dir);
246 prepare_alt_odb(r);
@@ -693,6 +711,9 @@ void write_commit_graph(const char *obj_dir,
711 int num_extra_edges;
712 struct commit_list *parent;
713
714 + if (!commit_graph_compatible(the_repository))
715 + return;
716 +
717 oids.nr = 0;
718 oids.alloc = approximate_object_count() / 4;
719
replace-object.c
+1 -1
@@ -32,7 +32,7 @@ static int register_replace_ref(struct repository *r,
32 return 0;
33 }
34
35 -static void prepare_replace_object(struct repository *r)
35 +void prepare_replace_object(struct repository *r)
36 {
37 if (r->objects->replace_map)
38 return;
replace-object.h
+2
@@ -10,6 +10,8 @@ struct replace_object {
10 struct object_id replacement;
11 };
12
13 +void prepare_replace_object(struct repository *r);
14 +
15 /*
16 * This internal function is only declared here for the benefit of
17 * lookup_replace_object(). Please do not call it directly.
t/t5318-commit-graph.sh
+22
@@ -259,6 +259,28 @@ test_expect_success 'check that gc computes commit-graph' '
259 test_cmp commit-graph-after-gc $objdir/info/commit-graph
260 '
261
262 +test_expect_success 'replace-objects invalidates commit-graph' '
263 + cd "$TRASH_DIRECTORY" &&
264 + test_when_finished rm -rf replace &&
265 + git clone full replace &&
266 + (
267 + cd replace &&
268 + git commit-graph write --reachable &&
269 + test_path_is_file .git/objects/info/commit-graph &&
270 + git replace HEAD~1 HEAD~2 &&
271 + git -c core.commitGraph=false log >expect &&
272 + git -c core.commitGraph=true log >actual &&
273 + test_cmp expect actual &&
274 + git commit-graph write --reachable &&
275 + git -c core.commitGraph=false --no-replace-objects log >expect &&
276 + git -c core.commitGraph=true --no-replace-objects log >actual &&
277 + test_cmp expect actual &&
278 + rm -rf .git/objects/info/commit-graph &&
279 + git commit-graph write --reachable &&
280 + test_path_is_file .git/objects/info/commit-graph
281 + )
282 +'
283 +
284 # the verify tests below expect the commit-graph to contain
285 # exactly the commits reachable from the commits/8 branch.
286 # If the file changes the set of commits in the list, then the