29

我在同一个分支上有两个提交,一个接一个。我在第一次提交中添加了对文件 A 的更改,然后对其他文件进行了一些更改,然后进行了另一次提交。现在我希望对文件 A 的更改在第二次提交而不是第一次提交。最优雅的方式是什么?

4

5 回答 5

18

我写了一个脚本来实现这个目的。你可以在这里结帐。

使用脚本将很简单:

mv-changes HEAD~ HEAD fileA
于 2016-01-31T20:28:19.043 回答
14

我知道这是一个老问题,但我有完全相同的要求,我只是想出了解决此问题的最佳方法:您需要使用交互式 rebase 并为要从中移动更改的两个提交选择“编辑”和到。

例如,假设您有 3 个提交:

$ git log -3 --oneline
97e9d62 Commit C, editing file2.txt
34b066b Commit B, creating file2.txt + editing file1.txt
73ff1bb Commit A, creating file1.txt

现在,如果您希望提交 B 仅包含 file2.txt 创建而不包含应该在提交 C 中的 file1.txt 版本,git rebase -i将显示以下内容:

pick 73ff1bb Commit A, creating file1.txt
pick 34b066b Commit B, creating file2.txt + editing file1.txt
pick 97e9d62 Commit C, editing file2.txt

# ...

如果我将 Commit B 和 Commit C 的“pick”替换为“edit”或“e”并关闭我的编辑器,git 将在第二次提交时停止并让我修改我的更改:

pick 73ff1bb Commit A, creating file1.txt
edit 34b066b Commit B, creating file2.txt + editing file1.txt
edit 97e9d62 Commit C, editing file2.txt
Stopped at 34b066b... Commit B, creating file2.txt + editing file1.txt
You can amend the commit now, with

    git commit --amend

Once you are satisfied with your changes, run

    git rebase --continue

$ vi file1.txt    # edit of file1.txt to remove the updated line
$ git commit --amend file1.txt
$ git rebase --continue

# -- git continues rebasing and stops on the Commit C to edit it

$ vi file1.txt   # edit of file1.txt to put the removed line
$ git commit --amend file1.txt
$ git rebase --continue

就是这样。

注意将您从第一次提交中删除的行保存在第二个提交中。它可以在剪贴板、文本文件等中。我想它也应该可以依赖,git stash但如果它是一个简单的更改,那么将它保存在剪贴板中会更容易。

于 2019-03-04T14:30:21.803 回答
5

如果它们是小提交,并且提交在 git 中应该总是很小,那么最简单的方法是 git reset HEAD^^然后再做一次。请注意,对此的任何解决方案都涉及重写历史记录,如果您已经将这些提交推送到某个地方,除非您知道自己在做什么,否则您不应该这样做。

于 2013-03-05T00:51:50.560 回答
1

这个问题的另一种解决方案

  • 在两次提交之前找到提交(可能这是主分支)
  • 运行git rebase -i <commit before commits to be reordered>git rebase -i master大多数情况下)
  • 在文本编辑器中,交换提交的顺序(对于 vim,ddp在应该向下移动的行上使用顺序)
  • 保存,退出,然后让 git rebase 完成剩下的工作
于 2018-02-18T01:52:38.040 回答
0

在您刚刚创建了这些提交的可能不太可能发生的事件中,使用 撤消第二次提交,git reset HEAD^然后使用 将更改添加到第一次提交git commit --amend

如果您已经继续前进并且提交是在过去的某个时间点,那么变基是您最好的选择。在不知道您的确切情况的情况下,引用可以很好地解释它的参考资料可能是最好的。

在第一个和第二个事件中,Pro Git 书籍关于重写历史的部分很好地解释了这些选项 - 何时应该使用它们以及何时应该谨慎使用。

6.4 Git 工具——重写历史

于 2013-03-05T02:28:08.360 回答