GitHub Template Repository使ってみた

この記事は[and factory.inc Advent Calendar 2021](https://qiita.com/advent-calendar/2021/andfactory) 22日目の記事です。
昨日は@MatsuNaoPenさんの[【android】折りたたみ式端末対応](https://qiita.com/MatsuNaoPen/items/d383ab3a6fe83118b4a9)でした。

# はじめに
[GitHub Template Repository](https://docs.github.com/ja/repositories/creating-and-managing-repositories/creating-a-template-repository) とは、GitHub上の任意のリポジトリを元に新たなリポジトリを生成できます。要は強くてニューゲームするという事になります。

初期実装の設計カタログのような使い方、ツール、環境構築などプロジェクト固有の実装とは関係ないものを切り離してこちらを利用できないかと考えています。

# 使ってみる
以下、ひとまず使ってみて手順をまとめました。

## 1. テンプレートとなるリポジトリの設定でチェックを入れる
リポジトリの[Settings]→[Options]の中にある`Template repository`をチェックします。

![スクリーンショット 2021-12-21 10.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369939/02ecf4cf-dd30-f168-2bc5-7dbf9b04fcc3.png)

## 2. 新しくリポジトリを生成する際にテンプレートを選択する
リポジトリ生成の際にテンプレートにしたいリポジトリを選択して`Create repository`押すとテンプレート側のmainブランチを元に新しく生成される。
**`Include all branches`をチェックするとテンプレート側のブランチを引き継ぎます。**
また、テンプレートリポジトリ側の`Use this template`でも同様に作成できます。

![スクリーンショット 2021-12-21 10.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369939/e5b2a762-9bc1-abbc-5c35-e3e0249c5144.png)

## 3. 完成！
これだけで完成しました。
テンプレートリポジトリ使用の特徴として、以下があります。あとは普段のリポジトリと同様です。

- テンプレートリポジトリ側のコミット履歴を引き継がない
- `generated from ...` 参照元のリポジトリが表示されている

![スクリーンショット 2021-12-21 10.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369939/b9a743df-7b42-bb12-becb-372ad9ef62c2.png)

## 気になったこと
クローンするところまではできましたが、実際に運用したと仮定して気になった点がありますので、調べてみました。

### テンプレートリポジトリの実装更新を取り入れられるのか？
プロジェクト実装中でも当たり前のように時が立ち、素晴らしい技術が生まれます。
その技術を実装中プロジェクトでも取り入れたいなと思います。ですが、実装範囲がテンプレートリポジトリのものが多々あると思います。
実装中プロジェクトで更新してしまうとテンプレートリポジトリの乖離が生じてしまうので、テンプレートリポジトリを更新して実装中プロジェクトに取り入れられないかと考えます。

調べてみると[こちらの質問](https://stackoverflow.com/questions/56577184/github-pull-changes-from-a-template-repository)で同様にできないかと困ってる人がいました。
実際に運用した際のケースとしてテンプレートリポジトリにissueをたて、PRレビュー後マージされた前提で以下試してみました。

#### 1. 実装中プロジェクトにテンプレートリポジトリのブランチを取り入れる
テンプレートリポジトリの設定をプロジェクト側に設定し、`git fetch --all`すると`template/**`というテンプレートリポジトリのブランチを取り込めました。

``` bash
$ git remote add template git@github.com:doihei/swiftui-template.git # テンプレート側リポジトリ
$ git fetch --all
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/develop
  remotes/origin/main
  remotes/origin/test
  remotes/template/develop
  remotes/template/main
  remotes/template/test
```

#### 2. 実際にマージ
マージしようとすると履歴の関係上で以下のように怒られますので、`--allow-unrelated-histories` つけたら問題なく入れ込めました。
ただコミットログを見るとライブラリ側のコミットにも追従してしまいます。

```bash:エラー起こった
$ git merge template/main
fatal: refusing to merge unrelated histories
```

```bash:パラメータつけた
$ git merge template/main --allow-unrelated-histories # これをつけないと怒られた
Merge made by the 'ort' strategy.
 README copy.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)
 create mode 100644 README copy.md
```

```bash:コミットログ
$ git log --oneline
298c76f (HEAD -> main) Merge remote-tracking branch 'template/main'
95b9929 (template/main) test commit
5a536c6 (origin/main, origin/HEAD) Initial commit
cc47850 Merge pull request #1 from ykkd/develop
46bf40f changed Profile Icons Appearance
de3f425 minor refactoring for AppDelegate & AssetCatalog
401541e fixed README
8a5a4e9 edit Makefile
afe3090 Revert "edit Makefile"
170622f edit Makefile
5b47502 (template/test) update readme
cef4c4b first commit
```

# まとめ
GitHub Template Repositoryはやはり使えるなと感じました。
設計カタログのような使い方、ツールだったり、環境構築系のものはまとめてもいいです。
テンプレートリポジトリ側の履歴を参照せず、クリーンな状態からできるのがいいですね。（切り離した状態で実装ができる）

ただ、気になった点でもあげている通り、テンプレートリポジトリの更新を実装中プロジェクトに取り入れるのはやはりやめたほうがよさそう。
今回試したのはファイル追加なので大丈夫でしたが、ファイル変更はおそらくコンフリクトするだろうし、クリーンな状態ということもなくなります。
なので、実装中プロジェクトでテンプレートリポジトリ実装範囲内いじる際は実装中プロジェクトで行い、後ほどissueなどをテンプレートリポジトリにあげて忘れないようにしておくべきかなと思います。