aboutsummaryrefslogtreecommitdiff
path: root/commit-graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'commit-graph.c')
-rw-r--r--commit-graph.c158
1 files changed, 86 insertions, 72 deletions
diff --git a/commit-graph.c b/commit-graph.c
index 474454db73..df4b4a125e 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -965,7 +965,7 @@ static int fill_commit_in_graph(struct commit *item,
do {
if (g->chunk_extra_edges_size / sizeof(uint32_t) <= parent_data_pos) {
error(_("commit-graph extra-edges pointer out of bounds"));
- free_commit_list(item->parents);
+ commit_list_free(item->parents);
item->parents = NULL;
item->object.parsed = 0;
return 0;
@@ -1127,18 +1127,12 @@ struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
}
-struct packed_commit_list {
- struct commit **list;
- size_t nr;
- size_t alloc;
-};
-
struct write_commit_graph_context {
struct repository *r;
struct odb_source *odb_source;
char *graph_name;
struct oid_array oids;
- struct packed_commit_list commits;
+ struct commit_stack commits;
int num_extra_edges;
int num_generation_data_overflows;
unsigned long approx_nr_objects;
@@ -1180,7 +1174,7 @@ static int write_graph_chunk_fanout(struct hashfile *f,
{
struct write_commit_graph_context *ctx = data;
int i, count = 0;
- struct commit **list = ctx->commits.list;
+ struct commit **list = ctx->commits.items;
/*
* Write the first-level table (the list is sorted,
@@ -1206,7 +1200,7 @@ static int write_graph_chunk_oids(struct hashfile *f,
void *data)
{
struct write_commit_graph_context *ctx = data;
- struct commit **list = ctx->commits.list;
+ struct commit **list = ctx->commits.items;
int count;
for (count = 0; count < ctx->commits.nr; count++, list++) {
display_progress(ctx->progress, ++ctx->progress_cnt);
@@ -1226,8 +1220,8 @@ static int write_graph_chunk_data(struct hashfile *f,
void *data)
{
struct write_commit_graph_context *ctx = data;
- struct commit **list = ctx->commits.list;
- struct commit **last = ctx->commits.list + ctx->commits.nr;
+ struct commit **list = ctx->commits.items;
+ struct commit **last = ctx->commits.items + ctx->commits.nr;
uint32_t num_extra_edges = 0;
while (list < last) {
@@ -1249,7 +1243,7 @@ static int write_graph_chunk_data(struct hashfile *f,
edge_value = GRAPH_PARENT_NONE;
else {
edge_value = oid_pos(&parent->item->object.oid,
- ctx->commits.list,
+ ctx->commits.items,
ctx->commits.nr,
commit_to_oid);
@@ -1280,7 +1274,7 @@ static int write_graph_chunk_data(struct hashfile *f,
edge_value = GRAPH_EXTRA_EDGES_NEEDED | num_extra_edges;
else {
edge_value = oid_pos(&parent->item->object.oid,
- ctx->commits.list,
+ ctx->commits.items,
ctx->commits.nr,
commit_to_oid);
@@ -1332,7 +1326,7 @@ static int write_graph_chunk_generation_data(struct hashfile *f,
int i, num_generation_data_overflows = 0;
for (i = 0; i < ctx->commits.nr; i++) {
- struct commit *c = ctx->commits.list[i];
+ struct commit *c = ctx->commits.items[i];
timestamp_t offset;
repo_parse_commit(ctx->r, c);
offset = commit_graph_data_at(c)->generation - c->date;
@@ -1355,7 +1349,7 @@ static int write_graph_chunk_generation_data_overflow(struct hashfile *f,
struct write_commit_graph_context *ctx = data;
int i;
for (i = 0; i < ctx->commits.nr; i++) {
- struct commit *c = ctx->commits.list[i];
+ struct commit *c = ctx->commits.items[i];
timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
display_progress(ctx->progress, ++ctx->progress_cnt);
@@ -1372,8 +1366,8 @@ static int write_graph_chunk_extra_edges(struct hashfile *f,
void *data)
{
struct write_commit_graph_context *ctx = data;
- struct commit **list = ctx->commits.list;
- struct commit **last = ctx->commits.list + ctx->commits.nr;
+ struct commit **list = ctx->commits.items;
+ struct commit **last = ctx->commits.items + ctx->commits.nr;
struct commit_list *parent;
while (list < last) {
@@ -1393,7 +1387,7 @@ static int write_graph_chunk_extra_edges(struct hashfile *f,
/* Since num_parents > 2, this initializer is safe. */
for (parent = (*list)->parents->next; parent; parent = parent->next) {
int edge_value = oid_pos(&parent->item->object.oid,
- ctx->commits.list,
+ ctx->commits.items,
ctx->commits.nr,
commit_to_oid);
@@ -1427,8 +1421,8 @@ static int write_graph_chunk_bloom_indexes(struct hashfile *f,
void *data)
{
struct write_commit_graph_context *ctx = data;
- struct commit **list = ctx->commits.list;
- struct commit **last = ctx->commits.list + ctx->commits.nr;
+ struct commit **list = ctx->commits.items;
+ struct commit **last = ctx->commits.items + ctx->commits.nr;
uint32_t cur_pos = 0;
while (list < last) {
@@ -1463,8 +1457,8 @@ static int write_graph_chunk_bloom_data(struct hashfile *f,
void *data)
{
struct write_commit_graph_context *ctx = data;
- struct commit **list = ctx->commits.list;
- struct commit **last = ctx->commits.list + ctx->commits.nr;
+ struct commit **list = ctx->commits.items;
+ struct commit **last = ctx->commits.items + ctx->commits.nr;
trace2_bloom_filter_settings(ctx);
@@ -1485,24 +1479,16 @@ static int write_graph_chunk_bloom_data(struct hashfile *f,
return 0;
}
-static int add_packed_commits(const struct object_id *oid,
- struct packed_git *pack,
- uint32_t pos,
- void *data)
+static int add_packed_commits_oi(const struct object_id *oid,
+ struct object_info *oi,
+ void *data)
{
struct write_commit_graph_context *ctx = (struct write_commit_graph_context*)data;
- enum object_type type;
- off_t offset = nth_packed_object_offset(pack, pos);
- struct object_info oi = OBJECT_INFO_INIT;
if (ctx->progress)
display_progress(ctx->progress, ++ctx->progress_done);
- oi.typep = &type;
- if (packed_object_info(ctx->r, pack, offset, &oi) < 0)
- die(_("unable to get type of object %s"), oid_to_hex(oid));
-
- if (type != OBJ_COMMIT)
+ if (*oi->typep != OBJ_COMMIT)
return 0;
oid_array_append(&ctx->oids, oid);
@@ -1511,6 +1497,22 @@ static int add_packed_commits(const struct object_id *oid,
return 0;
}
+static int add_packed_commits(const struct object_id *oid,
+ struct packed_git *pack,
+ uint32_t pos,
+ void *data)
+{
+ enum object_type type;
+ off_t offset = nth_packed_object_offset(pack, pos);
+ struct object_info oi = OBJECT_INFO_INIT;
+
+ oi.typep = &type;
+ if (packed_object_info(pack, offset, &oi) < 0)
+ die(_("unable to get type of object %s"), oid_to_hex(oid));
+
+ return add_packed_commits_oi(oid, &oi, data);
+}
+
static void add_missing_parents(struct write_commit_graph_context *ctx, struct commit *commit)
{
struct commit_list *parent;
@@ -1585,7 +1587,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
struct compute_generation_info {
struct repository *r;
- struct packed_commit_list *commits;
+ struct commit_stack *commits;
struct progress *progress;
int progress_cnt;
@@ -1622,7 +1624,7 @@ static void compute_reachable_generation_numbers(
struct commit_list *list = NULL;
for (i = 0; i < info->commits->nr; i++) {
- struct commit *c = info->commits->list[i];
+ struct commit *c = info->commits->items[i];
timestamp_t gen;
repo_parse_commit(info->r, c);
gen = info->get_generation(c, info->data);
@@ -1729,7 +1731,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
if (!ctx->trust_generation_numbers) {
for (i = 0; i < ctx->commits.nr; i++) {
- struct commit *c = ctx->commits.list[i];
+ struct commit *c = ctx->commits.items[i];
repo_parse_commit(ctx->r, c);
commit_graph_data_at(c)->generation = GENERATION_NUMBER_ZERO;
}
@@ -1738,7 +1740,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
compute_reachable_generation_numbers(&info, 2);
for (i = 0; i < ctx->commits.nr; i++) {
- struct commit *c = ctx->commits.list[i];
+ struct commit *c = ctx->commits.items[i];
timestamp_t offset = commit_graph_data_at(c)->generation - c->date;
if (offset > GENERATION_NUMBER_V2_OFFSET_MAX)
ctx->num_generation_data_overflows++;
@@ -1760,8 +1762,8 @@ void ensure_generations_valid(struct repository *r,
struct commit **commits, size_t nr)
{
int generation_version = get_configured_generation_version(r);
- struct packed_commit_list list = {
- .list = commits,
+ struct commit_stack list = {
+ .items = commits,
.alloc = nr,
.nr = nr,
};
@@ -1804,7 +1806,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
_("Computing commit changed paths Bloom filters"),
ctx->commits.nr);
- DUP_ARRAY(sorted_commits, ctx->commits.list, ctx->commits.nr);
+ DUP_ARRAY(sorted_commits, ctx->commits.items, ctx->commits.nr);
if (ctx->order_by_pack)
QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
@@ -1851,18 +1853,16 @@ struct refs_cb_data {
struct progress *progress;
};
-static int add_ref_to_set(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED, void *cb_data)
+static int add_ref_to_set(const struct reference *ref, void *cb_data)
{
+ const struct object_id *maybe_peeled = ref->oid;
struct object_id peeled;
struct refs_cb_data *data = (struct refs_cb_data *)cb_data;
- if (!peel_iterated_oid(data->repo, oid, &peeled))
- oid = &peeled;
- if (odb_read_object_info(data->repo->objects, oid, NULL) == OBJ_COMMIT)
- oidset_insert(data->commits, oid);
+ if (!reference_get_peeled_oid(data->repo, ref, &peeled))
+ maybe_peeled = &peeled;
+ if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) == OBJ_COMMIT)
+ oidset_insert(data->commits, maybe_peeled);
display_progress(data->progress, oidset_size(data->commits));
@@ -1935,7 +1935,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
goto cleanup;
}
for_each_object_in_pack(p, add_packed_commits, ctx,
- FOR_EACH_OBJECT_PACK_ORDER);
+ ODB_FOR_EACH_OBJECT_PACK_ORDER);
close_pack(p);
free(p);
}
@@ -1967,13 +1967,28 @@ static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx)
{
+ struct odb_source *source;
+ enum object_type type;
+ struct odb_for_each_object_options opts = {
+ .flags = ODB_FOR_EACH_OBJECT_PACK_ORDER,
+ };
+ struct object_info oi = {
+ .typep = &type,
+ };
+
if (ctx->report_progress)
ctx->progress = start_delayed_progress(
ctx->r,
_("Finding commits for commit graph among packed objects"),
ctx->approx_nr_objects);
- for_each_packed_object(ctx->r, add_packed_commits, ctx,
- FOR_EACH_OBJECT_PACK_ORDER);
+
+ odb_prepare_alternates(ctx->r->objects);
+ for (source = ctx->r->objects->sources; source; source = source->next) {
+ struct odb_source_files *files = odb_source_files_downcast(source);
+ packfile_store_for_each_object(files->packed, &oi, add_packed_commits_oi,
+ ctx, &opts);
+ }
+
if (ctx->progress_done < ctx->approx_nr_objects)
display_progress(ctx->progress, ctx->approx_nr_objects);
stop_progress(&ctx->progress);
@@ -1994,26 +2009,26 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
oid_array_sort(&ctx->oids);
for (i = 0; i < ctx->oids.nr; i = oid_array_next_unique(&ctx->oids, i)) {
unsigned int num_parents;
+ struct commit *commit;
display_progress(ctx->progress, i + 1);
- ALLOC_GROW(ctx->commits.list, ctx->commits.nr + 1, ctx->commits.alloc);
- ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.oid[i]);
+ commit = lookup_commit(ctx->r, &ctx->oids.oid[i]);
if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE &&
- commit_graph_position(ctx->commits.list[ctx->commits.nr]) != COMMIT_NOT_FROM_GRAPH)
+ commit_graph_position(commit) != COMMIT_NOT_FROM_GRAPH)
continue;
if (ctx->split && flags == COMMIT_GRAPH_SPLIT_REPLACE)
- repo_parse_commit(ctx->r, ctx->commits.list[ctx->commits.nr]);
+ repo_parse_commit(ctx->r, commit);
else
- repo_parse_commit_no_graph(ctx->r, ctx->commits.list[ctx->commits.nr]);
+ repo_parse_commit_no_graph(ctx->r, commit);
- num_parents = commit_list_count(ctx->commits.list[ctx->commits.nr]->parents);
+ num_parents = commit_list_count(commit->parents);
if (num_parents > 2)
ctx->num_extra_edges += num_parents - 1;
- ctx->commits.nr++;
+ commit_stack_push(&ctx->commits, commit);
}
stop_progress(&ctx->progress);
}
@@ -2332,7 +2347,7 @@ static void merge_commit_graph(struct write_commit_graph_context *ctx,
oid_to_hex(&g->oid),
(uintmax_t)st_add(ctx->commits.nr, g->num_commits));
- ALLOC_GROW(ctx->commits.list, ctx->commits.nr + g->num_commits, ctx->commits.alloc);
+ commit_stack_grow(&ctx->commits, g->num_commits);
for (i = 0; i < g->num_commits; i++) {
struct object_id oid;
@@ -2345,10 +2360,8 @@ static void merge_commit_graph(struct write_commit_graph_context *ctx,
/* only add commits if they still exist in the repo */
result = lookup_commit_reference_gently(ctx->r, &oid, 1);
- if (result) {
- ctx->commits.list[ctx->commits.nr] = result;
- ctx->commits.nr++;
- }
+ if (result)
+ commit_stack_push(&ctx->commits, result);
}
}
@@ -2369,14 +2382,14 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
_("Scanning merged commits"),
ctx->commits.nr);
- QSORT(ctx->commits.list, ctx->commits.nr, commit_compare);
+ QSORT(ctx->commits.items, ctx->commits.nr, commit_compare);
ctx->num_extra_edges = 0;
for (i = 0; i < ctx->commits.nr; i++) {
display_progress(ctx->progress, i + 1);
- if (i && oideq(&ctx->commits.list[i - 1]->object.oid,
- &ctx->commits.list[i]->object.oid)) {
+ if (i && oideq(&ctx->commits.items[i - 1]->object.oid,
+ &ctx->commits.items[i]->object.oid)) {
/*
* Silently ignore duplicates. These were likely
* created due to a commit appearing in multiple
@@ -2387,10 +2400,10 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx)
} else {
unsigned int num_parents;
- ctx->commits.list[dedup_i] = ctx->commits.list[i];
+ ctx->commits.items[dedup_i] = ctx->commits.items[i];
dedup_i++;
- num_parents = commit_list_count(ctx->commits.list[i]->parents);
+ num_parents = commit_list_count(ctx->commits.items[i]->parents);
if (num_parents > 2)
ctx->num_extra_edges += num_parents - 1;
}
@@ -2597,7 +2610,8 @@ int write_commit_graph(struct odb_source *source,
replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE;
}
- ctx.approx_nr_objects = repo_approximate_object_count(r);
+ if (odb_count_objects(r->objects, ODB_COUNT_OBJECTS_APPROXIMATE, &ctx.approx_nr_objects) < 0)
+ ctx.approx_nr_objects = 0;
if (ctx.append && g) {
for (i = 0; i < g->num_commits; i++) {
@@ -2668,7 +2682,7 @@ int write_commit_graph(struct odb_source *source,
cleanup:
free(ctx.graph_name);
free(ctx.base_graph_name);
- free(ctx.commits.list);
+ commit_stack_clear(&ctx.commits);
oid_array_clear(&ctx.oids);
clear_topo_level_slab(&topo_levels);