ということで、今更ですけど git は便利ですね〜。もう subversion には戻れません。気が向いたので、個人的に気に入っていることをちょっと書いてみます。

1) 直前のコミットに対して、コミットし忘れたものを追加できる

よくありがちなパターンですね。一通りコミットしたあとに「あっ!○○をコミットし忘れた!」とか、「××を一カ所修正し忘れていた」みたいなことってあると思います。subversion だとそういうのでコミットが増えて履歴が汚くなってしまうものですが、git だと簡単に直前のコミットに忘れてたものを追加して隠蔽(笑)することが可能です。

例えば hoge というファイルをコミットし忘れた場合を考えてみます。

$ touch hoge fuga foo
$ git add fuga foo # hoge を add し忘れた!!
$ git commit -m "add new"
$ git log --oneline
7a99ab5 add new

hoge を add し、コミットするときに特殊な --amend というオプションを使います。エディターが立ち上がるのでメッセージを指定しましょう。原理的には直前のコミットは捨て、新規にコミットを行い、それを最新コミットとして利用することになるので、ハッシュ値 (subversionのリビジョンにあたるもの) が変わります (7a99ab5 → d83385f) 。

$ git add hoge
$ git commit --amend # --amend を付ける!!
$ git log --oneline
d83385f add new

コミットメッセージは変える必要がない場合はこのように -C HEAD を付ければエディターは起動しません(直前のコミットメッセージがそのまま使われます)。

$ git commit -C HEAD --amend

2) 複数のコミットを一つのコミットとしてまとめられる

こちらも便利です。ブランチを作ってそこで開発しているとコミットが増えて履歴が汚れてしまったりします。それを master にマージするタイミングで、複数あるコミットを一つのコミットにすることが出来れば奇麗ですね。

適当に hoge, fuga, foo を変更し、それらを別々にコミットしたとします。そのとき git log はこのようになっているはずです。

$ git log --oneline
3fbdd3b modify foo
8442811 modify fuga
90880ea modify hoge
d83385f add new

では hoge, fuga, foo を修正したコミットを一つにまとめてみましょう。このコマンドを使います(HEAD~3 の 3 は最新の三つのコミットを対象とする、という意味です)。

$ git rebase -i HEAD~3

そうするとこのような編集画面が立ち上がってきます。

pick 90880ea modify hoge
pick 8442811 modify fuga
pick 3fbdd3b modify foo

# Rebase cf088d4..3fbdd3b onto cf088d4
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.


デフォルトでは pick が選択されており、このままだと上から順に "90880ea modify hoge" → ”8442811 modify fuga” → "3fbdd3b modify foo" とそのままコミットが採用されます。ここの pick を squash に変更することで、あるコミットでの変更内容を別のコミットに含めることが可能です。

pick 90880ea modify hoge
s 8442811 modify fuga
s 3fbdd3b modify foo

例えばこのように変更しすると、まず "90880ea modify hoge" のコミットが採用されます。その次に ”8442811 modify fuga” が処理されますが、このコミットには squash が指定されているのでこの変更内容はその前のコミット ("90880ea modify hoge") に含まれます。さらにその次の "3fbdd3b modify foo" での変更内容もその前のコミット ("90880ea modify hoge") に含まれます。

結局コミットは一つしか行われないわけです。

$ gi lo --oneline
f075ab7 modify hoge fuga foo
d83385f add new

というわけで・・

git は強力なツールで、ほんとにいろいろなことが出来ます。今回紹介したのはあくまでも一部で、ログ周りばかりでしたが、個人的に特に気に入っているものでした。

あ、大事なことを書き忘れてました。これらの変更が行えるのはあくまで手元のコミットに対してだけで、リポジトリに push してしまったコミットに対して行うことは出来ません。それが出来てしまうと同じリポジトリを使っている多数の人に影響が出ちゃいますので。

というわけで、git を使いこなしてかっこよくキーボードを叩けるようになりたいですね!

地獄のミサワ
このエントリーをはてなブックマークに追加