1 本地修改
由于以下修改本身是對版本曆史的修改,在需要push到遠端倉庫時,往往是不成功的,隻能強行push,這樣會出現的一個問題就是,如果你是push到多人協作的遠端倉庫中,會對其他人的遠端操作構成影響。通常情況下,建議與項目遠端倉庫的管理者進行溝通,在完成你強制push操作後,通知其他人同步。
1.1 修改最近一次的commit修改送出的描述git commit --amend
然後會進入一個文本編輯器界面,修改commit的描述内容,即可完成操作。修改送出的檔案git add # 或者 git rmgit commit --amend # 将緩存區的内容做為最近一次送出
1.2 修改任意送出曆史位置的commit
可以通過變基指令,修改最近一次送出以前的某次送出。不過修改的送出到目前送出之間的所有送出的hash值都會改變。
變基操作需要非常小心,一定要多用git status指令來檢視你是否還處于變基操作,可能某次誤操作的會對後面的送出曆史造成很大影響。
首先檢視送出日志,以便變基後,确認送出曆史的修改git log
變基操作。 可以用commit~n或commit^^這種形式替代:前者表示目前送出到n次以前的送出,後者^符号越多表示的範圍越大,commit可以是HEAD或者某次送出的hash值;-i參數表示進入互動模式。git rebase -i
以上變基指令會進入文本編輯器,其中每一行就是某次送出,把pick修改為edit,儲存退出該文本編輯器。
注意:變基指令打開的文本編輯器中的commit順序跟git log檢視的順序是相反的,也就是最近的送出在下面,老舊的送出在上面
注意:變基指令其實可以同時對多個送出進行修改,隻需要修改将對應行前的pick都修改為edit,儲存退出後會根據你修改的數目多次打開修改某次commit的文本編輯器界面。但是這個範圍内的最終祖先commit不能修改,也就是如果有5行commit資訊,你隻能修改下面4行的,這不僅限于commit修改,重排、删除以及合并都如此。git commit --amend
接下來修改送出描述内容或者檔案内容,跟最近一次的commit的操作相同,不贅述。
然後完成變基操作git rebase --continue
有時候會完成變基失敗,需要git add --all才能解決,一般git會給出提示。
再次檢視送出日志,對比變基前後的修改,可以看到的内的所有送出的hash值都被修改了git log
如果過了一段時間後,你發現這次曆史修改有誤,想退回去怎麼辦?請往下繼續閱讀
1.3 重排或删除某些送出
變基指令非常強大,還可以将送出曆史重新手動排序或者删除某次送出。這為某些誤操作,導緻不希望公開資訊的送出,提供了補救措施
git rebase -i
如前面描述,這會進入文本編輯器,對某行送出進行排序或者删除,儲存退出。可以是多行修改。
後續操作同上。
1.4 合并多次送出
非關鍵性的送出太多會讓版本曆史很難看、備援,是以合并多次送出也是挺有必要的。同樣是使用以上的變基指令,不同的是變基指令打開的文本編輯器裡的内容的修改。
将pick修改為squash,可以是多行修改,然後儲存退出。這個操作會将标記為squash的所有送出,都合并到最近的一個祖先送出上。
注意:不能對的第一行commit進行修改,至少保證第一行是接受合并的祖先送出。
後續操作同上。
1.5 分離某次送出
變基指令還能分離送出,這裡不描述,詳情檢視後面的參考連結
終極手段
git還提供了修改版本曆史的“大殺器”——filter-branch,可以對整個版本曆史中的每次送出進行修改,可用于删除誤操作送出的密碼等敏感資訊。
删除所有送出中的某個檔案git filter-branch --treefilter 'rm -f password.txt' HEAD
将建立的主目錄作為所有送出的根目錄git filter-branch --subdirectory-filter trunk HEAD
本地回退
回退操作也是對過往送出的一劑“後悔藥”,常用的回退方式有三種:checkout、reset和revert
checkout
對單個檔案進行回退。不會修改目前的HEAD指針的位置,也就是送出并未回退
可以是某次送出的hash值,或者HEAD(預設即預設)git checkout -- reset
回退到某次送出。回退到的指定送出以後的送出都會從送出日志上消失
注意:工作區和暫存區的内容都會被重置到指定送出的時候,如果不加--hard則隻移動HEAD的指針,不影響工作區和暫存區的内容。git reset --hard
結合git reflog找回送出日志上看不到的版本曆史,撤回某次操作前的狀态
git reflog # 找到某次操作前的送出hash值
git reset
這個方法可以對你的回退操作進行回退,因為這時候git log指令已經找不到曆史送出的hash值了。
revert
這個方法是最溫和,最受推薦的,因為本質上不是修改過去的版本曆史,而是将回退版本曆史作為一次新的送出,是以不會改變版本曆史,在push到遠端倉庫的時候也不會影響到團隊其他人。
git revert
遠端修改
對遠端倉庫的版本曆史修改,都是在本地修改的基礎上進行的:本地修改完成後,再push到遠端倉庫。
但是除了git revert可以直接push,其他都會對原有的版本曆史修改,隻能使用強制push
git push -f
總結
git commit --amend改寫單次commit
git rebase -i 删改排以及合并多個commit
git checkout -- 擷取曆史版本的某個檔案
git reset [--hard] 移動HEAD指針
git revert 建立一個回退送出
git push -f 強制push,覆寫原有遠端倉庫
作者:芥末無疆sss
連結:https://www.jianshu.com/p/7f043dd8eae1
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。