git clone --mirror $URL
- bare リポジトリが作られる
-
git init --bare
と大体同じ
-
- --mirror オプション付きでリモートリポジトリが追加される
-
git remote add --mirror origin $URL
と大体同じ
-
- リモートリポジトリが fetch される
-
git fetch origin
と大体同じ
-
git push --mirror $NAME
- ローカルリポジトリの refs/ がそのままリモートリポジトリの refs/ にプッシュされる
-
git push $NAME "refs/*:refs/*"
と大体同じ
-
git remote add --mirror=push $NAME $URL
-
config の
remote.$NAME
に下記が追記されるurl = $URL mirror = true
git remote add --mirror=fetch $NAME $URL
-
config の
remote.$NAME
に下記が追記されるurl = $URL fetch = +refs/*:refs/*
git remote add --mirror $NAME $URL
- --mirror=push と --mirror=fetch の両方
- ただし使うなと警告が表示される
config の mirror = true
の効果
- git push で自動的に --mirror オプションが指定されたように振る舞う
config の fetch = +refs/*:refs/*
の効果
- git fetch でリモートリポジトリの refs/ がローカルリポジトリの refs/ にそのまま保存される
- 通常はリモートリポジトリの refs/heads/ がローカルリポジトリの refs/remotes/*/ に保存される
- つまり リモート追跡ブランチ=追跡ブランチ=ローカルブランチ となる
まとめ
リモートをローカルにミラー
git clone --mirror $URL
または
git init --bare
git remote add --mirror=fetch origin $URL
git fetch origin
ローカルをリモートにミラー
git remote add --mirror=push origin $URL
git push origin
ローカルをリモートにミラーのダメな例
git remote add origin $URL
git push --mirror origin
この手順だと git remote add origin $URL
で config に fetch = +refs/heads/*:refs/remotes/origin/*
が追記されます。
そのため、git push でリモートリポジトリを更新した後にローカルリポジトリにリモート追跡ブランチが作成されます。
push の --mirror オプションは refs/ をすべてプッシュするため、もう一度 git push するとリモート追跡ブランチまで一緒にリモートリポジトリにプッシュされます。
(ローカルリポジトリ・リモートリポジトリ共に refs/remotes/origin/master のようなブランチが作成される)
リモートAをローカルを経由してリモートBにミラー
git clone --mirror git@example.com:repo.git
cd repo.git
git remote add --mirror=push new git@example.net:repo.git
git push new
さいごに
git push の --mirror オプションの存在意義がわからない。
おまけ
リモートAをローカルを経由してリモートBにミラー、ただしローカルはワーキングツリーを持つ(not bare)
git clone git@example.com:repo.git
cd repo.git
git remote set-head -d origin
git remote add new git@example.net:repo.git
git push --tags new "refs/remotes/origin/*:refs/heads/*"