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/*"
