git如何修改已提交的commit


本地修改

由於以下修改本身是對版本歷史的修改,在需要push到遠程倉庫時,往往是不成功的,只能強行push,這樣會出現的一個問題就是,如果你是push到多人協作的遠程倉庫中,會對其他人的遠程操作構成影響。通常情況下,建議與項目遠程倉庫的管理員進行溝通,在完成你強制push操作后,通知其他人同步。

  1. 修改最近一次的commit

    修改提交的描述

    git commit --amend

    然后會進入一個文本編輯器界面,修改commit的描述內容,即可完成操作。

    修改提交的文件

    git add <filename> # 或者 git rm git commit --amend # 將緩存區的內容做為最近一次提交
  2. 修改任意提交歷史位置的commit

    可以通過變基命令,修改最近一次提交以前的某次提交。不過修改的提交到當前提交之間的所有提交的hash值都會改變。
    變基操作需要非常小心,一定要多用git status命令來查看你是否還處於變基操作,可能某次誤操作的會對后面的提交歷史造成很大影響。

    首先查看提交日志,以便變基后,確認提交歷史的修改

    git log

    變基操作。 可以用commit~ncommit^^這種形式替代:前者表示當前提交到n次以前的提交,后者^符號越多表示的范圍越大,commit可以是HEAD或者某次提交的hash值;-i參數表示進入交互模式。

    git rebase -i <commit range>

    以上變基命令會進入文本編輯器,其中每一行就是某次提交,把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

    如果過了一段時間后,你發現這次歷史修改有誤,想退回去怎么辦?請往下繼續閱讀

  3. 重排或刪除某些提交

    變基命令非常強大,還可以將提交歷史重新手動排序或者刪除某次提交。這為某些誤操作,導致不希望公開信息的提交,提供了補救措施

    git rebase -i <commit range>

    如前面描述,這會進入文本編輯器,對某行提交進行排序或者刪除,保存退出。可以是多行修改。

    后續操作同上。

  4. 合並多次提交

    非關鍵性的提交太多會讓版本歷史很難看、冗余,所以合並多次提交也是挺有必要的。同樣是使用以上的變基命令,不同的是變基命令打開的文本編輯器里的內容的修改。

    pick修改為squash,可以是多行修改,然后保存退出。這個操作會將標記為squash的所有提交,都合並到最近的一個祖先提交上。

    **注意:**不能對的第一行commit進行修改,至少保證第一行是接受合並的祖先提交。

    后續操作同上。

  5. 分離某次提交

    變基命令還能分離提交,這里不描述,詳情查看后面的參考鏈接

  6. 終極手段

    git還提供了修改版本歷史的“大殺器”——filter-branch,可以對整個版本歷史中的每次提交進行修改,可用於刪除誤操作提交的密碼等敏感信息。

    刪除所有提交中的某個文件

    git filter-branch --treefilter 'rm -f password.txt' HEAD

    將新建的主目錄作為所有提交的根目錄

    git filter-branch --subdirectory-filter trunk HEAD

本地回退

回退操作也是對過往提交的一劑“后悔葯”,常用的回退方式有三種:checkoutresetrevert

  1. checkout

    對單個文件進行回退。不會修改當前的HEAD指針的位置,也就是提交並未回退

    可以是某次提交的hash值,或者HEAD(缺省即默認)

    git checkout <commit> -- <filename>
  2. reset

    回退到某次提交。回退到的指定提交以后的提交都會從提交日志上消失
    **注意:**工作區和暫存區的內容都會被重置到指定提交的時候,如果不加--hard則只移動HEAD的指針,不影響工作區和暫存區的內容。

    git reset --hard <commit>

    結合git reflog找回提交日志上看不到的版本歷史,撤回某次操作前的狀態

    git reflog # 找到某次操作前的提交hash值 git reset <commit>

    這個方法可以對你的回退操作進行回退,因為這時候git log命令已經找不到歷史提交的hash值了。

  3. revert

    這個方法是最溫和,最受推薦的,因為本質上不是修改過去的版本歷史,而是將回退版本歷史作為一次新的提交,所以不會改變版本歷史,在push到遠程倉庫的時候也不會影響到團隊其他人。

    git revert <commit>

遠程修改

對遠程倉庫的版本歷史修改,都是在本地修改的基礎上進行的:本地修改完成后,再push到遠程倉庫。

但是除了git revert可以直接push,其他都會對原有的版本歷史修改,只能使用強制push

git push -f <remote> <branch>

總結

git commit --amend改寫單次commit
git rebase -i <commit range>刪改排以及合並多個commit
git checkout <commit> -- <filename>獲取歷史版本的某個文件
git reset [--hard] <commit>移動HEAD指針
git revert <commit>創建一個回退提交
git push -f <remote> <branch>強制push,覆蓋原有遠程倉庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM