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