Skip to content

Commit a0c5e8c

Browse files
committed
Do re-download corrupt objects with GVFS (#782)
As of 9e59b38, Git will loudly complain about corrupt objects. That is fine, as long as the idea isn't to re-download locally-corrupted objects. But that's exactly what we want to do in VFS for Git. This is even tested for in the functional tests of VFS for Git, which has been identified as a regression in microsoft/VFSForGit#1853.
2 parents c49aebd + 052ec52 commit a0c5e8c

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

commit.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,14 @@ int repo_parse_commit_internal(struct repository *r,
567567
int flags = OBJECT_INFO_LOOKUP_REPLACE | OBJECT_INFO_SKIP_FETCH_OBJECT |
568568
OBJECT_INFO_DIE_IF_CORRUPT;
569569

570-
/* But the GVFS Protocol _does_ support missing commits! */
570+
/*
571+
* But the GVFS Protocol _does_ support missing commits!
572+
* And the idea with VFS for Git is to re-download corrupted objects,
573+
* not to fail!
574+
*/
571575
if (gvfs_config_is_set(r, GVFS_MISSING_OK))
572-
flags ^= OBJECT_INFO_SKIP_FETCH_OBJECT;
576+
flags &= ~(OBJECT_INFO_SKIP_FETCH_OBJECT |
577+
OBJECT_INFO_DIE_IF_CORRUPT);
573578

574579
if (!item)
575580
return -1;

odb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,9 @@ void *odb_read_object(struct object_database *odb,
11401140
unsigned flags = OBJECT_INFO_DIE_IF_CORRUPT | OBJECT_INFO_LOOKUP_REPLACE;
11411141
void *data;
11421142

1143+
if (gvfs_config_is_set(odb->repo, GVFS_MISSING_OK))
1144+
flags &= ~OBJECT_INFO_DIE_IF_CORRUPT;
1145+
11431146
oi.typep = type;
11441147
oi.sizep = size;
11451148
oi.contentp = &data;

t/t1060-object-corruption.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
test_description='see how we handle various forms of corruption'
44

55
. ./test-lib.sh
6+
. "$TEST_DIRECTORY"/lib-diff-data.sh
67

78
# convert "1234abcd" to ".git/objects/12/34abcd"
89
obj_to_file() {
@@ -62,6 +63,35 @@ test_expect_success 'streaming a corrupt blob fails' '
6263
)
6364
'
6465

66+
test_expect_success PERL 'truncated objects can be re-retrieved via GVFS' '
67+
git init truncated &&
68+
COPYING_test_data >truncated/COPYING &&
69+
git -C truncated add COPYING &&
70+
test_tick &&
71+
git -C truncated commit -m initial COPYING &&
72+
73+
# set up the `read-object` hook so that it overwrites the corrupt object
74+
mkdir -p truncated/.git/hooks &&
75+
sed -e "1s|/usr/bin/perl|$PERL_PATH|" \
76+
-e "s/system/unlink \".git\/objects\/\" . substr(\$sha1, 0, 2) . \"\/\" . substr(\$sha1, 2); &/" \
77+
<$TEST_DIRECTORY/t0410/read-object \
78+
>truncated/.git/hooks/read-object &&
79+
chmod +x truncated/.git/hooks/read-object &&
80+
81+
# ensure that the parent repository has a copy of the object, from
82+
# where the `read-object` can read it
83+
sha="$(git hash-object -w truncated/COPYING)" &&
84+
file=$(obj_to_file $sha) &&
85+
size=$(test_file_size $file) &&
86+
chmod u+w truncated/$file &&
87+
test-tool truncate truncated/$file $(($size-8)) &&
88+
89+
rm truncated/COPYING &&
90+
test_must_fail git -C truncated reset --hard &&
91+
git -C truncated -c core.gvfs=4 -c core.virtualizeObjects \
92+
reset --hard
93+
'
94+
6595
test_expect_success 'getting type of a corrupt blob fails' '
6696
(
6797
cd bit-error &&

0 commit comments

Comments
 (0)