gitでコミットをいくつか進めているうちに「以前のコミットにこの修正もまとめたい」ということが結構ある。
そういう場合に fixup と autosquash が使える。
squash
加えたい修正が直前のコミットに対してだったら commit --amend によるコミットの訂正で対応できる。
いくつか前のコミットだった場合には rebase -i でのインタラクティブ編集画面で過去のコミットを edit にして状態を戻してから編集するか、
修正をコミットしておき rebase -i でコミット順を並べ替えて pick を squash に変更してまとめてやる必要がある。
例えば以下のような状態の時:
$ git log --oneline |
「1つ目の修正コミット」を「1つ目のコミット」にまとめたい場合、 git rebase -i HEAD~3 として表示されるコミット履歴を編集する:
pick 904b22f 1つ目のコミット |
するとまとめるコミットのメッセージ編集画面が開いて、それを保存して閉じることでまとめられる。
fixup
上記の手順で、 squash の代わりに fixup とすることで、メッセージの編集をスキップすることができる。
fixup に指定したコミットメッセージは破棄され、その上のメッセージが維持されるので、簡単にまとめることができる。
fixup に関しては rebsae -i の編集画面に説明がされている:
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous |
commit –fixup
squash や fixup でまとめる時にコミット順を自分で入れ替えるのが面倒。
そこで修正コミットを commit するときにオプションで --fixup <対象コミット> とすることで簡単に行うことができる。
例えば上記の「1つ目の修正コミット」をコミットする際に、 git commit --fixup 904b22f と
「1つ目のコミット」のハッシュ値を指定することで、そのコミットに対する修正コミットだということを指定できる:
$ git commit --fixup 904b22f |
コミットメッセージは自動的に「fixup! (対象コミットのタイトル)」となる。
rebase –autosquash
commit --fixup は単にコミットが追加されるだけなので、 rebase -i してやる必要がある。
その際に --autosquash というオプションを指定すると自動的に並び替えられた状態で表示してくれる:
$ git rebase -i --autosquash HEAD~3 |
そのまま保存して閉じれば目的が達成される。
--autosquash オプションを毎度指定するのも面倒なので、 gitconfig に指定することで自動的にできる:
$ git config --global rebase.autosquash true |
エイリアス登録
fixupとautosquashの手順が分かれているが、気持ちとしては1動作で済ませたい。
そこでエイリアスを登録してやる。
ここではエイリアス名を fix とする:
# .gitconfig |
直接.gitconfigファイルを編集してもよいし、 git config --global --edit で編集してもよい
(コマンドラインから直接 git config --global alias.fix ... と登録するのは、エスケープが大変なのでおすすめしない)。
これによって修正コミットを git fix <対象コミット> とすることで、自動的に変更を対象コミットに適用できる:
$ git fix 904b22f |
エディタも開かずに勝手に適用して欲しいが、そこまではわからなかった。
以下に追記:
エディタを開かずに修正する
Git interactive rebase without opening the editor - Stack Overflow
にエディタを開かない方法が書かれていた。
rebase のオプションに -c sequence.editor=: を指定すればよい:
# .gitconfig |