aboutsummaryrefslogtreecommitdiff
path: root/shallow.c
diff options
context:
space:
mode:
Diffstat (limited to 'shallow.c')
-rw-r--r--shallow.c145
1 files changed, 88 insertions, 57 deletions
diff --git a/shallow.c b/shallow.c
index d9cd4e219c..a8ad92e303 100644
--- a/shallow.c
+++ b/shallow.c
@@ -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);