-
1. 起步
-
2. Git 基础
-
3. Git 分支
-
4. 服务器上的 Git
- 4.1 协议
- 4.2 在服务器上部署 Git
- 4.3 生成 SSH 公钥
- 4.4 架设服务器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管服务
- 4.10 小结
-
5. 分布式 Git
-
A1. 附录 A: Git 在其他环境
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小结
-
A2. 附录 B: 在应用程序中嵌入 Git
-
A3. 附录 C: Git 命令
7.4 Git 工具 - 签名您的工作
签名您的工作
Git 在密码学上是安全的,但并非万无一失。如果您从互联网上的其他人那里获取工作,并希望验证提交确实来自可信来源,Git 提供了一些使用 GPG 签名和验证工作的方法。
GPG 简介
首先,如果您想签名任何内容,需要配置 GPG 并安装您的个人密钥。
$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub 2048R/0A46826A 2014-06-04
uid Scott Chacon (Git signing key) <schacon@gmail.com>
sub 2048R/874529A9 2014-06-04
如果您没有安装密钥,可以使用 gpg --gen-key 生成一个。
$ gpg --gen-key
一旦您有了用于签名的私钥,您可以通过设置 user.signingkey 配置项来配置 Git 以便使用它来签名内容。
$ git config --global user.signingkey 0A46826A!
现在,如果您愿意,Git 将默认使用您的密钥来签名标签和提交。
签名标签
如果您已设置 GPG 私钥,现在就可以使用它来签名新标签。您只需要使用 -s 而不是 -a。
$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Ben Straub <ben@straub.cc>"
2048-bit RSA key, ID 800430EB, created 2014-05-04
如果您运行 git show 查看该标签,您可以看到您的 GPG 签名已附加到其中。
$ git show v1.5
tag v1.5
Tagger: Ben Straub <ben@straub.cc>
Date: Sat May 3 20:29:41 2014 -0700
my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
Change version number
验证标签
要验证签名标签,请使用 git tag -v <tag-name>。此命令使用 GPG 来验证签名。要使其正常工作,您需要在您的密钥环中有签名者的公钥。
$ git tag -v v1.4.2.1
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
GIT 1.4.2.1
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
gpg: aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
如果您没有签名者的公钥,您将看到类似这样的内容。
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.4.2.1'
签名提交
在较新版本的 Git (v1.7.9 及更高版本) 中,您现在也可以签名单个提交。如果您有兴趣直接签名提交而不是仅签名标签,您所需要做的就是在 git commit 命令中添加 -S。
$ git commit -a -S -m 'Signed commit'
You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04
[master 5c3386c] Signed commit
4 files changed, 4 insertions(+), 24 deletions(-)
rewrite Rakefile (100%)
create mode 100644 lib/git.rb
要查看和验证这些签名,还有一个 --show-signature 选项可用于 git log。
$ git log --show-signature -1
commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
gpg: Signature made Wed Jun 4 19:49:17 2014 PDT using RSA key ID 0A46826A
gpg: Good signature from "Scott Chacon (Git signing key) <schacon@gmail.com>"
Author: Scott Chacon <schacon@gmail.com>
Date: Wed Jun 4 19:49:17 2014 -0700
Signed commit
此外,您可以配置 git log 来检查它找到的任何签名,并在其输出中使用 %G? 格式列出它们。
$ git log --pretty="format:%h %G? %aN %s"
5c3386c G Scott Chacon Signed commit
ca82a6d N Scott Chacon Change the version number
085bb3b N Scott Chacon Remove unnecessary test code
a11bef0 N Scott Chacon Initial commit
在这里,我们可以看到只有最新的提交被签名且有效,而之前的提交则不是。
在 Git 1.8.3 及更高版本中,可以通过 --verify-signatures 命令指示 git merge 和 git pull 在合并不包含可信 GPG 签名的提交时进行检查并拒绝。
如果您在合并分支时使用此选项,并且该分支包含未签名且无效的提交,则合并将无法进行。
$ git merge --verify-signatures non-verify
fatal: Commit ab06180 does not have a GPG signature.
如果合并仅包含有效的签名提交,则合并命令将显示所有已检查的签名,然后继续进行合并。
$ git merge --verify-signatures signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
Updating 5c3386c..13ad65e
Fast-forward
README | 2 ++
1 file changed, 2 insertions(+)
您也可以将 -S 选项与 git merge 命令一起使用,以签名生成的合并提交本身。以下示例同时验证了要合并的分支中的每个提交都已签名,并且还签名了生成的合并提交。
$ git merge --verify-signatures -S signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04
Merge made by the 'recursive' strategy.
README | 2 ++
1 file changed, 2 insertions(+)
每个人都必须签名
签名标签和提交很棒,但如果您决定在日常工作流程中使用此功能,您必须确保团队中的每个人都了解如何进行。这可以通过要求所有处理该存储库的人运行 git config --local commit.gpgsign true 来实现,以便该存储库中的所有提交默认都自动签名。否则,您将花费大量时间帮助人们弄清楚如何用签名版本重写他们的提交。在将此作为标准工作流程的一部分之前,请确保您了解 GPG 以及签名内容的益处。