- 原文地址:The Smart Ways to Correct Mistakes in Git
- 原文作者:Tobias Günther
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:EmilyQiRabbit
- 校對者:shixi-li,kezhenxu94
在軟體開發的世界,有無窮無盡的方法能夠把事情搞得一團糟:錯刪東西,程式碼混亂,提交資訊寫錯了字,這些都僅僅是冰山一角。
幸運的是,當我們使用版本控制時,Git 提供給我們了一個很完美的安全網。當然啦,不是我們倆需要它,因為我們從來不犯錯的,對吧?嗯嗯當然當然。但是為了他人的利益,我們還是一起來看看那些可以拯救我們的 Git “撤回”工具。
修改最後提交
搞砸一次提交非常容易。經典的場景包括:提交資訊裡寫了錯字。其他的?還有忘記將修改新增到臨時區(staging area)。還有很多時候,我們忽然意識到程式碼中有錯誤 —— 但是當然是在點選了提交的確認鍵之後。
幸運的是,Git 讓修改最後一次提交這件事出乎意料的簡單。假如我們剛剛確認了下面這個命令:
git commit -m "Massage full of typohs"
複製程式碼
並且(好像這個拼寫錯誤還沒那麼糟糕)假如我們還忘記了新增某個已經修改的檔案到臨時區。我們可以使用如下兩行命令修正這兩個錯誤:
git add forgotten-changes.js
git commit --amend -m "A sensible message"
複製程式碼
神奇之處就在於 --amend
標識:當我們跟著 commit 命令使用它的時候,Git 將會修改最後一次提交 —— 新增臨時區的修改,並替換為新的說明資訊。
但是有一點需要提示:只能在沒有推送到遠端倉庫的提交上使用 --amend
。原因是 Git 會用修改了的版本取代原來的,有錯誤的提交。這之後,看上去就像是原來的提交從來沒有過。是的,這種方式用來處理錯誤很好,但是必須是當我們還沒有將過這個錯誤釋出到遠端倉庫的時候。
撤銷本地修改
每個人都有類似的經歷:用了一早晨的時間尋找解決辦法,但是最後只好承認這幾個小時就是在浪費時間。必須從頭開始了,並且要撤銷大部分(或者所有)的程式碼。
但是這其實是使用 Git 的初衷之一 —— 它能讓你不用害怕破壞了什麼,而可以隨意的嘗試不同的方法。
讓我們來看一個例子:
git status
modified: about.html
deleted: imprint.html
modified: index.html
複製程式碼
現在我們假設,這些修改就是在前文說的浪費時間的場景。我們需要撤銷 about.html 的修改並且恢復已經刪除的 imprint.html。我們現在想要的就是,丟棄這些檔案當前的更改 —— 但是保留 index.html 中的超讚的已經寫好的程式碼。這時,git checkout
命令就能夠有所幫助。但是,我們需要像這樣指明是哪些檔案:
git checkout HEAD about.html imprint.html
複製程式碼
這行命令將 about.html 和 imprint.html 恢復到了最後提交的狀態。哎,我們可以不用熬夜來撤銷它們了!
我們可以更進一步,可以在一個修改過的檔案裡僅丟棄特定幾行程式碼,而不是恢復整個檔案!我必須承認,在命令列完成這項任務比較複雜,但使用 像 Tower 這樣的 Git 桌面客戶端 則是一個很好的方法:
在程式碼真的糟透了的時候,我們就想掏出一把大槍:
git reset --hard HEAD
複製程式碼
這次我們不是僅僅使用 checkout
恢復指定的檔案,而是重置了所有修改過的副本。換句話說,reset
將所有專案檔案恢復到了最後一次提交的狀態。和 --amend
類似,使用 checkout
和 reset
的時候需要牢記:使用這些命令丟棄的本地修改無法恢復!它們還從來沒有被提交到倉庫中,所以不能被恢復也是合理的。請確認你真的想要刪除它們,因為刪除了就沒法找回了!
撤銷並還原更早的提交
很多情況下,我們一段時間後才意識到程式碼的錯誤,而它已經被提交到倉庫裡很久了。
我們如何才能刪除掉這個錯誤的提交呢?答案是在大多數場景下,我們其實不應該這樣做。就算是“撤銷”內容的時候,通常情況下 Git 並沒有真的刪除資料。它通過新增新的資料來修正內容。用這個例子,我們來看看它是如何工作的:
git revert 2b504bee
複製程式碼
通過對這個提交執行 git revert
,我們並沒有刪除任何東西。相反的是:
Git 自動建立了一個新的提交來撤銷錯誤提交所造成的修改。所以,如果我們一開始有三個提交,然後試圖修正中間的那個,那麼我們就會有四個提交了,新增的那個用來修改 revert
的目標提交。
恢復專案之前的版本
另一個情境是我們希望恢復到專案之前的版本。我們不是僅僅撤銷提交歷史中的一個特定的版本,而是想讓時間倒流,直接退回到這個版本。
在下面的場景中,我們宣告“C2”之後的所有提交都是不需要的。我們想要回到“C2”這次提交的狀態,它之後的提交統統刪除:
根據我們已經講述過的內容,我想你已經(至少部分)熟悉了所需的命令:
git reset --hard 2b504bee
複製程式碼
這個命令通知了 git reset
我們想要返回的提交的 SHA-1 雜湊值。C3 和 C4 提交將會從專案歷史中消失。
如果你在使用 Git 客戶端,例如 Tower,提交專案的右鍵選單中的 git revert
和 git reset
兩者都可以使用:
刪除提交,恢復刪除的分支,處理衝突等等
當然,軟體專案中還有很多其他會把事情搞砸的方式。但是幸運的是,Git 提供了很多工具來撤銷錯誤。
如果你想要學習本篇文章提到的場景中的更多的內容,或者其他題目,例如如何在分支之間移動提交,刪除舊提交,恢復刪除的分支,或者優雅的處理衝突,看一下專案 "Git 急救包",它是我和其他一些 Tower 團隊的人建立的。這是一份完全免費的教程,包括了 17 個視訊以及一份很方便的備忘單,你可以下載並儲存到你的裝置上。
同時,祝你撤銷得愉快!
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。