【Windows】patchコマンドでRedmineの差分を適用する

# はじめに
仕事では運用チームの開発担当をしています。普段は1人開発なのですが、サーバーリプレース案件(Windows Server 2008R2 + Oracle11g -> Windows Server 2016 + PostgreSQL 9.6)で20種類以上ある既存アプリケーションの改修と動作検証の対応することになり、手伝いしてくれる方がきたのでプロジェクト管理としてRedmineを導入することにしました。

[bitnami Redmine](https://bitnami.com/stack/redmine/installer)というオールインワンパッケージをインストール(Redmine Ver 3.4.6.stable)しまして、「[view customize plugin](https://github.com/onozaty/redmine-view-customize)」という定番プラグインとかも入れました。

ガントチャート関連でいい拡張機能と思ったものは、修正パッチという形で提供されていまして、今回は下記パッチの適用を例に説明していきます。

 * [Feature #20481: ガントチャートの表示領域の幅をドラッグでリサイズ](http://www.redmine.org/issues/20481)

参照：[Redmineを改善するパッチを書いて、OSSへの貢献もする仕事](https://www.farend.co.jp/blog/2017/08/redmine-development/)

# パッチファイル
Feature #20481: ガントチャートの表示領域の幅をドラッグでリサイズのサイトからパッチファイル「change_to_right_and_left_resizable_panel_v2.patch」を取得します。
http://www.redmine.org/issues/20481

中身は単純なテキストファイルです。[TortoiseSVN](https://ja.osdn.net/projects/tortoisesvn/) がインストールされていると、TortoiseUDiffツールにより下図のようにシンタックスハイライトされます。

![patchViewer.png](https://qiita-image-store.s3.amazonaws.com/0/14053/d73832ec-5e32-bfa7-1994-5d00566442b7.png)

# パッチ適用
今回は4パターンによるパッチ適用を試しました。

* 手修正
* コマンドプロンプト
* Git Bash
* WSL(Ubuntu)

オープンソース系にはこれまであまり関わってきてなかったので、知識が疎いです。
会社ではパッチ適用方法が分からなかったので、短いしそのまま手修正していきました。その後に「patch」コマンドがあることを知り、自宅のPC(Windows 10 Home)に、[bitnami Redmine](https://bitnami.com/stack/redmine/installer)をインストールして試していきました。

## 適用準備
### patchフォルダ作成
redmine導入フォルダ(例 C:\redmine) 配下にある`apps\redmine\htdocs`フォルダに`patch`フォルダを作成して、「change_to_right_and_left_resizable_panel_v2.patch」を格納します。

### patchコマンドの導入
patch.exe は、Windowsでは標準にインストールされていません。
下記サイトからダウンロードできます。
[patch.exe ユーザーアカウント制御(UAC)対応](https://blogs.osdn.jp/2015/01/13/patch.html)

もう少し調べると、[Git for Windows](https://gitforwindows.org/) がインストールされている場合、`Git\usr\bin\patch.exe` に含まれています。
既にGit for Windowsはインストール済みだったので、コマンドプロンプトで`patch -v`が実行できました。今回はこの`patch.exe`を使います。

## 手修正
パッチファイルの中身をみて、編集対象ファイルを確認します。先頭のaとbはダミーフォルダです。

```bat:編集対象ファイル例>
--- a/app/views/gantts/show.html.erb
+++ b/app/views/gantts/show.html.erb

--- a/public/javascripts/gantt.js
+++ b/public/javascripts/gantt.js
```

編集対象ファイルをテキストエディタで開いて、差分分の削除と追加をしていきます。
少なければいいですが、多いと手作業ではさすがに大変になってきます。

## コマンドプロンプト
redmine導入フォルダ(例 C:\redmine) 配下にある`apps\redmine\htdocs`フォルダに移動して、下記コマンドを実行します。

※-p1オプションは、手修正で説明したaとbのダミーフォルダ以降を対象フォルダにします。

```bat:コマンド
C:\redmine>cd C:\redmine\apps\redmine\htdocs
C:\redmine\apps\redmine\htdocs>patch -p1 < patch\change_to_right_and_left_resizable_panel_v2.patch
patching file app/views/gantts/show.html.erb
```

結果として、patchコマンドを実行するとpatchがハングしました。

```bat:結果
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Assertation failed!

Program: C:\Perl64\c\bin\patch.exe
File: .\src\patch\2.5.9\patch-2.5.9-src\patch.c, Line 354

Expression: hunk

C:\redmine\apps\redmine\htdocs>
```
## Git Bash
Git Bashを実行するとMINGW64が起動します。

```bat:コマンド
PC MINGW64 /C/redmine/apps/redmine/htdocs
$ patch -p1 < patch/change_to_right_and_left_resizable_panel_v2.patch
```

`show.html.erb`と`gantt.js`が正しく修正されました。

```bat:結果
patching file app/views/gantts/show.html.erb
Hunk #1 succeeded at 131 (offset -6 lines).
Hunk #2 succeeded at 138 (offset -6 lines).
Hunk #3 succeeded at 264 (offset -6 lines).
Hunk #4 succeeded at 361 (offset -6 lines).
patching file public/javascripts/gantt.js
Hunk #1 succeeded at 239 with fuzz 2 (offset 66 lines).
```

バックアップとして、origの拡張子ファイルができます。
![patchDiff.png](https://qiita-image-store.s3.amazonaws.com/0/14053/de0226eb-907e-9453-e3ca-85dbe9c5c679.png)

## WSL(Ubuntu)
Linuxではpatchコマンドが標準でインストールされています。
Windows 10にはWSL(Windows Subsystem for Linux)のサブシステムができるようになっており、自分は Ubuntu を入れています。

[Git for Windows](https://gitforwindows.org/) をインストールしたくない場合、この方法が使えます。
[Windows Subsystem for Linux内からWindows側のファイルにアクセスする](http://ascii.jp/elem/000/001/250/1250797/)

スタートメニューの「Ubuntu」をクリックします。

```bat:コマンド
PC:~$ cd /mnt/c/redmine/apps/redmine/htdocs
PC:/mnt/c/redmine/apps/redmine/htdocs$ patch -p1 < patch/change_to_right_and_left_resizable_panel_v2.patch
patching file app/views/gantts/show.html.erb
```

`show.html.erb`と`gantt.js`が正しく修正されました。

```bat:結果
Hunk #1 succeeded at 131 (offset -6 lines).
Hunk #2 succeeded at 138 (offset -6 lines).
Hunk #3 succeeded at 264 (offset -6 lines).
Hunk #4 succeeded at 361 (offset -6 lines).
patching file public/javascripts/gantt.js
Hunk #1 succeeded at 239 with fuzz 2 (offset 66 lines).
```

バックアップとして、origの拡張子ファイルができます。
![patchDiff2.png](https://qiita-image-store.s3.amazonaws.com/0/14053/bd33f550-948e-1aea-4ecb-f84cd0a3ba4e.png)

【2018/07/17追記】
下記サイトを知ったので試してみました。
[Windows 10のコマンドプロンプトからWSL上のLinuxコマンドを呼び出す（バージョン1803対応版）](http://www.atmarkit.co.jp/ait/articles/1805/24/news022.html)

コマンドプロンプト上で先頭にWSLを付けてpatchコマンドが呼び出せました。
これは便利です。Git Bashよりいいのではないでしょうか。

```bat:結果
C:\redmine>cd c:\redmine\apps\redmine\htdocs

c:\redmine\apps\redmine\htdocs>wsl patch -p1 < patch\change_to_right_and_left_resizable_panel_v2.patch

patching file app/views/gantts/show.html.erb
Hunk #1 succeeded at 131 (offset -6 lines).
Hunk #2 succeeded at 138 (offset -6 lines).
Hunk #3 succeeded at 264 (offset -6 lines).
Hunk #4 succeeded at 361 (offset -6 lines).
patching file public/javascripts/gantt.js
Hunk #1 succeeded at 239 with fuzz 2 (offset 66 lines).
```

# パッチ適用結果
`Bitnami Redmine Stack Manager`を起動してRedmineサービスを再起動します。

パッチの「ガントチャートの表示領域の幅をドラッグでリサイズ」が出来るようになりました。

![GanttChart_patch.gif](https://qiita-image-store.s3.amazonaws.com/0/14053/b23b4581-7ced-b107-f54d-117be90c82f7.gif)

# 他の修正パッチ
続けて残り2つの修正パッチをあててみました。

 * [Feature #10485: ガントチャートでコンテキストメニューを表示](http://www.redmine.org/issues/10485#note-10)
 * [Feature #26409: ガントチャートに担当者を表示](http://www.redmine.org/issues/26409#note-2)

「show.html.erb.rej」ファイルが出来ました。これは適用できなかった箇所(reject)の差分ファイルです。
[LinuxコマンドTips（109）：【 patch 】コマンド――テキストファイルに差分を適用する（応用編その2）](http://www.atmarkit.co.jp/ait/articles/1705/12/news016.html)


```bat:show.html.erb.rej
--- app/views/gantts/show.html.erb
+++ app/views/gantts/show.html.erb
@@ -53,6 +53,15 @@
               </label>
             </fieldset>
           </td>
+          <td>
+            <fieldset>
+              <legend><%= l(:field_assigned_to) %></legend>
+              <label for="draw_assigned_to_names">
+                <%= check_box 'query', 'draw_assigned_to_names', :id => 'draw_assigned_to_names' %>
+                <%= l(:label_display) %>
+              </label>
+            </fieldset>
+          </td>
         </tr>
       </table>
     </div>
```

連続して修正パッチをあてるとズレがでますからね、他の箇所もあるかも知れません。
Githubに手修正したRedmineのガントチャートパッチファイルを置いておきました。
https://github.com/yaju/redmine_patch

# 最後に
コマンドプロンプトでpatchコマンドを使ってハングした時はどうしようかと思いましたが、Linux系の力をかりてどうにかなりました。

WSL(Windows Subsystem for Linux)のサブシステムは、いろいろ応用が効きそうな予感がしてきました。