resolve_ref(): report breakage to the caller without warning

629cd3a (resolve_ref(): emit warnings for improperly-formatted references, 2011-09-15) made resolve_ref() warn against files that are found in the directories the ref dwimmery looks at. The intent may be good, but these messages come from a wrong level of the API hierarchy. Instead record the breakage in "flags" whose purpose is to explain the result of the function to the caller, who is in a much better position to make intelligent decision based on the information. This updates sha1_name.c::dwim_ref() to warn against such a broken candidate only when it does not appear directly below $GIT_DIR to restore the traditional behaviour, as we know many files directly underneath $GIT_DIR/ are not refs. Warning against "git show config --" with "$GIT_DIR/config does not look like a well-formed ref" does not make sense, and we may later tweak the dwimmery not to even consider them as candidates, but that is a longer term topic. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Oct 19, 2011 at 13:55 UTC 55956350024f0706294001cb50d513cf0fa038a1
1 file changed +11 -7
refs.c
+11 -7
@@ -489,7 +489,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
489 ssize_t len;
490 char buffer[256];
491 static char ref_buffer[256];
492 - char path[PATH_MAX];
492
493 if (flag)
494 *flag = 0;
@@ -498,6 +497,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
497 return NULL;
498
499 for (;;) {
500 + char path[PATH_MAX];
501 struct stat st;
502 char *buf;
503 int fd;
@@ -570,21 +570,22 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
570 */
571 if (prefixcmp(buffer, "ref:"))
572 break;
573 + if (flag)
574 + *flag |= REF_ISSYMREF;
575 buf = buffer + 4;
576 while (isspace(*buf))
577 buf++;
578 if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) {
577 - warning("symbolic reference in %s is formatted incorrectly",
578 - path);
579 + if (flag)
580 + *flag |= REF_ISBROKEN;
581 return NULL;
582 }
583 ref = strcpy(ref_buffer, buf);
582 - if (flag)
583 - *flag |= REF_ISSYMREF;
584 }
585 /* Please note that FETCH_HEAD has a second line containing other data. */
586 if (get_sha1_hex(buffer, sha1) || (buffer[40] != '\0' && !isspace(buffer[40]))) {
587 - warning("reference in %s is formatted incorrectly", path);
587 + if (flag)
588 + *flag |= REF_ISBROKEN;
589 return NULL;
590 }
591 return ref;
@@ -1107,8 +1108,11 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
1108 *ref = xstrdup(r);
1109 if (!warn_ambiguous_refs)
1110 break;
1110 - } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD"))
1111 + } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) {
1112 warning("ignoring dangling symref %s.", fullref);
1113 + } else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {
1114 + warning("ignoring broken ref %s.", fullref);
1115 + }
1116 }
1117 free(last_branch);
1118 return refs_found;