git圖解2:代碼回退

圖片描述

關於 git 的基本理解, 在第一篇git文章已介紹。 上一篇文章主要講解了git的提交操做, 本篇在上篇基礎上着重寫git代碼的逆向操做:代碼回退。網上關於git回退的文章比較多, 本文是我的理解實踐的彙總, 不當、不全之處請評論區指出。
首先,回顧下git代碼存在的5個區域, 分別是 工做區間工做現場緩存區(或叫暫存區)、本地倉庫(或叫當前分支)、遠程倉庫(或叫遠程分支);以下圖:
圖片描述html

1.緩存區代碼覆蓋工做區代碼

場景: 緩存區存有上次改動代碼,即以前有執行:git

git add

當前工做區間代碼想廢棄, 可將緩存區中代碼覆蓋之:github

clipboard.png

對應指令:segmentfault

// 將緩存區某一文件代碼 覆蓋本地工做區: 
git checkout -- testReset.txt

// 將匹配的文件覆蓋:
git checkout -- *.txt

// 將全部文件覆蓋:
git checkout -- .

2.本地倉庫代碼覆蓋緩存區代碼

場景:發現以前add的文件不須要了,又不想工做區間從新改回去。緩存

clipboard.png

對應指令:編輯器

// 將本地倉庫某一文件覆蓋緩存區: 
git reset HEAD testReset.txt 

// 將匹配的文件覆蓋緩存區:
git reset HEAD *.txt

// 將全部文件覆蓋緩存區:
git reset HEAD .

注意: 改變的是緩存區代碼, 工做區間代碼不變(編輯器代碼不會改變)學習

3.本地倉庫代碼覆蓋工做區代碼(經常使用)

上述兩場景在實際開發中沒那麼經常使用,接下來 本地倉庫 代碼 覆蓋 工做區間 代碼 則常常會用到。
場景: 當前 工做區間 代碼混亂(通常更新或合併分支後) , 廢棄當前改動;測試

clipboard.png

對應指令:網站

// 將本地倉庫某一文件代碼 覆蓋本地工做區: 
git checkout head testReset.txt

// 將本地倉庫全部文件代碼 覆蓋本地工做區:(謹慎操做):
git checkout head .

咱們知道本地倉庫中有一個commit列表, 記錄了全部commit的記錄, 查看commit列表指令:spa

// 查看commit id, 查看提交記錄(git commit的記錄)
git log 
git log --pretty=oneline 

// 查看以往提交歷史(包括 撤銷回退 記錄) 
git reflog

clipboard.png

根據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。

clipboard.png

對應指令:

// 本地工做區間代碼回退到遠程版本 
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區別圖:

clipboard.png

clipboard.png

5.遠程倉庫代碼回滾(線上代碼回滾)

場景: 提交了一個commit(該提交包含不少文件), 發現有問題, 須要回滾, 將線上分支(master)回滾到上一次commit;
網上有刪除分支進行線上代碼回滾的教程, 那種操做其實很危險, 由於通常線上的分支是master分支, 而這個分支不容許刪除。
合理一些的是使用 git reset或git revert方式進行回滾;
git reset方式圖解:

clipboard.png

git revert方式圖解:

clipboard.png

咱們可使用git revert將新的commit替換掉;(不用git reset而用git revert的緣由是保留commit方便後續代碼恢復)
對應指令:

// 替換掉上次提交的代碼文件(上次的commit記錄會保留)
git revert HEAD
git commit -m "回滾上次commit"
git push origin master

參考資料:
時光機穿梭 - 廖雪峯的官方網站
GitHub - wteam-xq/testGit: git學習、博文測試工程
Git HowTo: revert a commit already pushed to a remote repository

相關文章:
git圖解1:git 代碼區域總結;
git圖解3:git分支操做;

相關文章
相關標籤/搜索