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 <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nguyễn Thái Ngọc Duy committed
Dec 5, 2013 at 20:02 UTC
79d3a236c551ad59719a6835bee03a1446296e65
4 files changed
+28
-4
Documentation/fetch-options.txt
+6
-2
@@ -14,8 +14,12 @@
14
branch history. Tags for the deepened commits are not fetched.
15
16
--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.
23
24
ifndef::git-pull[]
25
--dry-run::
shallow.c
+5
-1
@@ -75,6 +75,7 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
75
struct commit_list *result = NULL;
76
struct object_array stack = OBJECT_ARRAY_INIT;
77
struct commit *commit = NULL;
78
+ struct commit_graft *graft;
79
80
while (commit || i < heads->nr || stack.nr) {
81
struct commit_list *p;
@@ -99,7 +100,10 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
100
if (parse_commit(commit))
101
die("invalid commit");
102
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)) {
107
commit_list_insert(commit, &result);
108
commit->object.flags |= shallow_flag;
109
commit = NULL;
t/t5537-fetch-shallow.sh
+16
@@ -79,6 +79,22 @@ EOF
79
)
80
'
81
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
+
98
test_expect_success 'fetch something upstream has but hidden by clients shallow boundaries' '
99
# the blob "1" is available in .git but hidden by the
100
# shallow2/.git/shallow and it should be resent
upload-pack.c
+1
-1
@@ -619,7 +619,7 @@ static void receive_needs(void)
619
if (depth > 0) {
620
struct commit_list *result = NULL, *backup = NULL;
621
int i;
622
- if (depth == INFINITE_DEPTH)
622
+ if (depth == INFINITE_DEPTH && !is_repository_shallow())
623
for (i = 0; i < shallows.nr; i++) {
624
struct object *object = shallows.objects[i].item;
625
object->flags |= NOT_SHALLOW;