如何在不将自己添加为提交者的情况下对其他作者所做的提交进行变基?

发布于 2024-10-28 09:54:43 字数 148 浏览 4 评论 0原文

通常,当您使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

王权女流氓 2024-11-04 09:54:43

所有 git 提交内部都有一个 committer 字段;您可以通过在提交某些内容后立即输入 git cat-file commit HEAD 来看到这一点。因此您无法删除它;您只能将其设置为等于作者字段。

也就是说,您可能会看到 git Ceramic 显示提交字段,因为日期戳已更改。显然,如果其他人正在变基,则不可能预测他们会得到什么提交日期时间戳,但您至少可以将其更改为等于原始提交时间戳。

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

这将改变 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.

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

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.

|煩躁 2024-11-04 09:54:43

尝试在变基时设置环境变量 GIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL(也可能是 GIT_COMMITTER_DATE)。 (不过,这将影响现在创建的所有提交。)

Try setting the environment variable GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL when rebasing (maybe also GIT_COMMITTER_DATE, too). (This will effect all commits created now, though.)

帅气尐潴 2024-11-04 09:54:43

通过将交互式变基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

说明:

  • 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
  • git commit --amend --no-edit - 使用上述三个环境变量修改提交,而不打开提交消息的编辑器。
  • %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:

[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

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 of instructionFormat).
  • %n - a line break; can double-up (%n%n) to add a blank line for readability.
  • exec - instructs git rebase to execute the rest of the line as a shell command.
    • It can be shortened to x (useful if you're using abbreviateCommands = 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.
    • Above two respect .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 with git 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:

  • You can see the output of the above config in the file as an exec line below each commit.
  • If you move a commit (changing the order of commits), be sure to move the corresponding exec line as well.
  • If you squash, fixup or drop commits, be sure to delete the corresponding 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 with SET 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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文