<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>@bnjbvr - til</title>
    <subtitle>Technical blog and random musings.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bouvier.cc/tags/til/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bouvier.cc"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-14T00:00:00+00:00</updated>
    <id>https://bouvier.cc/tags/til/atom.xml</id>
    <entry xml:lang="en">
        <title>TIL: automatically signing Git commits and adding signoffs</title><published>2026-09-14T00:00:00+00:00</published>
        <author>
          <name>Benjamin Bouvier</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bouvier.cc/tech/gpg-signing-signoffs/"/>
        <id>https://bouvier.cc/tech/gpg-signing-signoffs/</id>
        <content type="html" xml:base="https://bouvier.cc/tech/gpg-signing-signoffs/">&lt;p&gt;For a new work project, I had to set up GPG signing and add the &lt;code&gt;signed-off-with&lt;/code&gt; trailer to all my commit messages. I’m using &lt;code&gt;lazygit&lt;/code&gt;, so while these options are available in the command line, I needed some more general way to do this. Here’s how I’ve done it, in case it’s useful to other folks.&lt;/p&gt;
&lt;span id=&quot;continue-reading&quot;&gt;&lt;/span&gt;&lt;h2 id=&quot;what-is-signing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-signing&quot; aria-label=&quot;Anchor link for: what-is-signing&quot;&gt;🔗&lt;/a&gt;What is signing?&lt;/h2&gt;
&lt;p&gt;Signing is committing a proof that you are who you claim you are, and/or that you are the one who did what you did. In some ways, it is the reciprocal operation of encrypting: signing (=~ “encrypting”) some public content makes use of your private key, so that people on the other end can check the signature (=~ “decrypt”) with the public key, and assert that the decrypted content is what they see too.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-gpg&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#setting-up-gpg&quot; aria-label=&quot;Anchor link for: setting-up-gpg&quot;&gt;🔗&lt;/a&gt;Setting up GPG&lt;/h2&gt;
&lt;p&gt;These commands have been tested against &lt;code&gt;gpg&lt;/code&gt; version 2.4.9.&lt;/p&gt;
&lt;p&gt;Create a new key:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;gpg&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; --full-generate-key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Show a list of your known keys:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;gpg&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; -k&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the long ID for your key (a string of random letters and numbers), then export it:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;gpg&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; --armor --export&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; LONG_ID&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This can then be copied into your Github/Gitlab settings, in the GPG key section.&lt;/p&gt;
&lt;h2 id=&quot;verify-commits-with-gpg-signing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#verify-commits-with-gpg-signing&quot; aria-label=&quot;Anchor link for: verify-commits-with-gpg-signing&quot;&gt;🔗&lt;/a&gt;Verify commits with GPG signing&lt;/h2&gt;
&lt;p&gt;You can decide to commit and sign individual commits:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; commit&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; -S&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, you can check that a commit has been signed by looking at the log; it’s not displayed by default:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; log&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; --show-signature&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;…Or request to always commit and sign with a GPG key, which can be handy if you’re using nice external tools wrapping &lt;code&gt;git&lt;/code&gt; like &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/jesseduffield/lazygit/&quot;&gt;&lt;code&gt;lazygit&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Within the context of one git repository:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; config commit.gpgsign&lt;/span&gt;&lt;span style=&quot;color: #FF9E64;&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; config user.signingkey LONG_ID&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or if you want to do it for &lt;em&gt;all&lt;/em&gt; your projects, add &lt;code&gt;--global&lt;/code&gt; to these commands.&lt;/p&gt;
&lt;h2 id=&quot;bonus-always-add-signed-off-with-mention-to-your-commits&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#bonus-always-add-signed-off-with-mention-to-your-commits&quot; aria-label=&quot;Anchor link for: bonus-always-add-signed-off-with-mention-to-your-commits&quot;&gt;🔗&lt;/a&gt;Bonus: always add &lt;code&gt;Signed-off-with&lt;/code&gt; mention to your commits&lt;/h2&gt;
&lt;p&gt;You can do it on a per-commit basis as well &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://bouvier.cc/tech/gpg-signing-signoffs/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; commit&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; -s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the following git hook, by writing a new file in &lt;code&gt;${PROJECT}/.git/hooks/prepare-commit-msg&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #51597D;font-style: italic;&quot;&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;NAME&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; config user.name&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;EMAIL&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;=$(&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; config user.email&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt; -z&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;$NAME&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot; ];&lt;/span&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #0DB9D7;&quot;&gt;    echo&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt;empty git config user.name&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #0DB9D7;&quot;&gt;    exit&lt;/span&gt;&lt;span style=&quot;color: #FF9E64;&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt; -z&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;$EMAIL&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot; ];&lt;/span&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #0DB9D7;&quot;&gt;    echo&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt;empty git config user.email&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #0DB9D7;&quot;&gt;    exit&lt;/span&gt;&lt;span style=&quot;color: #FF9E64;&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #BB9AF7;&quot;&gt;fi&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; interpret-trailers&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; --if-exists&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; doNothing&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt; --trailer&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;    &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt;Signed-off-by: &lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;$NAME&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;$EMAIL&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt;    --in-place&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E0AF68;&quot;&gt;$1&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure the git hook is executable with:&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #A9B1D6; background-color: #1A1B26;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;chmod&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt; +x&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt; ${&lt;/span&gt;&lt;span style=&quot;color: #C0CAF5;&quot;&gt;PROJECT&lt;/span&gt;&lt;span style=&quot;color: #89DDFF;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #9ECE6A;&quot;&gt;/.git/hooks/prepare-commit-msg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Courtesy of this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://stackoverflow.com/questions/15015894/git-add-signed-off-by-line-using-format-signoff-not-working&quot;&gt;StackOverflow answer&lt;/a&gt;.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Yay for the options being &lt;code&gt;-s&lt;/code&gt; for adding the &lt;code&gt;signed-off-with&lt;/code&gt; mention in the commit message, and &lt;code&gt;-S&lt;/code&gt; for signing with GPG. Ergonomics, amirite? &lt;a href=&quot;https://bouvier.cc/tech/gpg-signing-signoffs/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
    </entry>
</feed>

