Skip to content

Commit 596e285

Browse files
jonathantanmygitster
authored andcommitted
commit-graph: add repo arg to graph readers
Add a struct repository argument to the functions in commit-graph.h that read the commit graph. (This commit does not affect functions that write commit graphs.) Because the commit graph functions can now read the commit graph of any repository, the global variable core_commit_graph has been removed. Instead, the config option core.commitGraph is now read on the first time in a repository that a commit is attempted to be parsed using its commit graph. This commit includes a test that exercises the functionality on an arbitrary repository that is not the_repository. Signed-off-by: Jonathan Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c1a3b50 commit 596e285

File tree

13 files changed

+162
-42
lines changed

13 files changed

+162
-42
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-prio-queue.o
719719
TEST_BUILTINS_OBJS += test-read-cache.o
720720
TEST_BUILTINS_OBJS += test-ref-store.o
721721
TEST_BUILTINS_OBJS += test-regex.o
722+
TEST_BUILTINS_OBJS += test-repository.o
722723
TEST_BUILTINS_OBJS += test-revision-walking.o
723724
TEST_BUILTINS_OBJS += test-run-command.o
724725
TEST_BUILTINS_OBJS += test-scrap-cache-tree.o

builtin/fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
830830

831831
check_connectivity();
832832

833-
if (core_commit_graph) {
833+
if (!git_config_get_bool("core.commitgraph", &i) && i) {
834834
struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
835835
const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL };
836836

cache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,6 @@ extern char *git_replace_ref_base;
813813

814814
extern int fsync_object_files;
815815
extern int core_preload_index;
816-
extern int core_commit_graph;
817816
extern int core_apply_sparse_checkout;
818817
extern int precomposed_unicode;
819818
extern int protect_hfs;

commit-graph.c

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ struct commit_graph *load_commit_graph_one(const char *graph_file)
183183
exit(1);
184184
}
185185

186-
static void prepare_commit_graph_one(const char *obj_dir)
186+
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
187187
{
188188
char *graph_name;
189189

190-
if (the_repository->objects->commit_graph)
190+
if (r->objects->commit_graph)
191191
return;
192192

193193
graph_name = get_commit_graph_filename(obj_dir);
194-
the_repository->objects->commit_graph =
194+
r->objects->commit_graph =
195195
load_commit_graph_one(graph_name);
196196

197197
FREE_AND_NULL(graph_name);
@@ -203,26 +203,34 @@ static void prepare_commit_graph_one(const char *obj_dir)
203203
* On the first invocation, this function attemps to load the commit
204204
* graph if the_repository is configured to have one.
205205
*/
206-
static int prepare_commit_graph(void)
206+
static int prepare_commit_graph(struct repository *r)
207207
{
208208
struct alternate_object_database *alt;
209209
char *obj_dir;
210+
int config_value;
210211

211-
if (the_repository->objects->commit_graph_attempted)
212-
return !!the_repository->objects->commit_graph;
213-
the_repository->objects->commit_graph_attempted = 1;
212+
if (r->objects->commit_graph_attempted)
213+
return !!r->objects->commit_graph;
214+
r->objects->commit_graph_attempted = 1;
214215

215-
if (!core_commit_graph)
216+
if (repo_config_get_bool(r, "core.commitgraph", &config_value) ||
217+
!config_value)
218+
/*
219+
* This repository is not configured to use commit graphs, so
220+
* do not load one. (But report commit_graph_attempted anyway
221+
* so that commit graph loading is not attempted again for this
222+
* repository.)
223+
*/
216224
return 0;
217225

218-
obj_dir = get_object_directory();
219-
prepare_commit_graph_one(obj_dir);
220-
prepare_alt_odb(the_repository);
221-
for (alt = the_repository->objects->alt_odb_list;
222-
!the_repository->objects->commit_graph && alt;
226+
obj_dir = r->objects->objectdir;
227+
prepare_commit_graph_one(r, obj_dir);
228+
prepare_alt_odb(r);
229+
for (alt = r->objects->alt_odb_list;
230+
!r->objects->commit_graph && alt;
223231
alt = alt->next)
224-
prepare_commit_graph_one(alt->path);
225-
return !!the_repository->objects->commit_graph;
232+
prepare_commit_graph_one(r, alt->path);
233+
return !!r->objects->commit_graph;
226234
}
227235

228236
static void close_commit_graph(void)
@@ -323,8 +331,6 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
323331
{
324332
uint32_t pos;
325333

326-
if (!core_commit_graph)
327-
return 0;
328334
if (item->object.parsed)
329335
return 1;
330336

@@ -334,20 +340,20 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
334340
return 0;
335341
}
336342

337-
int parse_commit_in_graph(struct commit *item)
343+
int parse_commit_in_graph(struct repository *r, struct commit *item)
338344
{
339-
if (!prepare_commit_graph())
345+
if (!prepare_commit_graph(r))
340346
return 0;
341-
return parse_commit_in_graph_one(the_repository->objects->commit_graph, item);
347+
return parse_commit_in_graph_one(r->objects->commit_graph, item);
342348
}
343349

344-
void load_commit_graph_info(struct commit *item)
350+
void load_commit_graph_info(struct repository *r, struct commit *item)
345351
{
346352
uint32_t pos;
347-
if (!prepare_commit_graph())
353+
if (!prepare_commit_graph(r))
348354
return;
349-
if (find_commit_in_graph(item, the_repository->objects->commit_graph, &pos))
350-
fill_commit_graph_info(item, the_repository->objects->commit_graph, pos);
355+
if (find_commit_in_graph(item, r->objects->commit_graph, &pos))
356+
fill_commit_graph_info(item, r->objects->commit_graph, pos);
351357
}
352358

353359
static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
@@ -373,9 +379,9 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
373379
return load_tree_for_commit(g, (struct commit *)c);
374380
}
375381

376-
struct tree *get_commit_tree_in_graph(const struct commit *c)
382+
struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
377383
{
378-
return get_commit_tree_in_graph_one(the_repository->objects->commit_graph, c);
384+
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
379385
}
380386

381387
static void write_graph_chunk_fanout(struct hashfile *f,
@@ -691,7 +697,7 @@ void write_commit_graph(const char *obj_dir,
691697
oids.alloc = approximate_object_count() / 4;
692698

693699
if (append) {
694-
prepare_commit_graph_one(obj_dir);
700+
prepare_commit_graph_one(the_repository, obj_dir);
695701
if (the_repository->objects->commit_graph)
696702
oids.alloc += the_repository->objects->commit_graph->num_commits;
697703
}

commit-graph.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ char *get_commit_graph_filename(const char *obj_dir);
1919
*
2020
* See parse_commit_buffer() for the fallback after this call.
2121
*/
22-
int parse_commit_in_graph(struct commit *item);
22+
int parse_commit_in_graph(struct repository *r, struct commit *item);
2323

2424
/*
2525
* It is possible that we loaded commit contents from the commit buffer,
2626
* but we also want to ensure the commit-graph content is correctly
2727
* checked and filled. Fill the graph_pos and generation members of
2828
* the given commit.
2929
*/
30-
void load_commit_graph_info(struct commit *item);
30+
void load_commit_graph_info(struct repository *r, struct commit *item);
3131

32-
struct tree *get_commit_tree_in_graph(const struct commit *c);
32+
struct tree *get_commit_tree_in_graph(struct repository *r,
33+
const struct commit *c);
3334

3435
struct commit_graph {
3536
int graph_fd;

commit.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ struct tree *get_commit_tree(const struct commit *commit)
342342
if (commit->graph_pos == COMMIT_NOT_FROM_GRAPH)
343343
BUG("commit has NULL tree, but was not loaded from commit-graph");
344344

345-
return get_commit_tree_in_graph(commit);
345+
return get_commit_tree_in_graph(the_repository, commit);
346346
}
347347

348348
struct object_id *get_commit_tree_oid(const struct commit *commit)
@@ -438,7 +438,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
438438
item->date = parse_commit_date(bufptr, tail);
439439

440440
if (check_graph)
441-
load_commit_graph_info(item);
441+
load_commit_graph_info(the_repository, item);
442442

443443
return 0;
444444
}
@@ -454,7 +454,7 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com
454454
return -1;
455455
if (item->object.parsed)
456456
return 0;
457-
if (use_commit_graph && parse_commit_in_graph(item))
457+
if (use_commit_graph && parse_commit_in_graph(the_repository, item))
458458
return 0;
459459
buffer = read_object_file(&item->object.oid, &type, &size);
460460
if (!buffer)

config.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,11 +1309,6 @@ static int git_default_core_config(const char *var, const char *value)
13091309
return 0;
13101310
}
13111311

1312-
if (!strcmp(var, "core.commitgraph")) {
1313-
core_commit_graph = git_config_bool(var, value);
1314-
return 0;
1315-
}
1316-
13171312
if (!strcmp(var, "core.sparsecheckout")) {
13181313
core_apply_sparse_checkout = git_config_bool(var, value);
13191314
return 0;

environment.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
6666
enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
6767
char *notes_ref_name;
6868
int grafts_replace_parents = 1;
69-
int core_commit_graph;
7069
int core_apply_sparse_checkout;
7170
int merge_log_config = -1;
7271
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */

ref-filter.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1713,7 +1713,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
17131713

17141714
for (p = want; p; p = p->next) {
17151715
struct commit *c = p->item;
1716-
load_commit_graph_info(c);
1716+
load_commit_graph_info(the_repository, c);
17171717
if (c->generation < cutoff)
17181718
cutoff = c->generation;
17191719
}

t/helper/test-repository.c

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "test-tool.h"
2+
#include "cache.h"
3+
#include "commit-graph.h"
4+
#include "commit.h"
5+
#include "config.h"
6+
#include "object-store.h"
7+
#include "object.h"
8+
#include "repository.h"
9+
#include "tree.h"
10+
11+
static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
12+
const struct object_id *commit_oid)
13+
{
14+
struct repository r;
15+
struct commit *c;
16+
struct commit_list *parent;
17+
18+
repo_init(&r, gitdir, worktree);
19+
20+
c = lookup_commit(&r, commit_oid);
21+
22+
if (!parse_commit_in_graph(&r, c))
23+
die("Couldn't parse commit");
24+
25+
printf("%"PRItime, c->date);
26+
for (parent = c->parents; parent; parent = parent->next)
27+
printf(" %s", oid_to_hex(&parent->item->object.oid));
28+
printf("\n");
29+
30+
repo_clear(&r);
31+
}
32+
33+
static void test_get_commit_tree_in_graph(const char *gitdir,
34+
const char *worktree,
35+
const struct object_id *commit_oid)
36+
{
37+
struct repository r;
38+
struct commit *c;
39+
struct tree *tree;
40+
41+
repo_init(&r, gitdir, worktree);
42+
43+
c = lookup_commit(&r, commit_oid);
44+
45+
/*
46+
* get_commit_tree_in_graph does not automatically parse the commit, so
47+
* parse it first.
48+
*/
49+
if (!parse_commit_in_graph(&r, c))
50+
die("Couldn't parse commit");
51+
tree = get_commit_tree_in_graph(&r, c);
52+
if (!tree)
53+
die("Couldn't get commit tree");
54+
55+
printf("%s\n", oid_to_hex(&tree->object.oid));
56+
57+
repo_clear(&r);
58+
}
59+
60+
int cmd__repository(int argc, const char **argv)
61+
{
62+
if (argc < 2)
63+
die("must have at least 2 arguments");
64+
if (!strcmp(argv[1], "parse_commit_in_graph")) {
65+
struct object_id oid;
66+
if (argc < 5)
67+
die("not enough arguments");
68+
if (parse_oid_hex(argv[4], &oid, &argv[4]))
69+
die("cannot parse oid '%s'", argv[4]);
70+
test_parse_commit_in_graph(argv[2], argv[3], &oid);
71+
} else if (!strcmp(argv[1], "get_commit_tree_in_graph")) {
72+
struct object_id oid;
73+
if (argc < 5)
74+
die("not enough arguments");
75+
if (parse_oid_hex(argv[4], &oid, &argv[4]))
76+
die("cannot parse oid '%s'", argv[4]);
77+
test_get_commit_tree_in_graph(argv[2], argv[3], &oid);
78+
} else {
79+
die("unrecognized '%s'", argv[1]);
80+
}
81+
return 0;
82+
}

t/helper/test-tool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static struct test_cmd cmds[] = {
2929
{ "read-cache", cmd__read_cache },
3030
{ "ref-store", cmd__ref_store },
3131
{ "regex", cmd__regex },
32+
{ "repository", cmd__repository },
3233
{ "revision-walking", cmd__revision_walking },
3334
{ "run-command", cmd__run_command },
3435
{ "scrap-cache-tree", cmd__scrap_cache_tree },

t/helper/test-tool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ int cmd__prio_queue(int argc, const char **argv);
2323
int cmd__read_cache(int argc, const char **argv);
2424
int cmd__ref_store(int argc, const char **argv);
2525
int cmd__regex(int argc, const char **argv);
26+
int cmd__repository(int argc, const char **argv);
2627
int cmd__revision_walking(int argc, const char **argv);
2728
int cmd__run_command(int argc, const char **argv);
2829
int cmd__scrap_cache_tree(int argc, const char **argv);

t/t5318-commit-graph.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,39 @@ test_expect_success 'git fsck (checks commit-graph)' '
431431
test_must_fail git fsck
432432
'
433433

434+
test_expect_success 'setup non-the_repository tests' '
435+
rm -rf repo &&
436+
git init repo &&
437+
test_commit -C repo one &&
438+
test_commit -C repo two &&
439+
git -C repo config core.commitGraph true &&
440+
git -C repo rev-parse two | \
441+
git -C repo commit-graph write --stdin-commits
442+
'
443+
444+
test_expect_success 'parse_commit_in_graph works for non-the_repository' '
445+
test-tool repository parse_commit_in_graph \
446+
repo/.git repo "$(git -C repo rev-parse two)" >actual &&
447+
echo $(git -C repo log --pretty="%ct" -1) \
448+
$(git -C repo rev-parse one) >expect &&
449+
test_cmp expect actual &&
450+
451+
test-tool repository parse_commit_in_graph \
452+
repo/.git repo "$(git -C repo rev-parse one)" >actual &&
453+
echo $(git -C repo log --pretty="%ct" -1 one) >expect &&
454+
test_cmp expect actual
455+
'
456+
457+
test_expect_success 'get_commit_tree_in_graph works for non-the_repository' '
458+
test-tool repository get_commit_tree_in_graph \
459+
repo/.git repo "$(git -C repo rev-parse two)" >actual &&
460+
echo $(git -C repo rev-parse two^{tree}) >expect &&
461+
test_cmp expect actual &&
462+
463+
test-tool repository get_commit_tree_in_graph \
464+
repo/.git repo "$(git -C repo rev-parse one)" >actual &&
465+
echo $(git -C repo rev-parse one^{tree}) >expect &&
466+
test_cmp expect actual
467+
'
468+
434469
test_done

0 commit comments

Comments
 (0)