mirror of
https://github.com/git/git.git
synced 2026-01-11 13:23:12 +09:00
Merge branch 'sp/shallow-deepen-relative-fix' into jch
* sp/shallow-deepen-relative-fix: shallow: handling fetch relative-deepen shallow: free local object_array allocations
This commit is contained in:
commit
bf751eebd4
45
shallow.c
45
shallow.c
@ -130,11 +130,12 @@ 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)
|
||||
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)
|
||||
{
|
||||
size_t i = 0;
|
||||
int cur_depth = 0;
|
||||
size_t i = 0, j;
|
||||
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 +169,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 (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,7 +213,9 @@ 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 && deepen_relative)
|
||||
*deepen_relative = cur_depth_shallow;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ int commit_shallow_file(struct repository *r, struct shallow_lock *lk);
|
||||
void rollback_shallow_file(struct repository *r, struct shallow_lock *lk);
|
||||
|
||||
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);
|
||||
struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv,
|
||||
int shallow_flag, int not_shallow_flag);
|
||||
|
||||
@ -955,6 +955,29 @@ test_expect_success 'fetching deepen' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'fetching deepen beyond merged branch' '
|
||||
test_create_repo shallow-deepen-merged &&
|
||||
(
|
||||
cd shallow-deepen-merged &&
|
||||
git commit --allow-empty -m one &&
|
||||
git commit --allow-empty -m two &&
|
||||
git commit --allow-empty -m three &&
|
||||
git switch -c branch &&
|
||||
git commit --allow-empty -m four &&
|
||||
git commit --allow-empty -m five &&
|
||||
git switch main &&
|
||||
git merge --no-ff branch &&
|
||||
cd - &&
|
||||
git clone --bare --depth 3 "file://$(pwd)/shallow-deepen-merged" deepen.git &&
|
||||
git -C deepen.git fetch origin --deepen=1 &&
|
||||
git -C deepen.git rev-list --all >actual &&
|
||||
for commit in $(sed "/^$/d" deepen.git/shallow)
|
||||
do
|
||||
test_grep "$commit" actual || exit 1
|
||||
done
|
||||
)
|
||||
'
|
||||
|
||||
test_negotiation_algorithm_default () {
|
||||
test_when_finished rm -rf clientv0 clientv2 &&
|
||||
rm -rf server client &&
|
||||
|
||||
@ -704,54 +704,11 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int get_reachable_list(struct upload_pack_data *data,
|
||||
struct object_array *reachable)
|
||||
static void get_shallows_depth(struct upload_pack_data *data)
|
||||
{
|
||||
struct child_process cmd = CHILD_PROCESS_INIT;
|
||||
int i;
|
||||
struct object *o;
|
||||
char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
|
||||
const unsigned hexsz = the_hash_algo->hexsz;
|
||||
int ret;
|
||||
|
||||
if (do_reachable_revlist(&cmd, &data->shallows, reachable,
|
||||
data->allow_uor) < 0) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) {
|
||||
struct object_id oid;
|
||||
const char *p;
|
||||
|
||||
if (parse_oid_hex(namebuf, &oid, &p) || *p != '\n')
|
||||
break;
|
||||
|
||||
o = lookup_object(the_repository, &oid);
|
||||
if (o && o->type == OBJ_COMMIT) {
|
||||
o->flags &= ~TMP_MARK;
|
||||
}
|
||||
}
|
||||
for (i = get_max_object_index(the_repository); 0 < i; i--) {
|
||||
o = get_indexed_object(the_repository, i - 1);
|
||||
if (o && o->type == OBJ_COMMIT &&
|
||||
(o->flags & TMP_MARK)) {
|
||||
add_object_array(o, NULL, reachable);
|
||||
o->flags &= ~TMP_MARK;
|
||||
}
|
||||
}
|
||||
close(cmd.out);
|
||||
|
||||
if (finish_command(&cmd)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
child_process_clear(&cmd);
|
||||
return ret;
|
||||
get_shallow_commits(&data->want_obj, &data->shallows,
|
||||
&data->deepen_relative, 0,
|
||||
SHALLOW, NOT_SHALLOW);
|
||||
}
|
||||
|
||||
static int has_unreachable(struct object_array *src, enum allow_uor allow_uor)
|
||||
@ -881,29 +838,14 @@ static void deepen(struct upload_pack_data *data, int depth)
|
||||
struct object *object = data->shallows.objects[i].item;
|
||||
object->flags |= NOT_SHALLOW;
|
||||
}
|
||||
} else if (data->deepen_relative) {
|
||||
struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
|
||||
struct commit_list *result;
|
||||
|
||||
/*
|
||||
* Checking for reachable shallows requires that our refs be
|
||||
* marked with OUR_REF.
|
||||
*/
|
||||
refs_head_ref_namespaced(get_main_ref_store(the_repository),
|
||||
check_ref, data);
|
||||
for_each_namespaced_ref_1(check_ref, data);
|
||||
|
||||
get_reachable_list(data, &reachable_shallows);
|
||||
result = get_shallow_commits(&reachable_shallows,
|
||||
depth + 1,
|
||||
SHALLOW, NOT_SHALLOW);
|
||||
send_shallow(data, result);
|
||||
free_commit_list(result);
|
||||
object_array_clear(&reachable_shallows);
|
||||
} else {
|
||||
struct commit_list *result;
|
||||
|
||||
result = get_shallow_commits(&data->want_obj, depth,
|
||||
if (data->deepen_relative)
|
||||
get_shallows_depth(data);
|
||||
|
||||
result = get_shallow_commits(&data->want_obj, NULL, NULL,
|
||||
data->deepen_relative + depth,
|
||||
SHALLOW, NOT_SHALLOW);
|
||||
send_shallow(data, result);
|
||||
free_commit_list(result);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user