Skip to content

Commit 79d3a23

Browse files
pcloudsgitster
authored andcommitted
upload-pack: make sure deepening preserves shallow roots
When "fetch --depth=N" where N exceeds the longest chain of history in the source repo, usually we just send an "unshallow" line to the client so full history is obtained. When the source repo is shallow we need to make sure to "unshallow" the current shallow point _and_ "shallow" again when the commit reaches its shallow bottom in the source repo. This should fix both cases: large <N> and --unshallow. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4820a33 commit 79d3a23

File tree

4 files changed

+28
-4
lines changed

4 files changed

+28
-4
lines changed

Documentation/fetch-options.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
branch history. Tags for the deepened commits are not fetched.
1515

1616
--unshallow::
17-
Convert a shallow repository to a complete one, removing all
18-
the limitations imposed by shallow repositories.
17+
If the source repository is complete, convert a shallow
18+
repository to a complete one, removing all the limitations
19+
imposed by shallow repositories.
20+
+
21+
If the source repository is shallow, fetch as much as possible so that
22+
the current repository has the same history as the source repository.
1923

2024
ifndef::git-pull[]
2125
--dry-run::

shallow.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
7575
struct commit_list *result = NULL;
7676
struct object_array stack = OBJECT_ARRAY_INIT;
7777
struct commit *commit = NULL;
78+
struct commit_graft *graft;
7879

7980
while (commit || i < heads->nr || stack.nr) {
8081
struct commit_list *p;
@@ -99,7 +100,10 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
99100
if (parse_commit(commit))
100101
die("invalid commit");
101102
cur_depth++;
102-
if (cur_depth >= depth) {
103+
if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
104+
(is_repository_shallow() && !commit->parents &&
105+
(graft = lookup_commit_graft(commit->object.sha1)) != NULL &&
106+
graft->nr_parent < 0)) {
103107
commit_list_insert(commit, &result);
104108
commit->object.flags |= shallow_flag;
105109
commit = NULL;

t/t5537-fetch-shallow.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,22 @@ EOF
7979
)
8080
'
8181

82+
test_expect_success 'fetch --unshallow from shallow clone' '
83+
(
84+
cd shallow2 &&
85+
git fetch --unshallow &&
86+
git fsck &&
87+
git log --format=%s origin/master >actual &&
88+
cat <<EOF >expect &&
89+
6
90+
5
91+
4
92+
3
93+
EOF
94+
test_cmp expect actual
95+
)
96+
'
97+
8298
test_expect_success 'fetch something upstream has but hidden by clients shallow boundaries' '
8399
# the blob "1" is available in .git but hidden by the
84100
# shallow2/.git/shallow and it should be resent

upload-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ static void receive_needs(void)
619619
if (depth > 0) {
620620
struct commit_list *result = NULL, *backup = NULL;
621621
int i;
622-
if (depth == INFINITE_DEPTH)
622+
if (depth == INFINITE_DEPTH && !is_repository_shallow())
623623
for (i = 0; i < shallows.nr; i++) {
624624
struct object *object = shallows.objects[i].item;
625625
object->flags |= NOT_SHALLOW;

0 commit comments

Comments
 (0)