特技はgit commit -a -m いろいろ修正
です!
ダメ。ゼッタイ。
しかしこまめにコミットするのは面倒臭いですよね。でもrebaseやらrevertやらcherry-pickするにもコミットログは綺麗にしたい。そんなズボラで凝り性なあなたはgit add -p
でコミットを整えるといいと思います。
1: 芹沢鴨
2: 原田左之助
3: 藤堂平助
4: 沖田総司
5: 山南敬助
適当な名簿があったとします。ここでは1コミットにつき1行の変更するのが決まりとしましょう。
下のように変更してみました。
-1: 芹沢鴨
+1: 近藤勇
2: 原田左之助
3: 藤堂平助
4: 沖田総司
-5: 山南敬助
+5: 土方歳三
さてこのままgit add
すると両方の変更が一度にステージングされてしまいます。
そこでgit add -p
すると以下のようなdiffがコンソールに表示されます。
diff --git a/members b/members
index 15440ce..1f43716 100644
--- a/members
+++ b/members
@@ -1,5 +1,5 @@
-1: 芹沢鴨
+1: 近藤勇
2: 原田左之助
3: 藤堂平助
4: 沖田総司
-5: 山南敬助
+5: 土方歳三
Stage this hunk [y,n,q,a,d,s,e,?]?
変更のひとかたまり(ハンク)を表示し、そのハンクに対しての指示を待ち受けます。サンプルが小さいのですべて表示されますが、ハンクの間が7行以上空くと別のハンクとして扱われます。
変更を分割する
コミットを分割するのが目的なのでここでs
を入力します。
Split into 2 hunks.
@@ -1,4 +1,4 @@
-1: 芹沢鴨
+1: 近藤勇
2: 原田左之助
3: 藤堂平助
4: 沖田総司
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?
するとハンクが2つに分割され、diffの表示される範囲が狭まり一人だけの変更になりました。y
でこの変更をステージングしましょう。
さらに次のハンクが表示されステージングするか否か選べますがひとまずn
でスキップするかq
で終了します。
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: members
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: members
#
git status
を見るとmembersステージされているにもかかわらずワークスペースに残った状態になってますね。
ここでgit diff
を見ると
@@ -2,4 +2,4 @@
2: 原田左之助
3: 藤堂平助
4: 沖田総司
-5: 山南敬助
+5: 土方歳三
最終行の変更だけが残っています。
そしてステージングされた状態を確認するためにgit diff --cached
すると
@@ -1,4 +1,4 @@
-1: 芹沢鴨
+1: 近藤勇
2: 原田左之助
3: 藤堂平助
4: 沖田総司
先頭の変更だけがステージングされていますね。
これで1つの変更だけどコミットすることができます。
さらに分割する
ハンク同士が1行以上空いている場合はs
で分割できますが、連続する行の場合はそうはいきません。
@@ -1,5 +1,5 @@
1: 芹沢鴨
-2: 原田左之助
-3: 藤堂平助
+2: 斎藤一
+3: 永倉新八
4: 沖田総司
5: 山南敬助
Stage this hunk [y,n,q,a,d,/,e,?]?
このように変更した行が連続する場合s
が使えません。もしこの状態を分割したい場合はe
で直接編集する必要があります。
# Manual hunk edit mode -- see bottom for a quick guide
@@ -1,5 +1,5 @@
1: 芹沢鴨
-2: 原田左之助
-3: 藤堂平助
+2: 斎藤一
+3: 永倉新八
4: 沖田総司
5: 山南敬助
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.
e
を押すとエディタが立ち上がり、diffの編集画面になります。元の状態からの差分を記述することでその変更を適用することができます。
# Manual hunk edit mode -- see bottom for a quick guide
@@ -1,5 +1,5 @@
1: 芹沢鴨
-2: 原田左之助
+2: 斎藤一
3: 藤堂平助
4: 沖田総司
5: 山南敬助
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.
上記のように内容を変更し保存するとステージングとして適用されます。ちなみにdiffとして正しければ何を書いてもいいのでこの画面で変更をさらに変更することもできます。フォーマットがおかしかったり差分が解決できない場合はステージングされません。
@@ -1,5 +1,5 @@
1: 芹沢鴨
-2: 原田左之助
+2: 斎藤一
3: 藤堂平助
4: 沖田総司
5: 山南敬助
これで連続した行の変更を分割してステージングすることができました。
これで綺麗なコミットログがつくれるね!
とは言うものの変更が増えた後にいちいちハンクを分割してコミットだのやってられないので作業のスコープをちゃんとしぼってこまめにコミットしたほうがいいと思います。ちなみに僕の特技はgit commit -a -m いろいろ修正
です!
おまけ:git add -pした時のコマンド一覧
-
y
- このハンクをステージングする -
n
- スキップする -
q
- 終了する -
a
- 以降のハンクをすべてステージングする -
d
- 以降のハンクをすべてスキップする -
g
- 指定したハンクへ移動 -
/
- 正規表現によるハンクの検索 -
j
- 未確定な次のハンクへ移動する -
J
- 次のハンクへ移動する -
k
- 未確定な前のハンクへ移動する -
K
- 前のハンクへ移動する -
s
- ハンクを分割する -
e
- 手動で現在のハンクを修正する -
?
- ヘルプを表示する