2013年9月20日金曜日

git stashで一部ファイルのみ入れる方法がわからない件

↑これは「git stash」って調べたら出て来た画像。なんだろう・・・


git stashに一部のファイルのみ指定してstashするコマンドが見つからなかった話・・・orz
どうしてこんなにあったら良いなって感じなのに無いのか、それとも知らないだけか
$git stash -p とかそれっぽいと思ったけどそんなことなかった。

git helpを見てみると知らないのとか多くて最近はおもしろい、git bisectとかgit blameとかあついよね!!

でもよく考えればgitコマンド打ちまくれば実現できるよね。。。ってことでちょっと書いてみた。 情弱iosエンジニアの僕(@jumbOS5)ががんばってみたのですがとんだクソコードが完成しましたね!
以下のような感じで使えます。


jumbosmba:stash_test hanedakentarou$ git status
# On branch master
# Changes not staged for commit:
# modified: first.html
# modified: test.php
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#no changes added to commit (use "git add" and/or "git commit -a")

$ php git.php  "こんな感じでtest.phpのみstash"  test.php
git status
git stash save "all"
git stash apply stash@{0}
git checkout  first.html
git stash save "こんな感じでtest.phpのみstash"
git stash apply stash@{1}
jumbosmba:stash_test hanedakentarou$ git stash list
stash@{0}: On master: こんな感じでtest.phpのみstash
stash@{1}: On master: all
stash@{2}: On master: first.html
stash@{3}: On master: all
stash@{4}: On master: save
stash@{5}: On master: all
stash@{6}: WIP on master: 705285f etet
stash@{7}: On master: all
stash@{8}: On master: kore
stash@{9}: On master: all
stash@{10}: WIP on master: 6003aaf 43
stash@{11}: WIP on master: b7092fa sas
stash@{12}: WIP on master: b7092fa sas
stash@{13}: WIP on master: b7092fa sas

$ git status
# On branch master
# 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:   first.html
# modified:   test.php
#
no changes added to commit (use "git add" and/or "git commit -a")

jumbosmba:stash_test hanedakentarou$ git stash show stash@{0}
  test.php | 2 ++ 1 file changed, 2 insertions(+)


ソースは以下
やってることは実行してもらえばわかるのですが

1, stashしてmodifiedになってるファイル記憶
2, いったん全部stash
3, もとに戻す
4, 引数のファイル以外checkout
5, 残った引数指定のファイルをメッセージ付きでstash
6, 2でstashしたファイル達を元に戻す
という。shellで書けば良かったとかなぜこんな書き方をしたのか後悔しか無いのですが
とりあえずあげておきます


一部のmodifiedのファイルのみstashするだけなのにすごく冗長的なスクリプト
 
/* git.php みたいな
   *使い方*
   $ php git.php "stash message" [stash_filepath1] [stash_filepath2]...
 */
$result = "";
$out = "";

$modifiedTexts = array();
$stashMessage = setStashMessage($argv);
$gitCommand = array("git status ","git stash save \"all\" ","git stash apply stash@{0} ","git checkout ","git stash save ","git stash apply stash@{1}");

foreach($gitCommand as $key => $command ){
  $commandResult = "";
  $commandOut = "";
  switch( $key ) {
  case 0:{
    echo $command."\n";
    exec($command, $commandResult, $commandOut);
    $modifiedTexts = saveModifiedList($commandResult);
    break;
   }
   case 1:{
    echo $command."\n";
    exec($command, $commandResult, $commandOut);
    break;
   }
   case 2:{
    echo $command."\n";
     exec($command, $commandResult, $commandOut);
    break;
   }
   case 3:{
    // 引数のソースをcheckout
    $checkoutCommnadParams = "";
    //var_dump($modifiedTexts);
    foreach($modifiedTexts as $modifieTxt){
     if(isCheckoutFileName($argv, $modifieTxt)){
      $checkoutCommnadParams .= " ".$modifieTxt;
     }else{
      //echo "is not able checkout ".$modifieTxt;
     }
    }
    $checkoutCommad  = $command.$checkoutCommnadParams;
    print( $checkoutCommad."\n");
    exec($checkoutCommad, $commandResult, $commandOut);
      
    break;
   }
   case 4:{
    $saveCommand = $command."\"".$stashMessage."\"";
    echo $saveCommand."\n";
    exec($saveCommand, $commandResult, $commandOut);
    break;
   }
   case 5:{
    echo $command."\n";
    exec($command, $commandResult, $commandOut);
    break;
   }

   default:
    break;
  }
}

function setStashMessage($params){
 /*$result;
 foreach($params as $param){
  //print($param."\n");
  preg_match_all('/\"(.*)\"/', $param, $result, PREG_PATTERN_ORDER);
  //var_dump($result);
  
  if(isset($result[0][0])){
   echo $result[1][0] . " <= is Stash message; \n";
   return $result[1][0];
  }
 }

 echo "not enter stash message; \n";
 return false;
  */
 return $params[1];
}

// stash指定されたもの以外checkoutする判定
function isCheckoutFileName($stashFileNames, $filename){
 //echo $filename;
 //var_dump($stashFileNames);
 foreach($stashFileNames as $stashName){
  if($filename == $stashName){
  return false;
  }
 }

 return true;
}

function saveModifiedList($status_result){
 $resultFileNames = array();;

 foreach($status_result as $value){
  $output = "";
  preg_match_all('/modified:\s\s\s(.*)/', $value, $output, PREG_PATTERN_ORDER);
  if(isset($output[1][0])){
   array_push($resultFileNames,$output[1][0]);
  }
 }
 return $resultFileNames; 
}

0 件のコメント:

コメントを投稿

ShareThis