fetch: add branch.*.merge to default ref-prefix extension
When running "git pull" with no arguments, we'll do a default "git fetch" and then try to merge the branch specified by the branch.*.merge config. There's code in get_ref_map() to treat that "merge" branch as something we want to fetch, even if it is not otherwise covered by the default refspec. This works fine with the v0 protocol, as the server tells us about all of the refs, and get_ref_map() is the ultimate decider of what we fetch. But in the v2 protocol, we send the ref-prefix extension to the server, asking it to limit the ref advertisement. And we only tell it about the default refspec for the remote; we don't mention the branch.*.merge config at all. This usually doesn't matter, because the default refspec matches "refs/heads/*", which covers all branches. But if you explicitly use a narrow refspec, then "git pull" on some branches may fail. The server doesn't advertise the branch, so we don't fetch it, and "git pull" thinks that it went away upstream. We can fix this by including any branch.*.merge entries for the current branch in the list of ref-prefixes we pass to the server. This only needs to happen when using the default configured refspec (since command-line refspecs are already added, and take precedence in deciding what we fetch). We don't otherwise need to replicate any of the "what to fetch" logic in get_ref_map(). These ref-prefixes are an optimization, so it's OK if we tell the server to advertise the branch.*.merge ref, even if we're not going to pull it. We'll just choose not to fetch it. The test here is based on one constructed by Johannes. I modified the branch names to trigger the ref-prefix issue (and be more descriptive), and to confirm that "git pull" actually updated the local ref, which should be more robust than just checking stderr. Reported-by: Lana Deere <lana.deere@gmail.com> Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
080bc4990f
commit
49ca2fba39
@ -1626,9 +1626,21 @@ static int do_fetch(struct transport *transport,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (transport->remote->fetch.nr)
|
} else {
|
||||||
refspec_ref_prefixes(&transport->remote->fetch,
|
struct branch *branch = branch_get(NULL);
|
||||||
&transport_ls_refs_options.ref_prefixes);
|
|
||||||
|
if (transport->remote->fetch.nr)
|
||||||
|
refspec_ref_prefixes(&transport->remote->fetch,
|
||||||
|
&transport_ls_refs_options.ref_prefixes);
|
||||||
|
if (branch_has_merge_config(branch) &&
|
||||||
|
!strcmp(branch->remote_name, transport->remote->name)) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < branch->merge_nr; i++) {
|
||||||
|
strvec_push(&transport_ls_refs_options.ref_prefixes,
|
||||||
|
branch->merge[i]->src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
|
if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
|
||||||
must_list_refs = 1;
|
must_list_refs = 1;
|
||||||
|
@ -218,6 +218,23 @@ test_expect_success 'fail if upstream branch does not exist' '
|
|||||||
test_cmp expect file
|
test_cmp expect file
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'fetch upstream branch even if refspec excludes it' '
|
||||||
|
# the branch names are not important here except that
|
||||||
|
# the first one must not be a prefix of the second,
|
||||||
|
# since otherwise the ref-prefix protocol extension
|
||||||
|
# would match both
|
||||||
|
git branch in-refspec HEAD^ &&
|
||||||
|
git branch not-in-refspec HEAD &&
|
||||||
|
git init -b in-refspec downstream &&
|
||||||
|
git -C downstream remote add -t in-refspec origin "file://$(pwd)/.git" &&
|
||||||
|
git -C downstream config branch.in-refspec.remote origin &&
|
||||||
|
git -C downstream config branch.in-refspec.merge refs/heads/not-in-refspec &&
|
||||||
|
git -C downstream pull &&
|
||||||
|
git rev-parse --verify not-in-refspec >expect &&
|
||||||
|
git -C downstream rev-parse --verify HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'fail if the index has unresolved entries' '
|
test_expect_success 'fail if the index has unresolved entries' '
|
||||||
git checkout -b third second^ &&
|
git checkout -b third second^ &&
|
||||||
test_when_finished "git checkout -f copy && git branch -D third" &&
|
test_when_finished "git checkout -f copy && git branch -D third" &&
|
||||||
|
Loading…
Reference in New Issue
Block a user