Skip to content

Commit

Permalink
fetch --all/--multiple: keep all the fetched branch information
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Feb 24, 2010
1 parent bba5322 commit e6cc510
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
29 changes: 22 additions & 7 deletions builtin-fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,17 @@ static void check_not_current_branch(struct ref *ref_map)
"of non-bare repository", current_branch->refname);
}

static int truncate_fetch_head(void)
{
char *filename = git_path("FETCH_HEAD");
FILE *fp = fopen(filename, "w");

if (!fp)
return error("cannot open %s: %s\n", filename, strerror(errno));
fclose(fp);
return 0;
}

static int do_fetch(struct transport *transport,
struct refspec *refs, int ref_count)
{
Expand All @@ -672,11 +683,9 @@ static int do_fetch(struct transport *transport,

/* if not appending, truncate FETCH_HEAD */
if (!append && !dry_run) {
char *filename = git_path("FETCH_HEAD");
FILE *fp = fopen(filename, "w");
if (!fp)
return error("cannot open %s: %s\n", filename, strerror(errno));
fclose(fp);
int errcode = truncate_fetch_head();
if (errcode)
return errcode;
}

ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
Expand Down Expand Up @@ -784,8 +793,8 @@ static int add_remote_or_group(const char *name, struct string_list *list)
static int fetch_multiple(struct string_list *list)
{
int i, result = 0;
const char *argv[10] = { "fetch" };
int argc = 1;
const char *argv[11] = { "fetch", "--append" };
int argc = 2;

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

if (!append && !dry_run) {
int errcode = truncate_fetch_head();
if (errcode)
return errcode;
}

for (i = 0; i < list->nr; i++) {
const char *name = list->items[i].string;
argv[argc] = name;
Expand Down
18 changes: 18 additions & 0 deletions t/t5521-pull-options.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,22 @@ test_expect_success 'git pull --force' '
)
'

test_expect_success 'git pull --all' '
mkdir clonedmulti &&
(cd clonedmulti && git init &&
cat >>.git/config <<-\EOF &&
[remote "one"]
url = ../parent
fetch = refs/heads/*:refs/remotes/one/*
[remote "two"]
url = ../parent
fetch = refs/heads/*:refs/remotes/two/*
[branch "master"]
remote = one
merge = refs/heads/master
EOF
git pull --all
)
'

test_done

0 comments on commit e6cc510

Please sign in to comment.