1. 程式人生 > >git修改歷史提交

git修改歷史提交

很多時候,在 Git 上工作的時候,你也許會由於某種原因想要修訂你的提交歷史。Git 的一個卓越之處就是它允許你在最後可能的時刻再作決定。你可以在你即將提交暫存區時決定什麼檔案歸入哪一次提交,你可以使用 stash 命令來決定你暫時擱置的工作,你可以重寫已經發生的提交以使它們看起來是另外一種樣子。這個包括改變提交的次序、改變說明或者修改提交中包含的檔案,將提交歸併、拆分或者完全刪除——這一切在你尚未開始將你的工作和別人共享前都是可以的。

在這一節中,你會學到如何完成這些很有用的任務以使你的提交歷史在你將其共享給別人之前變成你想要的樣子。

改變最近一次提交

改變最近一次提交也許是最常見的重寫歷史的行為。對於你的最近一次提交,你經常想做兩件基本事情:改變提交說明,或者改變你剛剛通過增加,改變,刪除而記錄的快照。

如果你只想修改最近一次提交說明,這非常簡單:

$ git commit --amend

這會把你帶入文字編輯器,裡面包含了你最近一次提交說明,供你修改。當你儲存並退出編輯器,這個編輯器會寫入一個新的提交,裡面包含了那個說明,並且讓它成為你的新的最近一次提交。

如果你完成提交後又想修改被提交的快照,增加或者修改其中的檔案,可能因為你最初提交時,忘了新增一個新建的檔案,這個過程基本上一樣。你通過修改檔案然後對其執行git add或對一個已被記錄的檔案執行git rm,隨後的git commit --amend會獲取你當前的暫存區並將它作為新提交對應的快照。

使用這項技術的時候你必須小心,因為修正會改變提交的SHA-1值。這個很像是一次非常小的rebase——不要在你最近一次提交被推送後還去修正它。

修改多個提交說明

要修改歷史中更早的提交,你必須採用更復雜的工具。Git沒有一個修改歷史的工具,但是你可以使用rebase工具來衍合一系列的提交到它們原來所在的HEAD上而不是移到新的上。依靠這個互動式的rebase工具,你就可以停留在每一次提交後,如果你想修改或改變說明、增加檔案或任何其他事情。你可以通過給git rebase增加-i選項來以互動方式地執行rebase。你必須通過告訴命令衍合到哪次提交,來指明你需要重寫的提交的回溯深度。

例如,你想修改最近三次的提交說明,或者其中任意一次,你必須給git rebase -i提供一個引數,指明你想要修改的提交的父提交,例如HEAD~2或者HEAD~3

。可能記住~3更加容易,因為你想修改最近三次提交;但是請記住你事實上所指的是四次提交之前,即你想修改的提交的父提交。

$ git rebase -i HEAD~3

再次提醒這是一個衍合命令——HEAD~3..HEAD範圍內的每一次提交都會被重寫,無論你是否修改說明。不要涵蓋你已經推送到中心伺服器的提交——這麼做會使其他開發者產生混亂,因為你提供了同樣變更的不同版本。

執行這個命令會為你的文字編輯器提供一個提交列表,看起來像下面這樣

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

很重要的一點是你得注意這些提交的順序與你通常通過log命令看到的是相反的。如果你執行log,你會看到下面這樣的結果:

$ git log --pretty=format:"%h %s" HEAD~3..HEAD
a5f4a0d added cat-file
310154e updated README formatting and added blame
f7f3f6d changed my name a bit

請注意這裡的倒序。互動式的rebase給了你一個即將執行的指令碼。它會從你在命令列上指明的提交開始(HEAD~3)然後自上至下重播每次提交裡引入的變更。它將最早的列在頂上而不是最近的,因為這是第一個需要重播的。

你需要修改這個指令碼來讓它停留在你想修改的變更上。要做到這一點,你只要將你想修改的每一次提交前面的pick改為edit。例如,只想修改第三次提交說明的話,你就像下面這樣修改檔案:

edit f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

當你儲存並退出編輯器,Git會倒回至列表中的最後一次提交,然後把你送到命令列中,同時顯示以下資訊:

$ git rebase -i HEAD~3
Stopped at 7482e0d... updated the gemspec to hopefully work better
You can amend the commit now, with

       git commit --amend

Once you’re satisfied with your changes, run

       git rebase --continue

這些指示很明確地告訴了你該幹什麼。輸入

$ git commit --amend

修改提交說明,退出編輯器。然後,執行

$ git rebase --continue

這個命令會自動應用其他兩次提交,你就完成任務了。如果你將更多行的 pick 改為 edit ,你就能對你想修改的提交重複這些步驟。Git每次都會停下,讓你修正提交,完成後繼續執行。

重排提交

你也可以使用互動式的衍合來徹底重排或刪除提交。如果你想刪除”added cat-file”這個提交併且修改其他兩次提交引入的順序,你將rebase指令碼從這個

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

改為這個:

pick 310154e updated README formatting and added blame
pick f7f3f6d changed my name a bit

當你儲存並退出編輯器,Git 將分支倒回至這些提交的父提交,應用310154e,然後f7f3f6d,接著停止。你有效地修改了這些提交的順序並且徹底刪除了”added cat-file”這次提交。

壓制(Squashing)提交

互動式的衍合工具還可以將一系列提交壓制為單一提交。指令碼在 rebase 的資訊裡放了一些有用的指示:

#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

如果不用”pick”或者”edit”,而是指定”squash”,Git 會同時應用那個變更和它之前的變更並將提交說明歸併。因此,如果你想將這三個提交合併為單一提交,你可以將指令碼修改成這樣:

pick f7f3f6d changed my name a bit
squash 310154e updated README formatting and added blame
squash a5f4a0d added cat-file

當你儲存並退出編輯器,Git 會應用全部三次變更然後將你送回編輯器來歸併三次提交說明。

# This is a combination of 3 commits.
# The first commit's message is:
changed my name a bit

# This is the 2nd commit message:

updated README formatting and added blame

# This is the 3rd commit message:

added cat-file

當你儲存之後,你就擁有了一個包含前三次提交的全部變更的單一提交。

拆分提交

拆分提交就是撤銷一次提交,然後多次部分地暫存或提交直到結束。例如,假設你想將三次提交中的中間一次拆分。將”updated README formatting and added blame”拆分成兩次提交:第一次為”updated README formatting”,第二次為”added blame”。你可以在rebase -i指令碼中修改你想拆分的提交前的指令為”edit”:

pick f7f3f6d changed my name a bit
edit 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

然後,這個指令碼就將你帶入命令列,你重置那次提交,提取被重置的變更,從中建立多次提交。當你儲存並退出編輯器,Git 倒回到列表中第一次提交的父提交,應用第一次提交(f7f3f6d),應用第二次提交(310154e),然後將你帶到控制檯。那裡你可以用git reset HEAD^對那次提交進行一次混合的重置,這將撤銷那次提交併且將修改的檔案撤回。此時你可以暫存並提交檔案,直到你擁有多次提交,結束後,執行git rebase --continue

$ git reset HEAD^
$ git add README
$ git commit -m 'updated README formatting'
$ git add lib/simplegit.rb
$ git commit -m 'added blame'
$ git rebase --continue

Git在指令碼中應用了最後一次提交(a5f4a0d),你的歷史看起來就像這樣了:

$ git log -4 --pretty=format:"%h %s"
1c002dd added cat-file
9b29157 added blame
35cfb2b updated README formatting
f3cc40e changed my name a bit

再次提醒,這會修改你列表中的提交的 SHA 值,所以請確保這個列表裡不包含你已經推送到共享倉庫的提交。

核彈級選項: filter-branch

如果你想用指令碼的方式修改大量的提交,還有一個重寫歷史的選項可以用——例如,全域性性地修改電子郵件地址或者將一個檔案從所有提交中刪除。這個命令是filter-branch,這個會大面積地修改你的歷史,所以你很有可能不該去用它,除非你的專案尚未公開,沒有其他人在你準備修改的提交的基礎上工作。儘管如此,這個可以非常有用。你會學習一些常見用法,藉此對它的能力有所認識。

從所有提交中刪除一個檔案

這個經常發生。有些人不經思考使用git add .,意外地提交了一個巨大的二進位制檔案,你想將它從所有地方刪除。也許你不小心提交了一個包含密碼的檔案,而你想讓你的專案開源。filter-branch大概會是你用來清理整個歷史的工具。要從整個歷史中刪除一個名叫password.txt的檔案,你可以在filter-branch上使用--tree-filter選項:

$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
Ref 'refs/heads/master' was rewritten

--tree-filter選項會在每次檢出專案時先執行指定的命令然後重新提交結果。在這個例子中,你會在所有快照中刪除一個名叫 password.txt 的檔案,無論它是否存在。如果你想刪除所有不小心提交上去的編輯器備份檔案,你可以執行類似git filter-branch --tree-filter 'rm -f *~' HEAD的命令。

你可以觀察到 Git 重寫目錄樹並且提交,然後將分支指標移到末尾。一個比較好的辦法是在一個測試分支上做這些然後在你確定產物真的是你所要的之後,再 hard-reset 你的主分支。要在你所有的分支上執行filter-branch的話,你可以傳遞一個--all給命令。

將一個子目錄設定為新的根目錄

假設你完成了從另外一個程式碼控制系統的匯入工作,得到了一些沒有意義的子目錄(trunk, tags等等)。如果你想讓trunk子目錄成為每一次提交的新的專案根目錄,filter-branch也可以幫你做到:

$ git filter-branch --subdirectory-filter trunk HEAD
Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
Ref 'refs/heads/master' was rewritten

現在你的專案根目錄就是trunk子目錄了。Git 會自動地刪除不對這個子目錄產生影響的提交。

全域性性地更換電子郵件地址

另一個常見的案例是你在開始時忘了執行git config來設定你的姓名和電子郵件地址,也許你想開源一個專案,把你所有的工作電子郵件地址修改為個人地址。無論哪種情況你都可以用filter-branch來更換多次提交裡的電子郵件地址。你必須小心一些,只改變屬於你的電子郵件地址,所以你使用--commit-filter

$ git filter-branch --commit-filter '
        if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ];
        then
                GIT_AUTHOR_NAME="Scott Chacon";
                GIT_AUTHOR_EMAIL="[email protected]";
                git commit-tree "[email protected]";
        else
                git commit-tree "[email protected]";
        fi' HEAD

這個會遍歷並重寫所有提交使之擁有你的新地址。因為提交裡包含了它們的父提交的SHA-1值,這個命令會修改你的歷史中的所有提交,而不僅僅是包含了匹配的電子郵件地址的那些。

相關推薦

Git 修改歷史提交中的使用者名稱和郵箱

Git 修改歷史提交中的使用者名稱和郵箱 最近幾次貢獻開原始碼總是遇到一個問題,我將 GitHub 上的專案 clone 到本地,完成編碼後直接 commit(提交) 。提交後才發現沒有使用 git config 來為專案配置私人使用者名稱和郵箱,因此提交中攜帶的是全域性配置中的公司

git 修改歷史提交的使用者名稱和郵箱

第一步clone 下git待修改的創庫,如果已經有了跳過 第二步執行如下指令碼 #!/bin/sh git filter-branch --env-filter ' OLD_EMAIL="老的郵箱" CORRECT_NAME="新使用者名稱" CORRECT_EMAIL="新郵箱" if [

Git 修改歷史提交

       git使用amend選項提供了最後一次commit的反悔。但是對於歷史提交呢,就必須使用rebase了。        git rebase -i HEAD~3        表示要修改當前版本的倒數第三次狀態。         這個命令出來之後,會出來三行東東:         pick:*

git修改歷史提交

很多時候,在 Git 上工作的時候,你也許會由於某種原因想要修訂你的提交歷史。Git 的一個卓越之處就是它允許你在最後可能的時刻再作決定。你可以在你即將提交暫存區時決定什麼檔案歸入哪一次提交,你可以使用 stash 命令來決定你暫時擱置的工作,你可以重寫已經發生的提交以使

git修改歷史記錄

-- mit 修改 inter bsp tro 編輯 rac div 1.git stash2.git rebase 45c2d5c --interactive 3.git stash pop4.git add5.git commit --amend 確認編輯後

git 修改提交的註釋

在git中,其commit提供了一個--amend引數,可以修改最後一次提交的資訊 修改最後一次提交註釋 git commit --amend 然後在出來的編輯介面,直接編輯註釋的資訊,儲存退出 git rebase -i HEAD~3 git使用amend選項提供了最後一次commit的反悔。但是對

Git 修改提交的郵箱和使用者資訊

實際過程中有的時候本地配置資訊郵箱有誤,導致git commit 提交作者的資訊有誤,這個時候就需要進行修改 git config --list user.email=xxx user.name=xxx

git--檢視歷史提交、撤銷

1、檢視提交歷史 在提交了若干更新,又或者克隆了某個專案之後,你也許想回顧下提交歷史。 完成這個任務最簡單而又有效的工具是 git log 命令。 一個常用的選項是 -p,用來顯示每次提交的內容差異。 你也可以加上 -2 來僅顯示最近兩次提交:  $ git log -

GIT修改上次提交的程式碼,做一次更完美的commit

在git中提交後,如果想修改剛剛提交的程式碼,做一次更完美的commit,可以這樣: (1)git reset commitId,(注:不要帶--hard)到上個版本 (2)git stash,暫存修改(3)git push --force, 強制push,遠端的最新的一

git_修改git歷史提交記錄

本修改僅限於修改本地的提交,提交的遠端的請勿修改,以防引起開發者混亂。 首先執行 git rebase -i HEAD~3 這裡首先rebase到HEAD~3的提交,這是你可以修改HEAD~2 - HEAD之間的提交。 此時,git為你提供一個編輯列表,如下: pi

git fork代碼並修改提交到自己的git倉庫

添加 detail 成功 開發 嘗試 fetch .com mes -m   最近在參加阿裏天池大數據中間件比賽(毫無頭緒,打醬油中).看參賽要求,需要將官網的git工程clone下來,在此基礎上做修改後提交到自己的倉庫中. 由於以前並沒有使用過git,所以差了比較多的資料

Git 查看提交歷史

gitGit 查看提交歷史在使用 Git 提交了若幹更新之後,又或者克隆了某個項目,想回顧下提交歷史,我們可以使用 git log 命令查看。針對我們前一章節的操作,使用 git log 命令列出歷史提交記錄如下:$ git log commit 88afe0e02adcdfea6844bb627de97da

Git 狀態 和 查看歷史提交

jpg check mit inf rdquo 表示 png 使用 bubuko 1、使用git status 命令查看當前狀態 上圖表示當前位於一個叫做master的分支中 工作目錄無需要提交的文件即工作目錄中文件沒有改動過 2、新建LICENSE文件 輸入

Git 修改最後一次提交,刪除文件,重命名文件

工作 刪除 comm clas 恢復 文件 git rm 忘記 body 1、修改最後一次提交 當忘記提交某個文件可以使用 git commit amend -m "新的提交說明" 暫存區的內容會提交到git倉庫而不產生新的快照 2、刪除文件 手動刪除工作區的文件後

iOS - Git 查看提交歷史(分布式版本控制系統)

使用 默認 name first reset grep tac relative let 1、查看提交歷史 在提交了若幹更新,又或者克隆了某個項目之後,你也許想回顧下提交歷史。完成這個任務最簡單而又有效的工具是 git log 命令。 $ git log commit c

【轉】git修改文件後,提交到遠程倉庫

log csdn 文件 遠程 ase git add 提交 gin mon 原文地址:https://blog.csdn.net/nly19900820/article/details/73613654 修改文件後,怎麽提交到遠程倉庫1.git status 查看git是否

git刪除所有提交歷史記錄

mes 代碼 upd 本地 delete 並且 one IT ren 把舊項目提交到git上,但是會有一些歷史記錄,這些歷史記錄中可能會有項目密碼等敏感信息。如何刪除這些歷史記錄,形成一個全新的倉庫,並且保持代碼不變呢? 以下方法是在當前的分支下新建一個分支,然後把之前分支

git檢視commit修改歷史詳情

本部落格所有文章採用的授權方式為 自由轉載-非商用-非衍生-保持署名 ,轉載請務必註明出處,謝謝。 宣告: 本部落格歡迎轉發,但請保留原作者資訊! 部落格地址: 孟阿龍的部落格 1. 比較兩次commit修改的檔案列表 git diff --name-o

git 檢視某檔案的修改歷史

git log命令 1、git log -- filename(git log filename) 可以看到該檔案相關的commit記錄 2、git log -p filename 可以顯示該檔案每次提交的diff 3、git show comit_id filename 可以檢視某次提

Git 修改提交的使用者名稱和郵箱名字

git 修改當前的project的使用者名稱的命令為: > git config user.name 你的目標使用者名稱; 1 2 git修改當前的project提交郵箱的命令為: > git config user.email 你的目標郵箱名;