前言
今天准备上线时,突然产品有大变动需要把这个版本的内容都废弃掉。因此我需要将dev分支的代码进行回滚,但我并没有dev分支的权限
找leader操作又觉得太麻烦了。那么有没有办法从dev切出来一个feat/rollback分支
,将代码回退到之前的代码,然后在提交一个PR
到dev
上。答案是有的,接下来采用git rebase + git revert
来实现
方案
- 第一种在
feat/rollback
执行git reset --hard <commit>
之后将feat/rollback
合并到dev
分支,显示没有更新的改动
。这是因为git reset
不会产生新的commit
节点,feat/rollback
的commitIddev分支
都有了 - 第二种在
feat/rollback
执行git revert start..end
, 这个会需要我们处理start
到end
的每一个节点。过于麻烦且每一次revert
都会产生一个新的commit
记录 - 第三种
git rebase -i ~ + git revert
将所有回滚的记录压缩成一个commit
,然后采用revert
回滚这个commit
,最终效果如下
实现
如下图: 我需要将f2a0c1ed
之后的所有commit都废弃掉
- 命令使用
ts
// dev分支
git checkout -b feat/rollback
// 执行变基
git rebase -i commitId
// 终止变基
git rebase --abort
// 继续
git rebase --continue
// 废弃掉某个commitId的改动并且生成一个新的commit记录
git revert commitId
- 回退的步骤
- 从dev分支切出来一个
feat/rollback
分支,使用git log --oneline
确定回退的commitId
- 执行
git rebase -i commitId
ts
git rebase -i f2a0c1ed
我会看到如下图,所有都是pick
状态 3. 合并..1b
~ ..41
到最旧的6f
上。在合并的commit时,选择pick(p)
最旧的6f
。然后将6f
之后的commit前的pick(p)
都改为squash(s)
如下图。然后执行exit
以及:wq
保存就会自动变基,将commit..1b
~ ..41
都会合并6f
节点上 4. 如果在上一步执行变基
的过程中会有冲突,那么解决冲突然后git add .
然后在git rebase --continue
直到变基完成 5. 合并dev
到feat/rollback
.
由于 feat/rollback
分支落后与 dev
分支,因此需要执行 git merge dev
将主分支向 feat/rollback
分支合并,合并后 git 会发现 ..1b
到 ..41
提交的内容和 feat/rollback
分支上 commitId
的修改内容是完全相同的,会自动进行合并,内容不变,但多了一个 commitId
。 6. 在 feat/rollback
执行 revert 反提交
git revert commitId
- 提交
feat/rollback
到dev
分支,在github
的diff面板就能看到回退的内容了。 相当于你手动把这些内容删除掉,然后提交的pr一样。
注意: 这么做也有一个好处,比如那天产品突然反悔了这个版本的内容我还是需要上线。那么就可以直接采用git revert
把上一次git revert
产生的commitId进行恢复即可
总结
这一节我们学习了git rebase + git revert
实现在新分支上回滚代码, 这么做的好处是不需要主分支的权限
、能快速找回此次废弃的代码
、新分支上执行回退操作
。
注: 一般情况下我们都要新建分支
来执行回退
或者合并
的操作