如何在交互式变基压缩后保留提交的 GPG 签名?

38

当我想通过交互式的 rebase 来压缩一些提交时:

git rebase -i HEAD~3

然后:

pick cbd03e3 Final commit (signed)
s f522f5d bla-bla-bla (signed)
s 09a7b7c bla-bla (signed)

# Rebase c2e142e..09a7b7c onto c2e142e
...

尽管所有这些提交具有相同的签名,但最终提交未进行gpg签名。在交互式变基压缩之后,是否可能保留提交的gpg签名?


“那些提交都有相同的签名”这句话没有意义。您可能是从同一密钥生成不同的签名,但签名本身不能相同。 - chpio
5个回答

67

像 Cupcake 所说的那样,您无法从未压缩的提交中保留旧签名,但如果您像这样变基,则可以为新的压缩提交进行签名:

git rebase --interactive --gpg-sign=myemail@example.com HEAD~4

--gpg-sign=myemail@example.com 添加为参数将对最终压缩提交进行签名。


这个在 git 1.8.3.1 或更新版本中还有效吗?运行这个命令会抛出以下错误:error: unknown option 'gpg-sign=me@example.com' - J.W.F.
1
@jflory7 我正在使用 git 2.13.3,这对我仍然有效。 - samurailink3
2
如果那不起作用,你可以使用 git rebase -i HEAD~4 命令,并使用 git commit --amend -S 命令编辑每个提交。 - Gabo Esquivel
1
我记得设置git配置变量commit.gpgsignuser.signingkey自动为我签署提交 - 这个设置不适用于变基吗? - Krishnan Shankar
1
@KrishnanShankar 如果你不说“edit”,就不会有任何变化。如果你说“edit”,每一步交互式变基都会产生一个提交,而这是你需要使用git commit命令,然后你可以添加-S选项,例如...或者使用其他选项。 - 0xC0000022L

16

你能保留签名并修改历史记录是没有意义的。gpg签名的整个目的就是为了验证代码是否被篡改。如果你在修改历史记录后仍然能保留签名,那么这将完全失去其意义。

我目前没有使用gpg对我的Git代码进行签名,所以我不知道确切的细节,但我猜它可能会对树的最终提交对象进行哈希。当你像你的例子中那样进行变基时,最终提交将具有不同的sha1 ID,因此它不是之前变基之前的相同对象,因此拥有相同的gpg签名可能是不可能的,而且正如我所说,这是没有意义的。


5
如果这些提交是你自己的,而且你想保留一个签名(而不是那个签名),那么这就有道理了。 - Andy Hayden
1
@AndyHayden 那么你应该辞去提交。在 rebase 之前,先挑一个新分支对我有概念上的帮助。我正在处理 work-01。我执行 git checkout work-02。我进行了 rebase,解决了合并冲突,并根据需要压缩了提交。work-01 没有任何变化。提交仍然保持原样。其中一些提交可能也存在于 work-02 中,有些可能几乎相同,但如果单个字符发生了变化,则具有新的提交哈希 ID。这个练习帮助我理解了 Git rebase。 - emory
2
这很有趣,但我想知道它是否100%有效。我们在功能分支上工作,我们的Gitlab配置为仅允许MR(合并请求),如果它们可以快进(准线性历史记录),因此如果基本分支发生更改,我们会将这些分支变基。当我提交到功能分支并签署提交时,然后我的同事变基分支,如果提交被选中而没有更改,则GPG签名应保持不变(因此我的签名仍然有效,因为它是我提交和签署的确切代码)。然而,当其他人变基已签署的提交时,GPG签名会丢失(我们刚刚检查过)。 - Wirone

7

一种选择是将commit.gpgSign设置为true。这会始终签署提交,包括重定位的提交。

在本地仓库中执行:

git config commit.gpgSign true

全局操作:

git config --global commit.gpgSign true

6
为了强调在rebase提交中不会保留签名,git 2.9.x+ (2016年第三季度)将明确指出 git pull --rebase 不会检查签名(因为rebase部分会丢失它们)。
请参见提交c57e501 (2016年5月20日),由Alexander Hirsch (``)撰写。
(由Junio C Hamano -- gitster --合并于提交73bc4b4,2016年6月20日)

pull: 在--rebase时使用--verify-signatures进行警告

git-pull在运行--rebase时默默地忽略了--verify-signatures选项,这可能会让用户误以为rebase操作会检查有效的GPG签名。

虽然曾经讨论过为git rebase实现--verify-signatures,但对于有效的工作流程存在疑虑。由于你通常将其他人的分支合并到你的分支中,因此你可能有兴趣确保他们的一侧具有有效的GPG签名。

然而,rebase是在其他人的工作基础上重建你的分支,以便将结果推回,即使你发现他们的提交缺少可接受的签名,也已经太晚了,无法拒绝他们的工作

让我们警告用户,在"pull --rebase"期间忽略--verify-signatures选项;这样用户就不会想知道如果他们的提交缺少可接受的签名会发生什么


1
有一种方法还没有被提到,但实际上它等同于一个交互式的变基(interactive rebase),对每个待签名的提交使用edit命令,并手动进行修订/提交(带有-S选项),但是以预定的命令和自动化方式执行。
git rebase --exec 'git commit --amend --no-edit -S' HEAD~3

使用--exec选项时,-i--interactive)是隐含的,根据文档,因此在上面没有给出。

在这里,我们按照问题中所示对HEAD~3进行变基,并对每个提交使用git commit --amend --no-edit -S。这通常只会要求一次输入PGP密钥的密码,然后快速处理剩下的提交。

NB:不用说,但由于有评论提到:与其他方法一样,你只能对自己的提交这样操作。去除--no-edit,你将进入编辑器,显示(在底部的注释中)你要处理的更改内容。这样你可以验证提交是否属于你(除非你已经通过git log或其他方式做过验证)。


可以说,在全局配置未设置时,要告诉Git进行签名,你也可以使用git -c commit.gpgSign=true(或其他相关配置选项),通过--exec传递的命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接