Skip to content

Commit f033388

Browse files
committed
Merge branch 'tb/fetch-all-configuration'
"git fetch" learned to pay attention to "fetch.all" configuration variable, which pretends as if "--all" was passed from the command line when no remote parameter was given. * tb/fetch-all-configuration: fetch: add new config option fetch.all
2 parents 5d1ee07 + 39487a1 commit f033388

File tree

4 files changed

+186
-3
lines changed

4 files changed

+186
-3
lines changed

Documentation/config/fetch.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ fetch.pruneTags::
5050
refs. See also `remote.<name>.pruneTags` and the PRUNING
5151
section of linkgit:git-fetch[1].
5252

53+
fetch.all::
54+
If true, fetch will attempt to update all available remotes.
55+
This behavior can be overridden by passing `--no-all` or by
56+
explicitly specifying one or more remote(s) to fetch from.
57+
Defaults to false.
58+
5359
fetch.output::
5460
Control how ref update status is printed. Valid values are
5561
`full` and `compact`. Default value is `full`. See the

Documentation/fetch-options.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
--all::
2-
Fetch all remotes.
1+
--[no-]all::
2+
Fetch all remotes. This overrides the configuration variable
3+
`fetch.all`.
34

45
-a::
56
--append::

builtin/fetch.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
100100

101101
struct fetch_config {
102102
enum display_format display_format;
103+
int all;
103104
int prune;
104105
int prune_tags;
105106
int show_forced_updates;
@@ -113,6 +114,11 @@ static int git_fetch_config(const char *k, const char *v,
113114
{
114115
struct fetch_config *fetch_config = cb;
115116

117+
if (!strcmp(k, "fetch.all")) {
118+
fetch_config->all = git_config_bool(k, v);
119+
return 0;
120+
}
121+
116122
if (!strcmp(k, "fetch.prune")) {
117123
fetch_config->prune = git_config_bool(k, v);
118124
return 0;
@@ -2130,7 +2136,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
21302136
const char *bundle_uri;
21312137
struct string_list list = STRING_LIST_INIT_DUP;
21322138
struct remote *remote = NULL;
2133-
int all = 0, multiple = 0;
2139+
int all = -1, multiple = 0;
21342140
int result = 0;
21352141
int prune_tags_ok = 1;
21362142
int enable_auto_gc = 1;
@@ -2335,11 +2341,20 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
23352341
fetch_bundle_uri(the_repository, bundle_uri, NULL))
23362342
warning(_("failed to fetch bundles from '%s'"), bundle_uri);
23372343

2344+
if (all < 0) {
2345+
/*
2346+
* no --[no-]all given;
2347+
* only use config option if no remote was explicitly specified
2348+
*/
2349+
all = (!argc) ? config.all : 0;
2350+
}
2351+
23382352
if (all) {
23392353
if (argc == 1)
23402354
die(_("fetch --all does not take a repository argument"));
23412355
else if (argc > 1)
23422356
die(_("fetch --all does not make sense with refspecs"));
2357+
23432358
(void) for_each_remote(get_one_remote_for_fetch, &list);
23442359

23452360
/* do not do fetch_multiple() of one */

t/t5514-fetch-multiple.sh

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ setup_repository () {
2424
)
2525
}
2626

27+
setup_test_clone () {
28+
test_dir="$1" &&
29+
git clone one "$test_dir" &&
30+
for r in one two three
31+
do
32+
git -C "$test_dir" remote add "$r" "../$r" || return 1
33+
done
34+
}
35+
2736
test_expect_success setup '
2837
setup_repository one &&
2938
setup_repository two &&
@@ -209,4 +218,156 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' '
209218
git fetch --multiple --jobs=0)
210219
'
211220

221+
create_fetch_all_expect () {
222+
cat >expect <<-\EOF
223+
one/main
224+
one/side
225+
origin/HEAD -> origin/main
226+
origin/main
227+
origin/side
228+
three/another
229+
three/main
230+
three/side
231+
two/another
232+
two/main
233+
two/side
234+
EOF
235+
}
236+
237+
for fetch_all in true false
238+
do
239+
test_expect_success "git fetch --all (works with fetch.all = $fetch_all)" '
240+
test_dir="test_fetch_all_$fetch_all" &&
241+
setup_test_clone "$test_dir" &&
242+
(
243+
cd "$test_dir" &&
244+
git config fetch.all $fetch_all &&
245+
git fetch --all &&
246+
create_fetch_all_expect &&
247+
git branch -r >actual &&
248+
test_cmp expect actual
249+
)
250+
'
251+
done
252+
253+
test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' '
254+
setup_test_clone test9 &&
255+
(
256+
cd test9 &&
257+
git config fetch.all true &&
258+
git fetch &&
259+
git branch -r >actual &&
260+
create_fetch_all_expect &&
261+
test_cmp expect actual
262+
)
263+
'
264+
265+
create_fetch_one_expect () {
266+
cat >expect <<-\EOF
267+
one/main
268+
one/side
269+
origin/HEAD -> origin/main
270+
origin/main
271+
origin/side
272+
EOF
273+
}
274+
275+
test_expect_success 'git fetch one (explicit remote overrides fetch.all)' '
276+
setup_test_clone test10 &&
277+
(
278+
cd test10 &&
279+
git config fetch.all true &&
280+
git fetch one &&
281+
create_fetch_one_expect &&
282+
git branch -r >actual &&
283+
test_cmp expect actual
284+
)
285+
'
286+
287+
create_fetch_two_as_origin_expect () {
288+
cat >expect <<-\EOF
289+
origin/HEAD -> origin/main
290+
origin/another
291+
origin/main
292+
origin/side
293+
EOF
294+
}
295+
296+
test_expect_success 'git config fetch.all false (fetch only default remote)' '
297+
setup_test_clone test11 &&
298+
(
299+
cd test11 &&
300+
git config fetch.all false &&
301+
git remote set-url origin ../two &&
302+
git fetch &&
303+
create_fetch_two_as_origin_expect &&
304+
git branch -r >actual &&
305+
test_cmp expect actual
306+
)
307+
'
308+
309+
for fetch_all in true false
310+
do
311+
test_expect_success "git fetch --no-all (fetch only default remote with fetch.all = $fetch_all)" '
312+
test_dir="test_no_all_fetch_all_$fetch_all" &&
313+
setup_test_clone "$test_dir" &&
314+
(
315+
cd "$test_dir" &&
316+
git config fetch.all $fetch_all &&
317+
git remote set-url origin ../two &&
318+
git fetch --no-all &&
319+
create_fetch_two_as_origin_expect &&
320+
git branch -r >actual &&
321+
test_cmp expect actual
322+
)
323+
'
324+
done
325+
326+
test_expect_success 'git fetch --no-all (fetch only default remote without fetch.all)' '
327+
setup_test_clone test12 &&
328+
(
329+
cd test12 &&
330+
git config --unset-all fetch.all || true &&
331+
git remote set-url origin ../two &&
332+
git fetch --no-all &&
333+
create_fetch_two_as_origin_expect &&
334+
git branch -r >actual &&
335+
test_cmp expect actual
336+
)
337+
'
338+
339+
test_expect_success 'git fetch --all --no-all (fetch only default remote)' '
340+
setup_test_clone test13 &&
341+
(
342+
cd test13 &&
343+
git remote set-url origin ../two &&
344+
git fetch --all --no-all &&
345+
create_fetch_two_as_origin_expect &&
346+
git branch -r >actual &&
347+
test_cmp expect actual
348+
)
349+
'
350+
351+
test_expect_success 'git fetch --no-all one (fetch only explicit remote)' '
352+
setup_test_clone test14 &&
353+
(
354+
cd test14 &&
355+
git fetch --no-all one &&
356+
create_fetch_one_expect &&
357+
git branch -r >actual &&
358+
test_cmp expect actual
359+
)
360+
'
361+
362+
test_expect_success 'git fetch --no-all --all (fetch all remotes)' '
363+
setup_test_clone test15 &&
364+
(
365+
cd test15 &&
366+
git fetch --no-all --all &&
367+
create_fetch_all_expect &&
368+
git branch -r >actual &&
369+
test_cmp expect actual
370+
)
371+
'
372+
212373
test_done

0 commit comments

Comments
 (0)