この記事ではファイルに対して行った変更を部分的にstageする方法を解説します。
最近、左隣に座っている先輩にこれから解説するgitの機能を教わりました。めちゃくちゃ便利です。
この方法を知るまではファイルに対して行った変更をその都度コミットすることが億劫で、git commit -m “色々変更” みたく、無茶苦茶なコミットを量産していました。部分的にstageする方法を知ってからは、何を変更したのかわかりやすいコミットが出来ています。(そう信じてる)
前置きはこのくらいにしておいて、さっそく解説します。
git add -p filenameを使う
-p(–patch)オプションを使うことで、変更を部分的にstageすることができます。例として以下のコードを使います。このコードに色々な変更を加えたときに、その変更を部分的にstageすることを通して、pオプションの使い方を解説します。
1 def add(x、 y):
2 """x+yの結果を返す"""
3 return x + y
4
5 def sub(x、 y):
6 """x-yの結果を返す"""
7 return x - y
このファイルに次のように変更したとします。
1 def add(x、 y):
2 return x + y
3
4 def sub(x、 y):
5 return x - y
6
7 def mul(x、 y):
8 return x * y
・関数の説明を消去
・掛け算の関数を追加
この2つの変更を加えました。
git diff calculator.pyでみると下画像のようになります。

git add -p calculator.pyとして、部分的にstageしていきます。

対話的にコマンドを入力していき、hunkと呼ばれる変更の1つの塊をstageしたり、しなかったりしていきます。ヘルプの意味は大体以下の通りです。
- y – 現在のhunkをstageする
- n – 現在のhunkをstageしない
- q – 終了する
- a – 現在のhunkとこれ以降のhunkをstageする
- d – 現在のファイルのhunkを何もstageしない
- s – 現在のhunkをより小さいhunkに分ける
- e – 手動でhunkを編集する
- ? – ヘルプを出力
s – hunkを小さく分割
関数の説明を削除した変更と、mul関数を加えた変更を別々にコミットしたいとします。現在のhunkは両方の変更が含まれているので、sを入力しenterを押すことでhunkを分割します。


sを入力しhunkをうまく分割できました。次のyを入力しenterでこのhunkをstageします。

次のhunkもコメント削除の変更なので、yを入力しenterでstageします。

次のhunkはmul関数追加の変更なのでstageしません。qを入力しenterを押して終了します。git diff –staged calculator.pyでステージングエリアとHEADの差分を見てみます。

きちんとコメントの削除のみがstageされていることがわかります。
e- 手動でhunkを編集
ここでは今まで行ったことをhunkを手動で編集することで実現してみます。 実は今回のようにsでhunkをうまく分割できる場合と、sを押してもそれ以上分割できない場合があります。そんなときはeでhunkを手動で編集します。早速eを入力し、enterを押します。

行頭に”+”か”-“がついている行が変更された行で、”+”は追記、”-“は削除を意味します。”+”の変更をstageしたくない場合には”+”の行をそのまま削除、”-“の変更をstageしたくない場合には”-“を” “(半角スペース)に置き換えます。ここでは関数の説明を削除した変更をstageしたいので、”+”の行(mul関数追加の変更)を削除します。

:wqで現在のhunkの編集を終了します。git diff –staged calculator.pyでステージングエリアとHEADの差分を見てみると、関数の説明削除の変更がstageされていることがわかります。

まとめ
- git add -p filenameで対話的にステージ出来る
- sでhunkを小さく分割
- eでhunkを手動で編集