如何在不将自己添加为提交者的情况下对其他作者所做的提交进行变基?
通常,当您使用 git 对其他作者的提交进行变基时,git 会添加一个包含您的姓名和电子邮件地址的 Commit:
标头。我遇到的情况是我不希望这种情况发生。我希望 rebase 提交最终得到与原作者自己进行等效 rebase 相同的 SHA1。这可能吗?
Normally, when you rebase another author's commit with git, git adds a Commit:
header with your name and email address. I have a situation where I don't want this to happen. I want the rebased commit to end up with the same SHA1 as it would have if the original author had done the equivalent rebase him/herself. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
所有 git 提交内部都有一个 committer 字段;您可以通过在提交某些内容后立即输入 git cat-file commit HEAD 来看到这一点。因此您无法删除它;您只能将其设置为等于作者字段。
也就是说,您可能会看到 git Ceramic 显示提交字段,因为日期戳已更改。显然,如果其他人正在变基,则不可能预测他们会得到什么提交日期时间戳,但您至少可以将其更改为等于原始提交时间戳。
这将改变 HEAD 历史中的 basecommit 之后的提交(包括 HEAD,不包括 basecommit),使其提交者字段在所有方面与作者字段相同。如果原作者同意做同样的事情,那么你可以获得一致的SHA1。
All git commits have a committer field internally; you can see this by typing
git cat-file commit HEAD
immediately after committing something. As such you cannot erase it; you can only make it equal to the author field.That said, you might be seeing git porcelain showing the commit field because the datestamp has changed. It's not possible to predict what someone else would get for the commit datestamp if they were rebasing, obviously, but you can alter it to be equal to the original commit timestamp, at least.
This will alter commits after basecommit, in the history of HEAD (including HEAD, not including basecommit), making their committer field identical to the author field in all respects. If the original author agrees to do the same thing, then you can get a consistent SHA1.
尝试在变基时设置环境变量
GIT_COMMITTER_NAME
和GIT_COMMITTER_EMAIL
(也可能是GIT_COMMITTER_DATE
)。 (不过,这将影响现在创建的所有提交。)Try setting the environment variable
GIT_COMMITTER_NAME
andGIT_COMMITTER_EMAIL
when rebasing (maybe alsoGIT_COMMITTER_DATE
, too). (This will effect all commits created now, though.)通过将交互式变基与
instructionFormat
结合使用,您可以在变基时保留原始提交者信息。在配置文件
.gitconfig
中,设置:说明:
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
文件(如果有)。要忽略该文件,请改用%cn
和%ce
。%n
- 换行符(在待办事项文件中添加一个空行以提高可读性;可以重复更多空行)。alias.rb
- 为了方便起见,定义了一个别名来使用git rb [new base]
快速调用交互式 rebase要使用它,请确保您已在您想要变基的分支,然后运行命令
git rb [new base]
,其中[new base]
是分支或commit-ish您想要在其顶部重新设置签出分支的基础。 (示例:git rb main
)编辑器将打开,其中包含交互式变基待办事项。 只需关闭编辑器即可。如果您知道自己在做什么并想要编辑它,请注意以下事项:
exec 每次提交下面的行。
exec
行。exec
行。注1:这只能通过交互式变基实现,因为常规变基不支持
instructionFormat
。您必须忍受编辑器无缘无故地打开,然后将其关闭(如果您不打算编辑它)。注2:即使您保留了所有提交者信息,您仍然可能无法获得相同的 SHA1,因为 SHA1 依赖于父提交。当父级发生变化时,SHA1 也会发生变化。但是,如果父级没有更改,您将始终获得相同的 SHA1。所以这是一个确定性操作。
注3:对于Windows,您需要使用Git Bash或WSL2。这在命令提示符和 PowerShell 中不起作用,因为 DOS 不支持内联环境变量。 (我不确定带有
SET
命令的多个exec
行是否可以工作。YMMV,但是仅使用 Git Bash 或 WSL2 比尝试创建要容易得多它在 DOS 下工作。)You can preserve the original committer information when rebasing by using Interactive Rebase with
instructionFormat
.In your config file
.gitconfig
, set this:Explanation:
rebase.instructionFormat
- a configuration for interactive rebase to give a custom instruction in the to-do file.%s
- the subject of the commit message (the default value ofinstructionFormat
).%n
- a line break; can double-up (%n%n
) to add a blank line for readability.exec
- instructsgit rebase
to execute the rest of the line as a shell command.x
(useful if you're usingabbreviateCommands = true
).GIT_COMMITTER_DATE=\"%cI\"
- get the commit date in strict ISO 8601 format.GIT_COMMITTER_NAME=\"%cN\"
- get the name of the committer.GIT_COMMITTER_EMAIL=\"%cE\"
- get the email address of the committer..mailmap
file if any found. To disregard the file, use%cn
and%ce
instead.git commit --amend --no-edit
- amend the commit with the above three environment variables, without opening an editor for the commit message.%n
- a line break (to add a blank line for readability in the to-do file; can repeat for more blank lines).alias.rb
- for convenience, an alias is defined to quickly call interactive rebase withgit rb [new base]
To use it, be sure you're checked out on the branch you wish to rebase, then run the command
git rb [new base]
where[new base]
is the branch or commit-ish on top of which you want to rebase the checked-out branch. (Example:git rb main
)An editor will open with the interactive rebase to-do. Simply close the editor. If you know what you're doing and want to edit it, note the following:
exec
line below each commit.exec
line as well.exec
lines.Note 1: This is only possible via Interactive Rebase, since the regular rebase doesn't support
instructionFormat
. You have to bear with the editor opening for no good reason, and just close it (if you have no plans to edit it).Note 2: Even if you preserve all of the committer information, you may still not get the same SHA1 because the SHA1 is dependent on the parent commit. When the parent changes, the SHA1 changes too. However, if the parent didn't change, you will always get the same SHA1. So this is a deterministic operation.
Note 3: For Windows, you need to use Git Bash or WSL2. This won't work in Command Prompt and PowerShell since DOS doesn't support inline environment variables. (I'm not sure if multiple
exec
lines withSET
commands can work. YMMV but it's so much easier to just use Git Bash or WSL2 than trying to make it work in DOS.)