Git现在可以使用git commit -S签署提交,这很不错,但是有时我忘记了commit的标志,有时我自己邮寄适用于am的补丁,并且该命令没有用于签署的标志。

是否可以将签名添加到已记录的提交中?

评论

作为记录,您可以告诉git始终通过配置对提交进行签名:git config commit.gpgsign true。

@nicooga希望您的评论得到更多好评,以便我早些注意到。我不得不提出至少六个问题,设置该标志将节省我很多时间。

如果提交已经发布,则不应出于任何目的(除了消除意外的数据泄漏)重写它们,因为这会更改其提交ID。您不需要显式地签名那些旧提交,至少不需要出于数据完整性目的。由于每个提交都包含其父基于SHA-1的ID,因此验证任何单个提交也将通过哈希链隐式验证其整个历史记录。 superuser.com/questions/1144817/…

#1 楼


进入交互式rebase模式。

要签名的每个提交之后添加以下行

exec git commit --amend --no-edit -S


这将在选择每个提交后运行此命令。

UPDATE:

更简单的方法是:

git rebase --exec 'git commit --amend --no-edit -n -S' -i development


这将使所有内容重新建立基础,直到开发(或任何哈希)为止,并且您不必在每次提交后都复制粘贴。

评论


哦,我希望我能早点找到它。我读了很多东西,甚至是从GitHub自己那里读到的东西,都说你不能辞职。这证明是完全错误的!我本可以保存成百上千的提交,而现在已经被压缩了。哦,很好。谢谢分享!我以此为别名。 resign =“!re(){git rebase --exec'git commit --amend --no-edit -n -S'-i $ 1;}; re”变成git resign哈希

–BarryMode
17年7月6日在21:16

这应该是常识!您为人类做了出色的服务(绝不差强人意!)!

–hopeseekr
18年2月3日在20:25



完全没有理由重新设置基础。只需运行git commit --amend --no-edit -n -S。

– Quolonel问题
18 Mar 6 '18 at 1:51

这不会改变历史,需要git push --force吗?

–史蒂夫
18年4月14日在17:21

@BarryMode人们是正确的,因为您不能辞职。从技术上讲,此答案不会放弃旧的提交,而只是创建一个包含相同内容并带有附加签名的新提交。需要强制推送不是同一次提交。

– SOFe
20-4-16在1:53



#2 楼

对提交进行签名会更改其内容,因此,取决于它的最新提交将更改其哈希值。

如果只想对最新提交进行签名,则git commit -S --amend将起作用。

评论


大多数时候,对最新提交进行签名,甚至在其上创建一个空的已签名提交都足以保证真实性。 Git提交是一棵Merkle树,因此修改任何祖先提交都需要重写其后代,从而使签名无效。

–gronostaj
20年7月22日在12:38

#3 楼

我使用git rebase -i --root(请参阅重写历史记录)并将pick更改为edit。然后我对每个提交使用git commit -S --amend --no-edit && git rebase --continue(在Windows上)。


这是手动签名对于每个提交。希望我们能找到更好的解决方案。


评论


我的主目录为git repo(用于dotfiles)。一些程序在重新设置基础时以交互方式获取更改,很有趣地看到正在实时回放的历史记录。它足够慢,因为签名很慢

– Avindra Goolcharan
17年1月22日在1:33

#4 楼

如果需要在当前分支上的特定提交之后对所有提交进行GPG签名,则可以改用以下代码:
git filter-branch --commit-filter 'git commit-tree -S "$@";' <COMMIT>..HEAD
其中<COMMIT>是提交ID(例如abc123e5)。这样做的好处是不会干扰提交元数据(包括提交日期)。但是,提交哈希值将发生变化(因为它是每个提交内容的摘要,并且正在向每个提交添加签名)。
如果您还想停止在每次提交时都提示您输入GPG密码, ,也请参见以下答案:
https://askubuntu.com/a/805550
注意:从gpg切换到gpg2进行GIT签名将要求您在GPG 2中重新导入私钥。 br />

评论


也可以添加--env-filter'export GIT_COMMITTER_DATE =“ $ GIT_AUTHOR_DATE”'以确保提交日期未重置为今天的日期。

– Arjan
20 Dec 27 '20:42

#5 楼

我也偶然发现了相同的问题,这是我的解决方案:

git rebase -i --root --exec 'git commit --amend --no-edit --no-verify -S'


这将签署我从第一个初始提交中提交的所有提交,并绕过我设置的提交钩子使用沙哑。无需将pick更改为edit

#6 楼

如果您只想过滤特定的提交并仅对它们进行签名,则可以使用filter-branch

git filter-branch --commit-filter 'if [ "$GIT_COMMITTER_EMAIL" = "user@domain.com" ];
  then git commit-tree -S "$@";
  else git commit-tree "$@";
  fi' HEAD


如果出于某种原因仅希望对自己的签名进行签名,这将很有用提交。

#7 楼

如果不需要对提交进行过滤,则首选使用rebase而不是filter-branch:

git rebase -i master --exec 'git commit --amend --no-edit --no-verify -S --reset-author'


否则,您可以不修改自己不拥有的提交。
~/.gitconfig中设置以下别名(将your@address.com替换为您的电子邮件地址):

resign = "!_() { : git checkout ; [ \"$#\" -eq 0 ] && echo 'Usage: resign <rev-list>' && exit 2; \
                   git filter-branch --commit-filter ' \
                   if [ \"$GIT_COMMITTER_EMAIL\" = \"your@address.com\" ]; then git commit-tree -S \"$@\"; else git commit-tree \"$@\"; fi' ; }; _"


然后,例如,在当前分支中放弃所有提交从大师那里拉出来,去做:

git resign master..



BarryMode和
Roberto Leinardi给以前的答案的积分

#8 楼

这是我用于所有提交的代码,是的,它将重写历史记录:

git rebase --exec 'git commit --amend --no-edit -n -S' -i --root


评论


请注意,这会将提交日期重置为今天的日期。

– Arjan
20 Dec 27 '20:43

#9 楼

要注销最后N次提交,您还可以执行以下操作:
git rebase HEAD~N --signoff

评论


注意--signoff与签名不同(例如,使用git commit -S时)。 AFAIK签名仅在提交消息中添加诸如<作者> <电子邮件>的签名行。

– stian
20-09-18在7:33