git の差分比較・マージを WinMerge で行う

## 概要
git diff ってやるとこういうふうに出る差分を

```text
> git diff
diff --git a/main.cpp b/main.cpp
index 198f012..6e1f7d5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -4,7 +4,8 @@
 int main()
 {
        A a;
-       printf("%X", &a);
+       printf("address = %X", &a);
+       hello();
        hello();
     return 0;
 }
```

WinMerge によってグラフィカルに確認・編集できるようにする。

![Image2.png](https://qiita-image-store.s3.amazonaws.com/0/25555/c8472029-6641-f47b-c6ef-b84c9030fa17.png)

同様にマージ作業も行えるようにする。

![merge2.png](https://qiita-image-store.s3.amazonaws.com/0/25555/6fb63db0-ed78-d62d-364a-22d087abc175.png)

## 環境について
今回の環境を参考までに。

- Windows 7 Home Premium 64bit
- [WinMerge](http://www.geocities.co.jp/SiliconValley-SanJose/8165/winmerge.html) 2.4.0.68+-jp-68 (Japanese Unicode X64)
- [git](https://git-scm.com/) version 2.6.4.windows.1

## 設定方法
{ユーザディレクトリ}/.gitconfig に以下を追記。

```
[diff]
	tool = WinMerge
[difftool "WinMerge"]
	path = C:/Program Files/WinMerge/WinMergeU.exe
	cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" -f \"*.*\" -e -u -r \"$LOCAL\" \"$REMOTE\"
[merge]
	tool = WinMerge
[mergetool "WinMerge"]
	path = C:/Program Files/WinMerge/WinMergeU.exe
	cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" -e -u \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
[alias]
	windiff = difftool -y -d -t WinMerge
	winmerge = mergetool -y -t WinMerge

```

エイリアス名はお好きに。（今回は「windiff」「winmerge」としてみた。ツール名とバッティングしていてややこしいが…）


## 差分比較
ローカルリポジトリ内で、さきほど付けたエイリアスコマンドを実行。

```
> git windiff
```

![windiff.png](https://qiita-image-store.s3.amazonaws.com/0/25555/e41844e3-583a-0fdb-c9e7-8408effd5bc9.png)

![Image2.png](https://qiita-image-store.s3.amazonaws.com/0/25555/c8472029-6641-f47b-c6ef-b84c9030fa17.png)

するとこんな感じに WinMerge で差分比較できる。

ファイルパスはテンポラリディレクトリ内の場所を示しているが、右側の編集は自動的に作業コピーの変更として反映される。

## リビジョン指定の比較
以下のようにリビジョン指定の比較も行える。

```
> git windiff HEAD~~~ HEAD~
```

![revision.png](https://qiita-image-store.s3.amazonaws.com/0/25555/551e7bd4-a631-a7bd-0c23-143727290f92.png)


## マージ
まずはコンフリクトの発生する状況を作ってみる。

```
> git checkout master
> git checkout -b branch1
> echo hello >> main.cpp
> git add . && git commit -m "change1"

> git checkout master
> git checkout -b branch2
> echo world >> main.cpp
> git add . && git commit -m "change2"

> git checkout master
> git merge branch1
Updating ef81702..34d9482
Fast-forward
 main.cpp | 1 -
 1 file changed, 1 deletion(-)

> git merge branch2
Auto-merging main.cpp
CONFLICT (content): Merge conflict in main.cpp
Automatic merge failed; fix conflicts and then commit the result.
```
コンフリクトが発生した。
続けてマージツールの起動を行う。（さきほど設定したエイリアス「winmerge」を用いる）

```
> git winmerge
```

![merge.png](https://qiita-image-store.s3.amazonaws.com/0/25555/0df44ffd-0de1-9d96-1f5d-4e2b953bafb9.png)

するとこんな感じに WinMerge 上でコンフリクトの解消作業を行うことができる。
一番右側のペインの編集はそのまま作業コピーに反映される。

## 以上
せっかく Windows を使ってるのだったら豊富なツール群の恩恵をふんだんに享受しましょう。

## 補足：WinMergeの引数
- ```-f "*.*"``` … 表示するファイルタイプ
- ```-e``` … ESCで閉じれるようにする
- ```-u``` … 履歴に追加しない
- ```-r``` … サブフォルダを含む比較

※どうやら WinMerge は前回比較のファイルタイプを覚えているようで、ファイルタイプ指定を明示的に行わないと、全てのファイル一覧が表示されないことがある。

## 参考
- http://tigawa.github.io/blog/2014/02/12/difftool/
- http://devlights.hatenablog.com/entry/20121114/p2
- http://stackoverflow.com/questions/5440610/git-and-difftool-problems-what-do-local-and-remote-point-to
- http://qiita.com/noromanba/items/b1740912c2e8ff029661
- https://gist.github.com/shawndumas/6158524
- http://manual.winmerge.org/Command_line.html