配置

名字和邮箱

在命令行输入:

git config --global user.name "Your Name"
git config --global user.email "email@example.com"

因为 Git 是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和邮箱。大多数情况下,Git 就是靠这些来确定身份的。

注意 git config 命令的 --global 参数,这表示将配置设置为全局的。全局设置对本机的每个仓库都生效。

SSH 密钥

SSH 密钥用于连接 GitHub 或者类似的托管服务。

首先查看你的 SSH 密钥是否已经生成。

ls ~/.ssh

如果你没有生成过 SSH 密钥,那么这个目录应该是不存在的。你可以使用 ssh-keygen 命令来生成一个新的密钥。

ssh-keygen -t rsa

如果在 Windows 系统上找不到 ssh-keygen 命令,那么可以在 Git Bash 中运行。

生成完成后,查看生成的公钥:

cat ~/.ssh/id_rsa.pub

在 GitHub 上添加这个公钥,然后检测一下是否成功:

$ ssh git@github.com
PTY allocation request failed on channel 0
Hi Wybxc! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

看到这样的欢迎信息,说明 SSH 密钥添加成功。

GPG 密钥

上面提到 Git 在确定身份的时候用的是名字和邮箱,但是,这也意味着只要知道了别人的名字和邮箱,就可以冒充他的身份。理论上,这种冒充是无法甄别的,甚至 GitHub 也无法避免。

所以,在名字和邮箱以外,Git 还有另一重保护措施:GPG 密钥。你可以使用自己的 GPG 私钥对提交进行签名,这样别人就能通过公钥鉴定身份。如果你的所有提交都经过签名,那么别人就知道没有签名的那些提交就是冒牌货。

生成 GPG 密钥:

gpg --full-generate-key

如果在 Windows 系统上提示找不到 gpg 命令,可以在 Git Bash 中运行。

基本按照默认配置即可。生成时需要填写名字和邮箱,需要和 Git 的配置一致,而且邮箱需要和 GitHub 账号认证的邮箱一致。

如果生成的是 RSA 密钥,需要设置密钥长度。GitHub 要求 RSA 密钥是 4096 位。

生成过程中会给密钥设置密码,这个密码是解锁私钥的关键。

生成完成后,查看生成的密钥:

$ gpg --list-secret-keys --keyid-format LONG
~/.gnupg/pubring.kbx
-----------------------------------------------
sec   ed25519/85E18D73E1B2E193 2022-06-15 [SC]
      6BBEA37A752DBC75008ABB6B85E18D73E1B2E193
uid                 [ultimate] 忘忧北萱草 <wybxc@qq.com>
ssb   cv25519/FB6CDE598D2CD679 2022-06-15 [E]

这里的 85E18D73E1B2E193 就是密钥 ID。

将 GPG 与 git 相关联:

git config --global user.signingkey 85E18D73E1B2E193
git config --global commit.gpgsign true

此时可以随便开一个 Git 仓库,测试一下 GPG 签名是否可用:

$ git init test
$ cd test
$ echo "test" > test.txt
$ git add .
$ git commit -m "test"
$ git cat-file commit HEAD
tree 02bdfa7bef60afbeb20ae09bb3145e2a4b1cb977
author 忘忧北萱草 <wybxc@qq.com> 1655478113 +0800
committer 忘忧北萱草 <wybxc@qq.com> 1655478113 +0800
gpgsig -----BEGIN PGP SIGNATURE-----

 iQIzBAABCgAdFiEEpRDvWeHZl2iUnVm+/Xek1OdFr8MFAmKsl2EACgkQ/Xek1OdF
 r8PWLQ/+JO2J99tFrMqK4eFPbhhDVbQJBxmYcJHS/iSVqxm6c8S97itQ//7QnLIe
 rpk1/jspbLm4E5f4EzYeoX4v9UstSDBpgrYnAQj81txwZ8l4Kps/XGv4lXDaaTrH
 E8V3Bk3zRj57RjLQwRC2TZGFZXJy6/bQUjgMS3jkiGdcpUsBzrVXmo5sOmPtM8GN
 m1yB1mgy/jjs8nuJIKG8hf1NuAaG+ST8hToEGDb5rYdBCLc4R8dPkp4Ha+3SHcZy
 MMBvAf5STWQAW7gq6Vwsdqj9IqF4DQga5yWvodnJkKtbkJY5RIvgh1NLrT4/M266
 KnVbRgd6ifPzUJb4yyhuOUR32y52JqYXz3SGb7HMkN541HtquaClSCt45lsTACzO
 2AhrtlMl3GYCL9EedQ8ql9cCn+Aj2Ol/PnizK49dE+Vfc/KtzUU+9vsMOD1aZ2vW
 2M8Nz5GLiLX7lpnOUviYnMf7/VStTbeielvcKnC4FQDbJK86yEmjjK+tCTgoiGo3
 Eive7LPB0H9ruenXx26hlOwP1vb2PUSWxXXM0bwEjktrvCRX8byE4w/q9gN8G8TZ
 kZJbvyPh5JBDnq1AIhhyPu9nnizmFml10ynWxqwPQplVG4g1SkV2kYTd8rvt2Jit
 Dj/ka9f1Sh6T2r5r06WNA+DvRJrbYWDovOU68Edj7XALTfmZNeM=
 =pF8U
 -----END PGP SIGNATURE-----

能够在 commit 中看到 GPG 签名,说明 GPG 签名已经在 Git 中配置成功。

如果配置 GPG 之后,提交时 Git 找不到 GPG,那么可以手动设置一下 GPG 的路径:

$ which gpg
/usr/bin/gpg
$ git config --global gpg.program /usr/bin/gpg

如果遇到 error: gpg failed to sign the data 的问题,可以尝试把 GPG_TTY 环境变量设置为 $(tty)参考):

$ git config user.signingKey 38AF394C
$ git config commit.gpgSign true
$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
gpg: signing failed: Inappropriate ioctl for device
gpg: [stdin]: clear-sign failed: Inappropriate ioctl for device

$ export GPG_TTY=$(tty)
$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
-----BEGIN PGP SIGNATURE-----
XXXXXX SUCCESS XXXX
-----END PGP SIGNATURE-----


ref: https://github.com/keybase/keybase-issues/issues/2798

接下来导出 GPG 公钥,然后添加到 GitHub 中:

$ gpg --armor --export 85E18D73E1B2E193
-----BEGIN PGP PUBLIC KEY BLOCK-----

mDMEYqn6LBYJKwYBBAHaRw8BAQdAdUKrYViGQwyP6OvG0zi4BtkztQSHmVSzJweG
RH5YbkC0HuW/mOW/p+WMl+iQseiNiSA8d3lieGNAcXEuY29tPoiTBBMWCgA7FiEE
a76jenUtvHUAirtrheGNc+Gy4ZMFAmKp+iwCGwMFCwkIBwICIgIGFQoJCAsCBBYC
AwECHgcCF4AACgkQheGNc+Gy4ZMLvgD+LPHZ/61I3V2QtcQxjhE7Mmx/zzf7nMu9
yoKsBS0DoHsBAOmGcnz8Ldxt8g5annPoS4JXhyC0vUgvBl5ks+LQ6WILuDgEYqn6
LBIKKwYBBAGXVQEFAQEHQKwoXBZT20+8mEfaqAuSEyMi4eeiE1Adjkj0TCZuV2UE
AwEIB4h4BBgWCgAgFiEEa76jenUtvHUAirtrheGNc+Gy4ZMFAmKp+iwCGwwACgkQ
heGNc+Gy4ZOtkwEAuyAAI2Va4xNuXwWf+WZg7Bt5KcXfcezYGG3EDFstaJMA/i6O
B1wiq7kByLBFmRVBGewKpDA2Z2UGnAQuSvCY5nwF
=FzfD
-----END PGP PUBLIC KEY BLOCK-----

之后,提交的 commit 在 GitHub 上就会显示 verified,表明这条 commit 是通过了 GPG 签名认证的。