summaryrefslogtreecommitdiff
path: root/commit-graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'commit-graph.c')
-rw-r--r--commit-graph.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/commit-graph.c b/commit-graph.c
index f78a8e9..30f1781 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -23,18 +23,12 @@
#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
#define GRAPH_CHUNKID_LARGEEDGES 0x45444745 /* "EDGE" */
-#define GRAPH_DATA_WIDTH 36
+#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16)
#define GRAPH_VERSION_1 0x1
#define GRAPH_VERSION GRAPH_VERSION_1
-#define GRAPH_OID_VERSION_SHA1 1
-#define GRAPH_OID_LEN_SHA1 GIT_SHA1_RAWSZ
-#define GRAPH_OID_VERSION GRAPH_OID_VERSION_SHA1
-#define GRAPH_OID_LEN GRAPH_OID_LEN_SHA1
-
#define GRAPH_OCTOPUS_EDGES_NEEDED 0x80000000
-#define GRAPH_PARENT_MISSING 0x7fffffff
#define GRAPH_EDGE_LAST_MASK 0x7fffffff
#define GRAPH_PARENT_NONE 0x70000000
@@ -44,13 +38,18 @@
#define GRAPH_FANOUT_SIZE (4 * 256)
#define GRAPH_CHUNKLOOKUP_WIDTH 12
#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * GRAPH_CHUNKLOOKUP_WIDTH \
- + GRAPH_FANOUT_SIZE + GRAPH_OID_LEN)
+ + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz)
char *get_commit_graph_filename(const char *obj_dir)
{
return xstrfmt("%s/info/commit-graph", obj_dir);
}
+static uint8_t oid_version(void)
+{
+ return 1;
+}
+
static struct commit_graph *alloc_commit_graph(void)
{
struct commit_graph *g = xcalloc(1, sizeof(*g));
@@ -125,15 +124,15 @@ struct commit_graph *load_commit_graph_one(const char *graph_file)
}
hash_version = *(unsigned char*)(data + 5);
- if (hash_version != GRAPH_OID_VERSION) {
+ if (hash_version != oid_version()) {
error(_("hash version %X does not match version %X"),
- hash_version, GRAPH_OID_VERSION);
+ hash_version, oid_version());
goto cleanup_fail;
}
graph = alloc_commit_graph();
- graph->hash_len = GRAPH_OID_LEN;
+ graph->hash_len = the_hash_algo->rawsz;
graph->num_chunks = *(unsigned char*)(data + 6);
graph->graph_fd = fd;
graph->data = graph_map;
@@ -149,7 +148,7 @@ struct commit_graph *load_commit_graph_one(const char *graph_file)
chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH;
- if (chunk_offset > graph_size - GIT_MAX_RAWSZ) {
+ if (chunk_offset > graph_size - the_hash_algo->rawsz) {
error(_("improper chunk offset %08x%08x"), (uint32_t)(chunk_offset >> 32),
(uint32_t)chunk_offset);
goto cleanup_fail;
@@ -230,8 +229,7 @@ static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
*/
static int prepare_commit_graph(struct repository *r)
{
- struct alternate_object_database *alt;
- char *obj_dir;
+ struct object_directory *odb;
int config_value;
if (r->objects->commit_graph_attempted)
@@ -252,13 +250,11 @@ static int prepare_commit_graph(struct repository *r)
if (!commit_graph_compatible(r))
return 0;
- obj_dir = r->objects->objectdir;
- prepare_commit_graph_one(r, obj_dir);
prepare_alt_odb(r);
- for (alt = r->objects->alt_odb_list;
- !r->objects->commit_graph && alt;
- alt = alt->next)
- prepare_commit_graph_one(r, alt->path);
+ for (odb = r->objects->odb;
+ !r->objects->commit_graph && odb;
+ odb = odb->next)
+ prepare_commit_graph_one(r, odb->path);
return !!r->objects->commit_graph;
}
@@ -504,7 +500,9 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
commit_to_sha1);
if (edge_value < 0)
- edge_value = GRAPH_PARENT_MISSING;
+ BUG("missing parent %s for commit %s",
+ oid_to_hex(&parent->item->object.oid),
+ oid_to_hex(&(*list)->object.oid));
}
hashwrite_be32(f, edge_value);
@@ -522,7 +520,9 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
nr_commits,
commit_to_sha1);
if (edge_value < 0)
- edge_value = GRAPH_PARENT_MISSING;
+ BUG("missing parent %s for commit %s",
+ oid_to_hex(&parent->item->object.oid),
+ oid_to_hex(&(*list)->object.oid));
}
hashwrite_be32(f, edge_value);
@@ -575,7 +575,9 @@ static void write_graph_chunk_large_edges(struct hashfile *f,
commit_to_sha1);
if (edge_value < 0)
- edge_value = GRAPH_PARENT_MISSING;
+ BUG("missing parent %s for commit %s",
+ oid_to_hex(&parent->item->object.oid),
+ oid_to_hex(&(*list)->object.oid));
else if (!parent->next)
edge_value |= GRAPH_LAST_EDGE;
@@ -649,26 +651,29 @@ static void add_missing_parents(struct packed_oid_list *oids, struct commit *com
static void close_reachable(struct packed_oid_list *oids, int report_progress)
{
- int i;
+ int i, j;
struct commit *commit;
struct progress *progress = NULL;
- int j = 0;
if (report_progress)
progress = start_delayed_progress(
- _("Annotating commits in commit graph"), 0);
+ _("Loading known commits in commit graph"), j = 0);
for (i = 0; i < oids->nr; i++) {
display_progress(progress, ++j);
commit = lookup_commit(the_repository, &oids->list[i]);
if (commit)
commit->object.flags |= UNINTERESTING;
}
+ stop_progress(&progress);
/*
* As this loop runs, oids->nr may grow, but not more
* than the number of missing commits in the reachable
* closure.
*/
+ if (report_progress)
+ progress = start_delayed_progress(
+ _("Expanding reachable commits in commit graph"), j = 0);
for (i = 0; i < oids->nr; i++) {
display_progress(progress, ++j);
commit = lookup_commit(the_repository, &oids->list[i]);
@@ -676,7 +681,11 @@ static void close_reachable(struct packed_oid_list *oids, int report_progress)
if (commit && !parse_commit(commit))
add_missing_parents(oids, commit);
}
+ stop_progress(&progress);
+ if (report_progress)
+ progress = start_delayed_progress(
+ _("Clearing commit marks in commit graph"), j = 0);
for (i = 0; i < oids->nr; i++) {
display_progress(progress, ++j);
commit = lookup_commit(the_repository, &oids->list[i]);
@@ -772,6 +781,7 @@ void write_commit_graph(const char *obj_dir,
int num_extra_edges;
struct commit_list *parent;
struct progress *progress = NULL;
+ const unsigned hashsz = the_hash_algo->rawsz;
if (!commit_graph_compatible(the_repository))
return;
@@ -872,7 +882,7 @@ void write_commit_graph(const char *obj_dir,
count_distinct++;
}
- if (count_distinct >= GRAPH_PARENT_MISSING)
+ if (count_distinct >= GRAPH_EDGE_LAST_MASK)
die(_("the commit graph format cannot write %d commits"), count_distinct);
commits.nr = 0;
@@ -899,7 +909,7 @@ void write_commit_graph(const char *obj_dir,
}
num_chunks = num_extra_edges ? 4 : 3;
- if (commits.nr >= GRAPH_PARENT_MISSING)
+ if (commits.nr >= GRAPH_EDGE_LAST_MASK)
die(_("too many commits to write graph"));
compute_generation_numbers(&commits, report_progress);
@@ -917,7 +927,7 @@ void write_commit_graph(const char *obj_dir,
hashwrite_be32(f, GRAPH_SIGNATURE);
hashwrite_u8(f, GRAPH_VERSION);
- hashwrite_u8(f, GRAPH_OID_VERSION);
+ hashwrite_u8(f, oid_version());
hashwrite_u8(f, num_chunks);
hashwrite_u8(f, 0); /* unused padding byte */
@@ -932,8 +942,8 @@ void write_commit_graph(const char *obj_dir,
chunk_offsets[0] = 8 + (num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH;
chunk_offsets[1] = chunk_offsets[0] + GRAPH_FANOUT_SIZE;
- chunk_offsets[2] = chunk_offsets[1] + GRAPH_OID_LEN * commits.nr;
- chunk_offsets[3] = chunk_offsets[2] + (GRAPH_OID_LEN + 16) * commits.nr;
+ chunk_offsets[2] = chunk_offsets[1] + hashsz * commits.nr;
+ chunk_offsets[3] = chunk_offsets[2] + (hashsz + 16) * commits.nr;
chunk_offsets[4] = chunk_offsets[3] + 4 * num_extra_edges;
for (i = 0; i <= num_chunks; i++) {
@@ -946,8 +956,8 @@ void write_commit_graph(const char *obj_dir,
}
write_graph_chunk_fanout(f, commits.list, commits.nr);
- write_graph_chunk_oids(f, GRAPH_OID_LEN, commits.list, commits.nr);
- write_graph_chunk_data(f, GRAPH_OID_LEN, commits.list, commits.nr);
+ write_graph_chunk_oids(f, hashsz, commits.list, commits.nr);
+ write_graph_chunk_data(f, hashsz, commits.list, commits.nr);
write_graph_chunk_large_edges(f, commits.list, commits.nr);
close_commit_graph(the_repository);