Skip to content

Commit 46c8f85

Browse files
committed
Merge branch 'jk/fsck-exit-code-fix' into maint
"git fsck" failed to report that it found corrupt objects via its exit status in some cases. * jk/fsck-exit-code-fix: fsck: return non-zero status on missing ref tips fsck: exit with non-zero status upon error from fsck_obj()
2 parents 102edda + 30d1038 commit 46c8f85

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed

builtin/fsck.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ static void fsck_sha1_list(void)
388388
unsigned char *sha1 = entry->sha1;
389389

390390
sha1_list.entry[i] = NULL;
391-
fsck_sha1(sha1);
391+
if (fsck_sha1(sha1))
392+
errors_found |= ERROR_OBJECT;
392393
free(entry);
393394
}
394395
sha1_list.nr = 0;
@@ -488,6 +489,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
488489
obj = parse_object(sha1);
489490
if (!obj) {
490491
error("%s: invalid sha1 pointer %s", refname, sha1_to_hex(sha1));
492+
errors_found |= ERROR_REACHABLE;
491493
/* We'll continue with the rest despite the error.. */
492494
return 0;
493495
}
@@ -504,7 +506,7 @@ static void get_default_heads(void)
504506
{
505507
if (head_points_at && !is_null_sha1(head_sha1))
506508
fsck_handle_ref("HEAD", head_sha1, 0, NULL);
507-
for_each_ref(fsck_handle_ref, NULL);
509+
for_each_rawref(fsck_handle_ref, NULL);
508510
if (include_reflogs)
509511
for_each_reflog(fsck_handle_reflog, NULL);
510512

t/t1450-fsck.sh

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ test_expect_success 'object with bad sha1' '
6969
git update-ref refs/heads/bogus $cmt &&
7070
test_when_finished "git update-ref -d refs/heads/bogus" &&
7171
72-
test_might_fail git fsck 2>out &&
72+
test_must_fail git fsck 2>out &&
7373
cat out &&
7474
grep "$sha.*corrupt" out
7575
'
@@ -101,7 +101,7 @@ test_expect_success 'email with embedded > is not okay' '
101101
test_when_finished "remove_object $new" &&
102102
git update-ref refs/heads/bogus "$new" &&
103103
test_when_finished "git update-ref -d refs/heads/bogus" &&
104-
git fsck 2>out &&
104+
test_must_fail git fsck 2>out &&
105105
cat out &&
106106
grep "error in commit $new" out
107107
'
@@ -113,7 +113,7 @@ test_expect_success 'missing < email delimiter is reported nicely' '
113113
test_when_finished "remove_object $new" &&
114114
git update-ref refs/heads/bogus "$new" &&
115115
test_when_finished "git update-ref -d refs/heads/bogus" &&
116-
git fsck 2>out &&
116+
test_must_fail git fsck 2>out &&
117117
cat out &&
118118
grep "error in commit $new.* - bad name" out
119119
'
@@ -125,7 +125,7 @@ test_expect_success 'missing email is reported nicely' '
125125
test_when_finished "remove_object $new" &&
126126
git update-ref refs/heads/bogus "$new" &&
127127
test_when_finished "git update-ref -d refs/heads/bogus" &&
128-
git fsck 2>out &&
128+
test_must_fail git fsck 2>out &&
129129
cat out &&
130130
grep "error in commit $new.* - missing email" out
131131
'
@@ -137,7 +137,7 @@ test_expect_success '> in name is reported' '
137137
test_when_finished "remove_object $new" &&
138138
git update-ref refs/heads/bogus "$new" &&
139139
test_when_finished "git update-ref -d refs/heads/bogus" &&
140-
git fsck 2>out &&
140+
test_must_fail git fsck 2>out &&
141141
cat out &&
142142
grep "error in commit $new" out
143143
'
@@ -151,11 +151,31 @@ test_expect_success 'integer overflow in timestamps is reported' '
151151
test_when_finished "remove_object $new" &&
152152
git update-ref refs/heads/bogus "$new" &&
153153
test_when_finished "git update-ref -d refs/heads/bogus" &&
154-
git fsck 2>out &&
154+
test_must_fail git fsck 2>out &&
155155
cat out &&
156156
grep "error in commit $new.*integer overflow" out
157157
'
158158

159+
test_expect_success 'malformatted tree object' '
160+
test_when_finished "git update-ref -d refs/tags/wrong" &&
161+
test_when_finished "remove_object \$T" &&
162+
T=$(
163+
GIT_INDEX_FILE=test-index &&
164+
export GIT_INDEX_FILE &&
165+
rm -f test-index &&
166+
>x &&
167+
git add x &&
168+
T=$(git write-tree) &&
169+
(
170+
git cat-file tree $T &&
171+
git cat-file tree $T
172+
) |
173+
git hash-object -w -t tree --stdin
174+
) &&
175+
test_must_fail git fsck 2>out &&
176+
grep "error in tree .*contains duplicate file entries" out
177+
'
178+
159179
test_expect_success 'tag pointing to nonexistent' '
160180
cat >invalid-tag <<-\EOF &&
161181
object ffffffffffffffffffffffffffffffffffffffff
@@ -282,4 +302,60 @@ test_expect_success 'fsck notices ".git" in trees' '
282302
)
283303
'
284304

305+
# create a static test repo which is broken by omitting
306+
# one particular object ($1, which is looked up via rev-parse
307+
# in the new repository).
308+
create_repo_missing () {
309+
rm -rf missing &&
310+
git init missing &&
311+
(
312+
cd missing &&
313+
git commit -m one --allow-empty &&
314+
mkdir subdir &&
315+
echo content >subdir/file &&
316+
git add subdir/file &&
317+
git commit -m two &&
318+
unrelated=$(echo unrelated | git hash-object --stdin -w) &&
319+
git tag -m foo tag $unrelated &&
320+
sha1=$(git rev-parse --verify "$1") &&
321+
path=$(echo $sha1 | sed 's|..|&/|') &&
322+
rm .git/objects/$path
323+
)
324+
}
325+
326+
test_expect_success 'fsck notices missing blob' '
327+
create_repo_missing HEAD:subdir/file &&
328+
test_must_fail git -C missing fsck
329+
'
330+
331+
test_expect_success 'fsck notices missing subtree' '
332+
create_repo_missing HEAD:subdir &&
333+
test_must_fail git -C missing fsck
334+
'
335+
336+
test_expect_success 'fsck notices missing root tree' '
337+
create_repo_missing HEAD^{tree} &&
338+
test_must_fail git -C missing fsck
339+
'
340+
341+
test_expect_success 'fsck notices missing parent' '
342+
create_repo_missing HEAD^ &&
343+
test_must_fail git -C missing fsck
344+
'
345+
346+
test_expect_success 'fsck notices missing tagged object' '
347+
create_repo_missing tag^{blob} &&
348+
test_must_fail git -C missing fsck
349+
'
350+
351+
test_expect_success 'fsck notices ref pointing to missing commit' '
352+
create_repo_missing HEAD &&
353+
test_must_fail git -C missing fsck
354+
'
355+
356+
test_expect_success 'fsck notices ref pointing to missing tag' '
357+
create_repo_missing tag &&
358+
test_must_fail git -C missing fsck
359+
'
360+
285361
test_done

t/t4212-log-corrupt.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ test_expect_success 'setup' '
1414
'
1515

1616
test_expect_success 'fsck notices broken commit' '
17-
git fsck 2>actual &&
17+
test_must_fail git fsck 2>actual &&
1818
test_i18ngrep invalid.author actual
1919
'
2020

0 commit comments

Comments
 (0)