在 Day 14 的內容中,提到 git rebase
的概念是「把 commit 所代表的步驟,試著在新的基點再做一次」,而正因為,每一個 commit,紀錄的是基於上一個步驟所作的變化,我們可以透過 Day 15 所提到的 git cherry-pick
,不但可以把一個步驟「抄來」用,也可以把一連串的 commit 一次抄過來。
那,我可不可以在抄過來的過程中,順便整理一下這些 commit 呢?
撰寫文章的時候,在完成初稿之後,我們會透過再次閱讀,發現,可能有些文字贅字需要移除、有些文句需要重新調整,在調整完之後,可以讓整篇文章更佳的順暢。
而在製作樂高手冊的過程中,有些積木的堆積,可能有些步驟聚集成一個步驟會更清楚,有些時候則是把步驟順序調整一下,會讓手冊更容易看懂,組裝更順利。
所謂的整理 commit,也是同一件事情。有些 commit 的先後順序,前後對調之後,閱讀者就可以更了解原始碼的變更主要想達成的目的;而又些 commit 所代表的原始碼變更,可能合併在一起,在閱讀上則較不繁瑣;還有些狀況是,當下寫的 commit message 可能少描述了一些,想再次的變更修改 message 內容。這些就是整理 commit 可以做的事情。
在 GIT 中,我們可以使用 git rebase -i
這個餐數來進行調整分支的工作,-i
這個參數,全名是 --interactive
,也就是互動模式,透過互動的介面,來完成整理 commit 的目的。這邊的「互動」,回歸到 rebase 的原意「把 commit 所代表的步驟,試著在新的基點再做一次」,我們可以解釋為「把 commit 所代表的步驟,試著在新的基點,由使用者互動時所設定的方法,再做一次」。
接下來,開始以 Day 15 提到的例子,來整理一下 apple 的這個分支:
假如我們要整理從 91d27e5
這個 commit 之後開始進行分支的整理,則我們可以執行指令 git rebase -i 91d27e5
。注意參數 -i
後面所帶的 HASH Code 是指要從該 HASH Code 後開始 rebase,而在執行指令後,會進入一個編輯界面,畫面中會有提示說明,分別有操作 pick、reword、edit 等操作的方法,以下就透過實際例子說明部分指令。
如果我們要針對 commit 660033a
的 commit message 作修改調整,則同樣的執行指令 git rebase -i 91d27e5
,因為目的是要調整 660033a
的 commit message 則我們在這個 commit 上標示,把原本標示pick
的字樣,改為 reword
,則在送出編輯之後,GIT 就會針對你設定為 reword 的這個 commit 詢問要修改的訊息內容。
在這邊用到 pick
代表使用這個 commit,內容不動。reword
代表,使用這個 commit,但修改 commit message。
使用 CLI 達成:
reword
91d27e5
之後的 HASH Code 都改變了。這是因為從 91d27e5
之後的 commit 都重新作了一次,自然會重新產出新的 HASH Code。使用 SourceTree GUI 達成:
同樣的執行指令 git rebase -i 91d27e5
,因為我們要合併 add apple 2 和 add apple 3 兩個 commit ,因此,我們需要把 430e431 這個 commit 的 pick 修改為 squash
代表和上一個 commit 合併在一起。
430e431
commit 為 squash
同樣的執行指令 git rebase -i 91d27e5
,進入編輯模式之後,只要把要調換的 commit 進行行對調即可。
62dacb9
及 430e431
兩個 commit 的順序
上面的例子中,每次其實可以作的動作不只一種,只是為了簡化範例,因此每個範例中都只做一個動作,也方便記憶,再重新整理分支的時候,可以一次調整多個,合併之後順便調整合併後的 commit message 等動作都是可行的。git rebase -i
還有很多指令可以使用,例如與 squash 類似的 fixup,都可以在嘗試執行,在這個章節就只針對比較常用的方法做介紹。
整理及調整 commit 的目的在於讓同樣使用這個儲存庫的人員,可以快速的了解原始碼變化的目的及原因,進而更快的容易這個儲存庫所存在的目標。所以在正式提交儲存庫之前,再次 review 目前尚未提交的儲存庫也是必要的過程。