协慌网

登录 贡献 社区

将先前的提交分解为多个提交

如果没有创建分支并在新分支上做一堆时髦的工作,是否有可能在提交到本地存储库后将单个提交分解为几个不同的提交?

答案

git rebase -i会做到的。

首先,从一个干净的工作目录开始: git status应显示没有待处理的修改,删除或添加。

要拆分最近的提交,首先:

$ git reset HEAD~

现在以通常的方式单独提交各个部分,根据需要生成尽可能多的提交。

如果它再远在树上,那么

$ git rebase -i HEAD~3

其中3是多少提交回来。

如果它在树中比你想要的更远,那么

$ git rebase -i 123abcd~

其中123abcd是您要拆分的提交的 SHA1。

当您获得 rebase 编辑屏幕时,找到您要拆分的提交。在该行的开头,将pick替换为edit (简称e )。保存缓冲区并退出。现在,Rebase 将在您要编辑的提交后立即停止。然后:

$ git reset HEAD~

以通常的方式单独提交各个部分,然后根据需要生成尽可能多的提交

$ git rebase --continue

git-rebase手册(SPLITTING COMMITS 部分)

在交互模式下,您可以使用 “编辑” 操作标记提交。但是,这并不一定意味着 git rebase 期望此编辑的结果恰好是一次提交。实际上,您可以撤消提交,也可以添加其他提交。这可以用于将提交拆分为两个:

  • 使用git rebase -i <commit>^启动交互式 rebase,其中<commit>是要分割的提交。实际上,只要包含该提交,任何提交范围都可以。

  • 使用 “编辑” 操作标记要拆分的提交。

  • 在编辑提交时,执行git reset HEAD^ 。结果是 HEAD 被一个重绕,索引也随之而来。但是,工作树保持不变。

  • 现在将更改添加到您希望在第一次提交中拥有的索引。您可以使用git add (可能是交互式)或git gui (或两者)来做到这一点。

  • 使用现在适当的提交消息提交 now-current 索引。

  • 重复最后两步,直到工作树干净。

  • git rebase --continue继续 rebase - 继续。

使用git rebase --interactive编辑之前的提交,运行git reset HEAD~ ,然后git add -p添加一些,然后进行提交,然后再添加一些并进行另一次提交,就像你喜欢的那样多次。当你完成后,运行git rebase --continue ,你将在堆栈的早期拥有所有拆分提交。

重要提示 :请注意,您可以随意播放并进行所需的所有更改,而不必担心丢失旧更改,因为您始终可以运行git reflog来查找项目中包含所需更改的点(让我们调用)它a8c4ab ),然后git reset a8c4ab

这是一系列命令,展示它是如何工作的:

mkdir git-test; cd git-test; git init

现在添加一个文件A

vi A

添加此行:

one

git commit -am one

然后将此行添加到 A:

two

git commit -am two

然后将此行添加到 A:

three

git commit -am three

现在文件 A 看起来像这样:

one
two
three

我们的git log看起来如下(好吧,我使用git log --pretty=oneline --pretty="%h %cn %cr ---- %s"

bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one

假设我们要分割第二个提交, two

git rebase --interactive HEAD~2

这会显示一条如下所示的消息:

pick 2b613bc two
pick bfb8e46 three

将第一个pick更改为e以编辑该提交。

git reset HEAD~

git diff告诉我们,我们刚刚取消了我们为第二次提交所做的提交:

diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two

让我们进行更改,然后在文件A那一行添加 “和第三个”。

git add .

这通常是交互式 rebase 期间我们运行git rebase --continue ,因为我们通常只想返回我们的提交堆栈来编辑早期的提交。但这一次,我们想要创建一个新的提交。所以我们将运行git commit -am 'two and a third' 。现在我们编辑文件A并添加第二行two and two thirds第三行。

git add . git commit -am 'two and two thirds' git rebase --continue

我们的提交有three冲突,所以让我们解决它:

我们会改变

one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three

one
two and a third
two and two thirds
three

git add .; git rebase --continue

现在我们的git log -p看起来像这样:

commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 13:57:00 2013 -0700

    three

diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
 one
 two and a third
 two and two thirds
+three

commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 14:07:07 2013 -0700

    two and two thirds

diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
 one
 two and a third
+two and two thirds

commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 14:06:40 2013 -0700

    two and a third

diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
 one
+two and a third

commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <[email protected]>
Date:   Sun Jul 7 13:56:40 2013 -0700

    one

diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one