假设我在本地分支上有以下提交历史:
A -- B -- C
如何在a和B之间插入新的提交?
假设我在本地分支上有以下提交历史:
A -- B -- C
如何在a和B之间插入新的提交?
当前回答
这里已经有很多好答案了。我只是想在4个简单的步骤中添加一个“无rebase”解决方案。
总结
git checkout A
# <<< modify your files at this point
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD
解释
(注意:这种解决方案的一个优点是,直到最后一步,当你100%确定你对最终结果满意时,你才会接触你的分支,所以你有一个非常方便的“预确认”步骤,允许AB测试。)
初始状态(我假设分支名为master)
A -- B -- C <<< master <<< HEAD
1)首先将HEAD指向正确的位置
git checkout A
B -- C <<< master
/
A <<< detached HEAD
(在这里,我们可以选择使用git checkout -b temp a创建一个临时分支,而不是分离HEAD,我们需要在进程结束时删除它。这两种变体都可以工作,做你喜欢的,因为其他一切都保持不变)
2)创建要插入的新提交D
# at this point, make the changes you wanted to insert between A and B, then
git commit -am "Message for commit D"
B -- C <<< master
/
A -- D <<< detached HEAD (or <<< temp <<< HEAD)
3)然后带来最后一个丢失的提交B和C的副本(即使中间有更多的提交,命令也会是相同的,因为这是在选择一个提交范围)
git cherry-pick A..C
# (if any, resolve potential conflicts between D and these last commits)
B -- C <<< master
/
A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)
(如果需要,可以在这里进行AB测试)
现在是检查代码的时候了,测试任何需要测试的东西,你还可以通过检查C或C'来区分/比较/检查你所拥有的和你在操作后将得到的。
4)根据你在C和C'之间的测试,它是OK还是KO。
(EITHER) 4-OK)最后,移动master的ref
git branch -f master HEAD
B -- C <<< (B and C are candidates for garbage collection)
/
A -- D -- B' -- C' <<< master
(OR) 4-KO)保持master不变
如果你创建了一个临时分支,只需使用git branch -d <name>删除它,但如果你选择分离HEAD路由,此时根本不需要任何操作,新的提交将在你用git checkout master重新连接HEAD后符合垃圾收集的条件
在这两种情况下(OK或KO),此时只需再次签出master以重新连接HEAD。
其他回答
其实很简单,答案就在这里。假设你在一个分支上。执行以下步骤:
在你想要插入新的提交(在本例中是commit a)之后,从commit创建一个临时分支: A .使用实例 执行更改并提交它们,创建一个commit,我们称它为N: git commit -a -m "Message" (或者git add后跟git commit) 在新的commit(在本例中是提交B和C)之后,将你想要的提交重新基于新的commit: Git重新建立临时分支
(可能你需要使用-p来保存合并,如果有的话-感谢ciekawy不再存在的注释)
删除临时分支: Git分支-d temp
在此之后,历史记录如下:
A -- N -- B -- C
当然,在改基过程中可能会出现一些冲突。
如果您的分支不是本地分支,这将引入重写历史,因此可能导致严重的问题。
更简单的解决方案:
在最后创建你的新commit, d。现在你有: A——b——c——d 然后运行: $ git rebase -i hash- a Git会打开你的编辑器,它看起来是这样的: 选B 选C 选D 只需要像这样将D移到顶部,然后保存并退出 选D 选B 选C 现在你将拥有: A d b c
这里已经有很多好答案了。我只是想在4个简单的步骤中添加一个“无rebase”解决方案。
总结
git checkout A
# <<< modify your files at this point
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD
解释
(注意:这种解决方案的一个优点是,直到最后一步,当你100%确定你对最终结果满意时,你才会接触你的分支,所以你有一个非常方便的“预确认”步骤,允许AB测试。)
初始状态(我假设分支名为master)
A -- B -- C <<< master <<< HEAD
1)首先将HEAD指向正确的位置
git checkout A
B -- C <<< master
/
A <<< detached HEAD
(在这里,我们可以选择使用git checkout -b temp a创建一个临时分支,而不是分离HEAD,我们需要在进程结束时删除它。这两种变体都可以工作,做你喜欢的,因为其他一切都保持不变)
2)创建要插入的新提交D
# at this point, make the changes you wanted to insert between A and B, then
git commit -am "Message for commit D"
B -- C <<< master
/
A -- D <<< detached HEAD (or <<< temp <<< HEAD)
3)然后带来最后一个丢失的提交B和C的副本(即使中间有更多的提交,命令也会是相同的,因为这是在选择一个提交范围)
git cherry-pick A..C
# (if any, resolve potential conflicts between D and these last commits)
B -- C <<< master
/
A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)
(如果需要,可以在这里进行AB测试)
现在是检查代码的时候了,测试任何需要测试的东西,你还可以通过检查C或C'来区分/比较/检查你所拥有的和你在操作后将得到的。
4)根据你在C和C'之间的测试,它是OK还是KO。
(EITHER) 4-OK)最后,移动master的ref
git branch -f master HEAD
B -- C <<< (B and C are candidates for garbage collection)
/
A -- D -- B' -- C' <<< master
(OR) 4-KO)保持master不变
如果你创建了一个临时分支,只需使用git branch -d <name>删除它,但如果你选择分离HEAD路由,此时根本不需要任何操作,新的提交将在你用git checkout master重新连接HEAD后符合垃圾收集的条件
在这两种情况下(OK或KO),此时只需再次签出master以重新连接HEAD。
假设你想要插入的提交是由D标识的:
# Temporarily append the commit you want to insert to the end
git cherry-pick D
# Results in D -- A -- B -- C
# Start interactive rebase
git rebase -i B^
# Let's imagine that this is what the rebase prompt looks like:
# pick B Third commit
# pick A Second commit
# pick D First commit
# Then reorder the commits:
# pick B Third commit
# pick D First commit
# pick A Second commit
# Save and exit
# After completing the rebase you will find
# A -- D -- B -- C
这比OP的回答还要简单。
git rebase -i <any earlier commit>. This displays a list of commits in your configured text editor. Find the commit you want to insert after (let's assume it's a1b2c3d). In your editor, for that line, change pick to edit. Begin the rebase by closing your text editor (save your changes). This leaves you at a command prompt with the commit you chose earlier (a1b2c3d) as if it has just been committed. Make your changes and git commit (NOT amending, unlike most edits). This creates new a commit after the one you chose. git rebase --continue. This replays the successive commits, leaving your new commit inserted in the correct place.
当心,这将改写历史,并破坏任何试图拉扯的人。