[譯] 修改 Git 錯誤的高明方法

在軟件開發的世界,有無窮無盡的方法可以把事情搞得一團糟:錯刪東西,代碼混亂,提交信息寫錯了字,這些都僅僅是冰山一角。css

幸運的是,當咱們使用版本控制時,Git 提供給咱們了一個很完美的安全網。固然啦,不是咱倆須要它,由於咱們歷來不犯錯的,對吧?嗯嗯固然固然。可是爲了他人的利益,咱們仍是一塊兒來看看那些能夠拯救咱們的 Git 「撤回」工具。html

修改最後提交

搞砸一次提交很是容易。經典的場景包括:提交信息裏寫了錯字。其餘的?還有忘記將修改添加到臨時區(staging area)。還有不少時候,咱們突然意識到代碼中有錯誤 —— 可是固然是在點擊了提交的確認鍵以後。前端

幸運的是,Git 讓修改最後一次提交這件事出乎意料的簡單。假如咱們剛剛確認了下面這個命令:android

git commit -m "Massage full of typohs"
複製代碼

而且(好像這個拼寫錯誤還沒那麼糟糕)假如咱們還忘記了添加某個已經修改的文件到臨時區。咱們可使用以下兩行命令修正這兩個錯誤:ios

git add forgotten-changes.js
​​git commit --amend -m "A sensible message"
複製代碼

神奇之處就在於 --amend​ 標識:當咱們跟着 commit 命令使用它的時候,Git 將會修改最後一次提交 —— 添加臨時區的修改,並替換爲新的說明信息。git

可是有一點須要提示:只能在沒有推送到遠端倉庫的提交上使用 --amend。緣由是 Git 會用修改了的版本取代原來的,有錯誤的提交。這以後,看上去就像是原來的提交歷來沒有過。是的,這種方式用來處理錯誤很好,可是必須是當咱們尚未將過這個錯誤發佈到遠端倉庫的時候。github

撤銷本地修改

每一個人都有相似的經歷:用了一早晨的時間尋找解決辦法,可是最後只好認可這幾個小時就是在浪費時間。必須從頭開始了,而且要撤銷大部分(或者全部)的代碼。後端

可是這實際上是使用 Git 的初衷之一 —— 它能讓你不用懼怕破壞了什麼,而能夠隨意的嘗試不一樣的方法。安全

讓咱們來看一個例子:bash

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 revertgit reset 二者均可以使用:

刪除提交,恢復刪除的分支,處理衝突等等

固然,軟件項目中還有不少其餘會把事情搞砸的方式。可是幸運的是,Git 提供了不少工具來撤銷錯誤。

若是你想要學習本篇文章提到的場景中的更多的內容,或者其餘題目,例如如何在分支之間移動提交,刪除舊提交,恢復刪除的分支,或者優雅的處理衝突,看一下項目 "Git 急救包",它是我和其餘一些 Tower 團隊的人建立的。這是一份徹底免費的教程,包括了 17 個視頻以及一份很方便的備忘單,你能夠下載並保存到你的設備上。

同時,祝你撤銷得愉快!

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索