git - 混帐 | 将旧提交移至另一个分支的过去
问题描述
我过去错误地分支,一个提交留在了另一个分支的开头:
* 03431cb (HEAD -> bar) a2
| * d332e4d (foo) b2
| * 9b29ae3 b1
| * 4656a98 a1
|/
* 6ebca20 (master) root
我怎样才能搬出a1
进入foo
,bar
这样的bar
历史是不是在?是否可以通过一个 git commit 来完成?
这不是推送的,因此无需担心破坏其他人的本地存储库。root -> a1 -> a2
a1
foo
我首先考虑做一个樱桃挑选a1
然后更正和之间的a2
顺序a1
。问题是这两个提交在我的真实案例场景中发生冲突,我必须在进行樱桃挑选和切换顺序时纠正冲突。
bash中的mwe:
#!/bin/bash
set -e
rm -rf .git
git init -b master
echo content > my-file
git add my-file
git commit -m root
git checkout -B foo
echo asd >> my-file
git add my-file
git commit -m a1
echo qwe >> my-file
git add my-file
git commit -m b1
echo zxc >> my-file
git add my-file
git commit -m b2
git checkout master
git checkout -B bar
echo jkl >> my-file
git add my-file
git commit -m a2
解决方案
我是语法的忠实粉丝git rebase --onto x y z
,这意味着:
从 z 开始,通过父链向后看,直到你即将到达 y 并停止。现在将这些提交,即从 y 到并包括 z 的所有内容重新设置为 x。
换句话说,使用这种语法,你可以清楚地说明在哪里剪断链。另外,您不必在变基之前切换分支。语法需要一些时间来适应,但一旦你熟练掌握它,你就会发现自己一直在使用它。
所以:
- 在 a1 创建一个临时分支只是为了给它一个名字:
git branch temp 4656a98
- 现在将 b1 和 b2 重新设置为根:
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
我相信这就是你所说的你想要的。
推荐阅读
- python - KivyMD - 如何使用 KivyMD BottomNavigationItems 和屏幕本身内的按钮在屏幕上导航?
- routes - 如何在 NestJs 中实现媒体类型版本控制?
- regex - 正则表达式/方法来评论日文文本
- excel - 保存 Excel 工作簿会导致用户窗体错误地响应 TAB 和 KeyDown 事件(但在代码环境中保存不会!)
- python - 我在新版本的 python 3.8 中遇到了下面提到的错误。任何人都可以建议如何解决它?
- r - 按行名排列数据框行
- python - 如何访问 GridSearchCV 中的 ColumnTransformer 元素
- angular - 来自 SO 的 Angular GetCookie 方法不再起作用
- python - 从python中的嵌套列表中提取最后一项
- java - 如何将错误捕获留给子类?