Git ログの圧縮法

何かのプロジェクトをバージョン管理をしていると,しばしば,

  • こまめにコミットしたい
    • その方が修正とかも効きやすいし,変更も追いやすい
    • ログも細かくなる分だけ分かりやすくなる
  • でもログが細かすぎるのは嫌だ
    • 後でざっと見返すときは大雑把な方がいい
    • 半端な状態のリビジョンを扱いたくない

という板挟みになります.


で,そういったとき, Git なら,
「基本的には大雑把な履歴で管理するけど,細かいログも残す」
という事が可能なので,その方法について軽くまとめてみました.

基本

master ブランチとは別に作業用ブランチを用意し(例えば work とか),普段はそこで細かく commit します.

$ git checkout -b work

(作業)
$ git commit -am "A"
(また作業)
$ git commit -am "B"
(もいっちょ)
$ git commit -am "C"

( ... )

ある程度 作業が溜まったら,キリのいいところで master に切り替え,
git merge --squash で work の変更を適用したら,適切なコメントと共に commit します.

$ git checkout master
$ git merge --squash work
$ git commit -m "ABC"

こうすることで, work には細かめのログを, master は整理されたログを,それぞれ残せます.


なお,二回目以降, merge の際に conflict が発生する場合もありますが,
その場合は merge オプションを

$ git merge --squash -s recursive -X theirs work

とすれば,殆どのケースで問題なく merge できます.

発展

うっかり merge するのを忘れていた場合など, work での進展を複数 commit に分けて master に適用したい場合には,
work の log を見てキリの良い commit の ID を調べ,そこに対して merge --squash します.

$ git checkout work
(作業して D 〜 F および G, H を commit )

$ git checkout master

$ git log --oneline work
23c5fb0 commit H
b617833 commit G
03fea7a commit F
ad0cad8 commit E
dab58a3 commit D

$ git merge --squash -s recursive -X theirs 03fea7a
$ git commit -m "DEF"

必要ならば,さらに別の commit に対して merge --squash していきます.
最後の commit は, work に対して merge --squash すれば大丈夫です.

$ git merge --squash -s recursive -X theirs work
$ git commit -m "GH"

できそうなこと

以下は,後で調べるための「できそうなこと」メモです.

  • cherry-pick -n を使うと「 D, E, G を一つの commit にまとめる」とかできそう
  • merge 時のオプション指定は,もしかしたら .gitconfig で設定できるかも?
  • っていうか conflict させない方法がありそうなので,調べる

何か知っていることがある方は,是非お教えください m(_ _)m