# 代码回滚

### 代码回滚

### Reset：常用在私有分支上

作用：在提交层面上，reset 将一个分支的末端指向另一个提交。

常用标记\
\--soft – 缓存区和工作目录都不会被改变\
\--mixed – 默认选项。缓存区和你指定的提交同步，但工作目录不受影响\
\--hard – 缓存区和工作目录都同步到你指定的提交

场景:

1. 开发合并发生冲突时，想和仓库代码一致，完全舍弃你没有提交的改动，使用git reset HEAD --hard

### Checkout

作用：切换分支或恢复工作区文件

常用命令

1. git checkout hotfix
2. git checkout file
3. git checkout HEAD\~2 //快速查看旧版本

### Revert：常用在公共分支上

作用：撤销一个/多个提交的同时会创建一个新的提交

常用命令：

1. git revert

场景：

1. 提交一个更新 commit id 为2e921a35020d022284d257464297d4a22c7f8b56
2. 执行命令 git revert 2e921a35020d022284d257464297d4a22c7f8b56
3. 保存即可

说明：

1. 撤销生成的提交是可以撤销的\
   先提交文件A，再撤销提交文件A（A删除），最后撤销"撤销操作"，文件A可以恢复
2. 撤销并不一定是最新的一次提交

### 图示

| 命令            | 作用域  | 情景                | 工作目录 | 暂存区  | 提交历史 |
| ------------- | ---- | ----------------- | ---- | ---- | ---- |
| Reset --soft  | 提交层面 | 在私有分支上舍弃一些没有提交的更改 | 不影响  | 不影响  | 影响   |
| Reset --mixed | 提交层面 | --                | 不影响  | 影响   | 影响   |
| Reset --hard  | 提交层面 | --                | 影响   | 影响   | 影响   |
| Checkout      | 提交层面 | 切换分支或查看旧版本        | 影响   | 不影响  | 不影响  |
| revert        | 提交层面 | 将文件从缓存区中移除        | 影响   | 提示保存 | 不影响  |
| Reset         | 文件层面 | 将文件从缓存区中移除        | 不影响  | 影响   | 影响   |
| Checkout      | 文件层面 | 舍弃工作目录中的更改        | 影响   | 不影响  | 不影响  |

### 注意

1. git revert 可以用在公共分支上，git reset 应该用在私有分支上。
2. git revert 不支持文件层面的操作

### 参考资料

* [代码回滚：Reset、Checkout、Revert 的选择](https://github.com/geeeeeeeeek/git-recipes/wiki/5.2-%E4%BB%A3%E7%A0%81%E5%9B%9E%E6%BB%9A%EF%BC%9AReset%E3%80%81Checkout%E3%80%81Revert-%E7%9A%84%E9%80%89%E6%8B%A9)
* [reset文档](https://git-scm.com/docs/git-reset)
