Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git - Detect if commit is signed off

Tags:

git

Is there any git command or easier format to determine if a commit is or isn't signed off?

like image 902
jshthornton Avatar asked Jul 07 '15 07:07

jshthornton


2 Answers

With Git 1.7.9, Oct. 2011, you how git log --show-signature (mentioned in Kris' answer), but with 2.10 (Q3 2016), you can simply set git config log.showSignature true, which will work with git-log, git-show, git-whatchanged and git-reflog.


To facilitate grepping "Signed-off-By", you now (Git 2.12, Q1 2017) can log with only the "trailer" part of the commit message. (The trailer includes the "Signed-off-By" and other "Acknowledged By" messages)

See commit b1d31c8, commit d9f31fb (19 Nov 2016) by Jacob Keller (jacob-keller). (Merged by Junio C Hamano -- gitster -- in commit f008159, 19 Dec 2016, Git 2.12.0-rc0)

pretty: add %(trailers) format for displaying trailers of a commit message

In addition to %(subject), %(body), "git log --pretty=format:..." learned a new placeholder %(trailers) and %(contents:trailers).


You also have git interpret-trailers, which has just evolved in Git 2.14.x/2.15 (Q3 2017)

See commit 5a0d0c0 (20 Aug 2017) by Martin Ågren (``).
See commit 58311c6, commit cc1735c, commit a388b10, commit 99e09da, commit 0000239, commit fdbdb64, commit 56c493e (15 Aug 2017), and commit 8abc898 (10 Aug 2017) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 06cf4f2, 27 Aug 2017)

"git interpret-trailers" has been taught a "--parse" and a few other options to make it easier for scripts to grab existing trailer lines from a commit log message.

git log --pretty=format:%(trailers:only:unfold)

Actually:

git log --pretty=format:%(trailers:only,unfold)
                                     ^^^^^

See commit 84ff053 (01 Oct 2017) by Taylor Blau (ttaylorr).
(Merged by Junio C Hamano -- gitster -- in commit 436b359, 07 Oct 2017)

pretty.c: delimit "%(trailers)" arguments with ","

In preparation for adding consistent "%(trailers)" atom options to git-for-each-ref(1)'s "--format" argument, change "%(trailers)" in pretty.c to separate sub-arguments with a ",", instead of a ":".

Multiple sub-arguments are given either as "%(trailers:unfold,only)" or "%(trailers:only,unfold)".

This change disambiguates between "top-level" arguments, and arguments given to the trailers atom itself. It is consistent with the behavior of "%(upstream)" and "%(push)" atoms.


Note: this is more robust with Git 2.20 (Q4 2018), since "git interpret-trailers" and its underlying machinery had a buggy code that attempted to ignore patch text after commit log message, which triggered in various codepaths that will always get the log message alone and never get such an input.

See commit 66e83d9, commit ffce7f5, commit e5fba5d, commit 1688c9a, commit c188668, commit 00a21f5, commit a3b636e, commit 0d2db00 (23 Aug 2018) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit fba9654, 17 Sep 2018)

sequencer: ignore "---" divider when parsing trailers

When the sequencer code appends a signoff or cherry-pick origin, it uses the default trailer-parsing options, which treat "---" as the end of the commit message.
As a result, it may be fooled by a commit message that contains that string and fail to find the existing trailer block. Even more confusing, the actual append code does not know about "---", and always appends to the end of the string.
This can lead to bizarre results.

E.g., appending a signoff to a commit message like this:

 subject

 body
 ---
 these dashes confuse the parser!

 Signed-off-by: A

results in output with a final block like:

 Signed-off-by: A

 Signed-off-by: A

The parser thinks the final line of the message is "body", and ignores everything else, claiming there are no trailers.
So we output an extra newline separator (wrong) and add a duplicate signoff (also wrong).

Since we know we are feeding a pure commit message, we can simply tell the parser to ignore the "---" divider.


Git 2.22 (Q2 2019) adds several options:

See commit 0b691d8, commit fd2015b, commit d9b936d, commit 250bea0, commit 3e3f347 (28 Jan 2019), commit 4f732e0 (29 Jan 2019), and commit 4261775 (08 Dec 2018) by Anders Waldenborg (wanders).
(Merged by Junio C Hamano -- gitster -- in commit 42977bf, 07 Mar 2019)

pretty: add support for separator option in %(trailers)

By default trailer lines are terminated by linebreaks ('\n').
By specifying the new 'separator' option they will instead be separated by user provided string and have separator semantics rather than terminator semantics.
The separator string can contain the literal formatting codes %n and %xNN allowing it to be things that are otherwise hard to type such as %x00, or comma and end-parenthesis which would break parsing.

E.g:

$ git log --pretty='%(trailers:key=Reviewed-by,valueonly,separator=%x00)'

And:

pretty: add support for "valueonly" option in %(trailers)

With the new "key=" option to %(trailers) it often makes little sense to show the key, as it by definition already is knows which trailer is printed there.
This new "valueonly" option makes it omit the key when printing trailers.

E.g.:

$ git show -s --pretty='%s%n%(trailers:key=Signed-off-by,valueonly)' aaaa881

will show:

upload-pack: fix broken if/else chain in config callback
Jeff King <[email protected]>
Junio C Hamano <[email protected]>

The parser for "git for-each-ref --format=...(man)" was too loose when parsing the "%(trailers...)" atom, and forgot that "trailers" and "trailers:<modifiers>" are the only two allowed forms, which has been corrected with Git 2.29 (Q4 2020).

See commit 2c22e10, commit a8e0f50 (21 Aug 2020) by Hariom Verma (harry-hov).
(Merged by Junio C Hamano -- gitster -- in commit e177238, 31 Aug 2020)

ref-filter: 'contents:trailers' show error if : is missing

Mentored-by: Christian Couder
Mentored-by: Heba Waly
Helped-by: Eric Sunshine
Signed-off-by: Hariom Verma

The 'contents' atom does not show any error if used with 'trailers' atom and colon is missing before trailers arguments.

e.g %(contents:trailersonly) works, while it shouldn't.

It is definitely not an expected behavior.

Let's fix this bug.


With Git 2.31 (Q1 2021), the "--format=%(trailers)" mechanism gets enhanced to make it easier to design output for machine consumption.

See commit 058761f, commit 9d87d5a, commit 8b966a0, commit 2762e17 (09 Dec 2020), and commit 7c1f79f (06 Dec 2020) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit b62bbd3, 06 Jan 2021)

pretty format %(trailers): add a "keyonly"

Signed-off-by: Ævar Arnfjörð Bjarmason

Add support for a "keyonly". This allows for easier parsing out of the key and value. Before if you didn't want to make assumptions about how the key was formatted. You'd need to parse it out as e.g.:

--pretty=format:'%H%x00%(trailers:separator=%x00%x00)' \
                   '%x00%(trailers:separator=%x00%x00,valueonly)'

And then proceed to deduce keys by looking at those two and subtracting the value plus the hardcoded ": " separator from the non-valueonly %(trailers) line. Now it's possible to simply do:

--pretty=format:'%H%x00%(trailers:separator=%x00%x00,keyonly)' \
                '%x00%(trailers:separator=%x00%x00,valueonly)'

Which at least reduces it to a state machine where you get N keys and correlate them with N values. Even better would be to have a way to change the ": " delimiter to something easily machine-readable (a key might contain ": " too). A follow-up change will add support for that.

I don't really have a use-case for just "keyonly" myself. I suppose it would be useful in some cases as "key=*" matches case-insensitively, so a plain "keyonly" will give you the variants of the keys you matched. I'm mainly adding it to fix the inconsistency with "valueonly".

pretty-formats now includes in its man page:

  • 'keyonly[=<BOOL>]': only show the key part of the trailer.
  • 'valueonly[=<BOOL>]': only show the value part of the trailer.

And:

See commit 058761f, commit 9d87d5a, commit 8b966a0, commit 2762e17 (09 Dec 2020), and commit 7c1f79f (06 Dec 2020) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit b62bbd3, 06 Jan 2021)

pretty format %(trailers): add a "key_value_separator"

Signed-off-by: Ævar Arnfjörð Bjarmason

Add a "key_value_separator" option to the "%(trailers)" pretty format, to go along with the existing "separator" argument.
In combination these two options make it trivial to produce machine-readable (e.g. \0 and \0\0-delimited) format output.

As elaborated on in a previous commit which added "keyonly" it was needlessly tedious to extract structured data from "%(trailers)" before the addition of this "key_value_separator" option.
As seen by the test being added here extracting this data now becomes trivial.

pretty-formats now includes in its man page:

  • 'key_value_separator=<SEP>': specify a separator inserted between trailer lines. When this option is not given each trailer key-value pair is separated by ": ".
    Otherwise it shares the same semantics as 'separator=<SEP>' above.
like image 179
VonC Avatar answered Sep 24 '22 21:09

VonC


You can use git log --invert-grep --grep="Signed-off-By" in Git 2.4 and above. (The --invert-grep option was added in 2.4.)

like image 26
AlBlue Avatar answered Sep 21 '22 21:09

AlBlue