SourceTreeの外部Diffでブランチ間のディレクトリ比較できると泣けるほど便利

## 動機

SourceTree から WinMerge（Windowsの人）や meld (Macの人)を 外部Diff ツールとして設定すると、SourceTree から 外部Diff ツールを利用してファイル差分を確認することができます。
ただ SourceTreeから呼び出す外部Diffは、ファイル単位での比較になりイマイチです。

一方 git コマンドでは difftool コマンドに --dir-diff オプションが用意されていてディレクトリ単位で外部Diffツールが利用できて便利です。

SourceTree でもディレクトリ単位で外部Diffやりたい。という思いで試してみてある程度うまくいったので記事にしてみました。

![winmerge-diff.png](https://qiita-image-store.s3.amazonaws.com/0/108308/57a34130-af23-d6bd-d428-19d4b289fe49.png)

---

## まずgitコマンドでの difftool について
SourceTree の説明の前に、git コマンド の difftool から説明します。
git difftool は外部Diffツールを利用して、diff の表示を行うコマンドなのですが、現在の新しいバージョンの Git では git difftool コマンドに --dir-diff というオプションが追加されています。
これを利用すると、ブランチ間の比較において、複数ファイルの比較を外部Diffツールを利用して行うことが可能です。


```
git difftool --dir-diff 876face dc6f85a
```

![winmerge-diff.png](https://qiita-image-store.s3.amazonaws.com/0/108308/05676c9d-205a-d139-fe5d-800a0efab7a3.png)

![winmerge-diff2.png](https://qiita-image-store.s3.amazonaws.com/0/108308/8e509752-24ed-3c95-a1a9-363cffa1e984.png)

### 設定方法

以下のページがとても参考になります。
そもそも --dir-diff のオプションはこのページを読んで知りました。本当にいい記事で感謝！！

[git difftool --dir-diff が便利すぎて泣きそうです](http://tech.nitoyon.com/ja/blog/2013/07/02/git-dir-diff/)

私は .gitconfig には以下設定しています。

Windows版(WinMergeを利用)
```
diff.tool=WinMerge
difftool.WinMerge.cmd="C:/Tool/WinMerge/WinMergeU.exe" -r -u "$LOCAL" "$REMOTE"
```
Mac版(Meldを利用)
```
diff.tool=meld
difftool.meld.cmd=/usr/local/bin/meld $LOCAL $REMOTE
```

※WinMerge/meld 以外にも --dir-diff に対応していているDiffツールは色々あるようなので他のツールでも基本可能です。

---

## SourceTree で外部Diff を利用するための設定について

SourceTree 画面の [メニュー]-[ツール]-[オプション] を起動します。
Diff タブを選択して、外部 Diff ツールが [システム標準]になっていることを確認。
※[システム標準]により、上記の git difftool で設定した内容を利用する模様。

![sourcetree-option-win.png](https://qiita-image-store.s3.amazonaws.com/0/108308/5e9f32dc-aad6-4f0c-ba66-c5919812a39f.png)

※ Mac の場合で [システム標準]が表示されない場合は以下のように設定。meld のインストールパスに合わせて設定します

```
外部Diffツール：カスタム
Diffコマンド：/usr/local/bin/meld
引数：$LOCAL $REMOTE
```

そうすると以下のようなファイルの比較において上記で設定した外部Diffツールを利用して表示することができます。
![SourceTree-diff-fil.png](https://qiita-image-store.s3.amazonaws.com/0/108308/86ceade3-cd98-f6e5-5fed-56fc8b344e74.png)

---
## 本題のSourceTree で ディレクトリ単位で比較するための設定

ここからが本題。SourceTree では上記のようにファイル単位の比較で外部Diffツールを利用できるのですが、git difftool --dir-diff のようにディレクトリ単位で比較したいですよね。ブランチ単位で比較したいですよね。以下を利用すればなんとか実現できます。

以下の記事を参考にしました。
[SourceTreeでコミット間の差分ファイルを抽出しよう](https://ics.media/entry/4475)

ただし、今回は**差分ファイルの抽出**ではなくて、**差分を外部Diffツールで比較したい**ので以下の様なバッチファイル（shellファイル）を用意します。
バッチファイル（shellファイル）を所定のフォルダに配置して、カスタム操作として追加します。
パラメータには [$SHA]を指定します。メニュー表示名は分かりやすい名称を付けましょう。

引数を元に git difftool を --dir-diff オプションを指定して呼び出しているだけのバッチファイルです。カスタム操作から[$SHA]でブランチのハッシュ値を受け取って実行します。

※ Mac の場合はshellファイルに実行権限を設定してください。
※ git difftool の --dir-diff オプションは git のバージョンが　1.7.11以降である必要があるかもしれません。


Windows版

```bat
@echo off

if not "%1"=="" (
  SET PARAM1=%1
)
if not "%2"=="" (
  SET PARAM2=%2
) else (
  SET PARAM2=HEAD
)

if "%1"=="" (
  echo ERROR:Need parameter!
)

git difftool --dir-diff %PARAM1% %PARAM2%
```

Mac版

```bash
#!/bin/bash

echo $#
if [ $# -eq 2 ]; then
  PARAM1=$1
  PARAM2=$2
elif [ $# -eq 1 ]; then
  PARAM1=HEAD
  PARAM2=$1
else
  echo "ERROR:Need parameter!"
fi

git difftool --dir-diff $PARAM1 $PARAM2
```

## 最後に

上記のカスタム操作でバッチファイルを利用すれば他にも色々自動化できそうですね。色々試して見たいと思います。
また便利なものができれば記事を書いてみたいと思います。
今回も色々な人の記事を参考にさせていただきました。ありがとうございます。