Qual é a diferença entre git clone –mirror e git clone –bare

A página de ajuda do git clone tem isto a dizer sobre --mirror :

Configure um espelho do repository remoto. Isso implica – --bare .

Mas não entra em detalhes sobre como o clone --mirror é diferente de um clone --bare .

A diferença é que ao usar --mirror , todas as referências são copiadas como estão . Isso significa tudo: ramificações de rastreamento remoto, notas, refs / originais / * (backups do ramo de filtro). O repo clonado tem tudo. Ele também é configurado para que uma atualização remota recupere tudo da origem (sobrescrevendo os refs copiados). A ideia é realmente espelhar o repository, para ter uma cópia total, para que você possa, por exemplo, hospedar seu repository central em vários lugares ou fazer backup dele. Pense em apenas copiar o repo, exceto de uma forma muito mais elegante.

A nova documentação praticamente diz tudo isso:

--mirror

Configure um espelho do repository de origem. Isso implica – --bare . Comparado a --bare , --bare não apenas mapeia as ramificações locais da origem para as ramificações locais do destino, ele mapeia todas as referências (incluindo ramificações remotas, notas etc.) e configura uma configuração refspec de forma que todas essas referências sejam sobrescritas. por uma git remote update no repository de destino.

Minha resposta original também observou as diferenças entre um clone nu e um clone normal (não nua) – o clone não-nu configura ramificações de rastreamento remoto, apenas criando um ramo local para HEAD , enquanto o clone nu copia os ramos diretamente.

Suponha que a origem tenha algumas ramificações ( master (HEAD) , next , pu e maint ), algumas tags ( v1 , v2 , v3 ), algumas ramificações remotas ( devA/master , devB/master ) e algumas outras refs ( refs/foo/bar , refs/foo/baz , que podem ser annotations, stashes, namespaces de outros desenvolvedores, quem sabe).

  • git clone origin-url (não nua): você obterá todas as tags copiadas, um master (HEAD) filial local master (HEAD) rastreando uma origin/master remota origin/master remota e origin/next ramificações remotas origin/next , origin/pu e origin/maint . As ramificações de rastreamento são configuradas para que, se você fizer algo como a git fetch origin , elas sejam buscadas conforme o esperado. Quaisquer ramificações remotas (no remoto clonado) e outras referências são completamente ignoradas.

  • git clone --bare origin-url : você obterá todas as tags copiadas, ramificações locais master (HEAD) , next , pu , e maint , nenhuma ramificação de rastreamento remoto. Ou seja, todas as ramificações são copiadas como estão e são configuradas completamente independentes, sem a expectativa de recuperar novamente. Quaisquer ramificações remotas (no remoto clonado) e outras referências são completamente ignoradas.

  • git clone --mirror origin-url : cada último desses refs será copiado como está. Você obterá todas as tags, ramificações locais master (HEAD) , next , pu e maint , ramificações remotas devA/master e devB/master , outras refs refs/foo/bar e refs/foo/baz . Tudo é exatamente como estava no controle remoto clonado. O rastreamento remoto é configurado para que, se você executar o git remote update todos os refs sejam sobrescritos da origem, como se você tivesse acabado de excluir o espelho e o recodificado. Como os docs originalmente disseram, é um espelho. É suposto ser uma cópia funcionalmente idêntica, intercambiável com o original.

 $ git clone --mirror $URL 

é um short-hand para

 $ git clone --bare $URL $ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL) 

(Copiado diretamente daqui )

Como a página atual do homem diz:

Comparado a --bare , --bare não apenas mapeia as ramificações locais da origem para as ramificações locais do destino, ele mapeia todas as referências (incluindo ramificações remotas, notas etc.) e configura uma configuração refspec de forma que todas essas referências sejam sobrescritas. por uma git remote update no repository de destino.

Meus testes com o git-2.0.0 hoje indicam que a opção –mirror não copia hooks, o arquivo de configuração, o arquivo de descrição, o arquivo info / exclude, e pelo menos no meu caso de teste alguns refs (que eu don ‘ Não entendo.) Eu não chamaria isso de “cópia funcionalmente idêntica, intercambiável com o original”.

 -bash-3.2$ git --version git version 2.0.0 -bash-3.2$ git clone --mirror /git/hooks Cloning into bare repository 'hooks.git'... done. -bash-3.2$ diff --brief -r /git/hooks.git hooks.git Files /git/hooks.git/config and hooks.git/config differ Files /git/hooks.git/description and hooks.git/description differ ... Only in hooks.git/hooks: applypatch-msg.sample ... Only in /git/hooks.git/hooks: post-receive ... Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ ... Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ Only in /git/hooks.git/refs/heads: fake_branch Only in /git/hooks.git/refs/heads: master Only in /git/hooks.git/refs: meta 

Um clone copia as referências do controle remoto e as coloca em um subdiretório chamado ‘estas são as referências que o controle tem’.

Um espelho copia as referências do controle remoto e as coloca em seu próprio nível superior – ele substitui suas próprias referências pelas do controle remoto.

Isto significa que quando alguém puxa do seu espelho e enche as refas do espelho em seu subdiretório, ele recebe as mesmas referências do original. O resultado da busca de um espelho atualizado é o mesmo que buscar diretamente do repository inicial.

Uma explicação diferenciada da documentação do GitHub sobre Duplicando um Repositório :

Tal como acontece com um clone nu, um clone espelhado inclui todos os ramos e tags remotos, mas todas as referências locais serão substituídas sempre que você buscar, por isso será sempre o mesmo que o repository original.

Eu adiciono uma imagem, mostro a diferença da config entre o espelho e o nu. insira a descrição da imagem aqui A esquerda está vazia, a direita é espelho. Você pode ser claro, o arquivo de configuração do mirror tem uma chave de fetch , o que significa que você pode atualizá-lo, por git remote update ou git fetch --all