From 6106ce4669051f1f4d3d21a2b22d24747e643147 Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 25 Aug 2010 12:52:55 -0500 Subject: [PATCH 1/2] t/t5510: demonstrate failure to fetch when current branch has merge ref When 'git fetch' is supplied just a repository URL (not a remote name), and without a fetch refspec, it should fetch from the remote HEAD branch and update FETCH_HEAD with the fetched ref. Currently, when 'git fetch' is called like this, it fails to retrieve anything, and does not update FETCH_HEAD, if the current checked-out branch has a configured merge ref. i.e. this fetch fails to retrieve anything nor update FETCH_HEAD: git checkout master git config branch.master.merge refs/heads/master git fetch git://git.kernel.org/pub/scm/git/git.git but this one does: git config --unset branch.master.merge git fetch git://git.kernel.org/pub/scm/git/git.git Add a test to demonstrate this flaw. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- t/t5510-fetch.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 721821ec92..950b7720e3 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -240,6 +240,12 @@ test_expect_success 'fetch with a non-applying branch..merge' ' git fetch blub ' +test_expect_failure 'fetch from GIT URL with a non-applying branch..merge' ' + git update-ref -d FETCH_HEAD && + git fetch one && + git rev-parse --verify FETCH_HEAD +' + # the strange name is: a\!'b test_expect_success 'quoting of a strangely named repo' ' test_must_fail git fetch "a\\!'\''b" > result 2>&1 && From 3ee1757baeecb6fe6c8b2446b3afe0519584b63f Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Wed, 25 Aug 2010 12:52:56 -0500 Subject: [PATCH 2/2] builtin/fetch.c: ignore merge config when not fetching from branch's remote When 'git fetch' is supplied a single argument, it tries to match it against a configured remote and then fetch the refs specified by the named remote's fetchspec. Additionally, or alternatively, if the current branch has a merge ref configured, and if the name of the remote supplied to fetch matches the one in the branch's configuration, then git also adds the merge ref to the list of refs to update. If the argument to fetch does not specify a named remote, or if the name supplied does not match the remote configured for the current branch, then the current branch's merge configuration should not be considered. git currently mishandles the case when the argument to fetch specifies a GIT URL(i.e. not a named remote) and the current branch has a configured merge ref. In this case, fetch should ignore the branch's merge ref and attempt to fetch from the remote repository's HEAD branch. But, since fetch only checks _whether_ the current branch has a merge ref configured, and does _not_ check whether the branch's configured remote matches the command line argument (until later), it will mistakenly enter the wrong branch of an 'if' statement and will not fall back to fetch the HEAD branch. The fetch ends up doing nothing and returns with a successful zero status. Fix this by comparing the remote repository's name to the branch's remote name, in addition to whether it has a configured merge ref, sooner, so that fetch can correctly decide whether the branch's configuration is interesting or not, and fall back to fetching from the remote's HEAD branch when appropriate. This fixes the test in t5510. Signed-off-by: Brandon Casey Signed-off-by: Junio C Hamano --- builtin/fetch.c | 4 +++- t/t5510-fetch.sh | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin/fetch.c b/builtin/fetch.c index 8470850415..3bfc081c6d 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -146,7 +146,9 @@ static struct ref *get_ref_map(struct transport *transport, struct remote *remote = transport->remote; struct branch *branch = branch_get(NULL); int has_merge = branch_has_merge_config(branch); - if (remote && (remote->fetch_refspec_nr || has_merge)) { + if (remote && + (remote->fetch_refspec_nr || + (has_merge && !strcmp(branch->remote_name, remote->name)))) { for (i = 0; i < remote->fetch_refspec_nr; i++) { get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0); if (remote->fetch[i].dst && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 950b7720e3..6a83771334 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -240,7 +240,7 @@ test_expect_success 'fetch with a non-applying branch..merge' ' git fetch blub ' -test_expect_failure 'fetch from GIT URL with a non-applying branch..merge' ' +test_expect_success 'fetch from GIT URL with a non-applying branch..merge' ' git update-ref -d FETCH_HEAD && git fetch one && git rev-parse --verify FETCH_HEAD