Skip to content

Commit c039f35

Browse files
committed
Merge branch 'jc/fetch-ignore-symref' into maint
"git fetch --mirror" and fetch that uses other forms of refspec with wildcard used to attempt to update a symbolic ref that match the wildcard on the receiving end, which made little sense (the real ref that is pointed at by the symbolic ref would be updated anyway). Symbolic refs no longer are affected by such a fetch. * jc/fetch-ignore-symref: fetch: ignore wildcarded refspecs that update local symbolic refs
2 parents 9a4a941 + f8fb971 commit c039f35

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

remote.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,16 @@ int branch_merge_matches(struct branch *branch,
13701370
return refname_match(branch->merge[i]->src, refname, ref_fetch_rules);
13711371
}
13721372

1373+
static int ignore_symref_update(const char *refname)
1374+
{
1375+
unsigned char sha1[20];
1376+
int flag;
1377+
1378+
if (!resolve_ref_unsafe(refname, sha1, 0, &flag))
1379+
return 0; /* non-existing refs are OK */
1380+
return (flag & REF_ISSYMREF);
1381+
}
1382+
13731383
static struct ref *get_expanded_map(const struct ref *remote_refs,
13741384
const struct refspec *refspec)
13751385
{
@@ -1383,7 +1393,8 @@ static struct ref *get_expanded_map(const struct ref *remote_refs,
13831393
if (strchr(ref->name, '^'))
13841394
continue; /* a dereference item */
13851395
if (match_name_with_pattern(refspec->src, ref->name,
1386-
refspec->dst, &expn_name)) {
1396+
refspec->dst, &expn_name) &&
1397+
!ignore_symref_update(expn_name)) {
13871398
struct ref *cpy = copy_ref(ref);
13881399

13891400
cpy->peer_ref = alloc_ref(expn_name);

t/t5535-fetch-push-symref.sh

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/sh
2+
3+
test_description='avoiding conflicting update thru symref aliasing'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'setup' '
8+
test_commit one &&
9+
git clone . src &&
10+
git clone src dst1 &&
11+
git clone src dst2 &&
12+
test_commit two &&
13+
( cd src && git pull )
14+
'
15+
16+
test_expect_success 'push' '
17+
(
18+
cd src &&
19+
git push ../dst1 "refs/remotes/*:refs/remotes/*"
20+
) &&
21+
git ls-remote src "refs/remotes/*" >expect &&
22+
git ls-remote dst1 "refs/remotes/*" >actual &&
23+
test_cmp expect actual &&
24+
( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
25+
( cd dst1 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
26+
test_cmp expect actual
27+
'
28+
29+
test_expect_success 'fetch' '
30+
(
31+
cd dst2 &&
32+
git fetch ../src "refs/remotes/*:refs/remotes/*"
33+
) &&
34+
git ls-remote src "refs/remotes/*" >expect &&
35+
git ls-remote dst2 "refs/remotes/*" >actual &&
36+
test_cmp expect actual &&
37+
( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
38+
( cd dst2 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
39+
test_cmp expect actual
40+
'
41+
42+
test_done

0 commit comments

Comments
 (0)