Skip to content

Commit e6cc510

Browse files
committed
fetch --all/--multiple: keep all the fetched branch information
Since "git fetch" learned "--all" and "--multiple" options, it has become tempting for users to say "git pull --all". Even though it may fetch from remotes that do not need to be fetched from for merging with the current branch, it is handy. "git fetch" however clears the list of fetched branches every time it contacts a different remote. Unless the current branch is configured to merge with a branch from a remote that happens to be the last in the list of remotes that are contacted, "git pull" that fetches from multiple remotes will not be able to find the branch it should be merging with. Make "fetch" clear FETCH_HEAD (unless --append is given) and then append the list of branches fetched to it (even when --append is not given). That way, "pull" will be able to find the data for the branch being merged in FETCH_HEAD no matter where the remote appears in the list of remotes to be contacted by "git fetch". Reported-by: Michael Lukashov Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent bba5322 commit e6cc510

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

builtin-fetch.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,17 @@ static void check_not_current_branch(struct ref *ref_map)
651651
"of non-bare repository", current_branch->refname);
652652
}
653653

654+
static int truncate_fetch_head(void)
655+
{
656+
char *filename = git_path("FETCH_HEAD");
657+
FILE *fp = fopen(filename, "w");
658+
659+
if (!fp)
660+
return error("cannot open %s: %s\n", filename, strerror(errno));
661+
fclose(fp);
662+
return 0;
663+
}
664+
654665
static int do_fetch(struct transport *transport,
655666
struct refspec *refs, int ref_count)
656667
{
@@ -672,11 +683,9 @@ static int do_fetch(struct transport *transport,
672683

673684
/* if not appending, truncate FETCH_HEAD */
674685
if (!append && !dry_run) {
675-
char *filename = git_path("FETCH_HEAD");
676-
FILE *fp = fopen(filename, "w");
677-
if (!fp)
678-
return error("cannot open %s: %s\n", filename, strerror(errno));
679-
fclose(fp);
686+
int errcode = truncate_fetch_head();
687+
if (errcode)
688+
return errcode;
680689
}
681690

682691
ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
@@ -784,8 +793,8 @@ static int add_remote_or_group(const char *name, struct string_list *list)
784793
static int fetch_multiple(struct string_list *list)
785794
{
786795
int i, result = 0;
787-
const char *argv[10] = { "fetch" };
788-
int argc = 1;
796+
const char *argv[11] = { "fetch", "--append" };
797+
int argc = 2;
789798

790799
if (dry_run)
791800
argv[argc++] = "--dry-run";
@@ -804,6 +813,12 @@ static int fetch_multiple(struct string_list *list)
804813
else if (verbosity < 0)
805814
argv[argc++] = "-q";
806815

816+
if (!append && !dry_run) {
817+
int errcode = truncate_fetch_head();
818+
if (errcode)
819+
return errcode;
820+
}
821+
807822
for (i = 0; i < list->nr; i++) {
808823
const char *name = list->items[i].string;
809824
argv[argc] = name;

t/t5521-pull-options.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,22 @@ test_expect_success 'git pull --force' '
7272
)
7373
'
7474

75+
test_expect_success 'git pull --all' '
76+
mkdir clonedmulti &&
77+
(cd clonedmulti && git init &&
78+
cat >>.git/config <<-\EOF &&
79+
[remote "one"]
80+
url = ../parent
81+
fetch = refs/heads/*:refs/remotes/one/*
82+
[remote "two"]
83+
url = ../parent
84+
fetch = refs/heads/*:refs/remotes/two/*
85+
[branch "master"]
86+
remote = one
87+
merge = refs/heads/master
88+
EOF
89+
git pull --all
90+
)
91+
'
92+
7593
test_done

0 commit comments

Comments
 (0)