From 98ac34b2b1968e16fbf7f6122a53b73c6caaff49 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 19 Oct 2011 13:45:50 -0700 Subject: [PATCH 1/2] resolve_ref(): expose REF_ISBROKEN flag Instead of keeping this as an internal API, let the callers find out the reason why resolve_ref() returned NULL is not because there was no such file in $GIT_DIR but because a file was corrupt. Signed-off-by: Junio C Hamano --- refs.c | 13 ++++++------- refs.h | 5 +++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/refs.c b/refs.c index e3692bd3d8..30e08482a0 100644 --- a/refs.c +++ b/refs.c @@ -4,9 +4,8 @@ #include "tag.h" #include "dir.h" -/* ISSYMREF=01 and ISPACKED=02 are public interfaces */ -#define REF_KNOWS_PEELED 04 -#define REF_BROKEN 010 +/* ISSYMREF=0x01, ISPACKED=0x02 and ISBROKEN=0x04 are public interfaces */ +#define REF_KNOWS_PEELED 0x10 struct ref_list { struct ref_list *next; @@ -309,12 +308,12 @@ static struct ref_list *get_ref_dir(const char *submodule, const char *base, flag = 0; if (resolve_gitlink_ref(submodule, ref, sha1) < 0) { hashclr(sha1); - flag |= REF_BROKEN; + flag |= REF_ISBROKEN; } } else if (!resolve_ref(ref, sha1, 1, &flag)) { hashclr(sha1); - flag |= REF_BROKEN; + flag |= REF_ISBROKEN; } list = add_ref(ref, sha1, flag, list, NULL); } @@ -613,8 +612,8 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim, return 0; if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) { - if (entry->flag & REF_BROKEN) - return 0; /* ignore dangling symref */ + if (entry->flag & REF_ISBROKEN) + return 0; /* ignore broken refs e.g. dangling symref */ if (!has_sha1_file(entry->sha1)) { error("%s does not point to a valid object!", entry->name); return 0; diff --git a/refs.h b/refs.h index d5ac133336..e4578856d7 100644 --- a/refs.h +++ b/refs.h @@ -10,8 +10,9 @@ struct ref_lock { int force_write; }; -#define REF_ISSYMREF 01 -#define REF_ISPACKED 02 +#define REF_ISSYMREF 0x01 +#define REF_ISPACKED 0x02 +#define REF_ISBROKEN 0x04 /* * Calls the specified function for each ref file until it returns nonzero, From 55956350024f0706294001cb50d513cf0fa038a1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 19 Oct 2011 13:55:49 -0700 Subject: [PATCH 2/2] 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 --- refs.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/refs.c b/refs.c index 30e08482a0..448f0271f8 100644 --- a/refs.c +++ b/refs.c @@ -489,7 +489,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * ssize_t len; char buffer[256]; static char ref_buffer[256]; - char path[PATH_MAX]; if (flag) *flag = 0; @@ -498,6 +497,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * return NULL; for (;;) { + char path[PATH_MAX]; struct stat st; char *buf; int fd; @@ -570,21 +570,22 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * */ if (prefixcmp(buffer, "ref:")) break; + if (flag) + *flag |= REF_ISSYMREF; buf = buffer + 4; while (isspace(*buf)) buf++; if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) { - warning("symbolic reference in %s is formatted incorrectly", - path); + if (flag) + *flag |= REF_ISBROKEN; return NULL; } ref = strcpy(ref_buffer, buf); - if (flag) - *flag |= REF_ISSYMREF; } /* Please note that FETCH_HEAD has a second line containing other data. */ 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 ref; @@ -1107,8 +1108,11 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) *ref = xstrdup(r); if (!warn_ambiguous_refs) break; - } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) + } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) { warning("ignoring dangling symref %s.", fullref); + } else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) { + warning("ignoring broken ref %s.", fullref); + } } free(last_branch); return refs_found;