Skip to content

Commit 8019e91

Browse files
committed
Merge branch 'jt/commit-graph-per-object-store' into pu
The singleton commit-graph in-core instance is made per in-core repository instance. * jt/commit-graph-per-object-store: commit-graph: add repo arg to graph readers commit-graph: store graph in struct object_store commit-graph: add free_commit_graph commit-graph: add missing forward declaration object-store: add missing include commit-graph: refactor preparing commit graph
2 parents 8c52fd7 + 596e285 commit 8019e91

17 files changed

+208
-63
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ TEST_BUILTINS_OBJS += test-read-cache.o
722722
TEST_BUILTINS_OBJS += test-read-midx.o
723723
TEST_BUILTINS_OBJS += test-ref-store.o
724724
TEST_BUILTINS_OBJS += test-regex.o
725+
TEST_BUILTINS_OBJS += test-repository.o
725726
TEST_BUILTINS_OBJS += test-revision-walking.o
726727
TEST_BUILTINS_OBJS += test-run-command.o
727728
TEST_BUILTINS_OBJS += test-scrap-cache-tree.o

builtin/commit-graph.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ static int graph_read(int argc, const char **argv)
115115
printf(" large_edges");
116116
printf("\n");
117117

118+
free_commit_graph(graph);
119+
118120
return 0;
119121
}
120122

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
@@ -877,7 +877,6 @@ extern char *git_replace_ref_base;
877877

878878
extern int fsync_object_files;
879879
extern int core_preload_index;
880-
extern int core_commit_graph;
881880
extern int core_apply_sparse_checkout;
882881
extern int precomposed_unicode;
883882
extern int protect_hfs;

commit-graph.c

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

186-
/* global storage */
187-
static struct commit_graph *commit_graph = NULL;
188-
189-
static void prepare_commit_graph_one(const char *obj_dir)
186+
static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
190187
{
191188
char *graph_name;
192189

193-
if (commit_graph)
190+
if (r->objects->commit_graph)
194191
return;
195192

196193
graph_name = get_commit_graph_filename(obj_dir);
197-
commit_graph = load_commit_graph_one(graph_name);
194+
r->objects->commit_graph =
195+
load_commit_graph_one(graph_name);
198196

199197
FREE_AND_NULL(graph_name);
200198
}
201199

202-
static int prepare_commit_graph_run_once = 0;
203-
static void prepare_commit_graph(void)
200+
/*
201+
* Return 1 if commit_graph is non-NULL, and 0 otherwise.
202+
*
203+
* On the first invocation, this function attemps to load the commit
204+
* graph if the_repository is configured to have one.
205+
*/
206+
static int prepare_commit_graph(struct repository *r)
204207
{
205208
struct alternate_object_database *alt;
206209
char *obj_dir;
210+
int config_value;
207211

208-
if (prepare_commit_graph_run_once)
209-
return;
210-
prepare_commit_graph_run_once = 1;
212+
if (r->objects->commit_graph_attempted)
213+
return !!r->objects->commit_graph;
214+
r->objects->commit_graph_attempted = 1;
211215

212-
obj_dir = get_object_directory();
213-
prepare_commit_graph_one(obj_dir);
214-
prepare_alt_odb(the_repository);
215-
for (alt = the_repository->objects->alt_odb_list;
216-
!commit_graph && alt;
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+
*/
224+
return 0;
225+
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;
217231
alt = alt->next)
218-
prepare_commit_graph_one(alt->path);
232+
prepare_commit_graph_one(r, alt->path);
233+
return !!r->objects->commit_graph;
219234
}
220235

221236
static void close_commit_graph(void)
222237
{
223-
if (!commit_graph)
224-
return;
225-
226-
if (commit_graph->graph_fd >= 0) {
227-
munmap((void *)commit_graph->data, commit_graph->data_len);
228-
commit_graph->data = NULL;
229-
close(commit_graph->graph_fd);
230-
}
231-
232-
FREE_AND_NULL(commit_graph);
238+
free_commit_graph(the_repository->objects->commit_graph);
239+
the_repository->objects->commit_graph = NULL;
233240
}
234241

235242
static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos)
@@ -324,8 +331,6 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
324331
{
325332
uint32_t pos;
326333

327-
if (!core_commit_graph)
328-
return 0;
329334
if (item->object.parsed)
330335
return 1;
331336

@@ -335,25 +340,20 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
335340
return 0;
336341
}
337342

338-
int parse_commit_in_graph(struct commit *item)
343+
int parse_commit_in_graph(struct repository *r, struct commit *item)
339344
{
340-
if (!core_commit_graph)
345+
if (!prepare_commit_graph(r))
341346
return 0;
342-
343-
prepare_commit_graph();
344-
if (commit_graph)
345-
return parse_commit_in_graph_one(commit_graph, item);
346-
return 0;
347+
return parse_commit_in_graph_one(r->objects->commit_graph, item);
347348
}
348349

349-
void load_commit_graph_info(struct commit *item)
350+
void load_commit_graph_info(struct repository *r, struct commit *item)
350351
{
351352
uint32_t pos;
352-
if (!core_commit_graph)
353+
if (!prepare_commit_graph(r))
353354
return;
354-
prepare_commit_graph();
355-
if (commit_graph && find_commit_in_graph(item, commit_graph, &pos))
356-
fill_commit_graph_info(item, 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);
357357
}
358358

359359
static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
@@ -379,9 +379,9 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
379379
return load_tree_for_commit(g, (struct commit *)c);
380380
}
381381

382-
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)
383383
{
384-
return get_commit_tree_in_graph_one(commit_graph, c);
384+
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
385385
}
386386

387387
static void write_graph_chunk_fanout(struct hashfile *f,
@@ -697,16 +697,18 @@ void write_commit_graph(const char *obj_dir,
697697
oids.alloc = approximate_object_count() / 4;
698698

699699
if (append) {
700-
prepare_commit_graph_one(obj_dir);
701-
if (commit_graph)
702-
oids.alloc += commit_graph->num_commits;
700+
prepare_commit_graph_one(the_repository, obj_dir);
701+
if (the_repository->objects->commit_graph)
702+
oids.alloc += the_repository->objects->commit_graph->num_commits;
703703
}
704704

705705
if (oids.alloc < 1024)
706706
oids.alloc = 1024;
707707
ALLOC_ARRAY(oids.list, oids.alloc);
708708

709-
if (append && commit_graph) {
709+
if (append && the_repository->objects->commit_graph) {
710+
struct commit_graph *commit_graph =
711+
the_repository->objects->commit_graph;
710712
for (i = 0; i < commit_graph->num_commits; i++) {
711713
const unsigned char *hash = commit_graph->chunk_oid_lookup +
712714
commit_graph->hash_len * i;
@@ -1027,3 +1029,15 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
10271029

10281030
return verify_commit_graph_error;
10291031
}
1032+
1033+
void free_commit_graph(struct commit_graph *g)
1034+
{
1035+
if (!g)
1036+
return;
1037+
if (g->graph_fd >= 0) {
1038+
munmap((void *)g->data, g->data_len);
1039+
g->data = NULL;
1040+
close(g->graph_fd);
1041+
}
1042+
free(g);
1043+
}

commit-graph.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include "repository.h"
66
#include "string-list.h"
77

8+
struct commit;
9+
810
char *get_commit_graph_filename(const char *obj_dir);
911

1012
/*
@@ -17,17 +19,18 @@ char *get_commit_graph_filename(const char *obj_dir);
1719
*
1820
* See parse_commit_buffer() for the fallback after this call.
1921
*/
20-
int parse_commit_in_graph(struct commit *item);
22+
int parse_commit_in_graph(struct repository *r, struct commit *item);
2123

2224
/*
2325
* It is possible that we loaded commit contents from the commit buffer,
2426
* but we also want to ensure the commit-graph content is correctly
2527
* checked and filled. Fill the graph_pos and generation members of
2628
* the given commit.
2729
*/
28-
void load_commit_graph_info(struct commit *item);
30+
void load_commit_graph_info(struct repository *r, struct commit *item);
2931

30-
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);
3134

3235
struct commit_graph {
3336
int graph_fd;
@@ -56,4 +59,6 @@ void write_commit_graph(const char *obj_dir,
5659

5760
int verify_commit_graph(struct repository *r, struct commit_graph *g);
5861

62+
void free_commit_graph(struct commit_graph *);
63+
5964
#endif

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
@@ -1320,11 +1320,6 @@ static int git_default_core_config(const char *var, const char *value)
13201320
return 0;
13211321
}
13221322

1323-
if (!strcmp(var, "core.commitgraph")) {
1324-
core_commit_graph = git_config_bool(var, value);
1325-
return 0;
1326-
}
1327-
13281323
if (!strcmp(var, "core.sparsecheckout")) {
13291324
core_apply_sparse_checkout = git_config_bool(var, value);
13301325
return 0;

environment.c

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

object-store.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#define OBJECT_STORE_H
33

44
#include "oidmap.h"
5+
#include "list.h"
6+
#include "sha1-array.h"
7+
#include "strbuf.h"
58

69
struct alternate_object_database {
710
struct alternate_object_database *next;
@@ -105,6 +108,9 @@ struct raw_object_store {
105108
*/
106109
struct oidmap *replace_map;
107110

111+
struct commit_graph *commit_graph;
112+
unsigned commit_graph_attempted : 1; /* if loading has been attempted */
113+
108114
/*
109115
* private data
110116
*

object.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "alloc.h"
1010
#include "object-store.h"
1111
#include "packfile.h"
12+
#include "commit-graph.h"
1213

1314
unsigned int get_max_object_index(void)
1415
{
@@ -507,6 +508,10 @@ void raw_object_store_clear(struct raw_object_store *o)
507508
oidmap_free(o->replace_map, 1);
508509
FREE_AND_NULL(o->replace_map);
509510

511+
free_commit_graph(o->commit_graph);
512+
o->commit_graph = NULL;
513+
o->commit_graph_attempted = 0;
514+
510515
free_alt_odbs(o);
511516
o->alt_odb_tail = NULL;
512517

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
}

0 commit comments

Comments
 (0)