summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--remote.c25
-rwxr-xr-xt/t5536-fetch-conflicts.sh14
2 files changed, 31 insertions, 8 deletions
diff --git a/remote.c b/remote.c
index 0848faffa4..dc56619d23 100644
--- a/remote.c
+++ b/remote.c
@@ -747,9 +747,28 @@ int for_each_remote(each_remote_fn fn, void *priv)
static void handle_duplicate(struct ref *ref1, struct ref *ref2)
{
- if (strcmp(ref1->name, ref2->name))
- die(_("%s tracks both %s and %s"),
- ref2->peer_ref->name, ref1->name, ref2->name);
+ if (strcmp(ref1->name, ref2->name)) {
+ if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status != FETCH_HEAD_IGNORE) {
+ die(_("Cannot fetch both %s and %s to %s"),
+ ref1->name, ref2->name, ref2->peer_ref->name);
+ } else if (ref1->fetch_head_status != FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+ warning(_("%s usually tracks %s, not %s"),
+ ref2->peer_ref->name, ref2->name, ref1->name);
+ } else if (ref1->fetch_head_status == FETCH_HEAD_IGNORE &&
+ ref2->fetch_head_status == FETCH_HEAD_IGNORE) {
+ die(_("%s tracks both %s and %s"),
+ ref2->peer_ref->name, ref1->name, ref2->name);
+ } else {
+ /*
+ * This last possibility doesn't occur because
+ * FETCH_HEAD_IGNORE entries always appear at
+ * the end of the list.
+ */
+ die(_("Internal error"));
+ }
+ }
free(ref2->peer_ref);
free(ref2);
}
diff --git a/t/t5536-fetch-conflicts.sh b/t/t5536-fetch-conflicts.sh
index 679c53e044..6c5d3a4ce0 100755
--- a/t/t5536-fetch-conflicts.sh
+++ b/t/t5536-fetch-conflicts.sh
@@ -22,7 +22,7 @@ verify_stderr () {
cat >expected &&
# We're not interested in the error
# "fatal: The remote end hung up unexpectedly":
- grep -v "hung up" <error >actual &&
+ grep -E '^(fatal|warning):' <error | grep -v 'hung up' >actual | sort &&
test_cmp expected actual
}
@@ -49,7 +49,7 @@ test_expect_success 'fetch conflict: config vs. config' '
cd ccc &&
test_must_fail git fetch origin 2>error &&
verify_stderr <<-\EOF
- fatal: refs/remotes/origin/branch1 tracks both refs/heads/branch1 and refs/heads/branch2
+ fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1
EOF
)
'
@@ -78,18 +78,22 @@ test_expect_success 'fetch conflict: arg vs. arg' '
refs/heads/*:refs/remotes/origin/* \
refs/heads/branch2:refs/remotes/origin/branch1 2>error &&
verify_stderr <<-\EOF
- fatal: refs/remotes/origin/branch1 tracks both refs/heads/branch1 and refs/heads/branch2
+ fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1
EOF
)
'
-test_expect_failure 'fetch conflict: criss-cross args' '
+test_expect_success 'fetch conflict: criss-cross args' '
setup_repository xaa \
"+refs/heads/*:refs/remotes/origin/*" && (
cd xaa &&
git fetch origin \
refs/heads/branch1:refs/remotes/origin/branch2 \
- refs/heads/branch2:refs/remotes/origin/branch1
+ refs/heads/branch2:refs/remotes/origin/branch1 2>error &&
+ verify_stderr <<-\EOF
+ warning: refs/remotes/origin/branch1 usually tracks refs/heads/branch1, not refs/heads/branch2
+ warning: refs/remotes/origin/branch2 usually tracks refs/heads/branch2, not refs/heads/branch1
+ EOF
)
'