文章導(dǎo)航河?xùn)|軟件園軟件下載安卓資源Mac軟件驅(qū)動(dòng)資源
時(shí)間:2015-07-02 10:04作者:本站來(lái)源:本站整理人氣:180我要評(píng)論(0)
如果你在使用電腦時(shí)無(wú)意將私人信息傳播出去了,該怎么撤回呢?很多人都會(huì)有這種困擾,因?yàn)樽约旱囊粫r(shí)疏忽,很有可能造成不必要的影響,現(xiàn)在Linux系統(tǒng)中有個(gè)Git撤銷設(shè)置,可以在Git里面撤銷掉一些錯(cuò)誤的操作,因?yàn)槟忝看尾僮麟娔X的時(shí)候,git都會(huì)保存之前的快照,想要撤銷之前的步驟的話只要?jiǎng)h除就可以了。下面小編就和大家分享這個(gè)操作方法,Linux系統(tǒng)如何在Git里撤銷操作。
當(dāng)你進(jìn)行一次新的提交的時(shí)候,Git 會(huì)保存你代碼庫(kù)在那個(gè)特定時(shí)間點(diǎn)的快照;之后,你可以利用 Git 返回到你的項(xiàng)目的一個(gè)早期版本。
在本篇博文里,我會(huì)講解某些你需要“撤銷”已做出的修改的常見場(chǎng)景,以及利用 Git 進(jìn)行這些操作的最佳方法。
撤銷一個(gè)“已公開”的改變
場(chǎng)景: 你已經(jīng)執(zhí)行了 git push, 把你的修改發(fā)送到了 GitHub,現(xiàn)在你意識(shí)到這些 commit 的其中一個(gè)是有問題的,你需要撤銷那一個(gè) commit.
方法: git revert 《SHA》
原理: git revert 會(huì)產(chǎn)生一個(gè)新的 commit,它和指定 SHA 對(duì)應(yīng)的 commit 是相反的(或者說(shuō)是反轉(zhuǎn)的)。如果原先的 commit 是“物質(zhì)”,新的 commit 就是“反物質(zhì)” — 任何從原先的 commit 里刪除的內(nèi)容會(huì)在新的 commit 里被加回去,任何在原先的 commit 里加入的內(nèi)容會(huì)在新的 commit 里被刪除。
這是 Git 最安全、最基本的撤銷場(chǎng)景,因?yàn)樗⒉粫?huì)改變歷史 — 所以你現(xiàn)在可以 git push 新的“反轉(zhuǎn)” commit 來(lái)抵消你錯(cuò)誤提交的 commit。
修正最后一個(gè) commit 消息
場(chǎng)景: 你在最后一條 commit 消息里有個(gè)筆誤,已經(jīng)執(zhí)行了 git commit -m “Fxies bug #42”,但在 git push 之前你意識(shí)到消息應(yīng)該是 “Fixes bug #42″。
方法: git commit --amend 或 git commit --amend -m “Fixes bug #42”
原理: git commit --amend 會(huì)用一個(gè)新的 commit 更新并替換最近的 commit ,這個(gè)新的 commit 會(huì)把任何修改內(nèi)容和上一個(gè) commit 的內(nèi)容結(jié)合起來(lái)。如果當(dāng)前沒有提出任何修改,這個(gè)操作就只會(huì)把上次的 commit 消息重寫一遍。
撤銷“本地的”修改
場(chǎng)景: 一只貓從鍵盤上走過,無(wú)意中保存了修改,然后破壞了編輯器。不過,你還沒有 commit 這些修改。你想要恢復(fù)被修改文件里的所有內(nèi)容 — 就像上次 commit 的時(shí)候一模一樣。
方法: git checkout -- 《bad filename》
原理: git checkout 會(huì)把工作目錄里的文件修改到 Git 之前記錄的某個(gè)狀態(tài)。你可以提供一個(gè)你想返回的分支名或特定 SHA ,或者在缺省情況下,Git 會(huì)認(rèn)為你希望 checkout 的是 HEAD,當(dāng)前 checkout 分支的最后一次 commit。
記?。耗阌眠@種方法“撤銷”的任何修改真的會(huì)完全消失。因?yàn)樗鼈儚膩?lái)沒有被提交過,所以之后 Git 也無(wú)法幫助我們恢復(fù)它們。你要確保自己了解你在這個(gè)操作里扔掉的東西是什么?。ㄒ苍S可以先利用 git diff 確認(rèn)一下)
重置“本地的”修改
場(chǎng)景: 你在本地提交了一些東西(還沒有 push),但是所有這些東西都很糟糕,你希望撤銷前面的三次提交 — 就像它們從來(lái)沒有發(fā)生過一樣。
方法: git reset 《last good SHA》 或 git reset --hard 《last good SHA》
原理: git reset 會(huì)把你的代碼庫(kù)歷史返回到指定的 SHA 狀態(tài)。 這樣就像是這些提交從來(lái)沒有發(fā)生過。缺省情況下, git reset 會(huì)保留工作目錄。這樣,提交是沒有了,但是修改內(nèi)容還在磁盤上。這是一種安全的選擇,但通常我們會(huì)希望一步就“撤銷”提交以及修改內(nèi)容 — 這就是 --hard 選項(xiàng)的功能。
在撤銷“本地修改”之后再恢復(fù)
場(chǎng)景: 你提交了幾個(gè) commit,然后用 git reset --hard 撤銷了這些修改(見上一段),接著你又意識(shí)到:你希望還原這些修改!
方法: git reflog 和 git reset 或 git checkout
原理: git reflog 對(duì)于恢復(fù)項(xiàng)目歷史是一個(gè)超棒的資源。你可以恢復(fù)幾乎 任何東西 — 任何你 commit 過的東西 — 只要通過 reflog。
你可能已經(jīng)熟悉了 git log 命令,它會(huì)顯示 commit 的列表。 git reflog 也是類似的,不過它顯示的是一個(gè) HEAD 發(fā)生改變的時(shí)間列表。
一些注意事項(xiàng):
它涉及的只是 HEAD 的改變。在你切換分支、用 git commit 進(jìn)行提交、以及用 git reset 撤銷 commit 時(shí),HEAD 會(huì)改變,但當(dāng)你用 git checkout -- 《bad filename》 撤銷時(shí)(正如我們?cè)谇懊嬷v到的情況),HEAD 并不會(huì)改變 — 如前所述,這些修改從來(lái)沒有被提交過,因此 reflog 也無(wú)法幫助我們恢復(fù)它們。
git reflog 不會(huì)永遠(yuǎn)保持。Git 會(huì)定期清理那些 “用不到的” 對(duì)象。不要指望幾個(gè)月前的提交還一直躺在那里。
你的 reflog 就是你的,只是你的。你不能用 git reflog 來(lái)恢復(fù)另一個(gè)開發(fā)者沒有 push 過的 commit。
那么…你怎么利用 reflog 來(lái)“恢復(fù)”之前“撤銷”的 commit 呢?它取決于你想做到的到底是什么:
如果你希望準(zhǔn)確地恢復(fù)項(xiàng)目的歷史到某個(gè)時(shí)間點(diǎn),用 git reset --hard 《SHA》
如果你希望重建工作目錄里的一個(gè)或多個(gè)文件,讓它們恢復(fù)到某個(gè)時(shí)間點(diǎn)的狀態(tài),用 git checkout 《SHA》 -- 《filename》
如果你希望把這些 commit 里的某一個(gè)重新提交到你的代碼庫(kù)里,用 git cherry-pick 《SHA》
利用分支的另一種做法
場(chǎng)景: 你進(jìn)行了一些提交,然后意識(shí)到你開始 check out 的是 master 分支。你希望這些提交進(jìn)到另一個(gè)特性(feature)分支里。
方法: git branch feature, git reset --hard origin/master, and git checkout feature
原理: 你可能習(xí)慣了用 git checkout -b 《name》 創(chuàng)建新的分支 — 這是創(chuàng)建新分支并馬上 check out 的流行捷徑 — 但是你不希望馬上切換分支。這里, git branch feature 創(chuàng)建一個(gè)叫做 feature 的新分支并指向你最近的 commit,但還是讓你 check out 在 master 分支上。
下一步,在提交任何新的 commit 之前,用 git reset --hard 把 master 分支倒回 origin/master。不過別擔(dān)心,那些 commit 還在 feature 分支里。
最后,用 git checkout 切換到新的 feature 分支,并且讓你最近所有的工作成果都完好無(wú)損。
及時(shí)分支,省去繁瑣
場(chǎng)景: 你在 master 分支的基礎(chǔ)上創(chuàng)建了 feature 分支,但 master 分支已經(jīng)滯后于 origin/master 很多?,F(xiàn)在 master 分支已經(jīng)和 origin/master 同步,你希望在 feature 上的提交是從現(xiàn)在開始,而不是也從滯后很多的地方開始。
方法: git checkout feature 和 git rebase master
原理: 要達(dá)到這個(gè)效果,你本來(lái)可以通過 git reset (不加 --hard, 這樣可以在磁盤上保留修改) 和 git checkout -b 《new branch name》 然后再重新提交修改,不過這樣做的話,你就會(huì)失去提交歷史。我們有更好的辦法。
git rebase master 會(huì)做如下的事情:
首先它會(huì)找到你當(dāng)前 check out 的分支和 master 分支的共同祖先。
然后它 reset 當(dāng)前 check out 的分支到那個(gè)共同祖先,在一個(gè)臨時(shí)保存區(qū)存放所有之前的提交。
然后它把當(dāng)前 check out 的分支提到 master 的末尾部分,并從臨時(shí)保存區(qū)重新把存放的 commit 提交到 master 分支的最后一個(gè) commit 之后。
大量的撤銷/恢復(fù)
場(chǎng)景: 你向某個(gè)方向開始實(shí)現(xiàn)一個(gè)特性,但是半路你意識(shí)到另一個(gè)方案更好。你已經(jīng)進(jìn)行了十幾次提交,但你現(xiàn)在只需要其中的一部分。你希望其他不需要的提交統(tǒng)統(tǒng)消失。
方法: git rebase -i 《earlier SHA》
原理: -i 參數(shù)讓 rebase 進(jìn)入“交互模式”。它開始類似于前面討論的 rebase,但在重新進(jìn)行任何提交之前,它會(huì)暫停下來(lái)并允許你詳細(xì)地修改每個(gè)提交。
rebase -i 會(huì)打開你的缺省文本編輯器,里面列出候選的提交。如下所示:
前面兩列是鍵:第一個(gè)是選定的命令,對(duì)應(yīng)第二列里的 SHA 確定的 commit。缺省情況下, rebase -i 假定每個(gè) commit 都要通過 pick 命令被運(yùn)用。
要丟棄一個(gè) commit,只要在編輯器里刪除那一行就行了。如果你不再需要項(xiàng)目里的那幾個(gè)錯(cuò)誤的提交,你可以刪除上例中的1、3、4行。
如果你需要保留 commit 的內(nèi)容,而是對(duì) commit 消息進(jìn)行編輯,你可以使用 reword 命令。 把第一列里的 pick 替換為 reword (或者直接用 r)。有人會(huì)覺得在這里直接重寫 commit 消息就行了,但是這樣不管用 —rebase -i 會(huì)忽略 SHA 列前面的任何東西。它后面的文本只是用來(lái)幫助我們記住 0835fe2 是干啥的。當(dāng)你完成 rebase -i 的操作之后,你會(huì)被提示輸入需要編寫的任何 commit 消息。
如果你需要把兩個(gè) commit 合并到一起,你可以使用 squash 或 fixup 命令,如下所示:
squash 和 fixup 會(huì)“向上”合并 — 帶有這兩個(gè)命令的 commit 會(huì)被合并到它的前一個(gè) commit 里。在這個(gè)例子里, 0835fe2 和 6943e85 會(huì)被合并成一個(gè) commit, 38f5e4e 和 af67f82 會(huì)被合并成另一個(gè)。
如果你選擇了 squash, Git 會(huì)提示我們給新合并的 commit 一個(gè)新的 commit 消息; fixup 則會(huì)把合并清單里第一個(gè) commit 的消息直接給新合并的 commit 。 這里,你知道 af67f82 是一個(gè)“完了完了…?!?的 commit,所以你會(huì)留著 38f5e4e 的 commit 消息,但你會(huì)給合并了 0835fe2 和 6943e85 的新 commit 編寫一個(gè)新的消息。
在你保存并退出編輯器的時(shí)候,Git 會(huì)按從頂部到底部的順序運(yùn)用你的 commit。你可以通過在保存前修改 commit 順序來(lái)改變運(yùn)用的順序。如果你愿意,你也可以通過如下安排把 af67f82 和 0835fe2 合并到一起:
修復(fù)更早期的 commit
場(chǎng)景: 你在一個(gè)更早期的 commit 里忘記了加入一個(gè)文件,如果更早的 commit 能包含這個(gè)忘記的文件就太棒了。你還沒有 push,但這個(gè) commit 不是最近的,所以你沒法用 commit --amend.
方法: git commit --squash 《SHA of the earlier commit》 和 git rebase --autosquash -i 《even earlier SHA》
原理: git commit --squash 會(huì)創(chuàng)建一個(gè)新的 commit ,它帶有一個(gè) commit 消息,類似于 squash! Earlier commit。 (你也可以手工創(chuàng)建一個(gè)帶有類似 commit 消息的 commit,但是 commit --squash 可以幫你省下輸入的工作。)
如果你不想被提示為新合并的 commit 輸入一條新的 commit 消息,你也可以利用 git commit --fixup 。在這個(gè)情況下,你很可能會(huì)用commit --fixup ,因?yàn)槟阒皇窍M?rebase 的時(shí)候使用早期 commit 的 commit 消息。
rebase --autosquash -i 會(huì)激活一個(gè)交互式的 rebase 編輯器,但是編輯器打開的時(shí)候,在 commit 清單里任何 squash! 和 fixup! 的 commit 都已經(jīng)配對(duì)到目標(biāo) commit 上了,如下所示:
在使用 --squash 和 --fixup 的時(shí)候,你可能不記得想要修正的 commit 的 SHA 了— 只記得它是前面第 1 個(gè)或第 5 個(gè) commit。你會(huì)發(fā)現(xiàn) Git 的 ^ 和 ~ 操作符特別好用。HEAD^ 是 HEAD 的前一個(gè) commit。 HEAD~4 是 HEAD 往前第 4 個(gè) – 或者一起算,倒數(shù)第 5 個(gè) commit。
停止追蹤一個(gè)文件
場(chǎng)景: 你偶然把 application.log 加到代碼庫(kù)里了,現(xiàn)在每次你運(yùn)行應(yīng)用,Git 都會(huì)報(bào)告在 application.log 里有未提交的修改。你把 *.login 放到了 .gitignore 文件里,可文件還是在代碼庫(kù)里 — 你怎么才能告訴 Git “撤銷” 對(duì)這個(gè)文件的追蹤呢?
方法: git rm --cached application.log
原理: 雖然 .gitignore 會(huì)阻止 Git 追蹤文件的修改,甚至不關(guān)注文件是否存在,但這只是針對(duì)那些以前從來(lái)沒有追蹤過的文件。一旦有個(gè)文件被加入并提交了,Git 就會(huì)持續(xù)關(guān)注該文件的改變。類似地,如果你利用 git add -f 來(lái)強(qiáng)制或覆蓋了 .gitignore, Git 還會(huì)持續(xù)追蹤改變的情況。之后你就不必用-f 來(lái)添加這個(gè)文件了。
如果你希望從 Git 的追蹤對(duì)象中刪除那個(gè)本應(yīng)忽略的文件, git rm --cached 會(huì)從追蹤對(duì)象中刪除它,但讓文件在磁盤上保持原封不動(dòng)。因?yàn)楝F(xiàn)在它已經(jīng)被忽略了,你在 git status 里就不會(huì)再看見這個(gè)文件,也不會(huì)再偶然提交該文件的修改了。
GIT操作里面有很多說(shuō)法,不是單純的撤銷就可以完成的,以上的教程可以帶大家對(duì)于Git功能有個(gè)大致的了解,但是具體的操作還是要根據(jù)使用說(shuō)明來(lái)的,希望大家可以派到用場(chǎng)!
相關(guān)閱讀 Ubuntu17.10在系統(tǒng)頂端顯示日期、秒數(shù)的方法Ubuntu17.10通過dpi更改系統(tǒng)字體大小比例的方法Ubuntu17.10安裝中文輸入法的方法解決ubuntu16.04軟件圖標(biāo)無(wú)法顯示在控制欄的方法處理ubuntu 16.04提示解壓失敗或解壓錯(cuò)誤的方法修改Ubuntu 16.04啟動(dòng)器顯示位置的方法Linux mint屏幕邊緣設(shè)置功能的方法處理ubuntu運(yùn)行軟件不顯示軟件窗口的方法ubuntu17.10修改桌面圖標(biāo)大小的方法在linux系統(tǒng)中修改賬戶密碼的方法
熱門文章 解決linux虛擬機(jī)無(wú)法上網(wǎng)的教程linux查看cpu使用率的方法ubuntu16.04下安裝配置genymotion安卓模擬器的方法處理ubuntu 16.04提示解壓失敗或解壓錯(cuò)誤的方法
最新文章
Ubuntu17.10在系統(tǒng)頂端顯示日期、秒數(shù)的方法Ubuntu17.10通過dpi更改系統(tǒng)字體大小比例的方法
Ubuntu17.10安裝中文輸入法的方法解決ubuntu16.04軟件圖標(biāo)無(wú)法顯示在控制欄的方法處理ubuntu 16.04提示解壓失敗或解壓錯(cuò)誤的方法修改Ubuntu 16.04啟動(dòng)器顯示位置的方法
人氣排行 解決linux虛擬機(jī)無(wú)法上網(wǎng)的教程linux查看cpu使用率的方法ubuntu16.04下安裝配置genymotion安卓模擬器的方法處理ubuntu 16.04提示解壓失敗或解壓錯(cuò)誤的方法解決ubuntu安裝網(wǎng)易云音樂失敗的方法Linux下IntelliJ IDEA 2017的安裝破解教程處理ubuntu運(yùn)行軟件不顯示軟件窗口的方法解決ubuntu16.04軟件圖標(biāo)無(wú)法顯示在控制欄的方法
蓋樓回復(fù)X
(您的評(píng)論需要經(jīng)過審核才能顯示)