git add -p が使えない場合の代替操作

Gitに乗り換えよう、と決意したきっかけの1つが
 「変更したファイルの一部だけをコミットできる」点。

しかしそのためのコマンド、
 git add -p
が、何故か使えませんでした・・・*1


 git add -i
で代替する操作方法。




きっかけは、機能追加中にPHP Noticeが出てることに気づいた*2ので、Noticeつぶし分だけコミットしようとしたこと。

git add -pした場合の結果。

[cake@cake AjaxChat]$ git add -p lib/trpg.php
usage: git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--] <filepattern>...

「-p? そんなオプションはねえ!」って言われましたー (T-T)


でも、この
 [--interactive | -i]
というのが、引っかかる。


interactive な git addの使い方に参考したサイト。
http://progit.org/book/ja/ch6-2.html

では、git add -iした場合に表示される、「5: patch」のコマンド指定して。。

[cake@cake AjaxChat]$ git add -i
           staged     unstaged path
  1:    unchanged       +20/-7 lib/trpg.php
  2:    unchanged        +2/-1 setup/orig/config-data-trpg.php
  3:    unchanged        +1/-1 write.php

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now> 5
           staged     unstaged path
  1:    unchanged       +20/-7 lib/trpg.php
  2:    unchanged        +2/-1 setup/orig/config-data-trpg.php
  3:    unchanged        +1/-1 write.php

コミットしたい差分が含まれるファイル、「1」を選んでみる。

Patch update> 1
diff --git a/lib/trpg.php b/lib/trpg.php
index cba4bbd..c08e165 100644
--- a/lib/trpg.php
+++ b/lib/trpg.php
@@ -10,10 +10,14 @@
  * 入力内容をダイス変換
  */
 function convert_dice($string) {
+    if (!isset($GLOBAL['AJAX_CHAT_TRPG']['count'])) {
+        $GLOBAL['AJAX_CHAT_TRPG']['count'] = 0;
+    }
+
     // 基本ダイス変換
     // [2d6+5@u(l)o4cr6mfz1]/3
     if (preg_match("/(.*)[[]([0-9]+)(d)([0-9]+)([-\+\*\/\s]*[0-9-\+\*\/\s]*)@?([ul][0-9]+s?o?)?(cr?[0-9\-]+m?)?(f?z?[0-9\-]*)[\]]([\/\*]{0,1}[1-9]*)(.*$)/i", $string, $dice)) {
-        $GLOBAL['AJAX_CHAT_TRPG']['count_one'] = true;
+        $GLOBAL['AJAX_CHAT_TRPG']['count']++;
         $dice_result = dice_convert($dice[2], $dice[4], $dice[5], $dice[6], $dice[7], $dice[8], $dice[9]);
         $string = $dice[1].$dice_result.$dice[10];
     }
Stage this hunk [y/n/a/d/j/J/s/?]? 

このファイルの全差分が出てるっぽい。


先程の参照サイトを参考に、
「s - split the current hunk into smaller hunks」
をしてみる。

Stage this hunk [y/n/a/d/j/J/s/?]? s
Split into 3 hunks.
@@ -10,4 +10,8 @@
  * 入力内容をダイス変換
  */
 function convert_dice($string) {
+    if (!isset($GLOBAL['AJAX_CHAT_TRPG']['count'])) {
+        $GLOBAL['AJAX_CHAT_TRPG']['count'] = 0;
+    }
+
     // 基本ダイス変換
Stage this hunk [y/n/a/d/j/J/?]?

よし!差分一箇所だけになった!! (^^)


では差分ごとにadd指定。
ひとまずこれはまだコミットしないので「n」と・・・

Stage this hunk [y/n/a/d/j/J/?]? n
@@ -13,3 +17,3 @@
     // 基本ダイス変換
-        // [2d6+5@u(l)o4cr6mfz1]/3
+    // [2d6+5@u(l)o4cr6mfz1]/3
     if (preg_match("/(.*)[[]([0-9]+)(d)([0-9]+)([-\+\*\/\s]*[0-9-\+\*\/\s]*)@?([ul][0-9]+s?o?)?(cr?[0-9\-]+m?)?(f?z?[0-9\-]*)[\]]([\/\*]{0,1}[1-9]*)(.*$)/i", $string, $dice)) {
Stage this hunk [y/n/a/d/K/j/J/?]?

次の差分が表示されました。

この調子で指定していくと、

Stage this hunk [y/n/a/d/K/j/J/s/?]? n
@@ -248,9 +261,9 @@ function dice_main($dicenum, $dicenumber, $revision, $c, $f, $pickup) {

             // ファンブルは0点の場合
             if (preg_match("/^fz([0-9]+)([\-]*)$/i", $f)) {
-                define(F_ZERO, true);
+                define('F_ZERO', true);
             } else {
-                define(F_ZERO, false);
+                define('F_ZERO', false);
             }

             // roll
Stage this hunk [y/n/a/d/K/j/J/s/?]?

あ、これは要る。
 と思ったら、「y」。

Stage this hunk [y/n/a/d/K/j/J/s/?]? y
@@ -310,7 +323,7 @@ function dice_main($dicenum, $dicenumber, $revision, $c, $f, $pickup) {

                         // 合計値
                         //最大値のみ加算する場合
-                        if ($pickup_one) {
+                        if (isset($pickup_one) && $pickup_one) {
                             if ((int)$d_result[$i]['add_number'] > (int)$d_result['result_max']) {
                                 $d_result['result_max'] = (int)$d_result[$i]['add_number'];
                             }
Stage this hunk [y/n/a/d/K/j/J/?]?

以下略。


ファイルの終端まで行ったら、コマンド選択画面に戻ります。

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now> 7
Bye.

他に追加点無いので、「7:quit」。


部分指定できたことを確認。

[cake@cake AjaxChat]$ git status
# On branch trpgchat_ver263
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   lib/trpg.php
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   lib/trpg.php
#       modified:   setup/orig/config-data-trpg.php
#       modified:   write.php
#
[cake@cake AjaxChat]$ git diff lib/trpg.php
(略)

あとはgit commit!

*1:gitバージョンは1.5.2.1。svnとの競合性保つためにyumインストールなのでバージョン変更したくない。

*2:環境依存性が高めのNoticeなので、サーバ環境変える前は出てなかった。

*3:partialだと思ってた ^^;