Git integrity
groups.google.com
groups.google.com
It's also not a Git-only issue. Mercurial has the exact same problem., defaulting to trust everything it's given, both on the client and the server. And while the server.validate option allows to enable consistency checking (no missing object), I don't think there is a setting to enforce SHA-1 validation. OTOH, on a repository the size of mozilla-central, this would have noticeable consequences because file lists (manifests) are flat (but that's changing thanks to the work for narrow clones).
server.validate ensures that all referenced revisions from changegroups are in fact present. It prevents repos from becoming "corrupt" (in the sense that `hg verify` will complain) due to missing data.
That said, while it doesn't during transfer, Git does check sha1s when objects are accessed. The code is in object.c in parse_object(), which calls check_sha1_signature(). But disappointingly not everything is going through that code path.
$ git init
$ echo a > a ; echo b > b
$ git add a b
$ git cat-file blob 78981922613b2afb6025042ff6bd878ac1994e85
a
$ cp -f .git/objects/61/780798228d17af2d34fce4cfbdf35556832472 .git/objects/78/981922613b2afb6025042ff6bd878ac1994e85
$ git cat-file blob 78981922613b2afb6025042ff6bd878ac1994e85
b
$ git show 78981922613b2afb6025042ff6bd878ac1994e85
error: sha1 mismatch 78981922613b2afb6025042ff6bd878ac1994e85
fatal: bad object 78981922613b2afb6025042ff6bd878ac1994e85
In the altered repository in the parent, actually doing a commit and then cloning (non-local, because local clones cheat) will yield an error about the missing 78981922613b2afb6025042ff6bd878ac1994e85.
That puzzled me, so I recorded every time addrevision and checkhash are called, and it turns out that Mercurial is not, in fact, checking the SHA-1 of everything. On the current bundle for mozilla-central, it checks:
- All 282460 changesets
- 256 manifests (of 282232)
- 262675 file revisions (of 1615480) for 237574 files, so slightly more than 1 file revision per file but less than 2, on average.
Edit: Reading the code, essentially, it trusts deltas from bundles.
Edit 2: For fairness, it does check SHA-1 when checking out and committing (it even checks the parent changeset 4 times and the new changeset twice), but not when doing hg verify.