by shigemk2

当面は技術的なことしか書かない

git add -p

git add と git rebase のちょっと応用的な使い方(add -p, rebase -i) - アジャイルSEを目指すブログ

hunk

gitでコミットしたとき、通常はファイルごとにまとめてコミットすると思われますが、
hunkを使って変更箇所ごとにコミットすることが可能となります。

git add -p

git add -p を使うことで、変更したコードの一部だけをStagedに上げることが出来ます。

まずこんな感じのコード(hoge.php)があったとしましょう。

<?php
function hoge($a) {
  $a = $a + 5;
  return $a;
}
var_dump(hoge(5));

それをこういう風に変更したいとします。

<?php
<?php
function hoge($a) {
  for($i = 0; $i < 5; $i++) { // 変更1
    $a *= $a;
  }
  return $a;
}
var_dump(hoge(10)); // 変更2

同じファイルの中の変更だけど、関数の中身の変更(変更1)と関数を呼び出す引数の値の変更(変更2)を
別々のコミットにしたい。

こういうときはgit add -pを使うとよいでしょう。

1. git add -pを実行する

$ git add -p hoge.php

2. するとこういう風なメッセージが表示される

diff --git a/hoge.php b/hoge.php
index e1c6739..28539e1 100644

@@ -1,6 +1,8 @@

  • $a = $a + 5;
  1. for($i = 0; $i < 5; $i++) {
  2. $a *= $a;
  3. }

return $a;
}

  • var_dump(hoge(5));

\ No newline at end of file

  1. var_dump(hoge(10));

\ No newline at end of file
Stage this hunk [y,n,q,a,d,/,s,e,?]?

3. ここで、sを叩く

Split into 2 hunks.
@@ -1,5 +1,7 @@

  • $a = $a + 5;
  1. for($i = 0; $i < 5; $i++) {
  2. $a *= $a;
  3. }

return $a;
}
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]?

修正が2つのhunkに分割され、前半部分の修正(変更1)をStagedに上げるかどうか聞いてくる。

4. ここでyを叩く

変更1がstageされてる。次に変更2をstageするかどうか聞いてくる。

@@ -4,3 +6,5 @@
return $a;
}

  • var_dump(hoge(5));

\ No newline at end of file

  1. var_dump(hoge(10));

\ No newline at end of file
Stage this hunk [y,n,q,a,d,/,K,g,e,?]?

5. ここでnを叩く

すると、変更1のみがstageされているのが分かる。

$ git status -v
(前半省略)
diff --git a/hoge.php b/hoge.php
index e1c6739..5bb2f74 100644

@@ -1,6 +1,8 @@

  • $a = $a + 5;
  1. for($i = 0; $i < 5; $i++) {
  2. $a *= $a;
  3. }

return $a;
}
var_dump(hoge(5));
\ No newline at end of file

なお、egg.elでも同様のことが出来るので、やってみたらよいと思うよ。