return !!first_generation;
}
+static void close_commit_graph_one(struct commit_graph *g)
+{
+ if (!g)
+ return;
+
+ close_commit_graph_one(g->base_graph);
+ free_commit_graph(g);
+}
+
void close_commit_graph(struct raw_object_store *o)
{
- free_commit_graph(o->commit_graph);
+ close_commit_graph_one(o->commit_graph);
o->commit_graph = NULL;
}
g->chunk_oid_lookup, g->hash_len, pos);
}
+static void load_oid_from_graph(struct commit_graph *g,
+ uint32_t pos,
+ struct object_id *oid)
+{
+ uint32_t lex_index;
+
+ while (g && pos < g->num_commits_in_base)
+ g = g->base_graph;
+
+ if (!g)
+ BUG("NULL commit-graph");
+
+ if (pos >= g->num_commits + g->num_commits_in_base)
+ die(_("invalid commit position. commit-graph is likely corrupt"));
+
+ lex_index = pos - g->num_commits_in_base;
+
+ hashcpy(oid->hash, g->chunk_oid_lookup + g->hash_len * lex_index);
+}
+
static struct commit_list **insert_parent_or_die(struct repository *r,
struct commit_graph *g,
- uint64_t pos,
+ uint32_t pos,
struct commit_list **pptr)
{
struct commit *c;
struct object_id oid;
- if (pos >= g->num_commits)
- die("invalid parent position %"PRIu64, pos);
+ if (pos >= g->num_commits + g->num_commits_in_base)
+ die("invalid parent position %"PRIu32, pos);
- hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos);
+ load_oid_from_graph(g, pos, &oid);
c = lookup_commit(r, &oid);
if (!c)
die(_("could not find commit %s"), oid_to_hex(&oid));
static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, uint32_t pos)
{
- const unsigned char *commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * pos;
+ const unsigned char *commit_data;
+ uint32_t lex_index;
+
+ while (pos < g->num_commits_in_base)
+ g = g->base_graph;
+
+ lex_index = pos - g->num_commits_in_base;
+ commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * lex_index;
item->graph_pos = pos;
item->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
}
uint32_t *parent_data_ptr;
uint64_t date_low, date_high;
struct commit_list **pptr;
- const unsigned char *commit_data = g->chunk_commit_data + (g->hash_len + 16) * pos;
+ const unsigned char *commit_data;
+ uint32_t lex_index;
- item->object.parsed = 1;
+ while (pos < g->num_commits_in_base)
+ g = g->base_graph;
+
+ if (pos >= g->num_commits + g->num_commits_in_base)
+ die(_("invalid commit position. commit-graph is likely corrupt"));
+
+ /*
+ * Store the "full" position, but then use the
+ * "local" position for the rest of the calculation.
+ */
item->graph_pos = pos;
+ lex_index = pos - g->num_commits_in_base;
+
+ commit_data = g->chunk_commit_data + (g->hash_len + 16) * lex_index;
+
+ item->object.parsed = 1;
item->maybe_tree = NULL;
*pos = item->graph_pos;
return 1;
} else {
- return bsearch_graph(g, &(item->object.oid), pos);
+ struct commit_graph *cur_g = g;
+ uint32_t lex_index;
+
+ while (cur_g && !bsearch_graph(cur_g, &(item->object.oid), &lex_index))
+ cur_g = cur_g->base_graph;
+
+ if (cur_g) {
+ *pos = lex_index + cur_g->num_commits_in_base;
+ return 1;
+ }
+
+ return 0;
}
}
struct commit *c)
{
struct object_id oid;
- const unsigned char *commit_data = g->chunk_commit_data +
- GRAPH_DATA_WIDTH * (c->graph_pos);
+ const unsigned char *commit_data;
+
+ while (c->graph_pos < g->num_commits_in_base)
+ g = g->base_graph;
+
+ commit_data = g->chunk_commit_data +
+ GRAPH_DATA_WIDTH * (c->graph_pos - g->num_commits_in_base);
hashcpy(oid.hash, commit_data);
c->maybe_tree = lookup_tree(r, &oid);