Recent versions of git (>= 1.7.9) support signing individual commits with GPG.
Is it possible to retroactively sign all commits within a tree?
retroactively sign all commits within a tree?
Yes: add a tag, that you would sign.
That is actually the preferred option when it comes to sign commits: sign a all set of them through a tag, rather than signing each one individually.
See "How to get pusher's Information in post-receive hooks?".
Note (update may 2017) that only Git 2.13.x/2.14 (Q3 2017) will completely fix the signing process, because "git cherry-pick" and other uses of the sequencer machinery and mishandled a trailer block whose last line is an incomplete line.
This has been fixed so that an additional sign-off etc. are added after completing the existing incomplete line.
See commit 44dc738 (26 Apr 2017) by Jonathan Tan (jhowtan).
(Merged by Junio C Hamano -- gitster -- in commit 6ebfa10, 16 May 2017)
sequencer: add newline before adding footers
When encountering a commit message that does not end in a newline, sequencer does not complete the line before determining if a blank line should be added.
This causes the "(cherry picked..." and sign-off lines to sometimes appear on the same line as the last line of the commit message.This behavior was introduced by commit 967dfd4 ("sequencer: use trailer's trailer layout", 2016-11-29). However, a revert of that commit would not resolve this issue completely: prior to that commit, a conforming footer was deemed to be non-conforming by
has_conforming_footer()if there was no terminating newline, resulting in both conforming and non-conforming footers being treated the same when they should not be.Resolve this issue, both for conforming and non-conforming footers, and in both
do_pick_commit()andappend_signoff(), by always adding a newline to the commit message if it does not end in one before checking the footer for conformity.
With Git 2.29 (Q4 2020), this will be more reliable.
See commit 842385b, commit 9dad073, commit 26e28fe, commit 75d3bee, commit 20f4b04, commit 5b9427e, commit 8d2aa8d, commit 424e28f, commit e885a84, commit 185e865 (30 Sep 2020) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 19dd352, 05 Oct 2020)
sequencer: handle
ignore_footerwhen parsing trailersSigned-off-by: Jeff King
The
append_signoff()function takes an"ignore_footer"argument, which specifies a number of bytes at the end of the message buffer which should not be considered (they cannot contain trailers, and the trailer is spliced in before them).But to find the existing trailers, it calls into
has_conforming_trailer(). That function takes anignore_footerparameter, but since 967dfd4d56 ("sequencer: use trailer's trailer layout", 2016-11-02, Git v2.12.0-rc0 -- merge listed in batch #2) the parameter is completely ignored.The trailer interface we're using takes a single string, with no option to tell it to use part of the string. However, since we have a mutable
strbuf, we can work around this by simply overwriting (and later restoring) the boundary with aNUL.I'm not sure if this can actually trigger a bug in practice. It's easy to get a non-zero
ignore_footerby doing something like this:git commit -F - --cleanup=verbatim <<-EOF subject body Signed-off-by: me # this looks like a comment, but is actually in the # message! That makes the earlier s-o-b fake. EOF git commit --amend -sThere git-commit calls
ignore_non_trailer()to count up the "#" cruft, which becomes theignore_footerheader. But it works even without this patch! That's because the trailer code also callsignore_non_trailer()and skips the cruft, too. So it happens to work because the only callers with a non-zeroignore_footerare using the exact same function that the trailer parser uses internally.And that seems true for all of the current callers, but there's nothing guaranteeing it. We're better off only feeding the correct buffer to the trailer code in the first place.