## 代码回滚

## 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 <commit>  

场景：
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)