Skip to content

Commit e34de73

Browse files
pcloudsgitster
authored andcommitted
upload-pack: reject shallow requests that would return nothing
Shallow clones with --shallow-since or --shalow-exclude work by running rev-list to get all reachable commits, then draw a boundary between reachable and unreachable and send "shallow" requests based on that. The code does miss one corner case: if rev-list returns nothing, we'll have no border and we'll send no shallow requests back to the client (i.e. no history cuts). This essentially means a full clone (or a full branch if the client requests just one branch). One example is the oldest commit is older than what is specified by --shallow-since. To avoid this, if rev-list returns nothing, we abort the clone/fetch. The user could adjust their request (e.g. --shallow-since further back in the past) and retry. Another possible option for this case is to fall back to a default depth (like depth 1). But I don't like too much magic that way because we may return something unexpected to the user. If they request "history since 2008" and we return a single depth at 2000, that might break stuff for them. It is better to tell them that something is wrong and let them take the best course of action. Note that we need to die() in get_shallow_commits_by_rev_list() instead of just checking for empty result from its caller deepen_by_rev_list() and handling the error there. The reason is, empty result could be a valid case: if you have commits in year 2013 and you request --shallow-since=year.2000 then you should get a full clone (i.e. empty result). Reported-by: Andreas Krey <[email protected]> Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a42a58d commit e34de73

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

shallow.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
175175
die("revision walk setup failed");
176176
traverse_commit_list(&revs, show_commit, NULL, &not_shallow_list);
177177

178+
if (!not_shallow_list)
179+
die("no commits selected for shallow requests");
180+
178181
/* Mark all reachable commits as NOT_SHALLOW */
179182
for (p = not_shallow_list; p; p = p->next)
180183
p->item->object.flags |= not_shallow_flag;

t/t5500-fetch-pack.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,17 @@ test_expect_success 'fetch shallow since ...' '
711711
test_cmp expected actual
712712
'
713713

714+
test_expect_success 'clone shallow since selects no commits' '
715+
test_create_repo shallow-since-the-future &&
716+
(
717+
cd shallow-since-the-future &&
718+
GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one &&
719+
GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two &&
720+
GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three &&
721+
test_must_fail git clone --shallow-since "900000000 +0700" "file://$(pwd)/." ../shallow111
722+
)
723+
'
724+
714725
test_expect_success 'shallow clone exclude tag two' '
715726
test_create_repo shallow-exclude &&
716727
(

0 commit comments

Comments
 (0)