Posted at

1つのファイルを分割して、任意の範囲を git add したい

Gitでソースコードを管理していて、コミット履歴をきれいに保ちたいときってありますよね。

レビューをお願いするためであったり、変更履歴を理解しやすい形で残すためであったり、理由は様々ですが、意味のある塊でコミットを管理することはチーム開発において不可欠です。

既にソースコードを書き上げてしまったとき、どうすればコミットを分割できるかを、この記事では紹介していきます。


git add -p を使う

-p のオプションを付与するだけで、任意の範囲を add することができます。

$ git add -p <ファイル名>

すると、下図のような画面が開きます。

git_add_-p.png

hunk = '塊' です。

y を入力すれば、 +- が左端に記されている行が stage に登録されます。

n を入力すれば、何も起きません。

しかし、この塊は自動で認識されるみたいです。

そのため、より細かく git add したい場合は、 e を入力します。


任意の範囲を add する

先ほどの画面で、 e を選択すると、 vi エディタが立ち上がります。

git_add_-p_e.png

左端が + の場合は追加されたコード、左端が - の場合は削除されたコード、何もない場合は変更なしを表しています。

stageに登録したい箇所には変更を加えません。

登録したくない箇所は、 + の場合は行をまるごと削除 (viならば dd)、 - の場合は - を空白 に置換します。

選択が終われば保存し、いつも通り git commit します。


既に commit したコードを分割したい

該当箇所に rebase をかけて、 reset したのちに、 git add -p します。

$ git log --oneline -3

uptod8t 最新のコミット
tosplit 分割したいコミット
1before 分割したいコミットの1つ前

# 分割したいコミットで、 `pick` を `e` に変更して保存する。
$ git rebase -i 1before
e tosplit 分割したいコミット
pick uptod8t 最新のコミット

$ git reset HEAD~
Unstaged changes after reset:
M main.py

$ git add -p main.py

これで、任意の箇所をstageに登録できるようになりました。


最後に

勢い余って、ソースコードをガリガリ書いた後に、分割してコミットしたいと思うことがあります。

そんなとき、なかなか git add -p を紹介してくれる記事がなかったので、書いてみました。

もし、さらに良い方法等があれば、コメントでご指摘いただけますと幸いです。


参考文献

https://git-scm.com/docs/git-add