Git を使って EC-CUBE を簡単アップデート

バージョンアップが、なかなか大変な EC-CUBE。
version 3 になって、マイグレーションできるようになりましたので、以前よりは楽にバージョンアップできるようになりました。

しかし、本体のコードをカスタマイズしてしまうと、簡単に上書きすることもできず、バージョンアップの難易度が格段に上ってしまいます。

**「プラグインでカスタマイズしろよ」** ってことでしょうが、何でもかんでもプラグインで頑張ろうとすると、開発・保守コストも上がってしまいます。
高度なプログラミングスキルも求められるため、なかなか簡単にはいきません。


**本当にプラグインにする必要があるのか？** 今一度考えてみましょう。

- 別の案件などで再利用したい
- アンインストール機能が必要
- Git などでソースコードのバージョン管理ができない

といった要件が無ければ、頑張ってプラグインにする必要性は少ないです。
プラグインにすることで、依存関係やソースコードが複雑化し、どこに、どんな処理が隠れているのか、わかりにくくなります。引継ぎなどで後任者が苦しむ結果にもなりかねません。

実は、 Git をうまく使えば、本体のコードをカスタマイズしても、簡単にアップデートできるのです。
この方法は 2系 でも利用可能です。
ただし、すべての状況において万能なアップデート方法ではありませんので、自己責任でお願い致します。

**俺は fork したやつを使いたいんだ** とか **プログラムが見えちゃ恥しいから bitbucket を使いたいんだ** という方は、ちょっと工夫することで対応可能です。コメント欄にでもリクエストいただければ加筆しようと思います。

また、汎用的にするため、すべてコマンドラインで記載していますが、 [SourceTree](https://ja.atlassian.com/software/sourcetree/overview) などの GUI ツールを使っても大丈夫です。

### 1. github から EC-CUBE のソースコードを clone します

- `<eccube version>` には、使用したい EC-CUBE のバージョン(例: 3.0.4)
- `<folder name>` には、宛先のフォルダ名を入力してください

```EC-CUBE3.x
git clone https://github.com/EC-CUBE/ec-cube.git -b <eccube version> <folder name>
```

```EC-CUBE2.x
git clone https://github.com/EC-CUBE/eccube-2_13.git -b <eccube version> <folder name>
# リポジトリ名が eccube-2_13 となっていますが、 古いバージョンでも使えます
# 例) eccube-2.4.4
```

### 2. 管理用のブランチを作成

`<new-branch-name>` には、ソースコードを管理するためのブランチ名(例: production) を入力します

```sh
cd <folder name>
git checkout -b <new-branch-name>
```

これで、カスタマイズしたソースコードを管理するための準備が整いました。
本番環境などからソースコードを取得し、 `<folder name>` に上書きしてください。


### 3. 差分の確認

カスタマイズしたソースコードと、 EC-CUBE 本体のソースコードに差分が発生しているかを `git status` コマンドで確認します。

```sh
git status

On branch production
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:   src/Eccube/Repository/ProductRepository.php

no changes added to commit (use "git add" and/or "git commit -a")
```

`src/Eccube/Repository/ProductRepository.php` に修正が入っていることがわかります。

どのような内容の修正か、 `git diff` コマンドで見てみましょう。

```sh
git diff

diff --git a/src/Eccube/Repository/ProductRepository.php b/src/Eccube/Repository/ProductRepository.php
index 6b469f5..44af46f 100644
--- a/src/Eccube/Repository/ProductRepository.php
+++ b/src/Eccube/Repository/ProductRepository.php
@@ -120,7 +120,7 @@ class ProductRepository extends EntityRepository
         // 価格順
         if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == '1') {
             $qb->innerJoin('p.ProductClasses', 'pc');
-            $qb->orderBy('pc.price02', 'DESC');
+            $qb->orderBy('pc.price02', 'ASC');
         // 新着順
         } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == '2') {
             $qb->innerJoin('p.ProductClasses', 'pc');

```

price02 降順だったが、昇順に修正されています。

### 4. 修正内容の保存

この修正内容を、 `git add` と `git commit` コマンドで保存しておきましょう。

```sh
git add .
```

```sh
git commit -m 'save production'

[production 37fb0e7] save production
 1 file changed, 1 insertion(+), 1 deletion(-)
```

`git add .` では、最後に「.(ドット)」を入れるのを忘れないようにしてください。
`git commit` の `-m` には、任意のコミットログを記録できます。どんな修正なのか書いておくと、後々役立ちます。

こうして日々の修正をコミットしておくと、差分の確認ができたり、万が一修正ミスが発生した時でも、安心して元に戻すことができます。

### 5. バージョンアップ

EC-CUBE の新バージョンがリリースされましたので、バージョンアップしましょう。

`git fetch origin <eccube version>` コマンドで、最新のソースを取得できます。
ここでは 3.0.5 のソースを取得します。バージョン番号は適宜読み替えてください。

```sh
git fetch origin 3.0.5

From https://github.com/EC-CUBE/ec-cube
 * tag               3.0.5      -> FETCH_HEAD
```

この時、 `git pull` は使用しないのがコツです。 `git pull` を使用すると、予期せぬ更新が反映されてしまう場合があります。

取得した差分を適用(merge)しましょう。

```sh
git merge 3.0.5

Updating 8710496..2d2b958
Fast-forward
 .gitignore                                         |    2 +-
 .gitmodules                                        |    2 +-
 .travis.yml                                        |    9 +-
 README.md                                          |   19 +-
 app/console                                        |    1 -
 appveyor.yml                                       |   11 +-
 composer.json                                      |    7 +-
 composer.lock                                      |  912 +++++++++++-------
 docs
...snip
```

大量にログが出力されますが、落ち着きましょう。
もう一度、 `git status` で正常に適用されたか確認しましょう。
改修した本体のソースコードが上書きされていないことも確認しましょう。

```sh
git status

On branch production
nothing to commit, working directory clean
```

*nothing to commit, working directory clean* と出ていれば、大丈夫です。

`composer.json` や `composer.lock` が変更されていた場合は、 以下のコマンドで vender を更新しましょう。

```sh
curl -sS https://getcomposer.org/installer | php
php ./composer.phar install --dev --no-interaction
```

この後、ソースコードをサーバーへアップロードし、[http://インストール先/install.php/migrationにアクセスしマイグレーションを実行](http://ec-cube.github.io/update.html) すればアップグレード完了です。


### 番外) 競合(コンフリクト)してしまった時は？

`git merge` の時に、ソースコードの修正が被ってしまい、バージョンアップの適用に失敗する場合があります。

```sh
git merge 3.0.5

Removing tests/Eccube/Tests/Form/Type/ShopMasterTypeTest.php
Auto-merging tests/Eccube/Tests/Form/Type/Master/CalcRuleTypeTest.php
Auto-merging tests/Eccube/Tests/Form/Type/Front/EntryTypeTest.php
Auto-merging tests/Eccube/Tests/Form/Type/Front/CustomerAddressTypeTest.php
Auto-merging tests/Eccube/Tests/Form/Type/Admin/SecurityTypeTest.php
Removing src/Eccube/Resource/template/default/Mypage/mail_view.twig
Removing src/Eccube/Resource/template/default/Mypage/error.twig
Auto-merging src/Eccube/Repository/ProductRepository.php
CONFLICT (content): Merge conflict in src/Eccube/Repository/ProductRepository.php
Auto-merging src/Eccube/Form/Type/ZipType.php
Removing src/Eccube/Form/Type/ShoppingShippingType.php
Removing src/Eccube/Form/Type/ShippingType.php
Removing src/Eccube/Form/Type/ShippingMultiType.php
...snip
Automatic merge failed; fix conflicts and then commit the result.
```

最後に *Automatic merge failed; fix conflicts and then commit the result.* という行が出たら修正が競合しています。

上記の例では、 `src/Eccube/Repository/ProductRepository.php` が CONFILICT となっています。

`git status` コマンドでも確認できます。

```sh
git status

On branch production
You have unmerged paths.
  (fix conflicts and run "git commit")

Changes to be committed:

	modified:   .gitignore
	modified:   .gitmodules
	modified:   .travis.yml
	modified:   README.md
	modified:   app/console
	modified:   appveyor.yml
	modified:   composer.json

...snip

	new file:   tests/createEcCubeData-v30.php

Unmerged paths:
  (use "git add <file>..." to mark resolution)

	both modified:   src/Eccube/Repository/ProductRepository.php
```

最後に `Unmerged paths:` と出ているのが、競合してしまったファイル一覧です。

`src/Eccube/Repository/ProductRepository.php` を開くと、競合した箇所を確認できます。
`<<<<<<<` で検索するとすぐに見つかります。

```php
            $qb->orderBy('pc.price02', 'ASC');
<<<<<<< HEAD
        // 新着順
        } elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == '2') {
            $qb->innerJoin('p.ProductClasses', 'pc');
            $qb->orderBy('pc.create_date', 'DESC');
=======
            // 新着順
        } else if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == '2') {
            $qb->orderBy('p.create_date', 'DESC');
>>>>>>> 3.0.5
        } else {

```

`=======` より上が、アップグレード前のソースコード、下がアップグレード後のソースコードです。
この場合は、下の方を残したいので、上の方を削除して正しいソースコードに修正します。

```php
            $qb->orderBy('pc.price02', 'ASC');
            // 新着順
        } else if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == '2') {
            $qb->orderBy('p.create_date', 'DESC');
        } else {
```

修正ができたら、コミットしておきましょう。

```sh
git add .
```

```sh
git commit -m 'save production'
[production b6da7e2] save production
```



小々長くなってしまいましたが、こうすることで、本体のソースコードに手を入れても、比較的簡単にアップデートすることができます。
プラグインを使っていても、本体の修正と競合する問題を完全に防ぐことは難しいです。
Git をうまく活用して、開発効率と安定性を両立させましょう。