Skip to content

Commit ee8f939

Browse files
HaraldNordgrengitster
authored andcommitted
remote: add "git remote add --limited-fetch"
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, 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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent b616bf0 commit ee8f939

3 files changed

Lines changed: 45 additions & 7 deletions

File tree

‎Documentation/git-remote.adoc‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SYNOPSIS
1010
--------
1111
[synopsis]
1212
git remote [-v | --verbose]
13-
git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
13+
git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] [--[no-]limited-fetch] <name> <URL>
1414
git remote rename [--[no-]progress] <old> <new>
1515
git remote remove <name>
1616
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>_
7070
is created. You can give more than one `-t <branch>` to track
7171
multiple branches without grabbing all branches.
7272
+
73+
With `--limited-fetch` option, instead of a `remote.<name>.fetch` refspec
74+
that tracks all branches, `remote.<name>.refmap` is set up so that a
75+
refspec-less `git fetch <name>` only fetches branches our local branches
76+
are built on. See the `--refmap` entry in linkgit:git-fetch[1] for
77+
details.
78+
+
7379
With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
7480
up to point at remote's _<master>_ branch. See also the set-head command.
7581
+

‎builtin/remote.c‎

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static int add(int argc, const char **argv, const char *prefix,
179179
{
180180
int fetch = 0, fetch_tags = TAGS_DEFAULT;
181181
unsigned mirror = MIRROR_NONE;
182+
int limited_fetch = -1; /* unspecified */
182183
struct string_list track = STRING_LIST_INIT_NODUP;
183184
const char *master = NULL;
184185
struct remote *remote;
@@ -198,6 +199,8 @@ static int add(int argc, const char **argv, const char *prefix,
198199
OPT_CALLBACK_F(0, "mirror", &mirror, "(push|fetch)",
199200
N_("set up remote as a mirror to push to or fetch from"),
200201
PARSE_OPT_OPTARG | PARSE_OPT_COMP_ARG, parse_mirror_opt),
202+
OPT_BOOL(0, "limited-fetch", &limited_fetch,
203+
N_("fetch only the branches we build on, instead of every branch")),
201204
OPT_END()
202205
};
203206

@@ -211,6 +214,10 @@ static int add(int argc, const char **argv, const char *prefix,
211214
die(_("specifying a master branch makes no sense with --mirror"));
212215
if (mirror && !(mirror & MIRROR_FETCH) && track.nr)
213216
die(_("specifying branches to track makes sense only with fetch mirrors"));
217+
if (limited_fetch == 1 && track.nr)
218+
die(_("--limited-fetch does not make sense with -t/--track"));
219+
if (limited_fetch == 1 && mirror)
220+
die(_("--limited-fetch does not make sense with --mirror"));
214221

215222
name = argv[0];
216223
url = argv[1];
@@ -230,13 +237,22 @@ static int add(int argc, const char **argv, const char *prefix,
230237
repo_config_set(the_repository, buf.buf, url);
231238

232239
if (!mirror || mirror & MIRROR_FETCH) {
240+
int use_limited_fetch = mirror == MIRROR_NONE && track.nr == 0 &&
241+
limited_fetch == 1;
242+
233243
strbuf_reset(&buf);
234-
strbuf_addf(&buf, "remote.%s.fetch", name);
235-
if (track.nr == 0)
236-
string_list_append(&track, "*");
237-
for (size_t i = 0; i < track.nr; i++) {
238-
add_branch(buf.buf, track.items[i].string,
239-
name, mirror, &buf2);
244+
if (use_limited_fetch) {
245+
strbuf_addf(&buf, "remote.%s.refmap", name);
246+
strbuf_reset(&buf2);
247+
strbuf_addf(&buf2, "+refs/heads/*:refs/remotes/%s/*", name);
248+
repo_config_set(the_repository, buf.buf, buf2.buf);
249+
} else {
250+
strbuf_addf(&buf, "remote.%s.fetch", name);
251+
if (track.nr == 0)
252+
string_list_append(&track, "*");
253+
for (size_t i = 0; i < track.nr; i++)
254+
add_branch(buf.buf, track.items[i].string,
255+
name, mirror, &buf2);
240256
}
241257
}
242258

‎t/t5505-remote.sh‎

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

140+
test_expect_success '--limited-fetch works in a full repository too' '
141+
test_when_finished "rm -rf full-add" &&
142+
git clone --no-local one full-add &&
143+
(
144+
cd full-add &&
145+
git remote add --limited-fetch upstream ../two &&
146+
test_cmp_config "+refs/heads/*:refs/remotes/upstream/*" \
147+
remote.upstream.refmap &&
148+
test_must_fail git config get remote.upstream.fetch
149+
)
150+
'
151+
152+
test_expect_success '--limited-fetch conflicts with -t' '
153+
test_must_fail git remote add --limited-fetch -t main upstream ../two
154+
'
155+
140156
test_expect_success 'check remote-tracking' '
141157
(
142158
cd test &&

0 commit comments

Comments
 (0)