mirror of
https://github.com/git/git.git
synced 2026-01-11 21:33:13 +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);
|
FREE_AND_NULL(*ptr);
|
||||||
}
|
}
|
||||||
struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
|
struct commit_list *get_shallow_commits(struct object_array *heads,
|
||||||
int shallow_flag, int not_shallow_flag)
|
struct object_array *shallows, int *deepen_relative,
|
||||||
|
int depth, int shallow_flag, int not_shallow_flag)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0, j;
|
||||||
int cur_depth = 0;
|
int cur_depth = 0, cur_depth_shallow = 0;
|
||||||
struct commit_list *result = NULL;
|
struct commit_list *result = NULL;
|
||||||
struct object_array stack = OBJECT_ARRAY_INIT;
|
struct object_array stack = OBJECT_ARRAY_INIT;
|
||||||
struct commit *commit = NULL;
|
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);
|
parse_commit_or_die(commit);
|
||||||
cur_depth++;
|
cur_depth++;
|
||||||
if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
|
if (shallows) {
|
||||||
(is_repository_shallow(the_repository) && !commit->parents &&
|
for (j = 0; j < shallows->nr; j++)
|
||||||
(graft = lookup_commit_graft(the_repository, &commit->object.oid)) != NULL &&
|
if (oideq(&commit->object.oid, &shallows->objects[j].item->oid))
|
||||||
graft->nr_parent < 0)) {
|
if ((!cur_depth_shallow) || (cur_depth < cur_depth_shallow))
|
||||||
commit_list_insert(commit, &result);
|
cur_depth_shallow = cur_depth;
|
||||||
commit->object.flags |= shallow_flag;
|
|
||||||
commit = NULL;
|
if ((is_repository_shallow(the_repository) && !commit->parents &&
|
||||||
continue;
|
(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) {
|
for (p = commit->parents, commit = NULL; p; p = p->next) {
|
||||||
int **depth_slot = commit_depth_at(&depths, p->item);
|
int **depth_slot = commit_depth_at(&depths, p->item);
|
||||||
if (!*depth_slot) {
|
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);
|
deep_clear_commit_depth(&depths, free_depth_in_slab);
|
||||||
|
object_array_clear(&stack);
|
||||||
|
if (shallows && deepen_relative)
|
||||||
|
*deepen_relative = cur_depth_shallow;
|
||||||
return result;
|
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);
|
void rollback_shallow_file(struct repository *r, struct shallow_lock *lk);
|
||||||
|
|
||||||
struct commit_list *get_shallow_commits(struct object_array *heads,
|
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);
|
int depth, int shallow_flag, int not_shallow_flag);
|
||||||
struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv,
|
struct commit_list *get_shallow_commits_by_rev_list(struct strvec *argv,
|
||||||
int shallow_flag, int not_shallow_flag);
|
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_negotiation_algorithm_default () {
|
||||||
test_when_finished rm -rf clientv0 clientv2 &&
|
test_when_finished rm -rf clientv0 clientv2 &&
|
||||||
rm -rf server client &&
|
rm -rf server client &&
|
||||||
|
|||||||
@ -704,54 +704,11 @@ error:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_reachable_list(struct upload_pack_data *data,
|
static void get_shallows_depth(struct upload_pack_data *data)
|
||||||
struct object_array *reachable)
|
|
||||||
{
|
{
|
||||||
struct child_process cmd = CHILD_PROCESS_INIT;
|
get_shallow_commits(&data->want_obj, &data->shallows,
|
||||||
int i;
|
&data->deepen_relative, 0,
|
||||||
struct object *o;
|
SHALLOW, NOT_SHALLOW);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int has_unreachable(struct object_array *src, enum allow_uor allow_uor)
|
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;
|
struct object *object = data->shallows.objects[i].item;
|
||||||
object->flags |= NOT_SHALLOW;
|
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 {
|
} else {
|
||||||
struct commit_list *result;
|
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);
|
SHALLOW, NOT_SHALLOW);
|
||||||
send_shallow(data, result);
|
send_shallow(data, result);
|
||||||
free_commit_list(result);
|
free_commit_list(result);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user