A Git Horror Story: Repository Integrity With Signed Commits
mikegerwitz.com
mikegerwitz.com
> What shall we do, then, if we receive a pull request for a
> certain feature or bugfix with, say, 300 commits
> 1. Request that the user squash all the commits into a
> single commit
> 2. Adopt a security policy that requires signing only the
> merge commit (forcing a merge commit to be created with
> --no-ff if needed).
> 3. Sign each commit to be introduced by the merge.
Or, tell them to rebase their branch on master, while cleaning up all their "oops", "revert", "typo", "debug" and whatnot commits; resulting in a sane history and 20 commits to be signed. I find this oversight especially sarcastic as he mentions how 2. ruins git bisect, while such uncleaned 300 commit branches ruin it just as effectively, as you can never be quite sure whether the commit you arrive at isn't reverted by one 20 commits later and the real issue was introduced another 20 commits later.It's only that i miss sane defaults and a common sense of workflow amongst the community. Currently it's this huge toolbox that can do everything in thousand ways, but to be honest, i don't want to be able to "get my copy of the sourcecode to the server" in a gazillion ways, i would very much prefer one way and one simple command. If you start googling for "how do i do X in git" you will find 10 ways to do X and 100 philosphical discussions why you should do X in a specific way and about "what would Jes^H^H^H Linus do?". For example, i'd love to have "git init" ask your name, email, if you'd like to sign with GPG, etc. etc. and then save this in git, so that every git commit will be signed with GPG without giving that stupid option. The common way a la "Git" would be to introduce bash aliases, i think. But that doesn't work across machines, OSs or even on the same machine in a different shell.
[alias]
lg = log --graph --decorate
llg = log --oneline --graph --decorate
ll = log --oneline
dc = diff --cached
st = status --short
ci = commit
rb = rebase
br = branch
co = checkout
Then you can just run (e.g.): $ git llgEven for one-line changes I compulsively check `git staged` before committing.
Do code reviews.
Write tests.
I don't see how test cases would fix this either. The attacker can break the test case just as easily as they can insert a backdoor.
To clarify: You can, e.g., use interactive rebase to remove a commit from a branch. But that creates a new HEAD with a different SHA - this is why rebasing published branches is such a bad thing.
The parent was implying you could change history without anyone noticing. This implies modifying a previous commit whilst keeping the current HEAD the same, which can't be done.
I started to sign all my commits in bzr, hg and git since more than 1 year, and it's very easy to do it: you should try to do it as well
(I disagree with Linus and other people who argue that you should just sign the merge commits, since otherwise you'd be "inflationing"/reducing the value of signatures if you'd sign everything: it would be like only signing the very important messages with gpg, and not doing it for the remaining majority: it's fine if you want to have deniability for your unsigned messages, but that's not what I want for my commits: ideally I'd want all of the changes to be auditable)