標籤:

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

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

前言

假如,當前我們處在需求分支feature-test,進行了多次提及,git log查看commit信息如下:

每一個提交的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 n

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

由遠及近列出了我們期望處理的三個提交,前面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

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

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

feature(read.txt) 添加read.txt第三行(reword修改commit message) n

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

合併歷史提交

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

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

git rebase -i df11bf944 n

然後修改pick值為squash

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

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

git rebase -i head~{num}

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

git rebase -i head~2 n

效果一樣:

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

撤銷提交

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

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

撤銷中間提交

當需要放棄的提交被合併後,我們想放棄該提交,需要先查看該提交的信息使用,執行指令:

git reflog n

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

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

dcbdde2 HEAD@{19}: commit: feature(read.txt): 添加read.txt第二行 n

GIT REVERT

執行以下指令撤銷該commit:

git revert head@{19} n

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

git revert dcbdde2 n

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

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

git add . n

然後繼續執行revert操作:

git revert --continue n

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

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

撤銷最近提交

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

5a7b985 Revert "feature(read.txt): 添加read.txt第二行"ndf11bf9 commit: "feat(RN-publish-up): React Native發布,熱更新原理介紹" n

GIT RESET

只需要使用git reset指令:

git reset commitHash / head~{num} n

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

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

git reset head~1 n

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

git reset df11bf9 n

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


推薦閱讀:

Windows 與 Mac 平台用 Dropbox 共享 Git 項目,怎麼設置不會出現衝突?
Github 有什麼優缺點?把項目直接搭建在 Github 上合適嗎?
一個奇怪的git問題,求大家幫忙分析一下?
如何在Linux上搭建一個Git中央倉庫

TAG:Git |