代碼回滾:Reset碧注、Checkout、Revert 的選擇

git reset糖赔、git checkoutgit revert 是你的 Git 工具箱中最有用的一些命令萍丐。它們都用來撤銷代碼倉庫中的某些更改,而前兩個(gè)命令不僅可以作用于提交放典,還可以作用于特定文件逝变。

因?yàn)樗鼈兎浅O嗨疲晕覀兘?jīng)常會(huì)搞混奋构,不知道什么場(chǎng)景下該用哪個(gè)命令壳影。在這篇文章中,我們會(huì)比較 git reset弥臼、git checkoutgit revert 最常見的用法宴咧。希望你在看完后能游刃有余地使用這些命令來管理你的倉庫。

[圖片上傳失敗...(image-6ef1fb-1522748340286)]

Git 倉庫有三個(gè)主要組成——工作目錄醋火,緩存區(qū)和提交歷史悠汽。這張圖有助于理解每個(gè)命令到底產(chǎn)生了哪些影響。當(dāng)你閱讀的時(shí)候芥驳,牢記這張圖柿冲。

提交層面的操作

你傳給 git resetgit checkout 的參數(shù)決定了它們的作用域。如果你沒有包含文件路徑兆旬,這些操作對(duì)所有提交生效假抄。我們這一節(jié)要探討的就是提交層面的操作。注意,git revert 沒有文件層面的操作宿饱。

Reset

在提交層面上熏瞄,reset 將一個(gè)分支的末端指向另一個(gè)提交。這可以用來移除當(dāng)前分支的一些提交谬以。比如强饮,下面這兩條命令讓 hotfix 分支向后回退了兩個(gè)提交。

git checkout hotfix
git reset HEAD~2

hotfix 分支末端的兩個(gè)提交現(xiàn)在變成了懸掛提交为黎。也就是說邮丰,下次 Git 執(zhí)行垃圾回收的時(shí)候,這兩個(gè)提交會(huì)被刪除铭乾。換句話說剪廉,如果你想扔掉這兩個(gè)提交,你可以這么做炕檩。reset 操作如下圖所示:

[圖片上傳失敗...(image-17efb6-1522748340286)]

如果你的更改還沒有共享給別人斗蒋,git reset 是撤銷這些更改的簡(jiǎn)單方法。當(dāng)你開發(fā)一個(gè)功能的時(shí)候發(fā)現(xiàn)「糟糕笛质,我做了什么泉沾?我應(yīng)該重新來過!」時(shí)妇押,reset 就像是 go-to 命令一樣爆哑。

除了在當(dāng)前分支上操作,你還可以通過傳入這些標(biāo)記來修改你的緩存區(qū)或工作目錄:

  • --soft – 緩存區(qū)和工作目錄都不會(huì)被改變
  • --mixed – 默認(rèn)選項(xiàng)舆吮。緩存區(qū)和你指定的提交同步揭朝,但工作目錄不受影響
  • --hard – 緩存區(qū)和工作目錄都同步到你指定的提交

把這些標(biāo)記想成定義 git reset 操作的作用域就容易理解多了。

[圖片上傳失敗...(image-f64e2a-1522748340286)]

這些標(biāo)記往往和 HEAD 作為參數(shù)一起使用色冀。比如潭袱,git reset --mixed HEAD 將你當(dāng)前的改動(dòng)從緩存區(qū)中移除,但是這些改動(dòng)還留在工作目錄中锋恬。另一方面屯换,如果你想完全舍棄你沒有提交的改動(dòng),你可以使用 git reset --hard HEAD与学。這是 git reset 最常用的兩種用法彤悔。

當(dāng)你傳入 HEAD 以外的其他提交的時(shí)候要格外小心,因?yàn)?reset 操作會(huì)重寫當(dāng)前分支的歷史索守。正如 rebase 黃金法則所說的晕窑,在公共分支上這樣做可能會(huì)引起嚴(yán)重的后果。

Checkout

你應(yīng)該已經(jīng)非常熟悉提交層面的 git checkout卵佛。當(dāng)傳入分支名時(shí)杨赤,可以切換到那個(gè)分支敞斋。

git checkout hotfix

上面這個(gè)命令做的不過是將HEAD移到一個(gè)新的分支,然后更新工作目錄疾牲。因?yàn)檫@可能會(huì)覆蓋本地的修改植捎,Git 強(qiáng)制你提交或者緩存工作目錄中的所有更改,不然在 checkout 的時(shí)候這些更改都會(huì)丟失阳柔。和 git reset 不一樣的是焰枢,git checkout 沒有移動(dòng)這些分支。

[圖片上傳失敗...(image-3980e4-1522748340286)]

除了分支之外舌剂,你還可以傳入提交的引用來 checkout 到任意的提交医咨。這和 checkout 到另一個(gè)分支是完全一樣的:把 HEAD 移動(dòng)到特定的提交。比如架诞,下面這個(gè)命令會(huì) checkout 到當(dāng)前提交的祖父提交。

git checkout HEAD~2

[圖片上傳失敗...(image-da5a1-1522748340286)]

這對(duì)于快速查看項(xiàng)目舊版本來說非常有用干茉。但如果你當(dāng)前的 HEAD 沒有任何分支引用谴忧,那么這會(huì)造成 HEAD 分離。這是非常危險(xiǎn)的角虫,如果你接著添加新的提交沾谓,然后切換到別的分支之后就沒辦法回到之前添加的這些提交。因此戳鹅,在為分離的 HEAD 添加新的提交的時(shí)候你應(yīng)該創(chuàng)建一個(gè)新的分支均驶。

Revert

Revert 撤銷一個(gè)提交的同時(shí)會(huì)創(chuàng)建一個(gè)新的提交。這是一個(gè)安全的方法枫虏,因?yàn)樗粫?huì)重寫提交歷史妇穴。比如,下面的命令會(huì)找出倒數(shù)第二個(gè)提交隶债,然后創(chuàng)建一個(gè)新的提交來撤銷這些更改腾它,然后把這個(gè)提交加入項(xiàng)目中。

git checkout hotfix
git revert HEAD~2

如下圖所示:

[圖片上傳失敗...(image-a2d811-1522748340286)]

相比 git reset死讹,它不會(huì)改變現(xiàn)在的提交歷史瞒滴。因此,git revert 可以用在公共分支上赞警,git reset 應(yīng)該用在私有分支上妓忍。

你也可以把 git revert 當(dāng)作撤銷已經(jīng)提交的更改,而 git reset HEAD 用來撤銷沒有提交的更改愧旦。

就像 git checkout 一樣世剖,git revert 也有可能會(huì)重寫文件。所以笤虫,Git 會(huì)在你執(zhí)行 revert 之前要求你提交或者緩存你工作目錄中的更改搁廓。

文件層面的操作

git resetgit checkout 命令也接受文件路徑作為參數(shù)引颈。這時(shí)它的行為就大為不同了。它不會(huì)作用于整份提交境蜕,參數(shù)將它限制于特定文件蝙场。

Reset

當(dāng)檢測(cè)到文件路徑時(shí),git reset 將緩存區(qū)同步到你指定的那個(gè)提交粱年。比如售滤,下面這個(gè)命令會(huì)將倒數(shù)第二個(gè)提交中的 foo.py 加入到緩存區(qū)中,供下一個(gè)提交使用台诗。

git reset HEAD~2 foo.py

和提交層面的 git reset 一樣完箩,通常我們使用HEAD而不是某個(gè)特定的提交。運(yùn)行 git reset HEAD foo.py 會(huì)將當(dāng)前的 foo.py 從緩存區(qū)中移除出去拉队,而不會(huì)影響工作目錄中對(duì) foo.py 的更改弊知。

[圖片上傳失敗...(image-7d2ed3-1522748340284)]

--soft--mixed--hard 對(duì)文件層面的 git reset 毫無作用粱快,因?yàn)榫彺鎱^(qū)中的文件一定會(huì)變化秩彤,而工作目錄中的文件一定不變。

Checkout

Checkout 一個(gè)文件和帶文件路徑 git reset 非常像事哭,除了它更改的是工作目錄而不是緩存區(qū)漫雷。不像提交層面的 checkout 命令,它不會(huì)移動(dòng) HEAD引用鳍咱,也就是你不會(huì)切換到別的分支上去降盹。

[圖片上傳失敗...(image-3fd75d-1522748340283)]

比如,下面這個(gè)命令將工作目錄中的 foo.py 同步到了倒數(shù)第二個(gè)提交中的 foo.py谤辜。

git checkout HEAD~2 foo.py

和提交層面相同的是蓄坏,它可以用來檢查項(xiàng)目的舊版本,但作用域被限制到了特定文件丑念。

如果你緩存并且提交了 checkout 的文件剑辫,它具備將某個(gè)文件回撤到之前版本的效果。注意它撤銷了這個(gè)文件后面所有的更改渠欺,而 git revert 命令只撤銷某個(gè)特定提交的更改妹蔽。

git reset 一樣,這個(gè)命令通常和 HEAD 一起使用挠将。比如 git checkout HEAD foo.py 等同于舍棄 foo.py 沒有緩存的更改胳岂。這個(gè)行為和 git reset HEAD --hard 很像,但只影響特定文件舔稀。

總結(jié)

你現(xiàn)在已經(jīng)掌握了 Git 倉庫中撤銷更改的所有工具乳丰。git resetgit checkoutgit revert 命令比較容易混淆内贮,但當(dāng)你想起它們對(duì)工作目錄产园、緩存區(qū)和提交歷史的不同影響汞斧,就會(huì)容易判斷現(xiàn)在應(yīng)該用哪個(gè)命令。

下面這個(gè)表格總結(jié)了這些命令最常用的使用場(chǎng)景什燕。記得經(jīng)常對(duì)照這個(gè)表格粘勒,因?yàn)槟闶褂?Git 時(shí)一定會(huì)經(jīng)常用到。

命令 作用域 常用情景
git reset 提交層面 在私有分支上舍棄一些沒有提交的更改
git reset 文件層面 將文件從緩存區(qū)中移除
git checkout 提交層面 切換分支或查看舊版本
git checkout 文件層面 舍棄工作目錄中的更改
git revert 提交層面 在公共分支上回滾更改
git revert 文件層面 (然而并沒有)

轉(zhuǎn)載: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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末屎即,一起剝皮案震驚了整個(gè)濱河市庙睡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌技俐,老刑警劉巖乘陪,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異雕擂,居然都是意外死亡护昧,警方通過查閱死者的電腦和手機(jī)咖熟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門突想,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滔迈,“玉大人推溃,你說我怎么就攤上這事尚猿《衅ⅲ” “怎么了深滚?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拔鹰,是天一觀的道長仪缸。 經(jīng)常有香客問我,道長列肢,這世上最難降的妖魔是什么恰画? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮瓷马,結(jié)果婚禮上拴还,老公的妹妹穿的比我還像新娘。我一直安慰自己欧聘,他們只是感情好片林,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怀骤,像睡著了一般费封。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蒋伦,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天弓摘,我揣著相機(jī)與錄音,去河邊找鬼痕届。 笑死韧献,一個(gè)胖子當(dāng)著我的面吹牛末患,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锤窑,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼璧针,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了果复?” 一聲冷哼從身側(cè)響起陈莽,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虽抄,沒想到半個(gè)月后走搁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迈窟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年私植,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片车酣。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡曲稼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出湖员,到底是詐尸還是另有隱情贫悄,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布娘摔,位于F島的核電站窄坦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏凳寺。R本人自食惡果不足惜鸭津,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肠缨。 院中可真熱鬧逆趋,春花似錦、人聲如沸晒奕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脑慧。三九已至惠窄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漾橙,已是汗流浹背杆融。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霜运,地道東北人脾歇。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓蒋腮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親藕各。 傳聞我的和親對(duì)象是個(gè)殘疾皇子池摧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • git reset和git revert都可以用于撤銷已存在的commit乌逐,其中g(shù)it reset可以細(xì)化到針對(duì)單...
    伊凡的一天閱讀 602評(píng)論 0 1
  • 第一章:苦逼的人生從來沒有因?yàn)闀r(shí)間的改變而變化竭讳,就像草原的牛屎一樣從來不會(huì)因?yàn)樗募镜淖兓枚l(fā)光。我叫江川浙踢,出...
    mrxu_d839閱讀 305評(píng)論 0 0
  • 這兩天遇見四件事: 1绢慢、送8899S保單過去,填單子的時(shí)候沒有填車船稅洛波,龔主任也沒有檢查就給了財(cái)務(wù)胰舆。 2、看到太平...
    捌柒玖零閱讀 225評(píng)論 0 1
  • 飛機(jī)尾部仿若紙片蹬挤,飛舞缚窿,碎裂。 ——《回憶錄》 陳宇雙手緊緊地握住箱子的把手焰扳,整個(gè)人斜掛在70度的峭壁上倦零,全靠銀色...
    熾魂BLASOUL閱讀 547評(píng)論 0 6
  • 此時(shí)此刻光绕,我還坐在圖書館和后天即將考試的計(jì)量經(jīng)濟(jì)學(xué)較勁女嘲,你在做什么呢畜份? 自從大學(xué)后,我們之間的交集...
    曖璃閱讀 175評(píng)論 0 0