Git必備技之隨意撤銷

Git作為一個版本管理系統(tǒng)(VCS)最基本的功能就是保證所有操作的追蹤和回退攻锰。但是晾嘶,很多初學者會被各種各樣的命令,各種參數(shù)給弄蒙了娶吞,加上命令行提示基本都是英文垒迂,所以就跟瞎子一樣,生怕一不小心把這弄丟了妒蛇,一不小心把庫弄壞了机断,pull不了,也push不了绣夺,不知道怎么辦了吏奸。實際上git中任何操作,包括破壞性陶耍、刪除性的操作都可以可以回退奋蔚。本文中蟲蟲就帶大家了解Git中各種撤消回退大法,等你熟悉了這些方法烈钞,可以讓你放開手一心只搞代碼泊碑,Git只是幫你插上翅膀,讓你在代碼庫中自由的翱翔毯欣。

分支策略(工作流)

Git是一個去中心化的分布式版本控制系統(tǒng)馒过,這意味著代碼倉的版本控制不是統(tǒng)一的,各個客戶端都是一個完整的倉庫酗钞,然后互相通過Git服務器基于commits進行變更的交換腹忽。為了避免這種多來源的變更導致混亂来累,開發(fā)人員必須遵循各自開發(fā)組工作流程(如果沒有的話,要制定一個)留凭,該流程取決于團隊內(nèi)部工作流程:如何撤消佃扼、如何更改某些變化?如何提交PR/MR蔼夜?如何審核和合并分支兼耀?。

有三個典型的協(xié)作流程:Git flow求冷,Github flow和 GitLab flow瘤运。利用可以在開發(fā)相同功能和無縫協(xié)作的情況下解決開發(fā)人員沖突和開發(fā)平衡。

Git flow

由Vincent Driessen提出匠题,主要是建立兩個長期分支Master和Devlop開發(fā)分支拯坟,同時又臨時性的功能分支、補丁分支和預發(fā)布分支韭山。版本衍變流程圖如下:

GitHub flow

Github flow 是Github提出的相比較Git flow簡配版郁季,是 Github網(wǎng)站使用的工作流程。

該流程簡練钱磅,主要為配合CI/CD(持續(xù)集成和發(fā)布)梦裂,實現(xiàn)快速迭代。

Gitlab flow

Gitlab flow結(jié)合了上面兩種流的優(yōu)點盖淡,是gitlab產(chǎn)品使用的方法年柠。Gitlab flow以master分支為基礎(chǔ),只有master接受的commit才可以合并得到其他分支

在該流程下褪迟,版本發(fā)布也是基于master分支來推進冗恨。

撤消本地的變化

在你沒有執(zhí)行push變化推送到遠程庫(Git服務器)之前,所有變化只會影響你自己味赃,不會影響其他人掀抹。所以你可以隨意處置這些變化,就算全部丟了心俗,也可以通過clone重新復制一份渴丸,你所丟失的只不過是本地一些變化,包括未push的歷史記錄(已經(jīng)commit未push)另凌,本地索引區(qū)staging(已經(jīng)add未commit)和工作區(qū)的變化(未add),以及我們在之前的文章《讓你提高工作效率的Git的技巧 》中提到的四種文件狀態(tài):已暫存 (Staged)戒幔,已修改(Modified),未修改(Unmodified)以及未跟蹤(Untracked)吠谢。

對于不同的階段的變化,撤銷的方法也各不相同:未分級的本地更改(在您提交之前)

未commit的工作區(qū)文件變化

對已經(jīng)更改但還沒有添加到暫存區(qū)的變化時诗茎,Git本身提供一種解決方案來撤銷對某個文件的更改工坊。假如我們我們編輯了一個文件vim <file>献汗,沒有添加的暫存區(qū),文件應為unstaged文件(如果文件已創(chuàng)建王污,未跟蹤Untracked)罢吃。可以通過git statu命令查看文件狀態(tài):

在該狀態(tài)下昭齐,你有三種方法選擇撤銷這個更改:

放棄所有本地更改尿招,但保存它們以便以后重復使用git stash 。

撤銷本地變化(永久丟棄)git checkout -- <file> 阱驾。

永久丟棄對所有文件的所有本地更改 git reset --hard 就谜。

快速保存本地更改(git stash)

你在開發(fā)正當中,接到一個緊急bug修復任務里覆。由于你功能沒完全寫丧荐,你沒法馬上就commit,但你需要換到另一個分支喧枷,以完成緊急的修復虹统。這時候你就需要祭出神器git stash來保存你時下的工作,切換到需要修復的分支隧甚,修復车荔,commit,push呻逆。再用git stash pop回到你的工作狀態(tài)夸赫,繼續(xù)寫你的代碼。

git stash 還支持如下其他操作:

git stash save xxx :可以在保存時添加備注信息(類似于commit信息)咖城,這這樣對于多個stash管理和識別將更加方便茬腿,設定備注信息后,可以在list中顯示這個信息宜雀。

git stash list :列出所有以前暫儲過的工作狀態(tài)(支持多次的git stash暫存)切平。

git stash pop :用戶回到上一個存儲的工作狀態(tài)并將其從stash存儲列表中刪除(類似于數(shù)組的pop的操作)。

git stash apply xxx : 回到指定的一個stach存儲列表的工作狀態(tài)辐董,但將不會從stashed列表中刪除悴品。

commit之前分階段的本地更改

假設已經(jīng)添加了一些文件到暫存區(qū),但是你不想在該該次commit中包含他們简烘。但是又不想撤銷對這些文件的修改苔严,只是想將他們從暫存區(qū)移除。當然如果你想撤銷這些變化的話孤澎,和上一部分提到那樣可使用git reset --hard或者git stash届氢。讓我們回到我們示例倉庫:

首先,用git status 看看目前的狀態(tài):

我要要從暫存去移除一些文件覆旭,比如我們移除four.txt:

git reset HEAD four.txt

結(jié)果退子,被移除的文件處于未跟蹤狀態(tài):

如果不添加文件岖妄,則會從暫存去移除所有的文件,但是文件修改都保存,都位于工作區(qū)寂祥。

git rest

可以使用git stash 保存所有工作區(qū)文件變化荐虐,以及添加到暫存區(qū)的文件狀態(tài),這是工作區(qū)會回到上一次commit狀態(tài)的文件狀態(tài)丸凭。但是可以之后隨時返回到該工作狀態(tài)福扬。

如果要丟棄所有文件變化,和暫存區(qū)的狀態(tài)贮乳,則使用git reset --hard忧换。結(jié)果和上一個方法類似趴捅。但是沒有stash的暫存項壕鹉,也無法在會到該工作狀態(tài)瘦馍。

commit的本地變更

commit提交后胸哥,版本控制系統(tǒng)就會正式記錄該變化板甘,以git對象的形式保存修改缺狠,進入歷史存檔丢间,可以push到遠程倉抱虐,并和其他人做版本交換颈将。在未push之前梢夯,該的修改是仍未公開(無法與其他開發(fā)者交換)。所以晴圾,做撤消操作不會影響別人颂砸,我們可以隨意操作。一旦代碼push到遠程倉死姚,我們的做撤銷操作就要格外注意了人乓,盡量不要影響,不然整改團隊都不能pull都毒,push色罚,別人會拿刀砍你,釀出血案的账劲。

不修改歷史(revert)

在實際的使用中戳护,有可能有些預先的commit可能最終不是預期要push到遠程倉的,或者是一個有bug的commit瀑焦。這是我們可以可以簡單地用git revert commit-id撤銷這個commit腌且。此命令會反轉(zhuǎn)該commit中的增加的git對象,并刪除commit榛瓮,它不會修改git歷史記錄铺董。

假設有以下順序提交的A,B榆芦,C柄粹,D,E提交:A-B-C-D-E匆绣,現(xiàn)在我們想要撤銷有問題代碼的到B的commit驻右。至于如何判別B是否bug問題,蟲蟲之前的文章中有提到過就是使用git bisect崎淳,這兒就不在詳述堪夭,可以關(guān)注蟲蟲,瀏覽以前的文章拣凹。git bisect A..??E

bisect會我們通過二分法reset到A到E之間的一個commit森爽,我們做測試,然后判斷代碼是否正常嚣镜,根據(jù)這個狀態(tài)來迭代知道找到問題的commit B爬迟。

撤銷B的commit引入的狀態(tài),我們使用:

git revert B-commit-id

如果僅僅是撤銷部分文件或者目錄菊匿,但是保存在暫存區(qū)付呕,則用:

git checkout B-commit-id <file>

如果要撤銷B的commit狀態(tài),并且暫存區(qū)移除則使用rest

git reset B-commit-i <file>

還有一個方法跌捆,我們也可以選用徽职,那就是創(chuàng)建一個新分支,從有問題的地方開一個bug分支佩厚。比如A-B-C-D歷史記錄姆钉,現(xiàn)在發(fā)現(xiàn)C和D有問題。這是除了我們重置到B commit抄瓦,并強推 F(這會導致與其他開發(fā)人員沖突)潮瓶。這是新的歷史揭露為A-B-F,大家都必須強制reset -f 才跟上你的push闺鲸。另一個更可取得方法是筋讨,不改變當前的歷史,從B開始新創(chuàng)建一個新的分支摸恍,并在該分支commit F悉罕。

git checkout B-commit-i

git checkout -b new-path-of-feature

git commit -a

修改commit歷史(rebase)

還有一個常用的修改的命令就死git rebase。他也提供-i選項實現(xiàn)交互式的操作立镶。在-i模式下壁袄,可以打開一個編輯器你在該編輯器中使用一些指令來操作commit歷史:

reword?commit信息還,編輯最近一次commit的消息媚媒。(可以用命令行g(shù)it commit --amend)

edit?編輯提交內(nèi)容(提交引入的修改)和消息

squash?將多個提交合并為一個提交嗜逻,并且提供自定義或整合的commit消息

drop?刪除commit

我們來舉個實例。假想現(xiàn)在我們的倉庫歷史為all-hello-new缭召,要刪除hello栈顷。

rebase當前提交范圍:

git rebase -i fbaf080184ed

命令打開你默認的編輯器逆日,你編輯其中只需寫下指令drop New,但你保留所有其他pick提交的默認內(nèi)容萄凤。

保存并退出編輯會自動執(zhí)行rebase室抽。結(jié)果:

如果你想修改commit hello中引入的東西,類似的方法:

git rebase -i fbaf08018

命令打開編輯器靡努,您可以在提交前編寫edit new坪圾,但保留所有其他pick提交的默認內(nèi)容。

保存并退出編輯器執(zhí)行惑朦,進行編輯和提交更改:

git commit -a

反悔你的撤消

有時你撤銷了一些修改兽泄,但是又發(fā)現(xiàn)這些修改還是有用的,又想反悔漾月。通過命令git reflog我們可以追回所有已經(jīng)分離的(git log不顯示)commit-id病梢。

要查看存儲庫歷史記錄并跟蹤舊提交,可以使用以下命令:

git reflog show

輸出顯示存儲庫的歷史記錄栅屏。第一列為commit-id飘千,其他列HEAD旁邊的數(shù)字表示之前commit了多少次,可以當做下表來做引用該次的commit栈雳,在git命令(commit护奈,rebase,merge哥纫,...)中當做參數(shù)代替commit-id使用霉旗,最后一列該記錄的描述。

撤銷遠程倉中的變更

不修改commit歷史撤消遠程變更

這操作和修改本地提交的本地不修改歷史撤銷更改大致相同蛀骇。它是撤消任何遠程庫上或者公共分支的commit的首選方法厌秒。對這種需求,最好的的方法是使用分支擅憔,分支使能夠在新開發(fā)中引入現(xiàn)有修改(通過合并)和還可以提供了明確的commit時間序列和開發(fā)結(jié)構(gòu)鸵闪。

要撤銷某些commit-id中引入的更改,我們可以通過revert簡單地創(chuàng)建的commit中恢復commit-id(置換添加和刪除)暑诸,比如上圖的需求刪除B蚌讼,我們可以通過revert

git revert B-commit-id

或創(chuàng)建一個新分支:

git checkout B-commit-id

git checkout -b new-path-of-feature

修改歷史記錄的撤消遠程更改

當你想隱藏遠程倉中有些敏感新的信息時候,則必須要用該方法(一般不要用个榕,不然結(jié)果見第三部的圖)篡石。比如倉庫中包含了token,密碼西采,SSH私鑰等凰萨。這樣做的會讓你失去了真正的commit 歷史進程。還要注意的是,即便是修改了歷史記錄胖眷,commit被分離(detach了)武通,依然可以通過commit-id訪問(git沒有執(zhí)行自動清理分離commit之前)。 還有就是別人如果還沒有同步該修改珊搀,他客戶端里的信息也是完全的厅须。

修改歷史記錄

確定好要修改的內(nèi)容之后(歷史記錄的范圍或范圍舊提交),使用git rebase -i commit-id食棕。然后,此命令將顯示所有提交當前版本選擇commit-id并允許修改错沽,壓縮簿晓,刪除提交。

git rebase -i commit1-id..commit3-id

然后根據(jù)我們第三部分提到指令做修改千埃。

修改后憔儿,通過git push -f強制推送到遠程庫生效(慎用慎用慎用!)放可。

篩選要刪除的敏感信息文件(git filter-branch)

Git還允許從過去的提交中刪除敏感信息谒臼。我們可以使用行g(shù)it filter-branch,它允許我們對rebase歷史記錄做過濾耀里。這個命令也是通過rebase修改歷史記錄蜈缤,比如要刪除某些歷史記錄歷史文件一共使用:

git filter-branch --tree-filter 'rm filename' HEAD

注意git filter-branch命令在大型庫上可會很慢。還有一些相對較快的冯挎,讓我們篩選特定文件的第三方工具底哥,比如BFG Repo-cleaner

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末房官,一起剝皮案震驚了整個濱河市趾徽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翰守,老刑警劉巖孵奶,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜡峰,居然都是意外死亡了袁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門事示,熙熙樓的掌柜王于貴愁眉苦臉地迎上來早像,“玉大人,你說我怎么就攤上這事肖爵÷校” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冀自。 經(jīng)常有香客問我揉稚,道長,這世上最難降的妖魔是什么熬粗? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任搀玖,我火速辦了婚禮,結(jié)果婚禮上驻呐,老公的妹妹穿的比我還像新娘灌诅。我一直安慰自己,他們只是感情好含末,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布猜拾。 她就那樣靜靜地躺著,像睡著了一般佣盒。 火紅的嫁衣襯著肌膚如雪挎袜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天肥惭,我揣著相機與錄音盯仪,去河邊找鬼。 笑死蜜葱,一個胖子當著我的面吹牛全景,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牵囤,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蚪燕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奔浅?” 一聲冷哼從身側(cè)響起馆纳,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汹桦,沒想到半個月后鲁驶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡舞骆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年钥弯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片督禽。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡脆霎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狈惫,到底是詐尸還是另有隱情睛蛛,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站忆肾,受9級特大地震影響荸频,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜客冈,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一旭从、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧场仲,春花似錦和悦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至褐健,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澜汤,已是汗流浹背蚜迅。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留俊抵,地道東北人谁不。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像徽诲,于是被迫代替她去往敵國和親刹帕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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

  • Git是目前最流行的版本管理系統(tǒng)谎替,也是最先進的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,707評論 1 17
  • Git 基礎(chǔ) 基本原理 客戶端并不是只提取最新版本的文件快照偷溺,而是把代碼倉庫完整的鏡像下來。這樣一來钱贯,任何一處協(xié)同...
    __silhouette閱讀 15,887評論 5 147
  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,486評論 1 26
  • 新學期又開始了挫掏。 元宵節(jié)的上午9點,學校開學大會上秩命,各位領(lǐng)導輪番上陣尉共。或強調(diào)規(guī)章制度弃锐,或宣揚奉獻精神吃虧精神袄友,或批...
    塵緣心語閱讀 160評論 0 0
  • 我們常常有一個既定的偏見是,覺得擅于社交券敌、友善開朗唾戚、性格外向就勢必喜歡熱鬧、熱衷于社交場合待诅,而相反的喜歡獨處叹坦、...
    金勇Maya閱讀 386評論 0 2