Subject: Re: how to (integrity) verify a whole git repo

From: Junio C Hamano <[email-masked]>
Date: Tue, 21 Apr 2020 12:14:21 -0700

Christoph Anton Mitterer <[email-masked]> writes:

> How to check everything else? Is it enough to git fsck --full?
>
> Everything earlier in the history of a verified tag/commit should be
> cryptographically safe (assuming SHA1 would be still secure enough),
> right?

Correct.

> 2) But this of course won't show me anything which is in the repo but
> not earlier in the history of the tag/commit I've checked, right?!
> Is there a way to e.g. have everything dropped which is not verifiable
> via some signed commit/tag?

You can compute the commits that are not reachable from any of the
signed tags.

    git rev-list --all --not $list_tags_and_commits_you_trust_here

will enumerate all the commits that are not reachable from those
tags.

But your "have everything dropped" is a fuzzy notion and you must be
more precise to define what you want.  Imagine this history:

    ----o-----o-----L-----x----x-----x-----x-----x----x HEAD (master)
                                          /
                                         /
                                        /
                   ... ------o----o----G

where you have two people you trust (Linus and Greg), HEAD is the
tip of your 'master' branch, probably you fetched from Linus, L and
G are the two recent tags Linus and Greg signed.

If you enumerate commits that are not reachable from L or G, you'll
get all commits that are marked with 'x'.  Commits marked with 'o'
are reachable from either 'L' or 'G', and you would want to keep
them.

Now, you need to define what you mean by "have everything dropped".
You can remove commits 'x' but then after that where would your
'master' branch point at?  There is no good answer to that question.

What you could do is remove all branches and tags except for the
signed tags you trust from your repository and then use "git repack"
the repository.  Then there will be tags that point at L and G but
you'd be discarding 'master' (which is not signed) and repack will
discard all 'x' in the sample history illustrated above.