diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2015-06-02 17:57:26 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-06-02 13:09:16 -0700 |
commit | 8afc493d115e35092be8de3a441317f175928ab5 (patch) | |
tree | 572e705a1a0e74ad6e585e73e43b7b9f9193dfd5 /builtin/for-each-ref.c | |
parent | t6301: new tests of for-each-ref error handling (diff) | |
download | tgif-8afc493d115e35092be8de3a441317f175928ab5.tar.xz |
for-each-ref: report broken references correctly
If there is a loose reference file with invalid contents, "git
for-each-ref" incorrectly reports the problem as being a missing
object with name NULL_SHA1:
$ echo '12345678' >.git/refs/heads/nonsense
$ git for-each-ref
fatal: missing object 0000000000000000000000000000000000000000 for refs/heads/nonsense
With an explicit "--format" string, it can even report that the
reference validly points at NULL_SHA1:
$ git for-each-ref --format='%(objectname) %(refname)'
0000000000000000000000000000000000000000 refs/heads/nonsense
$ echo $?
0
This has been broken since
b7dd2d2 for-each-ref: Do not lookup objects when they will not be used (2009-05-27)
, which changed for-each-ref from using for_each_ref() to using
git_for_each_rawref() in order to avoid looking up the referred-to
objects unnecessarily. (When "git for-each-ref" is given a "--format"
string that doesn't include information about the pointed-to object,
it does not look up the object at all, which makes it considerably
faster. Iterating with DO_FOR_EACH_INCLUDE_BROKEN is essential to this
optimization because otherwise for_each_ref() would itself need to
check whether the object exists as part of its brokenness test.)
But for_each_rawref() includes broken references in the iteration, and
"git for-each-ref" doesn't itself reject references with REF_ISBROKEN.
The result is that broken references are processed *as if* they had
the value NULL_SHA1, which is the value stored in entries for broken
references.
Change "git for-each-ref" to emit warnings for references that are
REF_ISBROKEN but to otherwise skip them.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/for-each-ref.c')
-rw-r--r-- | builtin/for-each-ref.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 008513c2f1..4a15f568f1 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -851,6 +851,11 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f return 0; } + if (flag & REF_ISBROKEN) { + warning("ignoring broken ref %s", refname); + return 0; + } + if (*cb->grab_pattern) { const char **pattern; int namelen = strlen(refname); |