SourceTreeのカスタムアクションでマージ済みのブランチを消す

## tl;dr

```RemoveMargedLocalBranch.sh
#!/bin/sh
git branch --merged master | grep -vE '^\*|master$' | xargs -I % git branch -d %
```
をファイルに保存してSourceTreeのカスタムアクションに登録して、叩くだけで masterブランチにマージ済みのブランチが消えます。

## 想定読者

- SourceTreeからでは実行が出来ないコマンドを登録し、実行する方法を知りたい人
- マージ済みのブランチが無限にローカルにある人

## 環境

xargs コマンド使ってるので、Windows では動作しない。（というか私自身がWindowsを開発で触らないのでわからない…。（分かる方がいたら別の記事で作ってくれるとイイデスネ））

以下、バージョン。

- OS: MacOS High Sierra 10.13.1
- SourceTree: Version 2.6.3
- Git: 2.15.0

## やること
### 実行用ファイルを用意。

```RemoveMargedLocalBranch.sh
#!/bin/sh
git branch --merged master | grep -vE '^\*|master$' | xargs -I % git branch -d %
```

これをわかり易い場所に配置しておく。あまり動かさないディレクトリのほうが良いかも。(SourceTreeに再度設定するのも面倒だし）

スクリプトの説明（超ざっくりで雑）
- `#!/bin/sh`: Shebangです。 **書かないと動かないよ**
- `git branch --merged master`: masterブランチにマージされているものの一覧を取得する、この時masterブランチ自身も含まれる点に注意。
- `grep -vE '^\*|master$'`: 現在のブランチ（`* ` で表示されるもの）とmasterで終わるブランチ **以外** を表示する
    - つまり、今回の処理対象外としたいブランチはココの正規表現を上手く変えてください。
- `xargs -I % git branch -d %`: xargsコマンドでgrepの結果を利用して、ローカルのブランチを削除する。

### 実行用ファイルのパーミッションを変更する（重要）

** これをやらないと、SourceTree側から呼び出せません。  SourceTreeから実行しようとした際に、 `launch path not accessible` というエラーメッセージが表示されます。**

terminalから、  `chmod +x [実行用スクリプトのファイル名]` で実行権限を与えてあげてください。

### 実行用ファイルを登録

メニューから、SourceTree→環境設定（または `⌘.` ）で、設定ウィンドウを開いたら、タブからカスタムアクションを表示します。

![スクリーンショット 2017-11-04 14.10.05.png](https://qiita-image-store.s3.amazonaws.com/0/72473/b01b3a3e-c686-08d1-0609-836956bb1d3f.png)

追加をクリックし、メニューキャプションを適当に入力し[^1]、実行するスクリプトに先ほど作成した実行用スクリプトのパスを入力します。（右側の `...` ボタンをクリックするとFinderから選択する画面に移動可能です）[^2]

![スクリーンショット_2017-11-04_14_11_23.png](https://qiita-image-store.s3.amazonaws.com/0/72473/9a332845-ec6f-d50f-d753-17646dd03990.png)


ここでOKを押すとカスタムアクションの登録が可能です。

## 実行する

まず実行前の状況を確認しましょう。

![スクリーンショット 2017-11-04 14.09.22.png](https://qiita-image-store.s3.amazonaws.com/0/72473/681fb1e8-75d7-4c3f-9737-639053899ffb.png)


`feature/issue2` というブランチがマージされているのに残ってしまっていますね。これを消します。

コミットログに合わせて、右クリックして、カスタムアクション→リポジトリのアクション→先程登録したメニューキャプションを選択します。

![スクリーンショット_2017-11-04_14_12_44.png](https://qiita-image-store.s3.amazonaws.com/0/72473/ce895193-cefd-0c73-3ec8-a69f91789061.png)



すると、コマンドが実行され、しばらくするとSourceTree上から `feature/issue2` コマンドが削除されます。（リロードに少し時間がかかるようです）

![スクリーンショット_2017-11-04_14_13_00.png](https://qiita-image-store.s3.amazonaws.com/0/72473/d9900d59-b17c-fcc6-6fd0-7654c37d4216.png)


## やってみた感想

**Shebang の `#!/bin/sh` を忘れていて10分くらい溶かした。これからは毎回ちゃんと書こうと思いました。 `Couldn't posix_spawn: error 8` とか全く身に覚えのないエラーが出るので非常に困惑しました。**

これまで毎回コマンド覚えていたものをSourceTree上で出来るのは楽でいいなと思いました。

gitconfigファイルに持っていけば、そのまま使えそうな感じもするので、よく使うコマンドとか、たまに使うけど忘れがちなコマンドはSourceTreeのカスタムアクションに登録しておくと良いかもしれませんね！

## 参考資料

[SourceTreeの使い方 | コミット間の差分ファイルの抽出 (カスタム操作を使う方法)]
(https://ics.media/entry/4475)

[Git管理ツール「SourceTree」で差分ファイルを抜き出す方法](http://liginc.co.jp/web/tool/169091)

元々これらの記事を見つけて、今回のやってみようかなと思ったので、好奇心を刺激していただき感謝です。

[miukoba/gitでマージ済みの(リモート|ローカル)ブランチを全て削除.md]
(https://gist.github.com/miukoba/fc3c10a25c1c675c1e97)

解説含め、わかりやすくて助かりやすく、非常に感謝しています。

コマンド自体はここのものを元にしまして、今回は削除対象から除外するものをmasterブランチだけに焦点を絞る形に変更して記事を書きました。

[#!/bin/sh は ただのコメントじゃないよ！ Shebangだよ！ on @Qiita ](https://qiita.com/mohira/items/566ca75d704072bcb26f)

ただのコメントだと思っていたので、ハマりました。助かりました。

[^1]: 今回は「リモートにないマージ済みブランチを削除」、としました 
[^2]: パスに含まれるユーザー名が実名になっているためモザイクかけてます。実際にはちゃんと表示されます。