學(xué)會這十種Git"撤銷"操作珠插,走遍Git天下都不怕了。

譯自:Github

JF杰微刊出品:如何在Git中撤銷一切

JF杰微刊:如何在Git中撤銷一切


任何一個版本控制系統(tǒng)中颖对,最有用的特性之一莫過于?“撤銷(undo)”操作捻撑。在Git中,“撤銷”有很多種含義。

當(dāng)你完成了一次新的提交(commit)顾患,Git會及時存儲當(dāng)前時刻倉庫(repository)的快照(snapshot)番捂;你能夠使用Git將項目回退到任何之前的版本。

下文中江解,我將列舉幾個常見的设预、需要“撤銷”的場景,并且展示如何使用Git來完成這些操作膘流。



一絮缅、撤銷一個公共修改 Undo?a?"public"?change

場景:你剛剛用git?push將本地修改推送到了GitHub,這時你意識到在提交中有一個錯誤呼股。你想撤銷這次提交耕魄。

使用撤銷命令:git?revert

發(fā)生了什么:git?revert將根據(jù)給定SHA的相反值,創(chuàng)建一個新的提交彭谁。如果舊提交是“matter”吸奴,那么新的提交就是“anti-matter”——舊提交中所有已移除的東西將會被添加進(jìn)到新提交中,舊提交中增加的東西將在新提交中移除缠局。

這是Git最安全则奥、也是最簡單的“撤銷”場景,因為這樣不會修改歷史記錄——你現(xiàn)在可以git?push下剛剛revert之后的提交來糾正錯誤了狭园。



二读处、修改最近一次的提交信息 Fix?the?last?commit?message

場景你只是在最后的提交信息中敲錯了字,比如你敲了git?commit?-m?"Fxies?bug?#42"唱矛,而在執(zhí)行g(shù)it?push之前你已經(jīng)意識到你應(yīng)該敲"Fixes?bug?#42"罚舱。

使用撤銷命令git?commit –amend或git?commit?--amend?-m?"Fixes?bug?#42"

發(fā)生了什么git?commit?–amend將使用一個包含了剛剛錯誤提交所有變更的新提交,來更新并替換這個錯誤提交绎谦。由于沒有staged的提交管闷,所以實際上這個提交只是重寫了先前的提交信息。



三窃肠、撤銷本地更改 Undo?"local"?changes

場景當(dāng)你的貓爬過鍵盤時包个,你正在編輯的文件恰好被保存了,你的編輯器也恰在此時崩潰了冤留。此時你并沒有提交過代碼碧囊。你期望撤銷這個文件中的所有修改——將這個文件回退到上次提交的狀態(tài)。

使用撤銷命令git?checkout?--

發(fā)生了什么git?checkout將工作目錄(working?directory)里的文件修改成先前Git已知的狀態(tài)纤怒。你可以提供一個期待回退分支的名字或者一個確切的SHA碼糯而,Git也會默認(rèn)檢出HEAD——即:當(dāng)前分支的上一次提交。

注意:用這種方法“撤銷”的修改都將真正的消失肪跋。它們永遠(yuǎn)不會被提交。因此Git不能恢復(fù)它們土砂。此時州既,一定要明確自己在做什么C涨ⅰ(或許可以用git?diff來確定)



四、重置本地修改 Reset?"local"?changes

場景你已經(jīng)在本地做了一些提交(還沒push)吴叶,但所有的東西都糟糕透了阐虚,你想撤銷最近的三次提交——就像它們從沒發(fā)生過一樣。

使用撤銷命令git?reset或git?reset?--hard

發(fā)生了什么git?reset 將你的倉庫紀(jì)錄一直回退到指定的最后一個SHA代表的提交蚌卤,那些提交就像從未發(fā)生過一樣实束。默認(rèn)情況下,git?reset會保留工作目錄 (working?directory)逊彭。這些提交雖然消失了咸灿,但是內(nèi)容還在磁盤上。這是最安全的做法侮叮,但通常情況是:你想使用一個命令來“撤銷”所有提 交和本地修改——那么請使用--hard參數(shù)吧避矢。



五、撤銷本地后重做 Redo?after?undo?"local"

場景你已經(jīng)提交了一些內(nèi)容囊榜,并使用git?reset?–hard撤銷了這些更改(見上面)审胸,突然意識到:你想還原這些修改!

使用撤銷命令git?reflog和git?reset,?或者git?checkout

發(fā)生了什么git?reflog是一個用來恢復(fù)項目歷史記錄的好辦法卸勺。你可以通過git?reflog恢復(fù)幾乎任何已提交的內(nèi)容砂沛。

你或許對git?log命令比較熟悉,它能顯示提交列表曙求。git?reflog與之類似碍庵,只不過git?reflog顯示的是HEAD變更次數(shù)的列表。

一些說明

1.?只 有HEAD會改變圆到。當(dāng)你切換分支時怎抛,用git?commit提交變更時,或是用git?reset撤銷提交時芽淡,HEAD都會改變马绝。但當(dāng)你用 git?checkout?--時,?HEAD不會發(fā)生改變挣菲。(就像上文提到的情形富稻,那些更改根本就沒有提交,因此reflog就不能幫助我們進(jìn)行恢復(fù) 了)

2.??git?reflog不會永遠(yuǎn)存在白胀。Git將會定期清理那些“不可達(dá)(unreachable)”的對象椭赋。不要期望能夠在reflog里找到數(shù)月前的提交記錄。

3.??reflog只是你個人的或杠。你不能用你的reflog來恢復(fù)其他開發(fā)者未push的提交哪怔。

JF杰微刊出品:如何在Git中撤銷一切

因此,怎樣合理使用reflog來找回之前“未完成”的提交呢?這要看你究竟要做什么:

1.?如果你想恢復(fù)項目歷史到某次提交认境,那請使用git?reset?--hard

2.?如果你想在工作目錄(working?direcotry)中恢復(fù)某次提交中的一個或多個文件胚委,并且不改變提交歷史,那請使用git?checkout--

3.?如果你想確切的回滾到某次提交叉信,那么請使用git?cherry-pick亩冬。



六、與分支有關(guān)的那些事 Once?more,?with?branching

場景你提交了一些變更硼身,然后你意識到你正在master分支上硅急,但你期望的是在feature分支上執(zhí)行這些提交。

使用撤銷命令git?branch?feature,?git?reset?--hard?origin/master,?和?git?checkout?feature

發(fā)生了什么你可能用的是git?checkout?-b來建立新的分支佳遂,這是創(chuàng)建和檢出分支的便捷方法——但實際你并不想立刻切換分支营袜。git?branch?feature會建立一個叫feature的分支,這個分支指向你最近的提交讶迁,但是你還停留在master分支上连茧。

git?reset?--hard將master回退至origin/master,并忽略所有新提交巍糯。別擔(dān)心啸驯,那些提交都還保留在feature上。

最后祟峦,git?checkout將分支切換到feature罚斗,這個分支原封不動的保留了你最近的所有工作。



七宅楞、事半功倍處理分支 Branch?in?time?saves?nine

場景:你基于master新建了一個feature分支针姿,但是master分支遠(yuǎn)遠(yuǎn)落后與origin/master。現(xiàn)在master分支與origin/master同步了厌衙,你期望此刻能在feature下立刻commit代碼距淫,并且不是在遠(yuǎn)遠(yuǎn)落后master的情況下。

使用撤銷命令git?checkout?feature和git?rebase?master

發(fā)生了什么你也許已經(jīng)敲了命令:git?reset(但是沒用--hard,有意在磁盤上保存這些提交內(nèi)容)婶希,然后敲了git?checkout?-b榕暇,之后重新提交更改,但是那樣的話喻杈,你將失去本地的提交記錄彤枢。不過,一個更好的方法:

使用git?rebase?master可以做到一些事情:

1.首先筒饰,它定位你當(dāng)前檢出分支和master之間的共同祖先節(jié)點(common?ancestor)缴啡。

2.然后,它將當(dāng)前檢出的分支重置到祖先節(jié)點(ancestor)瓷们,并將后來所有的提交都暫存起來业栅。

3.最后秒咐,它將當(dāng)前檢出分支推進(jìn)至master末尾,同時在master最后一次提交之后碘裕,再次提交那些在暫存區(qū)的變更反镇。



八、批量撤銷/找回 Mass?undo/redo

場景你開始朝一個既定目標(biāo)開發(fā)功能娘汞,但是中途你感覺用另一個方法更好。你已經(jīng)有十幾個提交夕玩,但是你只想要其中的某幾個你弦,其他的都可以刪除不要。

使用撤銷命令git?rebase?-i

發(fā)生了什么-i將rebases設(shè)置為“交互模式(interactive?mode)”燎孟。rebase開始執(zhí)行的操作就像上文討論的一樣禽作,但是在重新執(zhí)行某個提交時,它會暫停下來揩页,讓你修改每一次提交旷偿。

rebase?–i將會打開你的默認(rèn)文本編輯器,然后列出正在執(zhí)行的提交爆侣,就像這樣:

JF杰微刊出品:如何在Git中撤銷一切


前兩列最關(guān)鍵:第一列是選擇命令萍程,它會根據(jù)第二列中的SHA碼選擇相應(yīng)的提交。默認(rèn)情況下兔仰,rebase?–i會認(rèn)為每個更改都正通過pick命令被提交茫负。

要撤銷一個提交,直接在編輯器刪除對應(yīng)的行就可以了乎赴。如果在你的項目不再需要這些錯誤的提交忍法,你可以直接刪除上圖中的第1行和3-4行。

如 果你想保留提交但修改提交信息榕吼,你可以使用reword命令饿序。即,將命令關(guān)鍵字pick換成reword(或者r)羹蚣。你現(xiàn)在可能想立刻修改提交消息原探,但這 么做不會生效——rebase?–i將忽略SHA列后的所有東西。現(xiàn)有的提交信息會幫助我們記住0835fe2代表什么度宦。當(dāng)你敲完rebase?–i命令 后踢匣,Git才開始提示你重寫那些新提交消息。

如果你需要將2個提交合并戈抄,你可以用squash或者fixup命令离唬,如下圖:

JF杰微刊出品:如何在Git中撤銷一切

squash和fixup都是“向上”結(jié)合的——那些用了這些合并命令(編者按:指squash、fixup)的提交划鸽,將會和它之前的提交合并:上圖中输莺,0835fe2和6943e85將會合并成一個提交戚哎,而38f5e4e和af67f82將會合并成另一個提交。

當(dāng) 你用squash時嫂用,Git將會提示是否填寫新的提交消息型凳;fixup則會給出列表中第一個提交的提交信息。在上圖中嘱函,af67f82是一個 “Ooops”信息甘畅,因為這個提交信息已經(jīng)同38f5e4e一樣了。但是你可以為0835fe2和6943e85合并的新提交編寫提交信息往弓。

當(dāng)你保存并退出編輯器時疏唾,Git將會按照從上到下的順序執(zhí)行你的提交。你可以在保存這些提交之前函似,修改提交的執(zhí)行順序槐脏。如果有需要,你可以將af67f82和0835fe2合并撇寞,并且可以這樣排序:

JF杰微刊出品:如何在Git中撤銷一切



九顿天、修復(fù)早先的提交 Fix?an?earlier?commit

場景之前的提交里落下了一個文件,如果先前的提交能有你留下的東西就好了蔑担。你還沒有push牌废,并且這個提交也不是最近的提交,因此你不能用commit?–amend啤握。

使用撤銷命git?commit?--squash和git?rebase?--autosquash?-i

發(fā)生了什么:git?commit?–squash將會創(chuàng)建一個新的提交畔规,該提交信息可能像這樣“squash!?Earlier?commit”。(你也可以手寫這些提交信息恨统,commit?–squash只是省得讓你打字了)叁扫。

如果你不想為合并的提交編寫信息,也可以考慮使用命令git?commit?--fixup畜埋。這種情況下莫绣,你可能會使用commit?--fixup,因為你僅希望在rebase中使用之前的提交信息悠鞍。

rebase?--autosquash?–i將會啟動rebase交互編輯器对室,編輯器會列出任何已完成的squash!和fixup!提交,如下圖:

JF杰微刊出品:如何在Git中撤銷一切

當(dāng) 使用--squash和–fixup時咖祭,你或許記不清你想修復(fù)的某個提交的SHA碼——只知道它可能在一個或五個提交之前掩宜。你或許可以使用Git的^和~ 操作符手動找回。HEAD^表示HEAD的前一次提交么翰。HEAD~4表示HEAD前的4次提交牺汤,加起來總共是前5次提交斤寂。



十窖壕、停止跟蹤一個已被跟蹤的文件 Stop?tracking?a?tracked?file

場景:你意外將application.log添加到倉庫中葬馋,現(xiàn)在你每次運(yùn)行程序悯衬,Git都提示application.log中有unstaged的提交。你在.gitignore中寫上”*.log”追迟,但仍舊沒用——怎樣告訴Git“撤銷”跟蹤這個文件的變化呢溶其?

使用撤銷命令: git?rm?--cached?application.log

發(fā)生了什么:盡 管.gitignore阻止Git跟蹤文件的變化,甚至是之前沒被跟蹤的文件是否存在敦间,但是瓶逃,一旦文件被add或者commit,Git會開始持續(xù)跟蹤這 個文件的變化廓块。類似的金闽,如果你用git?add?–f來“強(qiáng)制”add,或者覆蓋.gitignore剿骨,Git還是會繼續(xù)監(jiān)視變化。所以以后最好不要使用 –f來add?.gitignore文件埠褪。

如果你希望移除那些應(yīng)當(dāng)被忽略的文件浓利,git?rm?–cached可以幫助你,并將這些文件保留在磁盤上钞速。因為這個文件現(xiàn)在被忽略了贷掖,你將不會在git?status中看到它,也不會再把這個文件commit了渴语。

以上就是如何在Git上撤銷的方法苹威。如果你想學(xué)習(xí)更多Git命令用法,可以移步下面相關(guān)的文檔:

· checkout

· commit

· rebase

· reflog

· reset

· revert

· rm



原文地址:Github

譯文地址:http://www.jointforce.com/jfperiodical/article/show/796?m=d03


如果您發(fā)現(xiàn)這篇譯文的任何問題驾凶,可隨時與我們聯(lián)系牙甫。

我們水平有限,但理想高遠(yuǎn)调违。我們旨在分享優(yōu)質(zhì)的內(nèi)容窟哺。


我們也同樣期待理想的您對這個世界的貢獻(xiàn)。歡迎任何目的的聯(lián)系技肩。


我們的郵箱是:weikan@jointforce.com且轨。


我們的QQ是:3272840549。



[轉(zhuǎn)載請保留原文出處虚婿、譯者和審校者旋奢。

可以不保留我們的鏈接]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市然痊,隨后出現(xiàn)的幾起案子至朗,更是在濱河造成了極大的恐慌,老刑警劉巖剧浸,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爽丹,死亡現(xiàn)場離奇詭異筑煮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)粤蝎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門真仲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人初澎,你說我怎么就攤上這事秸应。” “怎么了碑宴?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵软啼,是天一觀的道長。 經(jīng)常有香客問我延柠,道長祸挪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任贞间,我火速辦了婚禮贿条,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘增热。我一直安慰自己整以,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布峻仇。 她就那樣靜靜地躺著公黑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摄咆。 梳的紋絲不亂的頭發(fā)上凡蚜,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音吭从,去河邊找鬼番刊。 笑死,一個胖子當(dāng)著我的面吹牛影锈,可吹牛的內(nèi)容都是我干的芹务。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼鸭廷,長吁一口氣:“原來是場噩夢啊……” “哼枣抱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辆床,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤佳晶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后讼载,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轿秧,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡中跌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了菇篡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漩符。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驱还,靈堂內(nèi)的尸體忽然破棺而出嗜暴,到底是詐尸還是另有隱情,我是刑警寧澤议蟆,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布闷沥,位于F島的核電站,受9級特大地震影響咐容,放射性物質(zhì)發(fā)生泄漏舆逃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一戳粒、第九天 我趴在偏房一處隱蔽的房頂上張望路狮。 院中可真熱鬧,春花似錦享郊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至又活,卻和暖如春苔咪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柳骄。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工团赏, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耐薯。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓舔清,卻偏偏與公主長得像,于是被迫代替她去往敵國和親曲初。 傳聞我的和親對象是個殘疾皇子体谒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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

  • Git是目前最流行的版本管理系統(tǒng),也是最先進(jìn)的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,678評論 1 17
  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,456評論 1 26
  • 往生酒臼婆,往生已舊抒痒。 這不僅僅只是一杯酒。 它由世間所有游魂的執(zhí)念釀成颁褂,又能夠消解所有的執(zhí)念故响。 每個來到幽冥司的游魂...
    千琉閱讀 1,436評論 5 9
  • 你說你有理想 說你自己有面包和茶 還說了要嫁就嫁給幸福 為什么你卻帶來了這樣一個他 奔馳是他的座駕 別墅是他的家 ...
    讀云軒札記閱讀 273評論 0 0
  • 看看王者榮耀帶給了我那些收獲 今年一個偶然的機(jī)會開始下下載了王者榮耀游戲傀广,一開始覺得這游戲挺好玩的,輕輕松松的就上...
    簡明估閱讀 777評論 0 0