[PATCH v12 5/5] remote: default to --limited-fetch in a shallow repository
flat view
HOTtoday
From: Harald Nordgren via GitGitGadget <hidden>
Date: 2026-10-27 12:24:52
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
Revision v12 (5 revisions archived).
Revisions (5)
From: Harald Nordgren <redacted> Adding a second remote to a shallow 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 in the first place (for example with --single-branch), 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 <redacted> --- Documentation/git-remote.adoc | 8 ++++- builtin/remote.c | 5 ++- t/t5505-remote.sh | 60 +++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-remote.adoc b/Documentation/git-remote.adoc
index 1f490819ba..245c0c4558 100644
--- a/Documentation/git-remote.adoc
+++ b/Documentation/git-remote.adoc@@ -57,6 +57,11 @@ Add a remote named _<name>_ for the repository at _<URL>_. The command `git fetch <name>` can then be used to create and update remote-tracking branches `<name>/<branch>`. + +If the repository is already a shallow repository (see linkgit:git-clone[1] +`--depth`) and neither `-t`, `--mirror` nor `--no-limited-fetch` is given, +`--limited-fetch` is turned on by default, so that `git fetch <name>` does +not need to negotiate history for every branch the remote has. ++ With `-f` option, `git fetch <name>` is run immediately after the remote information is set up. +
@@ -79,7 +84,8 @@ With `--limited-fetch` option, instead of a `remote.<name>.fetch` refspec that tracks all branches, `remote.<name>.fetchRefmap` is set up so that a refspec-less `git fetch <name>` only fetches branches our local branches are built on. See the `--refmap` entry in linkgit:git-fetch[1] for -details. +details. `--no-limited-fetch` explicitly disables this, overriding the +shallow-repository default described above. + With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set up to point at remote's _<master>_ branch. See also the set-head command.
diff --git a/builtin/remote.c b/builtin/remote.c
index 5f8a8a2f71..5d2388a26c 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c@@ -16,6 +16,7 @@ #include "rebase.h" #include "refs.h" #include "refspec.h" +#include "shallow.h" #include "odb.h" #include "strvec.h" #include "commit-reach.h"
@@ -238,7 +239,9 @@ static int add(int argc, const char **argv, const char *prefix, if (!mirror || mirror & MIRROR_FETCH) { bool use_limited_fetch = mirror == MIRROR_NONE && track.nr == 0 && - limited_fetch == 1; + (limited_fetch == 1 || + (limited_fetch == -1 && + is_repository_shallow(the_repository))); strbuf_reset(&buf); if (use_limited_fetch) {
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 90cba75f93..68063a47b8 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh@@ -137,6 +137,66 @@ test_expect_success 'filters are listed by git remote -v only' ' test_grep ! "\[blob:none\]" out ' +test_expect_success 'add remote -t keeps an explicit refspec in a shallow repository' ' + test_when_finished "rm -rf shallow-add" && + git clone --no-local --depth=1 --branch main --single-branch \ + one shallow-add && + ( + cd shallow-add && + git remote add -t main upstream ../two && + test_cmp_config "+refs/heads/main:refs/remotes/upstream/main" \ + remote.upstream.fetch + ) +' + +test_expect_success 'add remote keeps the wildcard refspec in a full repository' ' + test_when_finished "rm -rf full-add" && + git clone --no-local one full-add && + ( + cd full-add && + git remote add upstream ../two && + test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \ + remote.upstream.fetch + ) +' + +test_expect_success 'a remote added in a shallow repository defaults to --limited-fetch' ' + test_when_finished "rm -rf shallow-add" && + git clone --no-local --depth=1 --branch main --single-branch \ + one shallow-add && + ( + cd shallow-add && + git remote add upstream ../two && + test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \ + remote.upstream.fetchRefmap && + test_must_fail git config get remote.upstream.fetch && + git fetch upstream main && + git branch --set-upstream-to=upstream/main && + test_cmp_config upstream branch.main.remote && + test_cmp_config refs/heads/main branch.main.merge && + git fetch upstream && + git for-each-ref --format="%(refname)" refs/remotes/upstream >actual && + cat >expect <<-\EOF && + refs/remotes/upstream/HEAD + refs/remotes/upstream/main + EOF + test_cmp expect actual + ) +' + +test_expect_success '--no-limited-fetch overrides the shallow-repository default' ' + test_when_finished "rm -rf shallow-add" && + git clone --no-local --depth=1 --branch main --single-branch \ + one shallow-add && + ( + cd shallow-add && + git remote add --no-limited-fetch upstream ../two && + test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \ + remote.upstream.fetch && + test_must_fail git config get remote.upstream.fetchRefmap + ) +' + test_expect_success '--limited-fetch works in a full repository too' ' test_when_finished "rm -rf full-add" && git clone --no-local one full-add &&
--
gitgitgadget