Is there a way to "autosign" commits in Git with a GPG key?

GitPublic Key-EncryptionGnupg

Git Problem Overview


Is there an easy way to make Git always signs each commit or tag that is created?

I tried it with something like:

alias commit = commit -S
But that didn't do the trick.

I don't want to install a different program to make this happen. Is it doable with ease?

Just a side question, maybe commits shouldn't be signed, only tags, which I never create, as I submit single commits for a project like Homebrew, etc.

Git Solutions


Solution 1 - Git

Note: if you don't want to add -S all the time to make sure your commits are signed, there is a proposal (branch 'pu' for now, December 2013, so no guarantee it will make it to a git release) to add a config which will take care of that option for you.
Update May 2014: it is in Git 2.0 (after being resend in this patch series)

See commit 2af2ef3 by Nicolas Vigier (boklm):

Add the commit.gpgsign option to sign all commits

> If you want to GPG sign all your commits, you have to add the -S option all the time.
The commit.gpgsign config option allows to sign all commits automatically.

commit.gpgsign

> A boolean to specify whether all commits should be GPG signed.
Use of this option when doing operations such as rebase can result in a large number of commits being signed. It may be convenient to use an agent to avoid typing your GPG passphrase several times.


That config is usually set per repo (you don't need to sign your private experimental local repos):

cd /path/to/repo/needing/gpg/signature
git config commit.gpgsign true

You would combine that with user.signingKey used as a global setting (unique key used for all repo where you want to sign commit)

git config --global user.signingkey F2C7AB29!
                                           ^^^

As ubombi suggests in the comments (and explain in "GPG Hardware Key and Git Signing", based on "How to Specify a User Id")

> When using gpg an exclamation mark (!) may be appended to force using the specified primary or secondary key, and not to try and calculate which primary or secondary key to use.


user.signingKey was introduced in git 1.5.0 (Jan. 2007) with commit d67778e:

> There shouldn't be a requirement that I use the same form of my name in my git repository and my gpg key.
Further I might have multiple keys in my keyring, and might want to use one that doesn't match up with the address I use in commit messages.

> This patch adds a configuration entry "user.signingKey" which, if present, will be passed to the "-u" switch for gpg, allowing the tag signing key to be overridden.

This is enforced with commit aba9119 (git 1.5.3.2) in order to catch the case where If the user has misconfigured user.signingKey in their .git/config or just doesn't have any secret keys on their keyring.

Notes:

Solution 2 - Git

git config --global user.signingKey 9E08524833CB3038FDE385C54C0AFCCFED5CDE14
git config --global commit.gpgSign true

Replace 9E08524833CB3038FDE385C54C0AFCCFED5CDE14 by your key ID. Remember: It's never a good idea to use the short ID.

UPDATE: Per a new git edict, all config keys should be in camelCase.

Solution 3 - Git

Edit: As of Git version 1.7.9, it is possible to sign Git commits (git commit -S). Updating the answer slightly to reflect this.

The question title is: > Is there a way to “autosign” commits in Git with a GPG key?

Short answer: yes, but don't do it.

Addressing the typo in the question: git commit -s does not sign the commit. Rather, from the man git-commit page:

> -s, --signoff
Add Signed-off-by line by the committer at the end of the commit log message.

This gives a log output similar to the following:


± $ git log                                                                                 [0:43:31]
commit 155deeaef1896c63519320c7cbaf4691355143f5
Author: User Name <user.name@example.com>
Date:   Mon Apr 16 00:43:27 2012 +0200



Added .gitignore

Signed-off-by: User Name <user.name@example.com>


Note the "Signed-off-by: ..." bit; that was generated by the -s flag on the git-commit.

Quoting the release announcement email: > * "git commit" learned "-S" to GPG-sign the commit; this can be shown with the "--show-signature" option to "git log".

So yes, you can sign commits. However, I personally urge caution with this option; automatically signing commits is next to pointless, see below:

> Just a side question, maybe commits shouldn't be signed, only tags, which I never create, as I submit single commits.

That's correct. Commits are not signed; tags are. The reason for this can be found in this message by Linus Torvalds, the last paragraph of which says:

> Signing each commit is totally stupid. It just means that you automate it, and you make the signature worth less. It also doesn't add any real value, since the way the git DAG-chain of SHA1's work, you only ever need one signature to make all the commits reachable from that one be effectively covered by that one. So signing each commit is simply missing the point.

I'd encourage a browse of the linked message, which clarifies why signing commits automatically is not a good idea in a far better way than I could.

However, if you want to automatically sign a tag, you would be able to do that by wrapping the git-tag -[s|u] in an alias; if you're going to do that, you probably want to setup your key id in ~/.gitconfig or the project-specific .git/config file. More information about that process can be seen in the git community book. Signing tags is infinitely more useful than signing each commit you make.

Solution 4 - Git

To make auto signing work pre git version 2.0, you'll have to add git alias for commit.

# git config --global alias.commit commit -S
[alias]
    commit = commit -S

Solution 5 - Git

First setup the public key using which you want to sign all your commits , tags and push. To get the public key, use the following command

% gpg --list-keys --keyid-format=short
/home/blueray/.gnupg/pubring.kbx
-------------------------------
pub   rsa3072/F6EED39A 2021-12-25 [SC] [expires: 2023-12-25]

In this case the public key is F6EED39A. Now run the following commands.

git config --global user.signingkey F6EED39A
git config --global commit.gpgSign true // sign all commits
git config --global tag.gpgSign true // sign all tags
git config --global push.gpgSign true // sign all push

Now all your commits , tags and push will be signed by your given public key automatically.

Sometimes you may need to override these settings.

For commits, use git commit --no-gpg-sign -m "Unsigned commit"

For tags, use git tag --no-sign <tag-name>

For push, use git push --no-signed

Solution 6 - Git

You need to make clear that if you sign a commit or tag, that you do not mean that you approve the whole history. In case of commits you only sign the change at hand, and in case of tag, well.. you need to define what you mean with it. You might have pulled a change which claims it is from you but was not (because somebody else pushed it to your remote). Or it is a change you dont want to be in, but you just signed the tag.

In typical OSS projects this might be less common, but in a enterprise scenario where you only touch code every now and then and you don't read the whole history it might get unnoticed.

Signing commits is a problem if they will get rebased or cherry-picked to other parents. But it would be good if a modified commit could point to the "original" commit which actually verifies.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMindToothView Question on Stackoverflow
Solution 1 - GitVonCView Answer on Stackoverflow
Solution 2 - GitFelipeView Answer on Stackoverflow
Solution 3 - GitsimontView Answer on Stackoverflow
Solution 4 - GitShubham ChaudharyView Answer on Stackoverflow
Solution 5 - GitAhmad IsmailView Answer on Stackoverflow
Solution 6 - GiteckesView Answer on Stackoverflow