それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

gitミラーリングを試す。gitlab の特定ブランチをgithub の指定ブランチへミラーリングしたい

gitlab の特定ブランチをgithub の指定ブランチへミラーリングしたい

開発中では、適当にコミットして適当にプッシュしたくないですか?

自分の作業内容がある程度まとまって git rebase などでコミットをまとめてから ブランチに切り出して、プッシュしたいじゃないですか。

作業内容のブランチでコミットメッセージを考えるのが面倒じゃないですか。

ローカル・ブランチでいいと思うんだけど、ローカルだけにデータ持つのが怖いじゃないですか。

mirror ブランチへpush したら github にプッシュしてほしい。

自動でブランチをミラーリングすればいいじゃないか。

そこで、作業用にはGitLabをつかって、見せられる状態に整理し、特定ブランチにプッシュ。そしたら Github にプッシュしたらいいじゃないですか。

それ、ローカルだけでできるじゃん?

2つレポジトリを作っておいて。

git remote add my-work ssh://my-git.example.com/takuya/project01
git remote add origin ssh://github.com/takuya/project01
## 作業中のコミット
git commit -m toda-saved
git push my-work work
## 整理したコミットをプッシュ
git push origin revised:branch/patch/1234

でも、レポジトリを使い間違えて、事故が起きやすいじゃないですか。

あと、git clone するたびに レポジトリの設定を書くのが面倒くさいじゃないですか。

そういうこと考えれば、レポジトリを完全に分けたいじゃないですか。

ミラーリングで解決できるか試す。

そこで、gitlab の特定のブランチにpushしたら、github の特定ブランチにミラーリングするようにしただろうだろうか。と思ったわけですよ。

つまり、Gitlab の workflow を使って、Gitlab からgithub の指定ブランチへミラーリングを自動実行できれば、楽になりそうじゃん。

準備

最終的に成果物を設置する github プロジェクト(レポジトリ)を作成。

そこに、デプロイ・キーを書き込み可能で作成する。

鍵を作成して

ssh-keygen -t ecdsa -f ./id_ecdsa
cat ./id_ecdsa.pub | pbcopy

書き込み可能にチェックして登録する

元レポジトリでミラーリングを入れる。

元になるプロジェクト(レポジトリ)をGitLabに作成して、デプロイキーを作成する

元レポジトリでCI/CDを作る

そして、プロジェクトのCI/CDのランナーを有効にして

GitLabでCIをするように設定する。

stages:
  - mirror


copy-to-github:
  stage: mirror
  tags:
      - takuya
  script:
    - echo Start mirroring
    - |
      ssh-keyscan -t rsa github.com >  ./known_hosts
      git switch mirror
      echo $GITHUB_DEPLOY_KEY
      cp $GITHUB_DEPLOY_KEY  id_ecdsa
      chmod 400 id_ecdsa
      (git remote | grep gh ) || git remote add gh git@github.com:takuya/mirror-test.git
      cat ./id_ecdsa
      cat ./known_hosts
      cat .git/config
      git -c core.sshCommand="ssh -i ./id_ecdsa -o UserKnownHostsFile=./known_hosts" push gh mirror
    - echo End mirroring
  only:
    - mirror  

これで、特定の名前(今回はmirror)にpush したら、github にもpush されるわけである。

git remote add origin https://my-git.example.com/takuya/project01
git push origin mirror

なんかすごいめんどくさいけど、github 側のブランチ名が大量に溢れかえることがなくなって非常に便利である。

整理整頓が大事。

大量ブランチが以前未整理の社内githubプロジェクトとか、高頻度で見かけますものね。

ブランチ名前を変えてプッシュ

名前を変えてブランチにプッシュしたいときは

git でローカルブランチを別名でpushする方法を使えばいい。

git push origin local_name:remoteName

ただ、この方法にも欠点があって、github~/.gitlab-ci.ymlが同期されてしまう。これはちょっと問題ですね。

gitlab を使うから、このような問題が発生するのであって、gogs やベアレポジトリ使って、プッシュ時のフック・スクリプトで対応すれば解決すると思うんだよね。っていうか作業用にGitlabのような高機能サーバーは要らんしね。

まとめ

今回使った同期(ミラーリング)のスクリプトのポイントは次の通り

## github.com のサーバー ホスト鍵を登録
ssh-keyscan -t rsa github.com >  ./known_hosts
## デプロイ用のSSH秘密鍵を登録。
cp $GITHUB_DEPLOY_KEY  id_ecdsa && chmod 400 id_ecdsa
## git remote を登録(すでに登録済みなら上書きしない。
(git remote | grep gh ) || git remote add gh git@github.com:takuya/mirror-test.git
## ミラーリングしたいブランチに切り替える。
git switch mirror
## git -c で ssh オプションを指定してい鍵とホスト鍵を使う。
git -c core.sshCommand="ssh -i ./id_ecdsa -o UserKnownHostsFile=./known_hosts" push gh mirror:mirror01

特に、git -csshオプションを指定して、ホスト鍵と秘密鍵を指定してる箇所がポイントになると思う。

sshなら、鍵さえクリアすれば、git コマンドを自動実行でpush / pull できるようになるので、自動実行が簡単になると思う。

もしhttps アクセスのときは、credential を作れば解決できるし、もう少し楽かも。