如何在不将自己添加为提交者的情况下重新提交另一位作者的提交?

Joh*_*ohn 24 git rebase

通常,当您使用git重新定义另一位作者的提交时,git会添加一个Commit:包含您的姓名和电子邮件地址的标头.我有一种情况,我不希望这种情况发生.我希望重新提交的提交最终使用与原始作者自己完成相同的rebase时相同的SHA1.这可能吗?

bdo*_*lan 24

所有git提交都在内部有一个committer字段; 你可以通过git cat-file commit HEAD在提交之后立即输入来看到这一点.因此你无法抹去它; 你只能使它等于作者字段.

也就是说,您可能会看到git瓷器显示提交字段,因为日期已更改.如果它们正在进行重新定位,显然不可能预测其他人为提交日期戳获得的内容,但至少可以将其更改为等于原始提交时间戳.

git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; git commit-tree "$@"' -- basecommit..HEAD
Run Code Online (Sandbox Code Playgroud)

这将改变basecommit后提交,在头的历史记录(包括头,不包括basecommit),使他们的提交场等同于各方面的作者字段.如果原作者同意做同样的事情,那么你可以获得一致的SHA1.


Paŭ*_*ann 6

尝试设置环境变量GIT_COMMITTER_NAME和变基GIT_COMMITTER_EMAIL(也可以GIT_COMMITTER_DATE).(但这会影响现在创建的所有提交.)

  • 你是对的——一旦我将所有 GIT_COMMITTER_NAME、GIT_COMMITTER_EMAIL 和 GIT_COMMITTER_DATE 设置为适当的值,生成的 SHA1 就会像原始作者在该日期执行相同的 rebase 一样。 (3认同)
  • 确保只为该命令设置这些变量,以避免影响其他提交:`GIT_COMMITER_NAME = ... ... git rebase ...`.否则,请确保在完成后"取消"它们! (2认同)

ADT*_*DTC 5

通过使用Interactive Rebase with进行变基时,您可以保留原始提交者信息instructionFormat

在您的配置文件中.gitconfig,设置:

[rebase]
    instructionFormat = %s%nexec GIT_COMMITTER_DATE=\"%cI\" GIT_COMMITTER_NAME=\"%cN\" GIT_COMMITTER_EMAIL=\"%cE\" git commit --amend --no-edit%n
[alias]
    rb = rebase --interactive
Run Code Online (Sandbox Code Playgroud)

解释:

  • rebase.instructionFormat-交互式变基配置,用于在待办事项文件中提供自定义指令。
  • %s- 提交消息的主题(默认值instructionFormat)。
  • %n- 换行符;可以将 ( ) 加倍%n%n以添加空行以提高可读性。
  • exec- 指示git rebase将该行的其余部分作为 shell 命令执行。
    • 它可以缩短为x(如果您使用的是有用的abbreviateCommands = true)。
  • GIT_COMMITTER_DATE=\"%cI\"- 以严格的 ISO 8601 格式获取提交日期。
  • GIT_COMMITTER_NAME=\"%cN\"- 获取提交者的姓名。
  • GIT_COMMITTER_EMAIL=\"%cE\"- 获取提交者的电子邮件地址。
    • .mailmap如果发现以上两个方面的文件。要忽略该文件,请使用%cnand%ce代替。
  • git commit --amend --no-edit- 使用上述三个环境变量修改提交,而不打开提交消息的编辑器。
  • %n- 换行符(在待办事项文件中添加一个空行以提高可读性;可以重复更多空行)。
  • alias.rb- 为了方便起见,定义了一个别名来快速调用交互式变基git rb [new base]

要使用它,请确保您已在要变基的分支上签出,然后运行命令 git rb [new base]where [new base]is thebranch 或 commit-ish 在其上要对签出的分支进行变基。(例子:git rb main

将打开一个编辑器,其中包含交互式变基待办事项。只需关闭编辑器即可。如果您知道自己在做什么并想要对其进行编辑,请注意以下事项:

  • 您可以在文件中看到上述配置的输出,即exec每个提交下方的一行。
  • 如果您移动提交(更改提交的顺序),请务必exec也移动相应的行。
  • 如果您压缩、修复或删除提交,请务必删除相应的exec行。

注意 1:这只能通过交互式 Rebase 实现,因为常规 rebase 不支持instructionFormat. 您必须忍受编辑器无缘无故地打开,然后将其关闭(如果您不打算编辑它)。

注意 2:即使保留所有提交者信息,您仍然可能无法获得相同的 SHA1,因为 SHA1 依赖于父提交。当父级发生变化时,SHA1 也会发生变化。但是,如果父级没有更改,您将始终获得相同的 SHA1。所以这是一个确定性操作。

注3:对于Windows,您需要使用Git Bash或WSL2。这在命令提示符和 PowerShell 中不起作用,因为 DOS 不支持内联环境变量。(我不确定多行命令是否exec可以SET工作。YMMV,但仅使用 Git Bash 或 WSL2 比尝试使其在 DOS 中工作要容易得多。)