变基子子分支提交到父分支出错后,如何回退并调整分支状态?
本地有三个分支:dev、bugfix、fix_1。从master分支创建dev分支,完成3次提交(A、B、C)后切换至新分支bugfix;在bugfix分支完成3次提交(x、y、z)后,切换至新分支fix_1并完成1次提交(fixcommit)。
原本只想将fix_1分支的fixcommit变基到dev分支的顶端,但执行变基后,bugfix分支的所有提交也被变基到了dev分支。
变基前分支状态:
STATE 1 :
dev --A--B--C | | bugfix x--y--z | | fix_1 fixcommit
变基后分支状态:
STATE 2 :
dev --A--B--C--x--y--z--fixcommit | | bugfix x--y--z | | fix_1 fixcommit
希望先恢复到目标状态1:
目标状态1 :
dev --A--B--C--fixcommit | | bugfix x--y--z | | fix_1 fixcommit
再调整至目标状态2:
目标状态2 :
dev --A--B--C--fixcommit | | bugfix x--y--z
一、恢复并实现目标状态1
找回变基前dev的提交C
执行git reflog查看本地Git操作记录,找到变基前dev分支指向的最后一个提交(也就是C)的哈希值,比如记录里类似abc123 dev@{0}: rebase: ...的前一条记录对应的哈希就是C的哈希,记为commit_C_hash。如果reflog找不到,也可以用git log --oneline遍历提交找到C的哈希。重置dev分支到提交C
git checkout dev git reset --hard commit_C_hash这一步会把dev分支恢复到变基前的状态。
单独将fixcommit移到dev顶端
两种方法任选其一:- 方法1:用cherry-pick直接复制提交
git checkout dev git cherry-pick fix_1 - 方法2:用rebase --onto精准移动指定提交
git rebase --onto dev bugfix fix_1 git checkout dev git reset --hard fix_1
完成后,dev分支就会变成
A--B--C--fixcommit,bugfix和fix_1分支保持原有状态,即达成目标状态1。- 方法1:用cherry-pick直接复制提交
二、从目标状态1切换到目标状态2
把bugfix分支的x、y、z提交移到dev的最新提交(fixcommit)顶端,直接执行变基即可:
git checkout bugfix git rebase dev
变基完成后,bugfix分支就会基于dev的fixcommit提交,形成A--B--C--fixcommit--x--y--z的结构,也就是目标状态2。
注意事项
- 如果变基过程中出现冲突,手动解决冲突后执行
git rebase --continue即可;如果想放弃变基,执行git rebase --abort。 git reset --hard会丢弃当前分支未提交的修改,执行前确保没有未保存的工作内容。
内容的提问来源于stack exchange,提问作者au7 au7

