如何在git裡撤銷(幾乎)任何操作

2021-07-16 08:54:58 字數 3285 閱讀 3882

如何在git裡撤銷(幾乎)任何操作

一、撤銷乙個已經公開的改變

場景:已經執行了gitpush,將修改傳送到了github,需要撤銷某乙個commit。

方法:git revert二、修正最後乙個commit訊息

場景:在最後一條commit訊息裡有乙個筆誤,已經執行git commit –m』***』,但在push之前發現說明資訊有誤

方法:git commit–-amend 或者git commit –amend –m』正確的資訊』

原理:git commit–amend會用乙個新的commit更新並替換最近的commit,這個心的commit會把任何修改內容和上乙個commit的內容結合起來。如果當前沒有提出任何修改,這個操作會把上次的commit訊息重寫一遍。

三、撤銷本地修改

場景:git add後恢復,撤銷git add。

方法:git checkout– filename

此種撤銷會使任何修改完全消失,所以使用前最好用git diff確認下。

四、重置本地的修改

場景:在本地提交了一些東西(還沒有push),希望撤銷前面的三次提交。

方法:git reset 或git reset –hard

原理:git reset會把**庫歷史返回到指定的sha狀態。這樣就像這些提交從來沒有發生過。預設情況下,git reset會保留工作目錄。這樣提交是沒有了,但是修改內容還在磁碟上。這是一種安全選擇,但通常希望一步就撤銷提交及修改內容,這就是—hard選項的功能了。

五、在撤銷了本地修改之後再恢復

場景:提交了幾個commit後,用git reset –-hard撤銷了這些修改,希望還原這些修改。

方法:git reflog和git reset或git checkout

原理:git reflog對於恢復專案歷史是乙個超棒的資源。可以恢復幾乎任何東西——任何你commit過得東西。

一些注意事項:

l  它涉及的只是head的改變。在切換分支、用git commit進行提交、以及用git reset撤銷commit時,head都會改變,但是當用git checkout -- 時,head並不會改變,因此reflog也無法恢復。

l  git reflog不會永遠保持。git會定期清理那些用不到的物件,不要指望幾個月前的提交還在那裡。

l  不能用reflog來恢復另乙個開發者沒有push過得commit。

l  如果下網準確恢復專案的歷史到某個時間點,用gitreset—hard

l  如果希望重建工作目錄裡的乙個或多個檔案,讓它們恢復到某個時間點的狀態,用git checkout --

l  如果希望把這些commit裡的某乙個重新提交到**庫,用git cherry-pick

六、利用分支的另一種做法

場景:進行了一些提交,然後意識到開始check out的是master分支。希望提交到另乙個分支(feature)。

方法:git branchfeature,git reset –-hard origin/master,and git checkoutfeature

原理:gitcheckout –b 建立新的分支,這是建立新分支並馬上check out的流行捷徑,但是如果不希望馬上切換分支。這裡。git branch feature建立乙個叫做feature的新分支並指向最近的commit,但還是checkout在master分支上。下一步,在提及任何新的commit之前,用git reset –-hard把master分支倒回到origin/master。不過那些commit還在feature中。最後,用git checkout切換到新的feature分支,並且讓你最近所有的工作都完好無損。

七、在master繁殖的基礎上建立了feature分支,但master分支已經滯後origin/master很多。現在master分支已經和origin/master同步,你希望在feature上的提交從現在開始,而不是從滯後很多的地方開始。

方法:git checkoutfeature和git rebase master

原理:要達到這個效果,你本來可以通過git reset (不加,--hard,這樣可以在磁碟上保留修改)和git checkout –b 然後再重新提交修改,不過這樣做的話就會失去提交歷史。

git rebase master會做如下事情:

ø  首先他會找到你當前check out的分支和master分支的共同祖先。

ø  然後它reset當前check out的分支到那個共同祖先,在乙個臨時儲存區存放所有之前的提交。

ø  然後它把當前check out的分支提交到master的末尾部分,並從臨時儲存區重新把存放的commit提交到master分支的最後乙個commit之後。

八、大量的撤銷/恢復

場景:進行了很多次提交,但是發現只需要其中一部分,其他提交需要捨棄。

方法:git rebase–i

原理:-i 引數讓rebase進入「互動模式」。它開始類似於前面討論的rebase,但在重新進行提交之前,它會暫停下來並允許詳細修改每個提交。

rebase –i 會開啟你的預設文字編譯器,裡面列出候選的提交。前面兩列是鍵:第乙個是選定命令,對應第二列裡的sha確定的commit。預設情況下,rebase–i假定每個commit都要通過pick命令。

要丟棄乙個commit,只要在編輯器裡刪除那一行就可以了。如果你需要commit的內容,而是對commit訊息進行編輯,可以使用reword命令。把第一列裡的pick替換為reword(或者直接用r)。有人會覺得這裡直接重寫commit訊息就行了,但是這樣不管用rebase –i會忽略sha列前面的任何東西,它後面的文字只是來幫助我們記住這個commit是來幹嘛的。當你完成rebase –i的操作之後,你會被提示輸入需要編寫的任何commit訊息。

如果比需要把兩個commit合併到一起,可以使用squash或者fixup命令。squash和fixup會向上合併,帶有這兩個命令的commit會被合併它的前乙個commit裡。如果選擇squash,git會提示給新合併的commit乙個新的commit訊息;fixup則會把合併清單裡第乙個commit的訊息直接給新合併的commit。當你儲存並退出編輯器時,git會按從頂部到底部的順序運用你的commit。可以通過在儲存前修改commit順序來改變運用的順序。

九、停止追蹤乙個檔案

原理:雖然.gitignore會阻止git追蹤檔案的修改,甚至不關心檔案是否存在,但這只是針對於那些以前從來沒有追蹤過得檔案。一旦有個檔案被加入提交,git就會持續關注該檔案的改變。如果你希望從git的追蹤物件中刪除那個本應忽略的檔案,git rm –-cached會從追蹤物件中刪除它,但讓檔案在磁碟上保持原封不動。因為現在它已經被忽略了,你再git status裡就不會再看見這個檔案,也不會再偶然提交該檔案的修改了。

Git如何撤銷merge操作

方法一,reset 到 merge 前的版本,然後再重做接下來的操作,要求每個合作者都曉得怎麼將本地的 head 都回滾回去 git checkout 行merge操作時所在的分支 git reset hard merge前的版本號 方法二,當 merge 以後還有別的操作和改動時,git 正好也有...

Git如何撤銷merge操作

方法一,reset 到 merge 前的版本,然後再重做接下來的操作,要求每個合作者都曉得怎麼將本地的 head 都回滾回去 git checkout 行merge操作時所在的分支 git reset hard merge前的版本號 方法二,當 merge 以後還有別的操作和改動時,git 正好也有...

如何撤銷Git操作?(阮一峰)

git 版本管理時,往往需要撤銷某些操作。本文介紹幾種最主要的情況,給出詳細的解釋。更多的命令可以參考 常用 git 命令清單 一文。一種常見的場景是,提交 以後,你突然意識到這個提交有問題,應該撤銷掉,這時執行下面的命令就可以了。git revert head上面命令的原理是,在當前提交後面,新增...