8afc493d11
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>
57 lines
1.6 KiB
Bash
Executable File
57 lines
1.6 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='for-each-ref errors for broken refs'
|
|
|
|
. ./test-lib.sh
|
|
|
|
ZEROS=$_z40
|
|
MISSING=abababababababababababababababababababab
|
|
|
|
test_expect_success setup '
|
|
git commit --allow-empty -m "Initial" &&
|
|
git tag testtag &&
|
|
git for-each-ref >full-list &&
|
|
git for-each-ref --format="%(objectname) %(refname)" >brief-list
|
|
'
|
|
|
|
test_expect_success 'Broken refs are reported correctly' '
|
|
r=refs/heads/bogus &&
|
|
: >.git/$r &&
|
|
test_when_finished "rm -f .git/$r" &&
|
|
echo "warning: ignoring broken ref $r" >broken-err &&
|
|
git for-each-ref >out 2>err &&
|
|
test_cmp full-list out &&
|
|
test_cmp broken-err err
|
|
'
|
|
|
|
test_expect_failure 'NULL_SHA1 refs are reported correctly' '
|
|
r=refs/heads/zeros &&
|
|
echo $ZEROS >.git/$r &&
|
|
test_when_finished "rm -f .git/$r" &&
|
|
echo "warning: ignoring broken ref $r" >zeros-err &&
|
|
git for-each-ref >out 2>err &&
|
|
test_cmp full-list out &&
|
|
test_cmp zeros-err err &&
|
|
git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err &&
|
|
test_cmp brief-list brief-out &&
|
|
test_cmp zeros-err brief-err
|
|
'
|
|
|
|
test_expect_success 'Missing objects are reported correctly' '
|
|
r=refs/heads/missing &&
|
|
echo $MISSING >.git/$r &&
|
|
test_when_finished "rm -f .git/$r" &&
|
|
echo "fatal: missing object $MISSING for $r" >missing-err &&
|
|
test_must_fail git for-each-ref 2>err &&
|
|
test_cmp missing-err err &&
|
|
(
|
|
cat brief-list &&
|
|
echo "$MISSING $r"
|
|
) | sort -k 2 >missing-brief-expected &&
|
|
git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err &&
|
|
test_cmp missing-brief-expected brief-out &&
|
|
test_must_be_empty brief-err
|
|
'
|
|
|
|
test_done
|