GitHubとGitLab両方でプライベートリポジトリを並行運用してみよう

# はじめに
年明け早々にGitHubにて無料ユーザーでもプライベートリポジトリ無制限という素晴らしいアップデートがありました。

[新しい年とともに、新しいGitHub を](https://github.blog/jp/2019-01-08-pricing-change-jp/)

私は昨年2月よりリモートリポジトリでの個人開発を行っており、当時GitHubは無料無制限ではなかったため、GitLabを選択しずっと使い続けています。

無料プランで出来ることは依然GitLabの方が勝っていますが、ネームバリューや周辺ツール等の情報量ではやはりGitHubの方が大きいです。
参考比較記事: [GitHub.com・BitBucket.org・GitLab.comの月額料金比較 + α](https://qiita.com/hiroponz/items/c1ed4d6c10484233bf88)

これを期にGitLabからGitHubへ乗り換えてみようかなと思いましたが、どちらか一方だけを使うのではなく、いっそ両方を同時に使っちゃおうという結論に至りました。
メリットとしてはどちらかが落ちていてももう一方を利用できるので可用性の向上が期待できます。

どちらもメンテや障害で止まる事もあるので。
昨年のGitHubの1日障害は記憶に新しいかと思います。
[GitHubが障害を総括、43秒間のネットワーク断が1日のサービス障害につながった（2018年10月）](http://www.atmarkit.co.jp/ait/articles/1810/31/news063.html)
[GitLab.comが操作ミスで本番データベース喪失。5つあったはずのバックアップ手段は役立たず、頼みの綱は6時間前に偶然取ったスナップショット（2017年2月）](https://www.publickey1.jp/blog/17/gitlabcom56.html)
[GitLab復旧実況中継 #savegitlab（2017年2月）](https://togetter.com/li/1076845)

# 運用にあたり
個人開発では私一人でリポジトリを運用するため、リモートに対して行う操作としては、

* **push/pull(fetch)**
* **リポジトリの作成**

ぐらいになります。

この2つの操作を現状と変わらない操作性で実現することを目標とします。



# push/pull(fetch)
GitHub/GitLabへ同時にpush/pull(fetch)できればおっけーです。
これは単純に`.gitconfig`の`remote`に`url`を追加すればいいだけでした。
[git push originで複数箇所にプッシュする](https://qiita.com/sasaplus1/items/ed518bb14ef8e3da06bf)

以下のコマンドでサクッとできます。

```cmd:リモートリポジトリの追加
# git remote set-url --add <remote name> <repository url>
$ git remote set-url --add origin https://github.com/miso-develop/example

# ちゃんと追加されたか確認 
$ git remote -v
origin  https://gitlab.com/miso_develop/example (fetch)
origin  https://gitlab.com/miso_develop/example (push)
origin  https://github.com/miso-develop/example (push)
```

これでいつもどおり`git push`するだけでGitHub/GitLabの両方へ同時にpushできます。



# リポジトリの作成
リポジトリは毎日ポンポン作成するわけではないので今までWeb画面ポチポチで行ってきましたが、GitHub/GitLabの両方で同じ操作をするのはさすがに億劫です。
これを期にCLIで操作するようにしてみました。

## CLIツール
GitHubは「[hub](https://github.com/github/hub)」、GitLabは「[NARKOZ/gitlab](https://github.com/NARKOZ/gitlab)」というCLIツールのシェアが高そうです。

他にもGitHubとGitLabとBitBucketマルチ対応のツールもありましたが、GitLabの最新APIに対応していないようでリポジトリが作れませんでした。
いけたらこれ一本でいきたかったです。
[GitLab&GitHubを操作するためのCLIツール、hlbのご紹介](https://qiita.com/mpppk/items/7c6030b50c9399fe01ea)



## hub (GitHub CLI)
**[github/hub](https://github.com/github/hub)**
[ドキュメント](https://hub.github.com/hub.1.html)

### インストール
私はWindowsユーザーなのでGitHubのReleasesからzip落としました。
[hub (Releases)](https://github.com/github/hub/releases)

### ユーザー名/アクセストークンを環境変数に
ちょっと抵抗がありますが、こうしないと`%USERPROFILE%.config\hub`（Unix系だと`~/.config/hub`）に平文ベタ書きのconfigファイルが作成されます。
環境変数に格納しておくとconfigファイルが作成されません。

```cmd:環境変数設定（Windows）
$ setx GITHUB_USER <your user name>
$ setx GITHUB_TOKEN <your access token>
```

credential-managerとか使えないのかな…

### httpsプロトコルを強制化
GitHub/GitLabともプロトコルはhttpsを使用しているので。

```cmd:httpsプロトコルを指定（hub）
$ git config --global --add hub.protocol https
```

### リポジトリ作成コマンド
以下のコマンドでリポジトリ作成。
`-p`オプションはプライベートリポジトリを指定です。
`remote add origin`までしてくれます。

```cmd:リポジトリ作成（hub）
$ hub create -p <repository name>
```




## NARKOZ/gitlab (GitLab CLI)
**[NARKOZ/gitlab](https://github.com/NARKOZ/gitlab)**
[ドキュメント](https://www.rubydoc.info/gems/gitlab/Gitlab/Client)


### インストール
Ruby製なのでgemを使います。

```cmd:インストール（gitlab）
$ gem install gitlab
```

### 環境変数の設定
GitLabのAPIエンドポイント（固定値）とアクセストークンを環境変数へ埋め込みます。

```cmd:環境変数設定（Windows）
$ setx GITLAB_API_ENDPOINT https://gitlab.com/api/v4
$ setx GITLAB_API_PRIVATE_TOKEN <your access token>
```

### リポジトリ作成コマンド
以下のコマンドでリポジトリ作成。
デフォルトはプライベートリポジトリ。
レスポンスで色々情報表示されるので`--only=web_url`でリポジトリURLのみ表示。

```cmd:リポジトリ作成（gitlab）
$ gitlab create_project <repository name> --only=web_url
```

ただ`remote add origin`までしてくれない…！
このコマンドめんどいし困った…



# バッチでまとめてやっちゃおう
リモートリポジトリの追加時も一度`git remote set-url --add`する必要があるし、GitHub/GitLabのリポジトリ作成時にまとめて色々やっちゃうバッチを作りました。

このバッチをパスの通ってるディレクトリに置けばどこからでもコマンドがわりに打てます。
初回コミットまで終えてるローカルリポジトリにて`createrepo`とコマンドを打ってみてください。


```cmd:createrepo.cmd
@echo off

:: get repository (directory) name
for %%A in (%CD%) do set REPOSITORY_NAME=%%~nxA
echo Repository name: %REPOSITORY_NAME%

:: create github
hub create -p %REPOSITORY_NAME%

:: create gitlab
for /f "tokens=1-12 skip=4 eol=+ delims=|" %%A in ('gitlab create_project %REPOSITORY_NAME%') do set REPOSITORY_URL=%%L
set REPOSITORY_URL=%REPOSITORY_URL: =%
echo %REPOSITORY_URL:.git=%
echo.

:: add remote gitlab
git remote set-url --add origin %REPOSITORY_URL%

:: push
git push -u origin master

echo Complate!
pause
exit /b


```



# （おまけ）GitLabのリポジトリをGitHubに複製するバッチ
GitLabにのみあるリポジトリをGitHubに複製するバッチです。
リポジトリの複製に自分用に作ったものですが良ければお使いください。
パスの通ってるディレクトリに置いてご使用ください。

```cmd:duphub.cmd
@echo off

:: remote確認
git remote -v
echo.

:: リポジトリ名取得
for /f "tokens=1-4 delims=/" %%A in ('git remote get-url origin') do set REPOSITORY_NAME=%%D
set REPOSITORY_NAME=%REPOSITORY_NAME:.git=%
echo %REPOSITORY_NAME%
echo.

:: リポジトリ名入力
set /p INPUTNAME=表示されたリポジトリ名でOKなら[Enter]を押して下さい。変更したい場合はリポジトリ名を入力して下さい: 
echo.
if %INPUTNAME%_ neq _ set REPOSITORY_NAME=%INPUTNAME%
echo %REPOSITORY_NAME%
echo.

:: GitHubにリポジトリ作成
for /f "tokens=1-2 delims=\" %%A in ('hub create -p %REPOSITORY_NAME%') do set REPOSITORY_URL=%%A
echo.

:: remoteにURL追加
git remote set-url --add origin %REPOSITORY_URL%.git
echo.

:: remote確認
git remote -v
echo.

:: push
git push -u origin master
echo.

echo Complete!
pause
exit

```



# おわりに
以上のようにさくっとGitHub/GitLabを並行運用して快適なGitライフを送りましょう！