LoginSignup
0
0

More than 5 years have passed since last update.

PowerShell を使った、 git のまとめて unstage

Last updated at Posted at 2018-09-07

initial commit 時、.gitignore に追加するべきだったのにその前に staging してしまった。
それらの一部をまとめて unstage

git status | ?{$_.Contains("hoge")} | %{$_.Split() | select -l 1} | %{git rm --cached $_}

説明

一つ目のパイプライン

PowerShell 以外のコマンドから渡されるのはほぼ全て string[]
Foreach-ObjectWhere-Object ではこれを1行ずつ処理する。
?Where-Object のエイリアス、 {} 内が true になったものだけを返す。
$_ は現在のループで回してる 1 オブジェクト。
ここでは string.Contains() を使って "hoge" が含まれてる行だけを返してる。

二つ目のパイプライン

%Foreach-Object のエイリアス、 一オブジェクト毎に {} 内を実行する。この場合、 1 行が 1 string。
string.Split() で 1 行の string をスペース区切り で string[] にしてる。
Split(';') とかすれば、 セミコロン区切りにできる。何も指定しないとスペース区切り。


new
file:


hoge/fuga/foo/bar

という感じになる。
スペースが続いてるところをひとつの区切りとしてくれないので、1個以上のスペースを区切りにしたければ、 $_ -split '\s'+ などと正規表現を使うと良いでしょう。
それで、これをパイプラインで渡す。

3つ目のパイプライン

2つ目のパイプラインの中の Foreach-Object 内でのパイプライン
selectSelect-Object のエイリアス。
-l-Last を略したもの。PowerShell のパラメーターは一意に決まるだけ書いてあれば問題無い。
つまりパイプラインで渡されたオブジェクトの Last の 1 個を返すので、
上の例で言う hoge/fuga/foo/bar になる。

4つ目のパイプライン

ここまでで hoge が含まれている行のパスだけが string として渡されているので、これを最後に git コマンドに渡してあげればよい。

最後に

contains に渡す文字列を変えて、最後の git コマンドを変えるだけでもいろいろと応用できる。
svn status でもパスは行末にくるので svn にも応用可。

他の例

git status | ?{$_.Contains('modified')} | %{$_.Split() | select -l 1} | %{git checkout -- $_}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0