git图解(2):代码回退

封面.jpg

关于 git 的基本理解, 在第一篇git文章已介绍。 上一篇文章主要讲解了git的提交操作, 本篇在上篇基础上着重写git代码的逆向操作:代码回退。网上关于git回退的文章比较多, 本文是个人理解实践的汇总, 不当、不全之处请评论区指出。
首先,回顾下git代码存在的5个区域, 分别是 工作区间工作现场缓存区(或叫暂存区)、本地仓库(或叫当前分支)、远程仓库(或叫远程分支);如下图:
1.png

1.缓存区代码覆盖工作区代码

场景: 缓存区存有上次改动代码,即之前有执行:

git add
```
当前**工作区间**代码想废弃, 可将**缓存区**中代码覆盖之:

![3.png](http://upload-images.jianshu.io/upload_images/615809-b6283ed165397d5f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**对应指令:**
```
// 将缓存区某一文件代码 覆盖本地工作区: 
git checkout -- testReset.txt

// 将匹配的文件覆盖:
git checkout -- *.txt

// 将所有文件覆盖:
git checkout -- .
```
# 2.本地仓库代码覆盖缓存区代码
场景:发现之前add的文件不需要了,又不想**工作区间**重新改回去。
![4.jpeg](http://upload-images.jianshu.io/upload_images/615809-530852aee221207b.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**对应指令:**
```
// 将本地仓库某一文件覆盖缓存区: 
git reset HEAD testReset.txt 

// 将匹配的文件覆盖缓存区:
git reset HEAD *.txt

// 将所有文件覆盖缓存区:
git reset HEAD .
```
注意: 改变的是**缓存区**代码, **工作区间**代码不变(编辑器代码不会改变)

# 3.本地仓库代码覆盖工作区代码(常用)
上述两场景在实际开发中没那么常用,接下来 **本地仓库** 代码 覆盖 **工作区间 **代码 则经常会用到。
场景: 当前 **工作区间** 代码混乱(一般更新或合并分支后) , 废弃当前改动;
![5.png](http://upload-images.jianshu.io/upload_images/615809-06b2d06489ebb0cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**对应指令:**
```
// 将本地仓库某一文件代码 覆盖本地工作区: 
git checkout head testReset.txt

// 将本地仓库所有文件代码 覆盖本地工作区:(谨慎操作):
git checkout head .
```
我们知道**本地仓库**中有一个commit 列表, 记录了所有commit的记录, 查看commit列表指令:
```
// 查看commit id, 查看提交记录(git commit的记录)
git log 
git log --pretty=oneline 

// 查看以往提交历史(包括 撤销回退 记录) 
git reflog 
```
![6.png](http://upload-images.jianshu.io/upload_images/615809-5536c973563a7f39.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
根据commit列表, **工作区间**代码能实现更灵活的回退:
```
// 本地工作区间代码 回退到上一次版本、上上次、前10个版本 
git reset --hard HEAD^ 
git reset --hard HEAD^^ 
git reset --hard HEAD~10 

// 本地工作区间代码 回退到指定版本(“d362816”为commit id) 
git reset --hard d362816 
```
# 4.远程仓库代码覆盖本地仓库代码(清除 未push 的commit)
场景: 有时候合并分支、切换分支、更新代码会导致提交絮乱的问题(没使用--rebase方式),具体体现在自动生成了commit且**工作区间** 代码很多冲突。使**工作区间**代码跟线上代码一致且删除新生成的commit。
![7.png](http://upload-images.jianshu.io/upload_images/615809-8f87fdd8461d2232.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**对应指令:**
```
// 本地工作区间代码回退到远程版本 
git reset –-hard origin/master 
```
写到了git reset指令, 就不得不说下它与 git revert 的区别:
> 1. git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。

> 2. 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit“中和”之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是直接把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。

> 3. git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。

git reset 与 git revert区别图:

![8.png](http://upload-images.jianshu.io/upload_images/615809-6a56dbb1295896a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![9.png](http://upload-images.jianshu.io/upload_images/615809-cc57f6657b49ce6d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# 5.远程仓库代码回滚(线上代码回滚)
场景: 提交了一个commit(该提交包含很多文件), 发现有问题, 需要回滚, 将线上分支(master)回滚到上一次commit;
网上有删除分支进行线上代码回滚的教程, 那种操作其实很危险, 因为一般线上的分支是master分支, 而这个分支不允许删除。
合理一些的是使用 git reset或git revert方式进行回滚;
**git reset方式图解:**

![10.png](http://upload-images.jianshu.io/upload_images/615809-a569b67b955fed97.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**git revert方式图解:**

![11.png](http://upload-images.jianshu.io/upload_images/615809-05f9b43a8565df67.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
我们可以使用git revert将新的commit替换掉;(不用git reset而用git revert的原因是保留commit方便后续代码恢复)
**对应指令:**
```
// 替换掉上次提交的代码文件(上次的commit记录会保留)
git revert HEAD
git commit -m "回滚上次commit"
git push origin master
```
参考资料:
[时光机穿梭 - 廖雪峰的官方网站](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743858312764dca7ad6d0754f76aa562e3789478044000)
[GitHub - wteam-xq/testGit: git学习、博文测试工程](https://github.com/wteam-xq/testGit)
[Git HowTo: revert a commit already pushed to a remote repository](http://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html)
相关文章:
[Git 图解(1):代码区域总结](http://www.jianshu.com/p/898e766d22e1)
[Git 图解(3):分支操作](http://www.jianshu.com/p/342a9f8db004)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容