Junio C Hamano [off-list ref] writes:
I just did this in an empty directory.
$ git init src
$ cd src
$ echo hello >greetings ; git add . ; git commit -m greetings
$ S=$(git rev-parse :greetings | sed -e 's|^..|&/|')
$ X=$(echo bye | git hash-object -w --stdin | sed -e 's|^..|&/|')
$ mv -f .git/objects/$X .git/objects/$S
The tip commit _thinks_ it has "greetings" that contains "hello", but
somebody replaced it with a corrupt "bye" that does not match self
integrity.
$ git fsck
error: sha1 mismatch ce013625030ba8dba906f756967f9e9ca394464a
error: ce013625030ba8dba906f756967f9e9ca394464a: object corrupt or missing
missing blob ce013625030ba8dba906f756967f9e9ca394464a
The "hello" blob is ce0136, and the tree contained in HEAD expects "hello"
in that loose object file, but notices the contents do not match the
filename.
So far, so good. Let's see what others see when they interact with this
repository.
cd ../
git init dst
cd dst
git config receive.fsckobjects true
git remote add origin ../src
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
git fetch
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From ../src
* [new branch] master -> origin/master
Oops? If we run "fsck" at this point, we would notice the breakage:
...
But the straight "fetch" did not notice anything fishy going on. Shouldn't
we have? Even though we may be reasonably safe, unpack-objects should be
able to do better, especially under receive.fsckobjects option.
We do not have fetch.fsckobjects, and here is a quick patch to add it. I
would also add transfer.fsckobjects to cover both with a single variable
in a follow-up patch, but with this, it fails as expected:
$ git config fetch.fsckobjects true
$ git fetch
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
error: unable to find ce013625030ba8dba906f756967f9e9ca394464a
fatal: object of unexpected type
fatal: unpack-objects failed
during the transfer phase. The "rev-list --verify-objects" addition is a
fix to a related but independent issue, so both are probably good to have,
but this makes it unnecessary to run fsck_object() during the update-ref
phase.
builtin/fetch-pack.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 412bd32..bfed536 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -16,6 +16,7 @@ static int fetch_unpack_limit = -1;
static int unpack_limit = 100;
static int prefer_ofs_delta = 1;
static int no_done = 0;
+static int fetch_fsck_objects;
static struct fetch_pack_args args = {
/* .uploadpack = */ "git-upload-pack",
};@@ -734,6 +735,8 @@ static int get_pack(int xd[2], char **pack_lockfile)
}
if (*hdr_arg)
*av++ = hdr_arg;
+ if (fetch_fsck_objects)
+ *av++ = "--strict";
*av++ = NULL;
cmd.in = demux.out;
@@ -853,6 +856,11 @@ static int fetch_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (!strcmp(var, "fetch.fsckobjects")) {
+ fetch_fsck_objects = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}