Git 回滚规范
结论
开发流程中,不免会遇到需要回滚 master 代码的时候。关于如何回滚,我们将统一采用 revert 方式进行回滚,以保留之前错误的提交,便于进行复盘与 CR
回滚步骤如下
- git checkout master —— 分支切换到 master
- git pull —— 更新 master 代码为最新
- 从 master 分支中开一个 feat 分支
- git log —— 查询提交记录,并找到需要回滚的 commit id
- git revert
或者 git revert -m 1 faulty merge —— 回滚 - push & 提交与 master 分支的 mr
Checkout、reset、revert 的择决
Checkout
git checkout 是一种便捷的方式,来将快照「解包」到你的工作目录上去。 git checkout
可以检出提交、也可以检出单个文件甚至还可以检出分支
1 | git checkout commitId |
检出 commitId 对应的提交,你会发现当前工作目录和commitId
完全一致,你可以查看这个版本的文件编辑、运行、测试都不会被保存到git仓库里面。你可以git checkout master
或者 git checkout -
回到原来的工作状态上来
Reset
git reset
有很多用法
1 | git reset <file> |
从暂存区移除特定文件,但不改变工作目录。它会取消这个文件的缓存,而不覆盖任何更改
1 | git reset |
重置暂存区,匹配最近的一次提交,但工作目录不变。它会取消所有文件的暂存,而不会覆盖任何修改,给你了一个重设暂存快照的机会
1 | git reset --hard |
加上--hard
标记后会告诉git要重置缓存区和工作目录的更改
1 | git reset <commit> |
将缓存区重设到这个提交,但不改变工作目录
1 | git reset --hard <commit> |
将当前分支的指针 head 移到对应的 commit id 提交
Revert
git revert
被用来撤销一个已经提交的快照。和 reset 是完全不同的。实质是在最后加上一个撤销了更改的新提交,而不是从项目历史中移除这个提交
1 | git revert <commit> |
生成一个撤消了,引入的修改的新提交,然后应用到当前分支
1 |
|
我们在3a395af
引入了一个 bug,我们明确是由于3a395af
造成的 bug 的时候,以其我们通过新的提交来 fix 这个 bug,git revert
, 让他来帮你剔除这个 bug
1 | git revert 3a395af |
得到结果
1 | cfb71fc Revert "bug" |
这个时候 bug 的改动被撤销了,产生了一个新的 commit,但是commit after bug
没有被清初。
所以相较于reset
,revert
不会改变项目历史,对那些已经发布到共享仓库的提交来说这是一个安全的操作。其次git revert
可以将提交历史中的任何一个提交撤销、而reset
会把历史上某个提交及之后所有的提交都移除掉
回滚错误的 merge
当一个有 bug 的分支 merge 进 master 后,且后续多个开发分支建立在该 merge 之后,将会给后续开发分支带来 bug,导致其余同学测试跑不通或者线上问题。
1 |
|
此时第一想到的应该是回滚掉错误的提交
1 | git revert -m ``1` `faulty merge |
-m
后面带的参数值 可以是 1 或者 2,对应着 parent 的顺序.上面列子:1 代表v3
,2 代表d2
所以该操作会保留 master 分支的修改,而撤销 feat 分支 merge 过来的修改。
提交历史变为
1 |
|
此处rev3
是一个常规 commit,其内容包含了之前在faulty merge
撤销掉的 feat 合并过来的 commit 的【反操作】的合集。
恢复之前的回滚
把之前 master 带有【反操作】的 commit 给撤销掉
1 | git checkout master``git revert rev3``git merge feat |
此时提交历史变成了
1 |
|