Git退出先前的提交?


78

我想知道如何-s在git中注销以前的提交?




1
我不知道这样做是否具有讽刺意味。通过或多或少签名,可以说“我声称以前的提交是安全的”。但是,如果您已经克隆了它们,等等,并且您没有对它们进行真正的检查,那么您就声明了您无法检查的内容。想象一下黑客以某种方式操纵提交。但是,签名确实可以防止在以后的阶段篡改提交。但是也许您应该将此添加到邮件中?
Willem Van Onsem 2015年

Answers:


109

要签署上一个提交,请使用amend选项:

git commit --amend --signoff

编辑:修改仅签发最新提交。要签收多次提交,filter-branchinterpret-trailers通过建议vonc等。等 应该使用。这对我有用。

首先,配置混帐更换令牌signSigned-off-by。此操作仅需执行一次,下一步便需要。

git config trailer.sign.key "Signed-off-by"

git filter-branch带有该开关的命令--msg-filter将为每次提交评估一次过滤器。筛选器可以是任何在stdin上接收提交消息并在stdout上输出的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-with-lease--force或更好地强制推入已发布的分支。

注意2)如果您打算编写自定义脚本,请注意git filter-branch将当前目录更改为<repo>/.git-rewrite/t。使用脚本的相对路径通常不起作用。相反,该脚本应位于您的脚本中,$PATH或作为绝对路径提供。


可能需要一个git push -f
Max

我试图通过更改为'HEAD〜6..HEAD'来更改最后6次提交,它又更改了很多提交。基本上是一团糟
Alex Punnen

31

尝试使用以下命令重做旧的提交-S

git filter-branch -f --commit-filter 'git commit-tree -S "$@"' HEAD

之后,您必须git push -f。但是请注意,提交ID将会更改,其他人将变得不同步。


1
这将签署所有提交,对吗?如何仅签署最近的X次提交?
阿斯科斯·范德拉(Akos Vandra),2017年

14
@Á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
Jashandeep Sohi

1
仅针对我的承诺而不是全部这样做怎么办?
kerner1000

3
我认为这有点混乱,大写-S是用于GPG-sign提交,我认为OP的意思是降低-s,只需Sign-off-by在提交消息的末尾添加行即可。
fgiraldeau

14

如果有人仍在寻找一种更好的自动签署方法。

尝试这个:

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

这将使所有内容恢复基础,直到提交哈希(X次提交)为止

然后git push -f需要将历史更改推回远程


1
要获得更精细的方法,请首先运行Interactive git rebase -i HEAD~x。然后,在编辑器中,x git commit -S -s --amend --no-edit在您想要弄乱的每个选定提交之后“注入” 。此答案中建议的解决方案可能是解决此问题的最简洁(也是最git)的方法。+1
Vexy '20

1
我爱比选择的最好和更好的答案。:)
tai271828

12

考虑签收修改提交消息,用于git filter-branch实现这一点。

git filter-branch --msg-filter \
    "cat - && echo && echo 'Signed-off-by: Dan McGee <email@example.com>'" \
    HEAD

(示例来自“git filter-branch魔术”)

或者,按照Curt J. Sampson建议,使用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在评论中添加一个示例:

使用git版本2.20.1,我必须在中省略“ Signed-off-by--trailer 'sign:,并按以下方式进行:

git filter-branch --msg-filter \
  "cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <vorburger@redhat.com>'" \
  HEAD

考虑使用git interpret-trailerswithgit filter-branch --msg-filter而不是Signed-off-by:手动添加或其他预告片。例如,这将使您避免重复预告片。
cjs

@ CurtJ.Sampson是的!谢谢。昨天我确实在记录在案:stackoverflow.com/a/41361273/6309
VonC

@ CurtJ.Sampson我已经相应地修改了答案。
VonC

使用git版本2.20.1,我必须在--trailer'sign中省略“'Signed-by-by':”,并像这样进行: git filter-branch --msg-filter \ "cat - && echo && git interpret-trailers --trailer 'sign: Michael Vorburger <vorburger@redhat.com>'" \ HEAD
vorburger

1
我必须删除命令前缀cat - && echo &&,否则它将失败并显示command not found错误。
fgiraldeau

10

对我来说,只是增加符号,实际上并没有在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

我有一个类似的问题。在这里,感谢来自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
$

5

带有-S标志的交互式变基将完成此工作。

假设您需要注销最近的n次提交(确保签出最近的n次提交)。

跑:

$ git rebase -S -i HEAD~n

# The `-S` flag is important.
# It tells Git to sign the following commits.

这给出了最后n提交的列表。

现在,改变pickedit 前缀为所有你要签名的承诺。

完成后,关闭编辑器。将打开一个新的编辑器,其中包含有关提交的所有信息。

由于在提交中不需要进行任何更改,因此请保存文件并退出编辑器。您还可以在其上更改提交消息。

对其他提交重复此操作。

要推送最新历史记录,git push remote branch -f

警告

有一个陷阱-它可以重写您的提交。

如果您签署了一个为期4个月的提交,它可能会覆盖其日期并使它看起来像今天创建的。因此,当您要保留提交历史记录时,不建议使用。


3

这些天(从Git 2.13开始),您通常可以做类似的事情

git rebase --signoff HEAD~2

Signed-off-by在最后2次提交中添加页脚(在此示例中)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.