Git 签署以前的提交?
Posted
技术标签:
【中文标题】Git 签署以前的提交?【英文标题】:Git sign off previous commits? 【发布时间】:2012-10-14 03:32:09 【问题描述】:我想知道如何签署(-s
)我过去在 git 中所做的先前提交?
【问题讨论】:
检查schacon.github.com/git/git-commit.html ***.com/questions/1962094/…的可能重复 我想知道这样做是不是很不安全。通过签署您或多或少地说“我声称以前的提交是安全的”。但是,如果您已经克隆了它们等,并且您没有对它们进行真正的检查,那么您就说明了一些您无法检查的内容。想象一个黑客以某种方式操纵提交。然而,签名确实可以防止人们在后期篡改提交。但也许您应该将其添加到消息中? 【参考方案1】:要签署之前的提交,请使用修改选项:
git commit --amend --signoff
编辑:修改只签核最新的提交。要签署多个提交,filter-branch
和 interpret-trailers
如 vonc 等所建议的那样。人。应该使用。这对我有用。
首先,配置 git 将令牌 sign
替换为 Signed-off-by
。这只需执行一次,并且在下一步中需要。
git config trailer.sign.key "Signed-off-by"
带有开关--msg-filter
的命令git filter-branch
将为每次提交评估一次过滤器。过滤器可以是任何在标准输入上接收提交消息并在标准输出上输出的 shell 命令。可以自己写过滤器,也可以用git interpret-trailers
,太无能了。这是一个示例,它将使用当前用户和电子邮件签署当前分支的最新两次提交:
export SIGNOFF="sign: $(git config --get user.name) <$(git config --get user.email)>"
git filter-branch -f --msg-filter \
"git interpret-trailers --trailer \"$SIGNOFF\"" \
HEAD~2..HEAD
注意 1) 修改提交消息会更改提交 ID,这意味着必须使用 --force
或更好的 --force-with-lease 强制推送已发布的分支。
注意 2) 如果您打算编写自定义脚本,请注意 git filter-branch
会将当前目录更改为 <repo>/.git-rewrite/t
。使用脚本的相对路径通常不起作用。相反,脚本应该在您的$PATH
中或作为绝对路径提供。
【讨论】:
可能需要git push -f
。
我尝试通过更改为 'HEAD~6..HEAD' 来更改最后 6 次提交,但它更改了更多提交。基本上是一团糟
我非常爱你和你的回答。谢谢你给了我我需要的确切命令。【参考方案2】:
尝试使用 -S
重做旧提交:
git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD
之后,你必须git push -f
。但要小心,提交 id 会改变,其他人会变得不同步。
【讨论】:
这将签署所有提交,对吗?如何仅签署最后 X 次提交? @ÁkosVandra 如果您仍在寻找答案:git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD~X..HEAD
,其中 X 是最后 X 次提交的数量。例如最后 2 次提交:git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD~2..HEAD
只为我的提交而不是全部这样做呢?
我认为有一点混乱,大写-S
用于GPG-sign 提交,我认为OP 意味着更低的-s
只需在提交末尾添加Sign-off-by
行消息。【参考方案3】:
如果有人仍在寻找一种更自动化的方式来签署提交。
试试这个:
git rebase --exec 'git commit --amend --no-edit -n -S' -i commit-hash
这将重新设置所有内容,直到提交哈希(X 次提交)
然后需要git push -f
将历史记录的更改推回远程
【讨论】:
对于更精细的方法,首先运行交互式git rebase -i HEAD~x
。然后,在编辑器中,在每个选择的提交之后“注入”x git commit -S -s --amend --no-edit
,你想搞砸。这个答案中提出的解决方案可能是解决这个问题的最干净(也是最git
)的方法。 +1
我喜欢的最好和更好的答案比选择的答案。 :)
这就像奶油一样光滑。谢谢克山!需要注意的一点是,这个变基直到 commit-hash
不包括 commit-hash
本身。
尝试另外指定--root
。【参考方案4】:
现在(从Git 2.13 开始)你通常可以做类似的事情
git rebase --signoff HEAD~2
将Signed-off-by
页脚添加到最后 2 次提交(在本例中)。
如果您的范围包括根提交,请将--root
选项添加到rebase
。
【讨论】:
我刚刚对其进行了测试,这与其他建议的答案具有相同的效果。要签署每个提交,请将 HEAD~2 替换为第一个提交的哈希。 这应该以某种方式到达顶部【参考方案5】:对我来说,只是修改 signof,实际上并没有验证我在 github 上的提交。
对我有用的解决方案是返回,然后用 -S
签署每个提交
git commit --amend -S
此外,如果您检查您的提交是否实际签名,并且您的电子邮件/姓名根本没有附加,请使用此命令
git show HEAD --show-signature
额外提示:如果您已经在修改您的提交,您可能希望在其中使用您的真实姓名(请参阅使用 git log
)。您可能正在使用您的 github 句柄名称,这不是必需的。只需要正确的电子邮件,在用户名字段中您应该使用您的全名,github 将使用您的 github 句柄名称正确跟踪它。因此,要更正您的用户名并签署最后一次提交,请使用:
git commit --amend --author="FULL NAME <email>" -S
并在将来为用户名设置全名
git config --global user.name "FULL NAME"
【讨论】:
【参考方案6】:考虑签核修改提交消息,使用git filter-branch
来实现。
git filter-branch --msg-filter \
"cat - && echo && echo 'Signed-off-by: Dan McGee <email@example.com>'" \
HEAD
(来自“git filter-branch
magic”的示例)
或者,跟随Curt J. Sampson的suggestion,使用git interpret-trailers
:
git config trailer.sign.key "Signed-off-by"
git filter-branch --msg-filter \
"cat - && echo && git interpret-trailers --trailer 'sign: 'Signed-off-by: Dan McGee <email@example.com>'" \
HEAD
警告:这将更改您现有提交的 SHA1,并且您可能必须强制推送结果,如果您的提交已被其他人共享,这可能会出现问题。
vorburger 添加in the comment 示例:
使用 git 版本 2.20.1,我不得不在
--trailer 'sign:
中省略“Signed-off-by
”,然后这样做:
git filter-branch --msg-filter \
"cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <vorburger@redhat.com>'" \
HEAD
【讨论】:
考虑将git interpret-trailers
与git filter-branch --msg-filter
一起使用,而不是手动添加Signed-off-by:
或其他预告片。例如,这将使您避免复制预告片。
@CurtJ.Sampson 是的!谢谢你。我昨天确实记录了这一点:***.com/a/41361273/6309.
@CurtJ.Sampson 我已经相应地修改了答案。
使用 git 版本 2.20.1,我不得不在 --trailer 'sign: 中省略 "'Signed-off-by" 并这样做:git filter-branch --msg-filter \ "cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <vorburger@redhat.com>'" \ HEAD
我必须删除命令前缀cat - && echo &&
,否则会失败并出现command not found
错误。【参考方案7】:
带有-S
标志的交互式变基将完成这项工作。
假设您需要签署最后的 n 次提交 (确保签出最新的 n 次提交)。
运行:
$ git rebase -S -i HEAD~n
# The `-S` flag is important.
# It tells Git to sign the following commits.
这给出了最后一次n
提交的列表。
现在,将您要签名的所有提交的 pick
更改为 edit
前缀。
完成后,关闭编辑器。将打开一个新编辑器,其中包含有关提交的所有内容。
由于提交中不需要更改任何内容,请保存文件并退出编辑器。您还可以在提交消息时更改它。
对其他提交重复此操作。
要推送最新历史,git push remote branch -f
。
警告
有一个问题 - 它可以重写你的提交。
如果您签署一个 4 个月前的提交,它可能会覆盖其日期并使其看起来像是今天创建的。因此,当您想保留提交历史记录时,不建议这样做。
【讨论】:
【参考方案8】:我遇到了类似的问题。在这里,感谢来自 Gentoo Linux 的 Robin Johnson,这是一个将签名添加到我之前所有未推送提交的技巧:
$ git pull && git rebase --gpg-sign --force-rebase origin/master && git push --signed
Already up-to-date.
Current branch master is up to date, rebase forced.
First, rewinding head to replay your work on top of it...
Applying: sci-biology/KING: new package
Applying: dev-lang/yaggo: version bump, fix install procedure
Applying: sci-libs/htslib: version bump
Applying: sci-biology/bcftools: version bump
Applying: sci-biology/samtools: version bump
Applying: sci-biology/libBigWig: new release with io.h renamed to bigWigIO.h
Applying: sci-biology/MaSuRCA: add more URLs to HOMEPAGE
Applying: sci-biology/SPAdes: update comments on bundled dev-libs/boost
Applying: sci-biology/khmer: added a comment how to proceed with src_compile()
Applying: sci-biology/picard: version bump
Applying: sci-biology/ruffus: pint EGIT_REPO_URI to the archive URL of code.google.com
Applying: sci-biology/vcftools: the 0.1.15_pre release was just renamed to 0.1.15 by upstream
Applying: sci-biology/nanopolish: new package
Applying: sci-biology/libBigWig: version bump
Counting objects: 75, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (75/75), done.
Writing objects: 100% (75/75), 14.51 KiB | 0 bytes/s, done.
Total 75 (delta 55), reused 0 (delta 0)
remote: To github.com:gentoo/sci.git
remote: 29c5e3f5d..b37457700 master -> master
To git+ssh://git.gentoo.org/proj/sci.git
29c5e3f5d..b37457700 master -> master
$
【讨论】:
【参考方案9】:签核最后 X 次提交的快速解决方案。
git rebase --signoff @~X
例如,签核最近 10 次提交
git rebase --signoff @~10
我发现这对我的案例来说是一个简单的解决方案。来源:https://pmhahn.github.io/git-signoff/
【讨论】:
【参考方案10】:不重写历史的解决方法:
-
创建一个新分支
从带有标志
--no-commit --no-ff
的旧的合并
git reset
删除所有提交(signed 或 unsigned)
git commit -S -am "commit message"
只需一次签名提交即可推送新分支
git status
...
On branch feature/branch_unsigned_commits
...
git checkout -b feature/branch_unsigned_commits_take2
git merge --no-commit --no-ff feature/branch_unsigned_commits
git reset
git commit -S -am "commit message"
git push
【讨论】:
这仍然重写历史,它只是在一个新的分支上这样做。以上是关于Git 签署以前的提交?的主要内容,如果未能解决你的问题,请参考以下文章
gpg 未能签署数据致命:未能写入提交对象 [Git 2.10.0]