何かのプロジェクトをバージョン管理をしていると,しばしば,
- こまめにコミットしたい
- その方が修正とかも効きやすいし,変更も追いやすい
- ログも細かくなる分だけ分かりやすくなる
- でもログが細かすぎるのは嫌だ
- 後でざっと見返すときは大雑把な方がいい
- 半端な状態のリビジョンを扱いたくない
という板挟みになります.
で,そういったとき, 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