diff options
Diffstat (limited to 'shallow.c')
| -rw-r--r-- | shallow.c | 145 |
1 files changed, 88 insertions, 57 deletions
@@ -40,7 +40,7 @@ int register_shallow(struct repository *r, const struct object_id *oid) oidcpy(&graft->oid, oid); graft->nr_parent = -1; if (commit && commit->object.parsed) { - free_commit_list(commit->parents); + commit_list_free(commit->parents); commit->parents = NULL; } return register_commit_graft(r, graft, 0); @@ -130,11 +130,24 @@ static void free_depth_in_slab(int **ptr) { FREE_AND_NULL(*ptr); } -struct commit_list *get_shallow_commits(struct object_array *heads, int depth, - int shallow_flag, int not_shallow_flag) +/* + * This is a common internal function that can either return a list of + * shallow commits or calculate the current maximum depth of a shallow + * repository, depending on the input parameters. + * + * Depth calculation is triggered by passing the `shallows` parameter. + * In this case, the computed depth is stored in `max_cur_depth` (if it is + * provided), and the function returns NULL. + * + * Otherwise, `max_cur_depth` remains unchanged and the function returns + * a list of shallow commits. + */ +static struct commit_list *get_shallows_or_depth(struct object_array *heads, + struct object_array *shallows, int *max_cur_depth, + int depth, int shallow_flag, int not_shallow_flag) { size_t i = 0; - int cur_depth = 0; + int cur_depth = 0, cur_depth_shallow = 0; struct commit_list *result = NULL; struct object_array stack = OBJECT_ARRAY_INIT; struct commit *commit = NULL; @@ -168,16 +181,30 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth, } parse_commit_or_die(commit); cur_depth++; - if ((depth != INFINITE_DEPTH && cur_depth >= depth) || - (is_repository_shallow(the_repository) && !commit->parents && - (graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL && - graft->nr_parent < 0)) { - commit_list_insert(commit, &result); - commit->object.flags |= shallow_flag; - commit = NULL; - continue; + if (shallows) { + for (size_t j = 0; j < shallows->nr; j++) + if (oideq(&commit->object.oid, &shallows->objects[j].item->oid)) + if (!cur_depth_shallow || cur_depth < cur_depth_shallow) + cur_depth_shallow = cur_depth; + + if ((is_repository_shallow(the_repository) && !commit->parents && + (graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL && + graft->nr_parent < 0)) { + commit = NULL; + continue; + } + } else { + if ((depth != INFINITE_DEPTH && cur_depth >= depth) || + (is_repository_shallow(the_repository) && !commit->parents && + (graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL && + graft->nr_parent < 0)) { + commit_list_insert(commit, &result); + commit->object.flags |= shallow_flag; + commit = NULL; + continue; + } + commit->object.flags |= not_shallow_flag; } - commit->object.flags |= not_shallow_flag; for (p = commit->parents, commit = NULL; p; p = p->next) { int **depth_slot = commit_depth_at(&depths, p->item); if (!*depth_slot) { @@ -198,10 +225,32 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth, } } deep_clear_commit_depth(&depths, free_depth_in_slab); + object_array_clear(&stack); + if (shallows && max_cur_depth) + *max_cur_depth = cur_depth_shallow; return result; } +int get_shallows_depth(struct object_array *heads, struct object_array *shallows) +{ + int max_cur_depth = 0; + get_shallows_or_depth(heads, shallows, &max_cur_depth, 0, 0, 0); + return max_cur_depth; + +} + +struct commit_list *get_shallow_commits(struct object_array *heads, + struct object_array *shallows, int deepen_relative, + int depth, int shallow_flag, int not_shallow_flag) +{ + if (shallows && deepen_relative) { + depth += get_shallows_depth(heads, shallows); + } + return get_shallows_or_depth(heads, NULL, NULL, + depth, shallow_flag, not_shallow_flag); +} + static void show_commit(struct commit *commit, void *data) { commit_list_insert(commit, data); @@ -267,7 +316,7 @@ struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv, break; } } - free_commit_list(not_shallow_list); + commit_list_free(not_shallow_list); /* * Now we can clean up NOT_SHALLOW on border commits. Having @@ -311,7 +360,7 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data) return 0; if (data->flags & QUICK) { if (!odb_has_object(the_repository->objects, &graft->oid, - HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) + ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR)) return 0; } else if (data->flags & SEEN_ONLY) { struct commit *c = lookup_commit(the_repository, &graft->oid); @@ -471,6 +520,7 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) { trace_printf_key(&trace_shallow, "shallow: prepare_shallow_info\n"); memset(info, 0, sizeof(*info)); + commit_stack_init(&info->commits); info->shallow = sa; if (!sa) return; @@ -478,7 +528,7 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) ALLOC_ARRAY(info->theirs, sa->nr); for (size_t i = 0; i < sa->nr; i++) { if (odb_has_object(the_repository->objects, sa->oid + i, - HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) { + ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR)) { struct commit_graft *graft; graft = lookup_commit_graft(the_repository, &sa->oid[i]); @@ -503,6 +553,7 @@ void clear_shallow_info(struct shallow_info *info) free(info->shallow_ref); free(info->ours); free(info->theirs); + commit_stack_clear(&info->commits); } /* Step 4, remove non-existent ones in "theirs" after getting the pack */ @@ -516,7 +567,7 @@ void remove_nonexistent_theirs_shallow(struct shallow_info *info) if (i != dst) info->theirs[dst] = info->theirs[i]; if (odb_has_object(the_repository->objects, oid + info->theirs[i], - HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR)) + ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR)) dst++; } info->nr_theirs = dst; @@ -626,14 +677,10 @@ static void paint_down(struct paint_info *info, const struct object_id *oid, free(tmp); } -static int mark_uninteresting(const char *refname UNUSED, - const char *referent UNUSED, - const struct object_id *oid, - int flags UNUSED, - void *cb_data UNUSED) +static int mark_uninteresting(const struct reference *ref, void *cb_data UNUSED) { struct commit *commit = lookup_commit_reference_gently(the_repository, - oid, 1); + ref->oid, 1); if (!commit) return 0; commit->object.flags |= UNINTERESTING; @@ -713,7 +760,7 @@ void assign_shallow_commits_to_refs(struct shallow_info *info, if (used) { int bitmap_size = DIV_ROUND_UP(pi.nr_bits, 32) * sizeof(uint32_t); - memset(used, 0, sizeof(*used) * info->shallow->nr); + MEMZERO_ARRAY(used, info->shallow->nr); for (i = 0; i < nr_shallow; i++) { const struct commit *c = lookup_commit(the_repository, &oid[shallow[i]]); @@ -737,23 +784,13 @@ void assign_shallow_commits_to_refs(struct shallow_info *info, free(shallow); } -struct commit_array { - struct commit **commits; - size_t nr, alloc; -}; - -static int add_ref(const char *refname UNUSED, - const char *referent UNUSED, - const struct object_id *oid, - int flags UNUSED, - void *cb_data) +static int add_ref(const struct reference *ref, void *cb_data) { - struct commit_array *ca = cb_data; - ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc); - ca->commits[ca->nr] = lookup_commit_reference_gently(the_repository, - oid, 1); - if (ca->commits[ca->nr]) - ca->nr++; + struct commit_stack *cs = cb_data; + struct commit *commit = lookup_commit_reference_gently(the_repository, + ref->oid, 1); + if (commit) + commit_stack_push(cs, commit); return 0; } @@ -778,11 +815,11 @@ static void post_assign_shallow(struct shallow_info *info, uint32_t **bitmap; size_t dst, i, j; size_t bitmap_nr = DIV_ROUND_UP(info->ref->nr, 32); - struct commit_array ca; + struct commit_stack cs = COMMIT_STACK_INIT; trace_printf_key(&trace_shallow, "shallow: post_assign_shallow\n"); if (ref_status) - memset(ref_status, 0, sizeof(*ref_status) * info->ref->nr); + MEMZERO_ARRAY(ref_status, info->ref->nr); /* Remove unreachable shallow commits from "theirs" */ for (i = dst = 0; i < info->nr_theirs; i++) { @@ -801,9 +838,8 @@ static void post_assign_shallow(struct shallow_info *info, } info->nr_theirs = dst; - memset(&ca, 0, sizeof(ca)); - refs_head_ref(get_main_ref_store(the_repository), add_ref, &ca); - refs_for_each_ref(get_main_ref_store(the_repository), add_ref, &ca); + refs_head_ref(get_main_ref_store(the_repository), add_ref, &cs); + refs_for_each_ref(get_main_ref_store(the_repository), add_ref, &cs); /* Remove unreachable shallow commits from "ours" */ for (i = dst = 0; i < info->nr_ours; i++) { @@ -816,7 +852,7 @@ static void post_assign_shallow(struct shallow_info *info, for (j = 0; j < bitmap_nr; j++) if (bitmap[0][j]) { /* Step 7, reachability test at commit level */ - int ret = repo_in_merge_bases_many(the_repository, c, ca.nr, ca.commits, 1); + int ret = repo_in_merge_bases_many(the_repository, c, cs.nr, cs.items, 1); if (ret < 0) exit(128); if (!ret) { @@ -828,7 +864,7 @@ static void post_assign_shallow(struct shallow_info *info, } info->nr_ours = dst; - free(ca.commits); + commit_stack_clear(&cs); } /* (Delayed) step 7, reachability test at commit level */ @@ -838,22 +874,17 @@ int delayed_reachability_test(struct shallow_info *si, int c) struct commit *commit = lookup_commit(the_repository, &si->shallow->oid[c]); - if (!si->commits) { - struct commit_array ca; - - memset(&ca, 0, sizeof(ca)); + if (!si->commits.nr) { refs_head_ref(get_main_ref_store(the_repository), - add_ref, &ca); + add_ref, &si->commits); refs_for_each_ref(get_main_ref_store(the_repository), - add_ref, &ca); - si->commits = ca.commits; - si->nr_commits = ca.nr; + add_ref, &si->commits); } si->reachable[c] = repo_in_merge_bases_many(the_repository, commit, - si->nr_commits, - si->commits, + si->commits.nr, + si->commits.items, 1); if (si->reachable[c] < 0) exit(128); |
