Skip to content

Commit 2b6e751

Browse files
HaraldNordgrengitster
authored andcommitted
remote: default to --limited-fetch in a shallow repository
Adding a second remote to a shallow, single-branch clone used to still fetch every branch that remote has, since "git remote add" always set up a wildcard remote.<name>.fetch refspec regardless of how shallow the repository already was. That defeats the purpose of having cloned shallow and single-branch in the first place, and can make a plain "git fetch" on that remote hang or take a very long time on a repository with many branches. Turn --limited-fetch on by default when the repository is already shallow and neither -t/--track nor --mirror was given, so that adding a remote there does not by itself commit to following every branch it has. --no-limited-fetch keeps the previous behavior for whoever wants it. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ee8f939 commit 2b6e751

3 files changed

Lines changed: 71 additions & 2 deletions

File tree

‎Documentation/git-remote.adoc‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ Add a remote named _<name>_ for the repository at
5252
_<URL>_. The command `git fetch <name>` can then be used to create and
5353
update remote-tracking branches `<name>/<branch>`.
5454
+
55+
If the repository is already a shallow repository (see linkgit:git-clone[1]
56+
`--depth`) and neither `-t`, `--mirror` nor `--no-limited-fetch` is given,
57+
`--limited-fetch` is turned on by default, so that `git fetch <name>` does
58+
not need to negotiate history for every branch the remote has.
59+
+
5560
With `-f` option, `git fetch <name>` is run immediately after
5661
the remote information is set up.
5762
+
@@ -74,7 +79,8 @@ With `--limited-fetch` option, instead of a `remote.<name>.fetch` refspec
7479
that tracks all branches, `remote.<name>.refmap` is set up so that a
7580
refspec-less `git fetch <name>` only fetches branches our local branches
7681
are built on. See the `--refmap` entry in linkgit:git-fetch[1] for
77-
details.
82+
details. `--no-limited-fetch` explicitly disables this, overriding the
83+
shallow-repository default described above.
7884
+
7985
With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
8086
up to point at remote's _<master>_ branch. See also the set-head command.

‎builtin/remote.c‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "rebase.h"
1717
#include "refs.h"
1818
#include "refspec.h"
19+
#include "shallow.h"
1920
#include "odb.h"
2021
#include "strvec.h"
2122
#include "commit-reach.h"
@@ -238,7 +239,9 @@ static int add(int argc, const char **argv, const char *prefix,
238239

239240
if (!mirror || mirror & MIRROR_FETCH) {
240241
int use_limited_fetch = mirror == MIRROR_NONE && track.nr == 0 &&
241-
limited_fetch == 1;
242+
(limited_fetch == 1 ||
243+
(limited_fetch == -1 &&
244+
is_repository_shallow(the_repository)));
242245

243246
strbuf_reset(&buf);
244247
if (use_limited_fetch) {

‎t/t5505-remote.sh‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,66 @@ test_expect_success 'filters are listed by git remote -v only' '
137137
test_grep ! "\[blob:none\]" out
138138
'
139139

140+
test_expect_success 'add remote -t keeps an explicit refspec in a shallow repository' '
141+
test_when_finished "rm -rf shallow-add" &&
142+
git clone --no-local --depth=1 --branch main --single-branch \
143+
one shallow-add &&
144+
(
145+
cd shallow-add &&
146+
git remote add -t main upstream ../two &&
147+
test_cmp_config "+refs/heads/main:refs/remotes/upstream/main" \
148+
remote.upstream.fetch
149+
)
150+
'
151+
152+
test_expect_success 'add remote keeps the wildcard refspec in a full repository' '
153+
test_when_finished "rm -rf full-add" &&
154+
git clone --no-local one full-add &&
155+
(
156+
cd full-add &&
157+
git remote add upstream ../two &&
158+
test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \
159+
remote.upstream.fetch
160+
)
161+
'
162+
163+
test_expect_success 'a remote added in a shallow repository defaults to --limited-fetch' '
164+
test_when_finished "rm -rf shallow-add" &&
165+
git clone --no-local --depth=1 --branch main --single-branch \
166+
one shallow-add &&
167+
(
168+
cd shallow-add &&
169+
git remote add upstream ../two &&
170+
test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \
171+
remote.upstream.refmap &&
172+
test_must_fail git config get remote.upstream.fetch &&
173+
git fetch upstream main &&
174+
git branch --set-upstream-to=upstream/main &&
175+
test_cmp_config upstream branch.main.remote &&
176+
test_cmp_config refs/heads/main branch.main.merge &&
177+
git fetch upstream &&
178+
git for-each-ref --format="%(refname)" refs/remotes/upstream >actual &&
179+
cat >expect <<-\EOF &&
180+
refs/remotes/upstream/HEAD
181+
refs/remotes/upstream/main
182+
EOF
183+
test_cmp expect actual
184+
)
185+
'
186+
187+
test_expect_success '--no-limited-fetch overrides the shallow-repository default' '
188+
test_when_finished "rm -rf shallow-add" &&
189+
git clone --no-local --depth=1 --branch main --single-branch \
190+
one shallow-add &&
191+
(
192+
cd shallow-add &&
193+
git remote add --no-limited-fetch upstream ../two &&
194+
test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \
195+
remote.upstream.fetch &&
196+
test_must_fail git config get remote.upstream.refmap
197+
)
198+
'
199+
140200
test_expect_success '--limited-fetch works in a full repository too' '
141201
test_when_finished "rm -rf full-add" &&
142202
git clone --no-local one full-add &&

0 commit comments

Comments
 (0)