Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions shallow.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ 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);

return result;
}
Expand Down
24 changes: 24 additions & 0 deletions t/t5500-fetch-pack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,30 @@ 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 &&
echo "Shallow:" && cat deepen.git/shallow &&
git -C deepen.git rev-list --all >actual &&
echo "All rev-lis:" && cat 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 &&
Expand Down
142 changes: 78 additions & 64 deletions upload-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "json-writer.h"
#include "strmap.h"
#include "promisor-remote.h"
#include "tag.h"

/* Remember to update object flag allocation in object.h */
#define THEY_HAVE (1u << 11)
Expand Down Expand Up @@ -704,54 +705,82 @@ static int do_reachable_revlist(struct child_process *cmd,
return -1;
}

static int get_reachable_list(struct upload_pack_data *data,
struct object_array *reachable)
define_commit_slab(commit_depth, int *);
static void free_depth_in_slab(int **ptr)
{
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;
FREE_AND_NULL(*ptr);
}
static void get_shallows_depth(struct upload_pack_data *data)
{
size_t i = 0, j;
int cur_depth = 0, cur_depth_shallow = 0;
struct object_array stack = OBJECT_ARRAY_INIT;
struct commit *commit = NULL;
struct commit_graft *graft;
struct commit_depth depths;
struct object_array *heads = &data->want_obj;
struct object_array *shallows = &data->shallows;

init_commit_depth(&depths);
while (commit || i < heads->nr || stack.nr) {
struct commit_list *p;
if (!commit) {
if (i < heads->nr) {
int **depth_slot;
commit = (struct commit *)
deref_tag(the_repository,
heads->objects[i++].item,
NULL, 0);
if (!commit || commit->object.type != OBJ_COMMIT) {
commit = NULL;
continue;
}
depth_slot = commit_depth_at(&depths, commit);
if (!*depth_slot)
*depth_slot = xmalloc(sizeof(int));
**depth_slot = 0;
cur_depth = 0;
} else {
commit = (struct commit *)
object_array_pop(&stack);
cur_depth = **commit_depth_at(&depths, commit);
}
}
}
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;
parse_commit_or_die(commit);
cur_depth++;
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;
}
for (p = commit->parents, commit = NULL; p; p = p->next) {
int **depth_slot = commit_depth_at(&depths, p->item);
if (!*depth_slot) {
*depth_slot = xmalloc(sizeof(int));
**depth_slot = cur_depth;
} else {
if (cur_depth >= **depth_slot)
continue;
**depth_slot = cur_depth;
}
if (p->next)
add_object_array(&p->item->object,
NULL, &stack);
else {
commit = p->item;
cur_depth = **commit_depth_at(&depths, commit);
}
}
}
close(cmd.out);

if (finish_command(&cmd)) {
ret = -1;
goto out;
}

ret = 0;

out:
child_process_clear(&cmd);
return ret;
deep_clear_commit_depth(&depths, free_depth_in_slab);
object_array_clear(&stack);
data->deepen_relative = cur_depth_shallow;
}

static int has_unreachable(struct object_array *src, enum allow_uor allow_uor)
Expand Down Expand Up @@ -881,29 +910,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,
data->deepen_relative + depth,
SHALLOW, NOT_SHALLOW);
send_shallow(data, result);
free_commit_list(result);
Expand Down
Loading