Git提交歷史的修改刪除合併

熊建剛發表於2017-12-13

今天主要針對在專案版本控制器Git的使用中遇到的一些和提交歷史操作相關的常見問題,進行實踐總結。在專案開發中經常會需要修改提交commit資訊,合併多個提交commit,甚至放棄當前修改回退至某一歷史提交的需求,那我們到底該如何操作呢,本篇一一闡述。

歡迎訪問我的個人部落格

前言

假如,當前我們處在需求分支feature-test,進行了多次提及,git log檢視commit資訊如下:

git log

每一個提交的commit都是獨立的,但是最近三個commit都是相關的,都是新增read.txt檔案內容,在本文中以此為例項依次介紹如何修改,合併,回退commit的。

檢視git歷史

如果要檢視git歷史可以使用git loggit reflog指令:

  1. git log:檢視當前分支的存在提交歷史記錄,不包括諸如刪除的或被合併的提交;
  2. git reflog:檢視當前分支所有操作歷史,諸如歷史提交記錄,撤銷,合併提交等詳細歷史記錄;

git rebase -i

需要用到的指令是git rebase -i commitHashcommitHash是commitID,是需要合併的commit的前一個commit節點的ID,對於本文例項中而言,是最近第四個提交df11bf944,所以執行如下指令:

git rebase -i df11bf944
複製程式碼

命令列終端會輸出如下內容:

git-rebase-i

由遠及近列出了我們期望處理的三個提交,前面pick代表的預設使用該提交commit,我們現在可以按i進入編輯模式,修改該欄位值,值可以如圖中描述,經常使用的如下:

  1. pick:簡寫p,啟用該commit;
  2. reword:簡寫r,使用該commit,但是修改提交資訊,修改後可以繼續編輯後面的提交資訊;
  3. edit:簡寫e,使用commit,停止合併該commit;
  4. squash:簡寫s,使用該commit,並將該commit併入前一commit;
  5. drop:簡寫d,移除該commit;

修改提交資訊

我們現在嘗試修改最近一次的提交commit資訊,將其前面pick修改成reword

reword

編輯後,按esc鍵退出編輯模式,然後輸入:wq,儲存當前編輯,會輸出如下內容:

reword info

我們可以開始編輯我們需要修改的commit資訊了,按i鍵進入編輯模式,修改提交資訊為:

feature(read.txt) 新增read.txt第三行(reword修改commit message)
複製程式碼

儲存退出後會有修改成功提示:

commit

合併歷史提交

前面修改commit成功,如果期望將多個提交合併成一個提交,使得整個提交歷史更乾淨,如何處理呢?

執行如下指令,df11bf944是需要合併的提交的前一個提交節點的commitID:

git rebase -i df11bf944
複製程式碼

然後修改pick值為squash

git-rebase -i & squash

儲存退出,會進入最終合併提交commit資訊編輯狀態,在這裡會列出合併commit的所有message,我們可以操作:

modify last comibination message

我們可以同時保留三次的提交資訊,也可以任意修改,此處我們只保留第一個提交的資訊,然後儲存退出,當我們再次使用git log檢視歷史提交資訊時,就會發現只剩下合併後的一個提交及之前未操作的提交:

git-log-2

git rebase -i head~{num}

前面提到的git rebase -i commitHash指令可以合併提交歷史,其實還可以換成一種快捷方式,如當需要合併最近兩個提交時,執行:

git rebase -i head~2
複製程式碼

效果一樣:

git rebase -i head~2

後續修改,合併,回退操作均一致。

撤銷提交

當需求發現變更,我們發現不需要某一歷史提交時,怎麼辦呢,怎麼放棄該修改提交?這也分兩種情況:

  1. 歷史提交中間某提交的撤銷;
  2. 最近提交的撤銷;

撤銷中間提交

當需要放棄的提交被合併後,我們想放棄該提交,需要先檢視該提交的資訊使用,執行指令:

git reflog
複製程式碼

該指令輸出詳細的操作歷史,包括提交,操作,修改等:

git reflog

我們找到需要撤銷的提交,如最近第二個提交,提交commitId為dcbdde2,索引為HEAD@{19}

dcbdde2 HEAD@{19}: commit: feature(read.txt): 新增read.txt第二行
複製程式碼

git revert

執行以下指令撤銷該commit:

git revert head@{19}
複製程式碼

git revert head@{19}

上面head@{19}指令也等效於:

git revert dcbdde2
複製程式碼

git revert撤銷一個提交的同時會建立一個新的提交。這是一個安全的方法,因為它不會重寫提交歷史。它會建立一個新的提交來撤銷指定更改,然後把新提交加入至專案中。

撤銷提交時若多個提交修改了同一檔案可能會出現衝突,需要處理衝突後,暫存:

git add .
複製程式碼

然後繼續執行revert操作:

git revert --continue
複製程式碼

git-revert —continue

然後檢視提交歷史,發現多了一個記錄:

git-log-3

此時已經撤銷了之前最近第二次提交的內容(即撤銷了read.txt檔案第二行)。

撤銷最近提交

如果期望撤銷的提交是最近獨立存在的,並沒有發生合併,以撤銷上一節git revert新生成的提交為例:

5a7b985 Revert "feature(read.txt): 新增read.txt第二行"
df11bf9 commit: "feat(RN-publish-up): React Native釋出,熱更新原理介紹"
複製程式碼

git reset

只需要使用git reset指令:

git reset commitHash / head~{num}
複製程式碼

commitHash是期望撤銷提交的上一次提交的commitID,等效於指定期望撤銷最近幾次提交,num值等於期望撤銷提交數。

具體提交的commitID可以使用git loggit reflog指令查詢,刪除執行指令:

git reset head~1
複製程式碼

等效於,df11bf9是需要撤銷提交commit的上一次提交commitID:

git reset df11bf9
複製程式碼

最後會發現提交內容變成未提交,使用git checkout.指令撤銷變更就行:

git reset

相關文章