当通过git rebase --interactive编辑提交时,我该如何保留提交信息?

17

我目前正在进行一个 git rebase --interactive 会话,其中我正在编辑一个提交。 我按照 如何分割嵌入历史记录的Git提交?所建议的方式继续进行,即运行git reset HEAD^并进行修改。 现在我想让rebase继续,这需要我提交我的更改。 我想修改旧的提交信息,但问题是,如果我运行 git commit --amend ,那么我将获得我实际修改的提交之前的提交信息 - 而我肯定不想将我的更改合并到该提交中。

那么我怎样才能检索我正在工作的提交的旧提交消息呢?


git commit --amend 应该显示您正在编辑的提交消息(我刚试过),这里一定有什么问题。 - CharlesB
1
@CharlesB 你是否尝试按照描述中的工作流程进行操作,即在执行了 git rebase --interactivegit reset HEAD^、进行了一些修改并将文件重新添加到索引后再试? - Bernhard Reiter
我非常确定我标记了正确的提交以进行编辑,并使用 git reset HEAD^ 重置索引确实取消了我想要处理的更改...(我实际上并不想拆分该提交,而只是修改它引入的一些更改。) - Bernhard Reiter
好的,我可以回答。 - CharlesB
@BernhardReiter,请更新您的问题,以明确您只想编辑提交,而不是拆分它,并且如果以下任何解决方案修复了您的问题,如果您接受它,将有助于未来其他人。 - user456814
显示剩余2条评论
4个回答

24

虽然CharlesB的解决方案是正确的,而且可能更容易, 但原帖作者看到要编辑的提交信息之前的提交信息是因为他使用了git commit--amend标志,这会修改上一个提交。

不要使用--amend提交您的更改,只需使用没有标志的git commit即可,这不会影响以前的提交。您还可以传递一个选项来重用使用git reset head^重置的提交的提交消息:

git commit --reuse-message=HEAD@{1}

# Or use -C, which is the same thing, but shorter:
git commit -C HEAD@{1}

HEAD@{1} 指向你在执行 git reset head^ 命令之前所在的提交。你也可以直接传入该提交的 sha id。

来自 git commit 文档

-C <commit>
--reuse-message=<commit>

Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.

当然,就像我说的那样,CharlesB的解决方案更简单,因为如果你不执行第一个git reset head^,你可以直接修改提交并修改你要修改的提交,当你执行git commit --amend时,你会自动获得上一个提交的消息,你不必传递提交sha。

2
小写的 head 在这里真的有效吗?我不得不使用全大写的版本。 - milkypostman
1
@milkypostman 这实际上取决于您的操作系统和shell环境,msysgit和OS X似乎可以接受小写的head,但Unix环境可能只接受大写的HEAD - user456814
在过去几年的所有git版本中,HEAD可以被替换为@,例如HEAD@{1}变成了@{1}HEAD~变成了@~。这样可以节省一些打字。 - Alex Palmer
@user456814 我怀疑如果你的文件系统不区分大小写,head 命令会起作用;它可能是指你的存储库中的 .git/HEAD 文件。但正如我之前提到的,如果你的 Git 版本相对较新,你可以使用 @ 代替 headHEAD - Alex Palmer

4

如果您不想拆分提交,请遵循拆分提交的指令 为什么要这样做

您不需要重置到HEAD^,这仅适用于拆分提交。只需在rebase -i中标记提交以进行编辑,进行更改,commit --amendrebase --continue即可。


你不是可以实际上使用 git reset head^,而不是使用 git commit --amend,只需使用 git commit,然后 rebase --continue 吗?同样的结果,是吧? - user456814
我觉得很难理解,在交互式 rebase 的过程中,怎么猜测 HEAD^ 是什么意思?修改提交很简单明了。 - CharlesB
不需要猜测,“git log --graph --oneline” 命令可以清楚地展示出 head^ 是什么,即使在 rebase -i 过程中也是如此。但我同意,直接修改提交记录会更简单。 - user456814

2

我有另一个答案,似乎更加可靠,但是没有文档记录。

$ git reset HEAD^
$ git add ...               # stage the first part of your split
$ git commit -m 'part one'
$ git commit -a -F $(git rev-parse --git-dir)/rebase-merge/message

再次强调,原帖作者不想拆分他的提交记录,因此进行两次提交并不是正确的解决方案。 - user456814

1

我改编了一些git-commit(1)git-reset(1)的例子:

$ git reset HEAD^
$ git add ...                 # stage the first part of your split
$ git commit -m 'part one'
$ git commit -a -c ORIG_HEAD  # start with the earlier commit message

如果你担心做某些事情会改变ORIG_HEAD,你可以尝试以下方式:

$ SAVED=$(git rev-parse HEAD)
$ git reset HEAD^
...
$ git commit -a -c $SAVED   # start with the earlier commit message

你回答中使用 commit 而没有带上 --amend 标志的部分是正确的。然而,正如原帖作者在这条评论中所述,他并不想拆分提交,因此将其拆分为两个独立的提交并不是正确的解决方案。 - user456814
1
此外,在你的回答中,ORIG_HEAD 指向原始提交之前的第一个提交。如果他正在编辑一个是 ORIG_HEAD 的祖先提交,则 ORIG_HEAD 不会包含该祖先提交的原始消息,这种情况下,你的解决方案的这一部分将是不正确的。 - user456814
我已按照问题的原文回答,我认为这是公平的。原帖作者可以自由编辑它。 :-) 谢谢您的纠正 - ORIG_HEAD 假设 git reset HEAD^ 已经发生,这不是我写的。现在已经修复了。 - Andrew
我本来很久以前就想再看一眼这个问题。我不确定我在评论中提到的任何内容是否正确,所以你的答案可能已经足够好了。 - user456814

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接