Git進階系列 | 6. 互動式Rebase

語言: CN / TW / HK

Git是最流行的程式碼版本控制系統,這一系列文章介紹了一些Git的高階使用方式,從而幫助我們可以更好的利用Git的能力。本系列一共8篇文章,這是第5篇。原文:Interactive Rebase: Clean up your Commit History[1]

互動式Rebase是Git命令中的瑞士軍刀,有很多用例和可能性,對任何開發人員的工具鏈都是極好的補充,允許我們在與團隊成員分享工作之前修改本地提交歷史。

我們看看使用互動式rebase可以做些什麼,然後看一些實際的例子。

Git進階系列: 1. 建立完美的提交 2. Git中的分支策略 3. 基於Pull Request實現更好的協作 4. 合併衝突 5. Rebase vs Merge 6. 互動式Rebase(本文) 7. Git中的Cherry-pick提交 8. 用Reflog恢復丟失的提交

重寫提交歷史

簡而言之,互動式rebase允許操作、優化和清理提交歷史。你可以…

  • 修改提交資訊
  • 合併多個提交
  • 拆分、編輯已有提交
  • 對提交重排序
  • 刪除提交

請記住,互動式rebase會重寫提交歷史,所有涉及的提交都將獲得新的雜湊ID。另外,簡單提醒一下: 提交id是用於識別提交的,是SHA-1校驗和。因此,通過改變雜湊,在技術上來說我們建立了全新的提交。這意味著不應該在已經推送到共享遠端程式碼庫的上使用互動式rebase。其他團隊成員的工作可能就基於這些提交,當我們使用互動式rebase重寫提交歷史時,就改變了這些基礎提交。

所有這些都意味著互動式的rebase是為了幫助我們在合併(並可能推入)到共享的團隊分支之前清理和優化自己的本地提交歷史。

互動式rebase工作流

在我們進行互動式rebase測試之前,先看看一般的工作流。無論做什麼,刪除提交、更改提交訊息、合併提交……這些步驟都是相同的。

第一步是確定要操作的提交的範圍,想回到多久以前?一旦有了答案,就可以開始互動式rebase會話了。在這裡,我們有機會編輯提交歷史,比方說可以通過重新排序、刪除、組合提交等方式操作所選擇的提交。

在第一步中,總是要通過檢視提交歷史記錄瞭解當前狀態,可以使用git log命令來檢查專案的歷史並顯示提交日誌。

下面是本文使用的示例程式碼庫:

檢查完後,就可以開始工作了。我們一步一步來,在示例中,我們將做以下事情:

  • 首先,修改舊的提交資訊。
  • 其次,合併兩個舊的提交。
  • 然後,分解一個提交。
  • 最後,刪除一個提交。

修改提交資訊

許多情況下,我們希望更改最近的提交。請記住,這個場景中有一個不涉及互動式rebase的捷徑:

shell $ git commit --amend

這個命令會開啟預設的文字編輯器,可以修改最近提交的內容和資訊。我們可以更改、儲存並退出編輯器。該操作不僅可以更新提交資訊,還會有效的更改提交本身並編寫一個新的提交。

如果已經將上次提交的檔案推送到遠端程式碼庫,同樣請小心,不要修改它!

對於任何其他提交(任何比最近一次更早的提交),都必須執行互動式rebase。要互動式執行git rebase,需要新增-i選項。

第一步是確定基礎提交: 要更改的提交的父提交。可以通過使用提交的雜湊ID或執行少量計數來實現這一點。要更改最後三個提交(或者至少其中一個),可以這樣定義父提交:

shell $ git rebase -i HEAD~3

該命令會開啟一個編輯器視窗,可以看到所選擇的三個提交(我說的“選擇”是指提交的範圍: 從HEAD一直到HEAD~3)。和git log不一樣,這個編輯器將最老的提交(HEAD~3)顯示在頂部,最新的在底部。

在這個視窗中,實際上並不需要更改提交,只需告訴Git要執行哪種操作。Git為此提供了一系列關鍵字,在我們的示例中,將單詞pick更改為reword,這允許我們更改提交資訊。儲存並關閉編輯器後,Git將顯示並允許更改實際的提交資訊。儲存並再次退出,就這樣!

合併提交

下一個示例,我們將兩個提交(“7b2317cf Change the page structure”和“6bcf266 Optimize markup”)合併成一個提交。同樣,第一步需要確定基礎提交。我們至少需要回到父提交:

shell $ git rebase -i HEAD~3

編輯器視窗再次開啟,但這次我們輸入的不是reword,而是squash。確切地說,我們在第2行中將pick替換為squash,以便將其與第1行合併。記住這一點很重要: squash關鍵字會將標記的行與它上面的行合併起來!

儲存更改並關閉視窗後,將彈出一個新的編輯器視窗。為什麼?因為通過合併兩個提交,我們建立了一個新的提交!而這個新的提交需要一條提交資訊。輸入資訊,儲存並關閉視窗……這樣就成功合併了兩次提交。多麼強大!

最後,給那些使用“Tower”Git桌面GUI的人一點“專業提示”: 為了執行squash,可以簡單的在提交檢視中互相拖放提交。如果想要更改提交資訊,只需右鍵單擊問題中的提交,並從上下文選單中選擇“Edit commit message”即可。

刪除提交

最後的例子將介紹一個大傢伙: 從提交歷史中刪除一個修訂!為此,我們使用drop關鍵字來標記想要刪除的提交:

drop 0023cdd Add simple robots.txt pick 2b504be Change headlines for about and imprint pick 6bcf266 Optimizes markup structure in index page

這可能是一個很好的時機來回答一個你可能已經思考了一段時間的問題: 如果正在進行rebase操作,並認為“哦,不,這不是一個好主意”,你能做什麼?沒有問題,可以隨時中止!只需輸入以下命令,程式碼庫就會回到rebase之前的狀態:

shell $ git rebase --abort

改變歷史

這些只是互動式rebase所能做的一些例子,還有很多其他方法可以控制和修改本地提交歷史記錄。

如果想更深入瞭解高階Git工具,可以免費檢視“Advanced Git Kit[3]”: 這是關於分支策略、互動式Rebase、Reflog、子模組等主題的短影片集合。

References: \ [1] Interactive Rebase: Clean up your Commit History: http://css-tricks.com/interactive-rebase-clean-up-your-commit-history/

你好,我是俞凡,在Motorola做過研發,現在在Mavenir做技術工作,對通訊、網路、後端架構、雲原生、DevOps、CICD、區塊鏈、AI等技術始終保持著濃厚的興趣,平時喜歡閱讀、思考,相信持續學習、終身成長,歡迎一起交流學習。 \ 微信公眾號:DeepNoMind