summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2013-10-30 06:33:12 +0100
committerJunio C Hamano <gitster@pobox.com>2013-10-30 14:16:42 -0700
commitf096e6e826678c29e4bfde4d9d1ae1df79074ce3 (patch)
tree64cca6251eb19dace502f26cf24688e7583e03aa
parent76ea6717fe7dda28966f586e09e02b7b0d5b76cf (diff)
downloadgit-mh/fetch-tags-in-addition-to-normal-refs.tar.gz
fetch: improve the error messages emitted for conflicting refspecsmh/fetch-tags-in-addition-to-normal-refs
If we find two refspecs that want to update the same local reference, emit an error message that is more informative based on whether one of the conflicting refspecs is an opportunistic update during a fetch with explicit command-line refspecs. And especially, do not die if an opportunistic reference update conflicts with an express wish of the user; rather, just emit a warning and skip the opportunistic reference update. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-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
)
'