1. 程式人生 > >git合併多個commit壓縮成一個點

git合併多個commit壓縮成一個點

原文地址:http://platinhom.github.io/2016/01/02/git-combine_commit/

有時commit多了看著會不爽.所以想合併掉一些commit. 這裡是最簡單的情況, 一條線下來N個commit, 合併掉末端的(沒有branch出去的).

假設有a,b,c,d四個commit, 從新到舊是a, b, c, d (也就是先d->c->b->a). 四個commit的SHA-1分別是a1,b1,c1,d1.

合併commit只能倒退, 就是說把a合到b(老的),順序是abc可以合併起來成k, 最後成k, d這樣.

過程:

# git log |head 
git rebase 
-i d1 # if fail, use git rebase --abort git push --force
  1. git log可以檢視commit的情況, 配著head命令可以檢視前幾個. git log --pretty=oneline一行一個commit更好了
  2. rebase前需要把狀態push掉. 就是說不能有unstaged的修改.
  3. -i 是選擇不動的commit, 比他新的commit都有被修改的可能.
  4. 執行rebase後如果出錯或者merge衝突什麼退出來, rebase會被鎖定, 再次執行時, 提示有三個選項:
    • git rebase --abort來忽略之前的rebase嘗試,並恢復HEAD到開始的分支.
    • git rebase --continue就繼續上次修改, 一般是rebase中間處理merge衝突後使用.
    • git rebase --skip是重新開始rebase並跳過現在所進行的處理.
  5. 執行rebase後會像commit一樣進入編輯狀態, 在開始會是幾個commit的SHA值, 從上到下是越來越新的commit. 如果沒有比-i指定的心的話會出現noop.
  6. 開始狀態所有出現的commit前面都是pick. 這個pick是對該commit進行的操作, 有:
    • pick就是說保留該commit, 也可以用縮寫p. (黃色)
    • squash, 使用該commit但合併到前一個老的commit去(常用). 可以用縮寫s
      代替 (綠色).
    • reword, 和pick類似, 但可以修改commit時的提交資訊(中間會彈出來讓你修改commit).可以用縮寫r代替 (紫紅色).
    • edit, 使用commit, 但停下來進行修改, 可能用於merge衝突.可以用縮寫e代替.
    • fixup, 和squash類似, 但會捨棄commit資訊. 可以用縮寫f (紅色)
    • exec, 執行shell命令.可以用縮寫x
  7. 如果該commit是空commit, 前面會被註釋掉#. 會被自動刪除.
  8. 執行完修改後,:wq退出vi, 這時開始進行rebase操作(1/10 這樣倒數). 中間會再次彈出修改檔案, 此時是修改commit資訊, 可以修改每次commit的資訊(如果是fixup會忽略掉commit提交資訊). 最後這個合併後的新commit顯示的資訊可能是多個commit的集合(多行).不想修改或改完後直接:wq退出vi即可.
  9. 所以都完成後需要一次強制的push, 要加入--force覆蓋掉github上的commit.git push --force

例如我上面-i d1會修改3個commit, 保留最老最上最靠近d1的c (用reword或者pick都可以),其餘a1和b1合併掉(squash或者fixup).最後生成一個新commit叫c2(就是3個合在一起了).所以從新到舊有c2, d1.