git 管理ディレクトリにシステム構成が同じアプリが 2 つ配置されている。一方の機能を patch で差分抽出してもう一方へ適用する方法は。



# 環境

* MacOSX - 10.12.5 
* git - 2.11.0
* patch - 2.5.8

# どのような状況を想定すればよいか

例えば以下のような

```アプリディレクトリ名だけが違って、ディレクトリ・ファイル構成が全く同じなプロジェクト``` があるとする。


```
project
|
|── .git
|
├── appAdmin
│   └── moduleX
│       └── logic.txt
└── appCustomer
    └── moduleX
        └── logic.txt
```

もう少し突っ込むと...

* それぞれのアプリ(```appAdmin```, ```appCustomer```) を管轄するサービスは同じものを指している
    * ```appAdmin``` は管理者向けアプリ
    * ```appCustomer``` はカスタマー向けアプリ

両アプリ基盤開発(DB 接続機能、ユーティリティ構築など)フェーズにて、

```appAdmin``` で構築した機能を ```appCustomer``` へパッチ(機能差分)として当てる。

各々のアプリ独自機能(カスタマー向け機能、管理者向け機能)を開発始める時に、パッチ取り込みをやめる。

そんなとこです。まあ、こういう git 運用もあると思って頂ければ。

# 本題の前に

## 例題プロジェクトをベースに話を進める

下記に掲げる例題プロジェクトにて、 ```どのような時にどうパッチを当てれば良いか``` を

記載しようと思う。

#### 例題プロジェクト構成図

```
project
|
|── .git
|
├── appAdmin
│   └── moduleX
│       └── logic.txt
└── appCustomer
    └── moduleX
        └── logic.txt
```

```appAdmin```, ```appCustomer``` 双方の ```logic.txt``` はファイル内容が同一であるとする。

```(appAdmin|appCustomer)/moduleX/logic.txt
# this is comment
Process A
Process B
Process C
```

### プロジェクトに機能が追加された時

上記プロジェクトにて ```appAdmin/moduleX/logic.txt``` に機能が追加された。

修正内容は以下のような想定だ。

#### 修正差分

```
$ git log --graph

*   commit 45314b635f10f52b6cab2c49945ea4c729e0aef1
|\  Merge: a74b4cf 8e0d948
| |     Merge branch 'add_process_to_admin'
| | 
| * commit 8e0d94839a3fc0b782ee001ada906eacaa95be01
|/  add process T and U
| 
* commit a74b4cf2943a74bfe31547b5641b129253e7e4d9
  add logic.txt
```

```
$ cat appAdmin/moduleX/logic.txt 
# this is comment
Process A
Process B
# this is T's comment
Process T
Process C
Process U
```

```
$ cat appCustomer/moduleX/logic.txt 
# this is comment
Process A
Process B
Process C
```

### パッチを一方に当てるにはどうすりゃいい？

さあ、運用の話で ```appAdmin```, ```appCustomer``` はまだ基盤開発というステージだとしよう。

つまり ```appAdmin/moduleX/logic.txt``` のパッチ(更新差分)を ```appCustomer/moduleX/logic.txt``` へ

取り込まねばならない。何をしなければいけないだろうか？

# 本題

例題プロジェクト構成図と 修正差分 を基に

```patch``` ファイルの適用方法を記載する。

## 例題プロジェクト構成図

```
project
|
|── .git
|
├── appAdmin
│   └── moduleX
│       └── logic.txt
└── appCustomer
    └── moduleX
        └── logic.txt
```

## 修正差分

```
$ git log --graph

*   commit 45314b635f10f52b6cab2c49945ea4c729e0aef1
|\  Merge: a74b4cf 8e0d948
| |     Merge branch 'add_process_to_admin'
| | 
| * commit 8e0d94839a3fc0b782ee001ada906eacaa95be01
|/  add process T and U
| 
* commit a74b4cf2943a74bfe31547b5641b129253e7e4d9
  add logic.txt
```

### patch ファイルを作る

#### a. プロジェクトディレクトリに移動する

```
$ cd {例題プロジェクト構成図　にある project ディレクトリ}

```

#### b. パッチを配置するディレクトリ作成する

```
$ mkdir patchdir
```

#### c. パッチファイルを作成する

```git diff 修正前のリビジョン 修正後のリビジョン > patchdir/適当な名前.patch```

でパッチを作成する。

```修正差分``` の ```git log --graph``` にあるリビジョンからすると

```git df a74b4cf 45314b6 > patchdir/001_add_function_T_and_U.patch```

(ハッシュコードは 7 桁で良いです。心配性な方は全桁記載してもらっても構わないです)

### patch ファイルをいじる

```
$ {YOUR_EDITOR} patchdir/001_add_function_T_and_U.patch
```

下記のように記載されているはず。

```patchdir/001_add_function_T_and_U.patch
1 diff --git a/appAdmin/moduleX/logic.txt b/appAdmin/moduleX/logic.txt
2 index db6b76e..17c004e 100644
3 --- a/appAdmin/moduleX/logic.txt
4 +++ b/appAdmin/moduleX/logic.txt
5 @@ -1,4 +1,7 @@
6  # this is comment
7  Process A
8  Process B
9  +# this is T's comment
10 +Process T
11  Process C
12 +Process U
```

ファイル内にある

* ```---```, ```+++``` のディレクトリ・ファイル名 (上記だと3, 4 行目)

を ```appAdmin``` > ```appCustomer``` へリネームする。

```patchdir/001_add_function_T_and_U.patch
1 diff --git a/appAdmin/moduleX/logic.txt b/appAdmin/moduleX/logic.txt
2 index db6b76e..17c004e 100644
3 --- a/appCustomer/moduleX/logic.txt
4 +++ b/appCustomer/moduleX/logic.txt
5 @@ -1,4 +1,7 @@
6  # this is comment
7  Process A
8  Process B
9  +# this is T's comment
10 +Process T
11  Process C
12 +Process U
```

### patch 取り込みをする

```
$ patch -p1 < patchdir/001_add_function_T_and_U.patch
patching file appCustomer/moduleX/logic.txt
```


オプション ```-p1``` の説明は ```man patch``` を見た方が早い。私が説明するより。

### 差分を確認する

```
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   appCustomer/moduleX/logic.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	patchdir/
```

```
$ git diff
diff --git a/appCustomer/moduleX/logic.txt b/appCustomer/moduleX/logic.txt
index db6b76e..17c004e 100644
--- a/appCustomer/moduleX/logic.txt
+++ b/appCustomer/moduleX/logic.txt
@@ -1,4 +1,7 @@
# this is comment
Process A
Process B
+# this is T's comment
+Process T
Process C
+Process U
```

```appCustomer``` に ```appAdmin``` のパッチ(機能差分)が適用された。 ```patchdir``` を ```add``` しないように。

# 後書

* 諸事情につき、所々の例えがよろしくないところはご容赦ください
* ```patch``` 回りの経験希いので自信の無いことは書いてません
    * このケースには適用できませんでした、などコメント頂けると幸いです

眠気を抑えて文章を書くものでは無い