混帐将旧提交移至另一个分支的过去
过去我错误地分支了,并且在另一个分支的开头留下了一个提交:
* 03431cb (HEAD -> bar) a2
| * d332e4d (foo) b2
| * 9b29ae3 b1
| * 4656a98 a1
|/
* 6ebca20 (master) root
* 03431cb (HEAD -> bar) a2
| * d332e4d (foo) b2
| * 9b29ae3 b1
| * 4656a98 a1
|/
* 6ebca20 (master) root
我如何才能将a1出foo成bar,使bar的历史root -> a1 -> a2和a1不foo?是否可以通过一次 git commit 来完成?
这不会被推送,因此无需担心破坏其他人的本地存储库。
我首先想到这样做的樱桃挑选a1,然后修正之间的秩序a2和a1。问题在于,这两个提交在我的真实案例中发生冲突,我必须在进行樱桃挑选和切换订单时纠正冲突。
bash中的mwe:
回答
我是语法的忠实粉丝git rebase --onto x y z,这意味着:
从 z 开始,回顾父链,直到您即将到达 y 并停止。现在将这些提交(即从 y 到并包括 z 的所有内容)重新设置到 x 上。
换句话说,使用此语法,您可以清楚地说明在何处剪断链。另外,您不必在变基之前切换分支。语法需要一些时间来适应,但是一旦你熟练掌握它,你就会发现自己一直在使用它。
所以:
- 在 a1 创建一个临时分支只是为了给它一个名字:
git branch temp 4656a98 - 现在将 b1 和 b2 变基到 root 上:
git rebase --onto master temp foo - 最后将 a2 变基到 a1:
git rebase --onto temp master bar - 现在,如果您愿意,您可以删除 temp:
git branch -D temp
当然,我们可以省去两个步骤,只使用 SHA 编号 4656a98 而不是名称 temp 来执行 2 和 3,但名称更好。
证明。
起始位置:
* 9a97622 (HEAD -> bar) a2
| * 83638ec (foo) b2
| * 7e7cbd0 b1
| * 931632a a1
|/
* 6976e30 (master) root
现在:
% git branch temp 931632a
% git rebase --onto master temp foo
% git rebase --onto temp master bar
% git branch -D temp
结果:
* 3a87b61 (HEAD -> bar) a2
* 931632a a1
| * bbb83d0 (foo) b2
| * 5fa70af b1
|/
* 6976e30 (master) root
我相信这就是你所说的你想要的。