Way*_*rad 1668
git rebase -i 会做的.
首先,从一个干净的工作目录开始:git status应显示没有待处理的修改,删除或添加.
要拆分最近的提交,首先:
$ git reset HEAD~
Run Code Online (Sandbox Code Playgroud)
现在以通常的方式单独提交各个部分,根据需要生成尽可能多的提交.
如果它再远在树上,那么
$ git rebase -i HEAD~3
Run Code Online (Sandbox Code Playgroud)
这里3是多少提交回它.
如果它在树中比你想要的更远,那么
$ git rebase -i 123abcd~
Run Code Online (Sandbox Code Playgroud)
123abcd您想要拆分的提交的SHA1 在哪里.
当您获得rebase编辑屏幕时,找到您要拆分的提交.在该行的开头,替换pick为edit(e简称).保存缓冲区并退出.现在,Rebase将在您要编辑的提交后立即停止.然后:
$ git rebase -i master
Run Code Online (Sandbox Code Playgroud)
以通常的方式单独提交各个部分,然后根据需要生成尽可能多的提交
$ git reset HEAD~
Run Code Online (Sandbox Code Playgroud)
MBO*_*MBO 296
从git-rebase手册(SPLITTING COMMITS部分)
在交互模式下,您可以使用"编辑"操作标记提交.但是,这并不一定意味着git rebase期望此编辑的结果恰好是一次提交.实际上,您可以撤消提交,也可以添加其他提交.这可以用于将提交拆分为两个:
启动交互式rebase
git rebase -i <commit>^,其中<commit>包含要分割的提交.实际上,只要包含该提交,任何提交范围都可以.使用"编辑"操作标记要拆分的提交.
在编辑提交时,执行
git reset HEAD^.结果是HEAD被一个重绕,索引也随之而来.但是,工作树保持不变.现在将更改添加到您希望在第一次提交中拥有的索引.您可以使用
git add(可能是交互式)或git gui(或两者)来做到这一点.使用现在适当的提交消息提交now-current索引.
重复最后两步,直到工作树干净.
继续使用rebase
git rebase --continue.
Ros*_*one 39
使用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
Run Code Online (Sandbox Code Playgroud)
我们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
Run Code Online (Sandbox Code Playgroud)
假设我们要分割第二次提交,two.
git rebase --interactive HEAD~2
这会显示一条如下所示的消息:
pick 2b613bc two
pick bfb8e46 three
Run Code Online (Sandbox Code Playgroud)
将第pick一个更改为a 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
Run Code Online (Sandbox Code Playgroud)
让我们进行更改,然后在文件中添加"和第三个" 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
Run Code Online (Sandbox Code Playgroud)
至
one
two and a third
two and two thirds
three
Run Code Online (Sandbox Code Playgroud)
git add .; git rebase --continue
现在我们git log -p看起来像这样:
commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <roseperrone@fake.com>
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 <roseperrone@fake.com>
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 <roseperrone@fake.com>
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 <roseperrone@fake.com>
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
Run Code Online (Sandbox Code Playgroud)
And*_*mer 34
以前的答案涵盖了git rebase -i编辑要拆分的提交以及将其部分提交的用法.
这在将文件拆分为不同的提交时效果很好,但如果要拆分对各个文件的更改,则需要了解更多信息.
完成了你想要分割,使用rebase -i和标记它的提交后edit,你有两个选择.
使用后git reset HEAD~,单独使用修补程序git add -p选择每个提交中所需的修补程序
编辑工作副本以删除您不想要的更改; 承认临时国家; 然后撤回下一轮的完整提交.
如果您要拆分大型提交,则选项2非常有用,因为它允许您检查临时版本是否在合并过程中构建并正常运行.这进行如下.
使用rebase -i和edit提交后,使用
git reset --soft HEAD~
Run Code Online (Sandbox Code Playgroud)
撤消提交,但将提交的文件保留在索引中.您也可以通过省略--soft来进行混合重置,具体取决于初始提交的最终结果的接近程度.唯一的区别在于您是从开始的所有更改开始还是从未加入所有更改开始.
现在进入并编辑代码.您可以删除更改,删除添加的文件,并执行您想要构建您正在寻找的系列的第一个提交.您还可以构建它,运行它,并确认您拥有一致的源集.
一旦你开心,根据需要暂存/取消暂存文件(我喜欢用git gui它),并通过UI或命令行提交更改
git commit
Run Code Online (Sandbox Code Playgroud)
这是第一次提交.现在,您希望将工作副本还原到分割提交后的状态,以便您可以为下次提交执行更多更改.要查找正在编辑的提交的sha1,请使用git status.在状态的前几行中,您将看到当前正在执行的rebase命令,您可以在其中找到原始提交的sha1:
$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
pick 4847406 US135756: add debugging to the file download code
e 65dfb6a US135756: write data and download from remote
(see more in file .git/rebase-merge/done)
...
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我正在编辑的提交有sha1 65dfb6a.知道了,我可以在我的工作目录中查看该提交的内容,使用其形式git checkout同时获取提交和文件位置.在这里,我.用作文件位置来替换整个工作副本:
git checkout 65dfb6a .
Run Code Online (Sandbox Code Playgroud)
不要错过最后的点!
这将检查并暂存您正在编辑的提交后的文件,但相对于您之前提交的提交,因此您已提交的任何更改都不会成为提交的一部分.
您可以现在继续并按原样提交以完成拆分,或者再次转发,在进行另一个临时提交之前删除提交的某些部分.
如果要为一个或多个提交重用原始提交消息,可以直接从rebase的工作文件中使用它:
git commit --file .git/rebase-merge/message
Run Code Online (Sandbox Code Playgroud)
最后,一旦你做出了所有的改变,
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
将继续并完成rebase操作.
小智 18
拆分提交的另一种方法是调用
git rebase -i <branch or commit>
Run Code Online (Sandbox Code Playgroud)
标记您想要拆分的提交edit,然后复制该行。这将在变基期间向您呈现两次提交。编辑第一个时,您可以删除第二个中想要的所有内容。完成后,(运行测试,如果适用)git add -A,git commit --amend(在此处调整提交消息)和git rebase --continue。您现在正在进行第二次提交,这只会带来您刚刚从第一次提交中删除的更改。
我认为这比必须小心使用git add -p要容易得多。
小智 17
git rebase --interactive可用于将提交拆分为较小的提交.关于rebase的Git文档对该过程进行了简明扼要的演练 - Splitting Commits:
在交互模式下,您可以使用"编辑"操作标记提交.但是,这并不一定意味着
git rebase期望此编辑的结果恰好是一次提交.实际上,您可以撤消提交,也可以添加其他提交.这可以用于将提交拆分为两个:
启动交互式rebase
git rebase -i <commit>^,其中<commit>包含要分割的提交.实际上,只要包含该提交,任何提交范围都可以.使用"编辑"操作标记要拆分的提交.
在编辑提交时,执行
git reset HEAD^.结果是HEAD被一个重绕,索引也随之而来.但是,工作树保持不变.现在将更改添加到您希望在第一次提交中拥有的索引.您可以使用
git add(可能是交互式)或git gui(或两者)来做到这一点.使用现在适当的提交消息提交now-current索引.
重复最后两步,直到工作树干净.
继续使用rebase
git rebase --continue.如果您不完全确定中间修订版是否一致(它们是编译的,通过测试套件等),那么
git stash在每次提交,测试和修改提交时,如果需要修复,您应该使用它来隐藏尚未提交的更改.
Gra*_*dma 13
如果您只想从现有提交中提取一些内容并保留原始提交,您可以使用
git reset --patch HEAD^
Run Code Online (Sandbox Code Playgroud)
代替git reset HEAD^。该命令允许您仅重置您需要的块。
选择要重置的块后,您将拥有将重置先前提交中的更改的暂存块。现在您更改最后一次提交,从中删除这些更改
git commit --amend --no-edit
Run Code Online (Sandbox Code Playgroud)
并且您有未暂存的块,您可以将其添加到单独的提交中
git add .
git commit -m "new commit"
Run Code Online (Sandbox Code Playgroud)
当然,git rebase --interactive按照上面的建议使用来转到之前的一些提交。
在 Mercurial 中,他们有——继我想在 git 中看到的hg split第二个功能。hg absorb
man*_*lds 10
您可以进行交互式rebase git rebase -i.手册页正是您想要的:
http://git-scm.com/docs/git-rebase#_splitting_commits
在没有交互式变基的情况下,最简单的事情是(可能)从要拆分的分支之前的提交开始创建一个新分支,cherry-pick -n 提交,重置,存储,提交文件移动,重新应用存储并提交更改,然后与前一个分支合并或挑选随后的提交。(然后将以前的分支名称切换为当前的分支名称。)(最好遵循 MBO 的建议并进行交互式变基。)
现在,在最新的Windows版TortoiseGit中,您可以轻松完成.
打开rebase对话框,对其进行配置,然后执行以下步骤.
Edit"(在pick,squash,delete ...中). Start"开始变基. Edit/Split"按钮并Amend直接点击" ".提交对话框打开.
commit". 非常有帮助,谢谢TortoiseGit!
请注意也有git reset --soft HEAD^.它类似于git reset(默认为--mixed)但它保留了索引内容.因此,如果您已添加/删除了文件,则已将它们包含在索引中.
事实证明,在巨型提交的情况下非常有用.
必要命令的快速参考,因为我基本上知道该怎么做但总是忘记正确的语法:
git rebase -i <sha1_before_split>
# mark the targeted commit with 'edit'
git reset HEAD^
git add ...
git commit -m "First part"
git add ...
git commit -m "Second part"
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
以下是如何在IntelliJ IDEA、PyCharm、PhpStorm等中拆分一个提交
在版本控制日志窗口中,选择要拆分的提交,右键单击并选择Interactively Rebase from Here
将要拆分的标记为edit,单击Start
Rebasing
您应该看到放置了一个黄色标签,这意味着 HEAD 已设置为该提交。右键单击该提交,选择Undo Commit
现在这些提交返回到暂存区域,然后您可以单独提交它们。提交所有更改后,旧提交将变为非活动状态。