清華大佬耗費(fèi)三個(gè)月吐血整理的幾百G的資源,免費(fèi)分享!....>>>
版本控制系統(tǒng)的一個(gè)好處就是你可以輕易地撤銷之前錯(cuò)誤的操作。
當(dāng)你用 git commit 提交了一個(gè)新的更改后 git 會(huì)將當(dāng)時(shí)的文件內(nèi)容暫時(shí)保存下來,之后你就可以用 git 隨意回滾到任意一個(gè)版本。
這篇文章會(huì)介紹一些常見的可能用到撤銷 undo 操作的情況。
撤銷一個(gè)已發(fā)布的更新
情景: 你已經(jīng)用 git push 將代碼提交到了 GitHub,然后你意識(shí)到這其中的一個(gè) commit 有錯(cuò)誤,于是你想撤銷那個(gè) commit。
操作: git revert <SHA>
效果: git 會(huì)新建一個(gè)新的 commit 來執(zhí)行提供的 對(duì)應(yīng) commit 的相反的更改,任何在該舊 commit 中刪除的內(nèi)容將會(huì)在新 commit 中添加進(jìn)去,反之亦然。
這是 git 里最安全的撤消操作的辦法,因?yàn)檫@不會(huì)影響你的提交歷史。于是現(xiàn)在你可以提交新的 commit 去撤銷之前錯(cuò)誤的操作了。
修改上次 commit 的提交信息
情景: 你在上次 commit 提交信息中打錯(cuò)了一個(gè)單詞,比如你執(zhí)行了git commit -m "fxied bug #42" 然后你意識(shí)到應(yīng)該是 fixed bug #42。
操作: git commit --amend 或 git commit --amend -m "Fixes bug #42"
效果: git commit --amend 結(jié)合最新的文件修改情況和上一次提交信息更新并替換上一次提交。沒有新的文件更改就直接覆蓋上次提交。
撤銷本地修改
情景: 你家的喵星人跑到你的鍵盤上裝逼用雙爪打字然后不知怎么還點(diǎn)了保存,然后編輯器還崩潰了,你還沒有 commit 這只貓做的修改,你想撤銷那個(gè)文件里被貓修改的內(nèi)容。
操作: git checkout -- <bad filename>
效果: git checkout 會(huì)將該文件的內(nèi)容恢復(fù)到上一次 git commit 的狀態(tài)。你可以提供一個(gè)分支名稱或者直接提供要回到的 SHA。
請(qǐng)記住,這種方法作出的撤銷是徹底的,這些內(nèi)容不會(huì)被 commit 所以之后你并不能再用 git 恢復(fù)這些內(nèi)容。
重置本地修改
情景: 你在本地 commit 了一些內(nèi)容(并沒有 push),但是你搞錯(cuò)了,你想撤銷最近這三個(gè) commit,就像讓它們從來不存在那樣。
操作: git reset <last good SHA> 或 git reset --hard <last good SHA>
效果: git reset 會(huì)讓你的 git 歷史會(huì)退到你指定的 SHA 的狀態(tài)。這些 commit 不存在了但是你硬盤上的這些文件還是維持在被修改了的狀態(tài),這是最安全的做法。但是有時(shí)你也想同時(shí)撤銷硬盤上的修改,這時(shí)加上 --hard 就會(huì)很有用。
撤銷本地修改之后重做
情景: 你提交了一些 commit,然后執(zhí)行 git reset --hard 來撤消這些 commit 并清除本地硬盤上的修改。但是最后你意識(shí)到你想要回這些 commit!
操作: git reflog 和 git reset 或 git checkout
效果: git reflog 是個(gè)修復(fù)項(xiàng)目提交歷史的好方法。你可以找回幾乎所有內(nèi)容 —— 所有你 commit 過的內(nèi)容 —— 用 reflog 就行。
你可能對(duì) git log 很熟悉,這個(gè)操作會(huì)列出你的 git 提交歷史。git reflog 很像它,但是列出的是 HEAD 修改的時(shí)間。
一些說明:
- HEAD 修改。在切換分支時(shí) HEAD 會(huì)被修改,用 commit 保存修改然后用 reset 撤消修改。但是在你 git checkout -- <bad filename> 時(shí)并不會(huì)被修改,就像上面說過的那樣,這些修改不會(huì)被 commit,所以 git reflog 也不能幫你找回這些內(nèi)容。
- git reflog 不是永遠(yuǎn)有用的。git 會(huì)定期清理那些無法追溯的內(nèi)容。不要期望能用git reflog 找回一個(gè)多月以前的內(nèi)容。
- 你的 git reflog 僅對(duì)你有用。你不能用 git reflog 來找回其他人 commit 的修改。
然后…接下來怎么做才能撤銷之前的撤銷?這取決你到你要干什么:
- 如果你想回到一個(gè)特定的時(shí)間,用 git reset --hard <SHA>。
- 如果你想在不修改提交歷史的情況下找回那些文件并作為新文件保存,用git checkout <SHA> -- <filename>。
- 如果你想使其中一個(gè) commit 回到你的項(xiàng)目歷史中,用 git cherry-pick <SHA>。
提交到了另一個(gè)分支
情景: 你提交了一些 commits,然后意識(shí)到你當(dāng)前是在 master 分支上,而你其實(shí)是想提交到一個(gè) feature 分支上。
操作: git branch feature, git reset --hard origin/master, 和git checkout feature
效果: 你可能常常使用 git checkout -b <name> 操作來檢出一個(gè)新分支,這是一個(gè)很方便的創(chuàng)建新分支的操作,但是你并不想同時(shí)切換到那個(gè)分支上?,F(xiàn)在使用git branch feature 既可以創(chuàng)建一個(gè) feature 新分支并且不會(huì)切換到那個(gè)分支,同時(shí)該分支會(huì)指向你當(dāng)前分支最新的一個(gè) commit。
下一步,用 git reset --hard 去恢復(fù) master 分支到 origin/master 的狀態(tài)。
最后,git checkout 到你的 feature 分支,你能看到所有的更改。
覆蓋整個(gè)分支
情景: 你基于 master 分支創(chuàng)建了 feature 分支,但是 master 分支遠(yuǎn)遠(yuǎn)落后origin/master 的更改?,F(xiàn)在 master 分支和 origin/master 同步了,你想馬上同步到 feature 分支,還不是再次遠(yuǎn)遠(yuǎn)落后。
操作: git checkout feature 和 git rebase master
效果: 你可能知道用 git reset 然后重新 commit 來達(dá)到類似效果,不過那樣會(huì)丟失 commit 歷史。
本文乃原文常用部分譯文: How to undo (almost) anything with Git —— 作者: jaw6
掃碼二維碼 獲取免費(fèi)視頻學(xué)習(xí)資料
- 本文固定鏈接: http://www.wangchenghua.com/j/git/1001038/
- 免費(fèi): Python視頻資料獲取