高度な競合の解決(ファイル単位で解決を行う)

はじめに
----------

競合が発生した場合、競合が発生したブロックレベルで解決を行っていくのは
非常に大変です。(競合箇所が1か所とか2か所くらいならまぁいいですが)

そのため、ファイル単位で現在のブランチの内容にしたいか、マージする
ブランチの内容にしたいのかを選択したくなることがあります。


ここではその手順を解説します。

* マージするブランチ側を採用する場合

  `git checkout MERGE_HEAD [file_name]`

* 現在のブランチ側を採用する場合

  `git checkout ORIG_HEAD [file_name]`


ファイル単位で解決を行う(マージするブランチ側を正とする場合)
--------------------------------------------------------------

現在のブランチを**master**として、マージするブランチを**topic**とします。

ここではコンフリクトが起きた場合、**topic**ブランチ側のファイルを採用
するケースを解説します。

masterブランチでファイルを作成

```bash
$ git branch -l
* master

$ vi MakeHtml.java
```

```java
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力する
 *  プログラムです
 */

import java.io.*;

public class MakeHtml {
    public static void main(String[] args) {
        System.out.println("<!DOCTYPE html>");
        System.out.println("<html>");
        System.out.println("<head>");
        System.out.println("<title>My Page</title>");
        System.out.println("</head>");
        System.out.println("<body>");

        String find_shikaku = "■";
        String find_maru = "●";

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                int shikaku = line.indexOf(find_shikaku);
                int maru = line.indexOf(find_maru);
                if (shikaku == 0) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (maru == 0) {
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        System.out.println("</body>");
        System.out.println("</html>");
    }
}
```

```bash
$ git add MakeHtml.java

$ git commit -m "add MakeHtml.java"
```

topicブランチで`MakeHtml.java`を編集

```bash
$ git checkout -b topic
$ vi MakeHtml.java
```

全体的に編集を行う

```java
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力にだす
 *  プログラムです
 */

import java.io.*;

public class MakeHtml2 {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line;
            System.out.println("<!DOCTYPE html>");
            System.out.println("<html>");
            System.out.println("<head>");
            System.out.println("<title>My Page</title>");
            System.out.println("</head>");
            System.out.println("<body>");
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("■")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("●") ){
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
            System.out.println("</body>");
            System.out.println("</html>");
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}
```

```bash
$ git commit -am "edit MakeHtml.java by topic branch"
```

masterブランチで`MakeHtml.java`を編集

```bash
$ git checkout master
$ vi MakeHtml.java
```

```java
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力する
 *  プログラムです。今日はこれをmasterブランチで少し変種しました。
 */

import java.io.*;

public class MakeHtml1_2 {
    public static void main(String[] args) {
        System.out.println("<!DOCTYPE html>");
        System.out.println("<html>");
        System.out.println("<head>");
        System.out.println("<title>My Page</title>");
        System.out.println("</head>");
        System.out.println("<body>");

        String find_shikaku = "X";
        String find_maru = "O";

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line = reader.readLine();
            while (line != null) {
                if (line.startsWith("X")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("O") {
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        System.out.println("</body>");
        System.out.println("</html>");
    }
}
```

```bash
$ git commit -am "edit MakeHtml.java by master branch"
```

masterブランチでtopicブランチをマージ

> ここでコンフリクトが発生する

```bash
$ git branch -l
* master
  topic

$ git diff topic                                          
diff --git a/MakeHtml.java b/MakeHtml.java
-public class MakeHtml2 {
+public class MakeHtml1_2 {
     public static void main(String[] args) {
+        System.out.println("<!DOCTYPE html>");
+        System.out.println("<html>");
+        System.out.println("<head>");
+        System.out.println("<title>My Page</title>");
+        System.out.println("</head>");
+        System.out.println("<body>");
+
+        String find_shikaku = "X";
+        String find_maru = "O";
+
-public class MakeHtml2 {
+public class MakeHtml1_2 {
     public static void main(String[] args) {
+        System.out.println("<!DOCTYPE html>");
+        System.out.println("<html>");
+        System.out.println("<head>");
+        System.out.println("<title>My Page</title>");
+        System.out.println("</head>");
+        System.out.println("<body>");
+
+        String find_shikaku = "X";
+        String find_maru = "O";
+
         BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
         try {
-            String line;
-            System.out.println("<!DOCTYPE html>");
-            System.out.println("<html>");
-            System.out.println("<head>");
-            System.out.println("<title>My Page</title>");
-            System.out.println("</head>");
-            System.out.println("<body>");
-            while ((line = reader.readLine()) != null) {
-                if (line.startsWith("■")) {
+            String line = reader.readLine();
+            while (line != null) {
+                if (line.startsWith("X")) {
                     System.out.println("<h1>" + line.substring(1) + "</h1>");
-                } else if (line.startsWith("●") ){
+                } else if (line.startsWith("O") {
                     System.out.println("<h2>" + line.substring(1) + "</h2>");
                 } else {                                                            
                     System.out.println("<p>" + line + "</p>");
                 }
             }
-            System.out.println("</body>");
-            System.out.println("</html>");
         } catch (IOException e) {
             System.out.println(e);
         }
+        System.out.println("</body>");
+        System.out.println("</html>");
     }
 }

$ git merge topic
Auto-merging MakeHtml.java
CONFLICT (content): Merge conflict in MakeHtml.java
Automatic merge failed; fix conflicts and then commit the result.

$ git status -s                                           
UU MakeHtml.java

$ cat MakeHtml.java                                       
<<<<<<< HEAD
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力する
 *  プログラムです。今日はこれをmasterブランチで少し変種しました。
=======
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力にだす
 *  プログラムです
>>>>>>> topic
 */

import java.io.*;

<<<<<<< HEAD
public class MakeHtml1_2 {
    public static void main(String[] args) {
        System.out.println("<!DOCTYPE html>");
        System.out.println("<html>");
        System.out.println("<head>");
        System.out.println("<title>My Page</title>");
        System.out.println("</head>");
        System.out.println("<body>");

        String find_shikaku = "X";
        String find_maru = "O";

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line = reader.readLine();
            while (line != null) {
                if (line.startsWith("X")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("O") {
=======
public class MakeHtml2 {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line;
            System.out.println("<!DOCTYPE html>");
            System.out.println("<html>");
            System.out.println("<head>");
            System.out.println("<title>My Page</title>");
            System.out.println("</head>");
            System.out.println("<body>");
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("■")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("●") ){
>>>>>>> topic
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
            System.out.println("</body>");
            System.out.println("</html>");
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}
```

topicブランチ側の'MakeHtml.java'を正として採用する

```bash
$ git checkout MERGE_HEAD MakeHtml.java

$ git status -s                                           
M  MakeHtml.java

$ cat MakeHtml.java 
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力にだす
 *  プログラムです
 */

import java.io.*;

public class MakeHtml2 {
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line;
            System.out.println("<!DOCTYPE html>");
            System.out.println("<html>");
            System.out.println("<head>");
            System.out.println("<title>My Page</title>");
            System.out.println("</head>");
            System.out.println("<body>");
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("■")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("●") ){
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
            System.out.println("</body>");
            System.out.println("</html>");
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}
```

最後に忘れずにコミットする

```bash
$ git commit -m "topicブランチ側のファイルを採用"
$ git log --graph                                         
*   commit 285c9b2cde90479563e3a37bd9a40a8f378971a6
|\  Merge: 4730de4 63494db
| | Author: spam ham
| | Date:   Mon Apr 28 12:37:44 2014 +0900
| | 
| |     topicブランチ側のファイルを採用
| |   
| * commit 63494dbda5d574deb8f1e15b092f77f0e852430f
| | Author: spam ham
| | Date:   Mon Apr 28 12:26:02 2014 +0900
| | 
| |     edit MakeHtml.java by topic branch
| |   
* | commit 4730de45f21b7c0b1b472b67527a0abcc2224a50
|/  Author: spam ham
|   Date:   Mon Apr 28 12:33:13 2014 +0900
|   
|       edit MakeHtml.java by master branch
|  
* commit 6888a07dfb84fbae958e2269b05ff84078a1480d
  Author: spam ham
  Date:   Mon Apr 28 12:20:16 2014 +0900
  
      add MakeHtml.java
```


ファイル単位で解決を行う(現在のブランチ側を正とする場合)
--------------------------------------------------------------

現在のブランチを**master**として、マージするブランチを**topic**とします。

ここではコンフリクトが起きた場合、**master**ブランチ側のファイルを採用
するケースを解説します。

マージする直後までの解説は*(マージするブランチ側を正とする場合)*と同じ内容
なので、そちらを参照してください。


topicブランチ側の'MakeHtml.java'を正として採用する

```bash
$ git checkout ORIG_HEAD MakeHtml.java

$ git status -s                                           

$ cat MakeHtml.java 
/** 標準入力から1行づつ読み取って、htmlファイルを標準出力する
 *  プログラムです。今日はこれをmasterブランチで少し変種しました。
 */

import java.io.*;

public class MakeHtml1_2 {
    public static void main(String[] args) {
        System.out.println("<!DOCTYPE html>");
        System.out.println("<html>");
        System.out.println("<head>");
        System.out.println("<title>My Page</title>");
        System.out.println("</head>");
        System.out.println("<body>");

        String find_shikaku = "X";
        String find_maru = "O";

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String line = reader.readLine();
            while (line != null) {
                if (line.startsWith("X")) {
                    System.out.println("<h1>" + line.substring(1) + "</h1>");
                } else if (line.startsWith("O") {
                    System.out.println("<h2>" + line.substring(1) + "</h2>");
                } else {
                    System.out.println("<p>" + line + "</p>");
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        System.out.println("</body>");
        System.out.println("</html>");
    }
}
```

最後に忘れずにコミットする

```bash
$ git commit -m "masterブランチ側のファイルを採用"
$ git log --graph
*   commit 4881e01fcd00638786f8be02f809d8a3c5416cf3
|\  Merge: 4730de4 63494db
| | Author: spam ham
| | Date:   Mon Apr 28 12:49:30 2014 +0900
| | 
| |     masterブランチ側のファイルを採用
| |   
| * commit 63494dbda5d574deb8f1e15b092f77f0e852430f
| | Author: spam ham
| | Date:   Mon Apr 28 12:26:02 2014 +0900
| | 
| |     edit MakeHtml.java by topic branch
| |   
* | commit 4730de45f21b7c0b1b472b67527a0abcc2224a50
|/  Author: spam ham
|   Date:   Mon Apr 28 12:33:13 2014 +0900
|   
|       edit MakeHtml.java by master branch
|  
* commit 6888a07dfb84fbae958e2269b05ff84078a1480d
  Author: spam ham
  Date:   Mon Apr 28 12:20:16 2014 +0900
  
      add MakeHtml.java
```