From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Phillip Wood <phillip.wood123@gmail.com>,
"D. Ben Knoble" <ben.knoble@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>,
Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v3 3/4] remote: add "git remote add --limited-fetch"
Date: Fri, 25 Sep 2026 10:50:01 +0000 [thread overview]
Message-ID: <604e5849565f9a1d1697cd0983809f80f0e1319b.1790333402.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2412.v3.git.git.1790333402.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
A remote added the ordinary way tracks every branch it has, via a
wildcard remote.<name>.fetch refspec. That is wasteful for a remote
whose history is only worth following for the branches actually in
use locally, and it can make "git fetch" negotiate history for
branches nobody asked for.
Give "git remote add" a --limited-fetch option that sets up
remote.<name>.refmap instead of remote.<name>.fetch, so that
"git fetch <name>" only fetches the branches already tracked, plus
the remote's default branch, as described in the previous commit.
It is rejected together with -t/--track or --mirror, since those
already say explicitly what to fetch.
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
Documentation/git-remote.adoc | 8 +++++++-
builtin/remote.c | 28 ++++++++++++++++++++++------
t/t5505-remote.sh | 16 ++++++++++++++++
3 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/Documentation/git-remote.adoc b/Documentation/git-remote.adoc
index eaae30aa88..74fbce6e0e 100644
--- a/Documentation/git-remote.adoc
+++ b/Documentation/git-remote.adoc
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[synopsis]
git remote [-v | --verbose]
-git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
+git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] [--[no-]limited-fetch] <name> <URL>
git remote rename [--[no-]progress] <old> <new>
git remote remove <name>
git remote set-head <name> (-a | --auto | -d | --delete | <branch>)
@@ -70,6 +70,12 @@ the `refs/remotes/<name>/` namespace, a refspec to track only _<branch>_
is created. You can give more than one `-t <branch>` to track
multiple branches without grabbing all branches.
+
+With `--limited-fetch` option, instead of a `remote.<name>.fetch` refspec
+that tracks all branches, `remote.<name>.refmap` is set up so that a
+refspec-less `git fetch <name>` only fetches branches our local branches
+are built on, plus the remote's default branch. See the `--refmap` entry
+in linkgit:git-fetch[1] for details.
++
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 de989ea3ba..f036dd5d6f 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -179,6 +179,7 @@ static int add(int argc, const char **argv, const char *prefix,
{
int fetch = 0, fetch_tags = TAGS_DEFAULT;
unsigned mirror = MIRROR_NONE;
+ int limited_fetch = -1; /* unspecified */
struct string_list track = STRING_LIST_INIT_NODUP;
const char *master = NULL;
struct remote *remote;
@@ -198,6 +199,8 @@ static int add(int argc, const char **argv, const char *prefix,
OPT_CALLBACK_F(0, "mirror", &mirror, "(push|fetch)",
N_("set up remote as a mirror to push to or fetch from"),
PARSE_OPT_OPTARG | PARSE_OPT_COMP_ARG, parse_mirror_opt),
+ OPT_BOOL(0, "limited-fetch", &limited_fetch,
+ N_("fetch only the branches we build on, instead of every branch")),
OPT_END()
};
@@ -211,6 +214,10 @@ static int add(int argc, const char **argv, const char *prefix,
die(_("specifying a master branch makes no sense with --mirror"));
if (mirror && !(mirror & MIRROR_FETCH) && track.nr)
die(_("specifying branches to track makes sense only with fetch mirrors"));
+ if (limited_fetch == 1 && track.nr)
+ die(_("--limited-fetch does not make sense with -t/--track"));
+ if (limited_fetch == 1 && mirror)
+ die(_("--limited-fetch does not make sense with --mirror"));
name = argv[0];
url = argv[1];
@@ -230,13 +237,22 @@ static int add(int argc, const char **argv, const char *prefix,
repo_config_set(the_repository, buf.buf, url);
if (!mirror || mirror & MIRROR_FETCH) {
+ int use_limited_fetch = mirror == MIRROR_NONE && track.nr == 0 &&
+ limited_fetch == 1;
+
strbuf_reset(&buf);
- strbuf_addf(&buf, "remote.%s.fetch", name);
- if (track.nr == 0)
- string_list_append(&track, "*");
- for (size_t i = 0; i < track.nr; i++) {
- add_branch(buf.buf, track.items[i].string,
- name, mirror, &buf2);
+ if (use_limited_fetch) {
+ strbuf_addf(&buf, "remote.%s.refmap", name);
+ strbuf_reset(&buf2);
+ strbuf_addf(&buf2, "+refs/heads/*:refs/remotes/%s/*", name);
+ repo_config_set(the_repository, buf.buf, buf2.buf);
+ } else {
+ strbuf_addf(&buf, "remote.%s.fetch", name);
+ if (track.nr == 0)
+ string_list_append(&track, "*");
+ for (size_t i = 0; i < track.nr; i++)
+ add_branch(buf.buf, track.items[i].string,
+ name, mirror, &buf2);
}
}
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 5fbfcb0848..0168d5abfe 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -137,6 +137,22 @@ test_expect_success 'filters are listed by git remote -v only' '
test_grep ! "\[blob:none\]" out
'
+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 &&
+ (
+ cd full-add &&
+ git remote add --limited-fetch upstream ../two &&
+ test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \
+ remote.upstream.refmap &&
+ test_must_fail git config get remote.upstream.fetch
+ )
+'
+
+test_expect_success '--limited-fetch conflicts with -t' '
+ test_must_fail git remote add --limited-fetch -t main upstream ../two
+'
+
test_expect_success 'check remote-tracking' '
(
cd test &&
--
gitgitgadget
next prev parent reply other threads:[~2026-09-25 10:50 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-19 14:47 [PATCH] fetch: add config to avoid fetching every branch in shallow repo Harald Nordgren via GitGitGadget
2026-09-21 13:28 ` Phillip Wood
2026-09-21 21:45 ` Harald Nordgren
2026-09-22 13:00 ` Harald Nordgren
2026-09-22 14:53 ` Phillip Wood
2026-09-22 15:37 ` Harald Nordgren
2026-09-23 15:14 ` Phillip Wood
2026-09-22 17:11 ` Junio C Hamano
2026-09-22 21:40 ` Harald Nordgren
2026-09-23 15:19 ` Phillip Wood
2026-09-23 15:34 ` Junio C Hamano
2026-09-23 16:55 ` D. Ben Knoble
2026-09-23 19:50 ` Junio C Hamano
2026-09-24 17:10 ` D. Ben Knoble
2026-09-24 18:02 ` Junio C Hamano
2026-09-23 20:35 ` [PATCH v2] fetch: avoid fetching every branch of a new remote in a " Harald Nordgren via GitGitGadget
2026-09-23 21:38 ` Junio C Hamano
2026-09-25 10:49 ` [PATCH v3 0/4] " Harald Nordgren via GitGitGadget
2026-09-25 10:49 ` [PATCH v3 1/4] fetch: add remote.<name>.refmap Harald Nordgren via GitGitGadget
2026-09-25 22:38 ` Junio C Hamano
2026-09-25 10:50 ` [PATCH v3 2/4] fetch: infer branches to fetch from a refmap-only remote Harald Nordgren via GitGitGadget
2026-09-25 23:26 ` Junio C Hamano
2026-09-25 10:50 ` Harald Nordgren via GitGitGadget [this message]
2026-09-25 10:50 ` [PATCH v3 4/4] remote: default to --limited-fetch in a shallow repository Harald Nordgren via GitGitGadget
2026-09-29 9:19 ` [PATCH v4 0/4] fetch: avoid fetching every branch of a new remote in a shallow repo Harald Nordgren via GitGitGadget
2026-09-29 9:19 ` [PATCH v4 1/4] fetch: add remote.<name>.refmap Harald Nordgren via GitGitGadget
2026-09-29 9:19 ` [PATCH v4 2/4] fetch: infer branches to fetch from a refmap-only remote Harald Nordgren via GitGitGadget
2026-09-29 9:27 ` Harald Nordgren
2026-09-29 20:17 ` Junio C Hamano
2026-09-29 9:19 ` [PATCH v4 3/4] remote: add "git remote add --limited-fetch" Harald Nordgren via GitGitGadget
2026-09-29 9:19 ` [PATCH v4 4/4] remote: default to --limited-fetch in a shallow repository Harald Nordgren via GitGitGadget
2026-09-29 19:36 ` [PATCH v4 0/4] fetch: avoid fetching every branch of a new remote in a shallow repo Junio C Hamano
2026-10-02 7:13 ` [PATCH v5 " Harald Nordgren via GitGitGadget
2026-10-02 7:13 ` [PATCH v5 1/4] fetch: add remote.<name>.refmap Harald Nordgren via GitGitGadget
2026-10-02 7:13 ` [PATCH v5 2/4] fetch: infer branches to fetch from a refmap-only remote Harald Nordgren via GitGitGadget
2026-10-02 7:13 ` [PATCH v5 3/4] remote: add "git remote add --limited-fetch" Harald Nordgren via GitGitGadget
2026-10-02 16:28 ` Junio C Hamano
2026-10-02 7:13 ` [PATCH v5 4/4] remote: default to --limited-fetch in a shallow repository Harald Nordgren via GitGitGadget
2026-10-04 8:31 ` [PATCH v6 0/4] fetch: avoid fetching every branch of a new remote in a shallow repo Harald Nordgren via GitGitGadget
2026-10-04 8:31 ` [PATCH v6 1/4] fetch: add remote.<name>.refmap Harald Nordgren via GitGitGadget
2026-10-04 8:31 ` [PATCH v6 2/4] fetch: infer branches to fetch from a refmap-only remote Harald Nordgren via GitGitGadget
2026-10-04 8:31 ` [PATCH v6 3/4] remote: add "git remote add --limited-fetch" Harald Nordgren via GitGitGadget
2026-10-04 8:31 ` [PATCH v6 4/4] remote: default to --limited-fetch in a shallow repository Harald Nordgren via GitGitGadget
2026-10-04 17:17 ` [PATCH v6 0/4] fetch: avoid fetching every branch of a new remote in a shallow repo Junio C Hamano
2026-10-04 19:51 ` Harald Nordgren
2026-10-05 12:17 ` Junio C Hamano
2026-10-05 18:09 ` Harald Nordgren
2026-10-07 21:56 ` [PATCH v7 " Harald Nordgren via GitGitGadget
2026-10-07 21:56 ` [PATCH v7 1/4] fetch: add remote.<name>.refmap Harald Nordgren via GitGitGadget
2026-10-07 21:56 ` [PATCH v7 2/4] fetch: infer branches to fetch from a refmap-only remote Harald Nordgren via GitGitGadget
2026-10-08 16:59 ` Junio C Hamano
2026-10-07 21:56 ` [PATCH v7 3/4] remote: add "git remote add --limited-fetch" Harald Nordgren via GitGitGadget
2026-10-07 21:56 ` [PATCH v7 4/4] remote: default to --limited-fetch in a shallow repository Harald Nordgren via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=604e5849565f9a1d1697cd0983809f80f0e1319b.1790333402.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=ben.knoble@gmail.com \
--cc=git@vger.kernel.org \
--cc=haraldnordgren@gmail.com \
--cc=phillip.wood123@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.