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>
This commit is contained in:
Junio C Hamano 2011-10-19 13:55:49 -07:00
Родитель 98ac34b2b1
Коммит 5595635002
1 изменённых файлов: 11 добавлений и 7 удалений

18
refs.c
Просмотреть файл

@ -489,7 +489,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
ssize_t len; ssize_t len;
char buffer[256]; char buffer[256];
static char ref_buffer[256]; static char ref_buffer[256];
char path[PATH_MAX];
if (flag) if (flag)
*flag = 0; *flag = 0;
@ -498,6 +497,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
return NULL; return NULL;
for (;;) { for (;;) {
char path[PATH_MAX];
struct stat st; struct stat st;
char *buf; char *buf;
int fd; int fd;
@ -570,21 +570,22 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
*/ */
if (prefixcmp(buffer, "ref:")) if (prefixcmp(buffer, "ref:"))
break; break;
if (flag)
*flag |= REF_ISSYMREF;
buf = buffer + 4; buf = buffer + 4;
while (isspace(*buf)) while (isspace(*buf))
buf++; buf++;
if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) { if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) {
warning("symbolic reference in %s is formatted incorrectly", if (flag)
path); *flag |= REF_ISBROKEN;
return NULL; return NULL;
} }
ref = strcpy(ref_buffer, buf); ref = strcpy(ref_buffer, buf);
if (flag)
*flag |= REF_ISSYMREF;
} }
/* Please note that FETCH_HEAD has a second line containing other data. */ /* Please note that FETCH_HEAD has a second line containing other data. */
if (get_sha1_hex(buffer, sha1) || (buffer[40] != '\0' && !isspace(buffer[40]))) { if (get_sha1_hex(buffer, sha1) || (buffer[40] != '\0' && !isspace(buffer[40]))) {
warning("reference in %s is formatted incorrectly", path); if (flag)
*flag |= REF_ISBROKEN;
return NULL; return NULL;
} }
return ref; return ref;
@ -1107,8 +1108,11 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
*ref = xstrdup(r); *ref = xstrdup(r);
if (!warn_ambiguous_refs) if (!warn_ambiguous_refs)
break; break;
} else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) {
warning("ignoring dangling symref %s.", fullref); warning("ignoring dangling symref %s.", fullref);
} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {
warning("ignoring broken ref %s.", fullref);
}
} }
free(last_branch); free(last_branch);
return refs_found; return refs_found;