Envie o repositório Git local para o novo controle remoto, incluindo todas as ramificações e tags


551

Eu tenho um repositório Git local que gostaria de enviar para um novo repositório remoto (novo repositório configurado no Beanstalk, se isso importa).
Meu repositório local possui algumas ramificações e tags e gostaria de manter toda a minha história.

Parece que eu basicamente só preciso fazer um git push, mas isso apenas carrega o masterramo.

Como envio tudo para obter uma réplica completa do meu repositório local no controle remoto?


Resposta mais curta e fácil - stackoverflow.com/a/39992258/6648326 .
MasterJoe2 26/03

Respostas:


898

Para enviar todas as suas ramificações , use (substitua REMOTE pelo nome do controle remoto, por exemplo "origem"):

git push REMOTE '*:*'
git push REMOTE --all

Para enviar todas as suas tags :

git push REMOTE --tags

Finalmente, acho que você pode fazer isso tudo em um comando com:

git push REMOTE --mirror

No entanto, além disso --mirror, também enviará seus controles remotos, portanto, isso pode não ser exatamente o que você deseja.


53
--allem vez de *:*parece mais amigável
Idan K

56
meu deus ............. rasguei toda a internet e descobri que o interruptor `--all` é AAAAALLLLLLLLLLLLLLLL que eu precisava!
Rakib 18/10/11

21
Apenas observando que git push REMOTE --allretornou sem No refs in common and none specified;fazer nada., Enquanto git push REMOTE "*:*na verdade empurrava todos os ramos para o controle remoto.
precisa saber é o seguinte

10
Use --dry-run para inspecionar o que vai acontecer, no caso de você ter "tmp" ou ramos "recurso" localmente que você realmente não quer atualização em REMOTO
Jonno

55
Se o controle remoto original ainda estiver disponível, é uma boa ideia git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron

157

No caso como eu, você adquiriu um repo e agora está mudando a origem remota para um repo diferente, um novo vazio ...

Portanto, você tem seu repositório e todos os ramos dentro, mas ainda precisa fazer check-out desses ramos para que o git push --allcomando efetue o envio deles também.

Você deve fazer isso antes de pressionar:

for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done

Seguido por

git push --all

4
Isso também é realmente útil, pois eu tive que fazer check-out de todos os ramos manualmente. Isso será bom para a próxima vez.
Cory Imdieke 9/10

10
Estranhamente, git push '*:*'empurrou todos os galhos. git push -allapenas empurrou o mestre. Eu estava transportando repositórios do github para o bitbucket.
Jerrymouse # 14/13

3
Em vez de verificar todas as ramificações, você deve fazer "git branch --track $ remote". Em grandes repositórios, verificar se um ramo antigo leva algum tempo
Moataz Elmasry

2
Eu tive que fazer uma pequena alteração para que isso funcionasse: em --track remotes/$remotevez de --track $remote. Aqui está a linha de comando completa:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

Obrigado, funciona para mim, a resposta acima não funciona tão bem.
Benyamin Jafari

90

Aqui está outra opinião sobre a mesma coisa que funcionou melhor para a situação em que eu estava. Ele resolve o problema em que você tem mais de um controle remoto, gostaria de clonar todos os ramos do controle remoto sourcepara o controle remoto, destinationmas sem precisar verificar todos eles previamente.

(O problema que tive com a solução de Daniel era que ele se recusaria a efetuar o check-out de uma filial de rastreamento a partir do sourcecontrole remoto, se eu já tivesse feito a verificação anteriormente, ou seja, não atualizaria minha filial local antes do envio)

git push destination +refs/remotes/source/*:refs/heads/*

Nota: Se você não estiver usando a CLI direta, deverá escapar dos asteriscos:

git push destination +refs/remotes/source/\*:refs/heads/\*

isso empurrará todas as ramificações remotas sourcepara uma ramificação principal destination, possivelmente fazendo um empurrão não rápido. Você ainda precisa enviar tags separadamente.


8
+1 Isso funcionou para mim, clonando de um remotepara outro. Obrigado!
21413 Laurence

4
Eu tive que escapar dos asteriscos:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr 17/10

2
Para mim, isso acabou empurrando um ramo chamado HEAD, o que não acho que seja intencional nesse cenário.
precisa saber é o seguinte

1
Essa resposta foi incrivelmente útil para mim. A única menção na página do manual git-push (1) deste uso de asteriscos está em um pequeno exemplo para a --pruneopção.
Laindir 17/05

4
Resposta excelente, muito diferente do que o --mirrorparâmetro usual que todos recomendam. Funciona perfeitamente para cenários em que você apenas deseja manter dois controles remotos sincronizados para fins de automação ou auditoria.
Vinicius Xavier

15

Esta é a maneira mais concisa que encontrei, desde que o destino esteja vazio. Mude para uma pasta vazia e, em seguida:

# Note the period for cwd >>>>>>>>>>>>>>>>>>>>>>>> v
git clone --bare https://your-source-repo/repo.git .
git push --mirror https://your-destination-repo/repo.git

Substitua https://...por file:///your/repoetc., conforme apropriado.


13

A página de manual git-pushvale uma leitura. Combinado com este site , escrevi o seguinte no meu .git/config:

[remote "origin"]
    url = …
    fetch = …
    push = :
    push = refs/tags/*

Os push = :meios "enviam qualquer ramificação 'correspondente' (ou seja, ramificações que já existem no repositório remoto e possuem uma contraparte local)", enquanto push = refs/tags/*significa "enviam todas as tags".

Então agora só tenho que correr git pushpara enviar todos os ramos e tags correspondentes.

Sim, isso não é exatamente o que o OP queria (todos os ramos a serem enviados já devem existir no lado remoto), mas pode ser útil para aqueles que encontrarem essa pergunta enquanto pesquisam "como faço para enviar ramos e tags ao mesmo tempo" Tempo".


13

No meu caso, o que funcionou foi.

git push origin --all

4
Simples e fácil. Funciona! originé um alias para o repositório Git de URL remoto.
Do Nhu Vy

8

Espelhando um Repositório

Crie um clone simples do repositório.

git clone --bare https://github.com/exampleuser/old-repository.git

Envio de espelho para o novo repositório.

cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git

Remova o repositório local temporário que você criou na etapa 1.

cd ..
rm -rf old-repository.git

Espelhando um repositório que contém objetos Git Large File Storage

Crie um clone simples do repositório. Substitua o nome de usuário de exemplo pelo nome da pessoa ou organização que possui o repositório e substitua o nome de repositório de exemplo pelo nome do repositório que você deseja duplicar.

git clone --bare https://github.com/exampleuser/old-repository.git

Navegue para o repositório que você acabou de clonar.

cd old-repository.git

Puxe os objetos Git Large File Storage do repositório.

git lfs fetch --all

Envio de espelho para o novo repositório.

git push --mirror https://github.com/exampleuser/new-repository.git

Envie os objetos Git Large File Storage do repositório para o seu espelho.

git lfs push --all https://github.com/exampleuser/new-repository.git

Remova o repositório local temporário que você criou na etapa 1.

cd ..
rm -rf old-repository.git

As instruções acima são da Ajuda do Github: https://help.github.com/articles/duplicating-a-repository/


1
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência. Veja aqui para obter instruções sobre como escrever melhores respostas "baseadas em link". Obrigado!
GhostCat

5

Eu encontrei as respostas acima ainda têm algumas coisas pouco claras, o que enganará os usuários. Primeiro, é certo que, git push new_origin --alle git push new_origin --mirrornão é possível duplicar todas as ramificações de origem, basta duplicar as ramificações locais existentes para o new_origin.

Abaixo estão dois métodos úteis que testei:

1, duplicado por clone repo bare. git clone --bare origin_url, digite a pasta e git push new_origin_url --mirror. Dessa forma, você também pode usar os git clone --mirror origin_urldois --baree --mirrorfará o download de um repositório simples, sem incluir o espaço de trabalho. por favor consulte isto

2, Se você possui um repositório git usando git clone, o que significa que possui um espaço de trabalho vazio para repositório e git, pode usar git remote add new_origin new_origin_url, e então git push new_origin +refs/remotes/origin/\*:refs/heads/\*e, em seguida ,git push new_origin --tags

Dessa forma, você obterá um ramo principal adicional, o que não faz sentido.


2

Para enviar ramificações e tags (mas não controles remotos):

git push origin 'refs/tags/*' 'refs/heads/*'

Isso seria equivalente a combinar as opções --tagse --allpara git push, que o git não parece permitir.


Existe uma opção adicional para enviar de outro controle remoto? Por exemplo, com+refs/remotes/source/*
Yves Martin

2

Baseado na resposta @Daniel, eu fiz:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done

2
Melhor ainda, | grep -v masterpode ser substituído por | sed 's/\*//'(suponho que você tenha excluído masterpara evitar o pouco desagradável *anexado ao ramo atualmente selecionado), que permite incluir mastere evitar problemas quando mastero ramo não estiver selecionado no momento. Também pena de necroposting, é só que esta resposta me ajudou hoje e eu queria partilhar a minha alteração, se pode ajudar os outros na minha posição ...
ToVine

1

Descobri que nada disso parecia funcionar corretamente para mim. Sinta-se à vontade para exterminar isso, mas, por algum motivo, não conseguiu que as outras opções funcionassem corretamente.

O resultado esperado foi um repo "clonado" para outro controle remoto (ou seja, do Github para outro provedor):

  • Todas as ramificações são criadas no novo controle remoto
  • Todo o histórico da filial é criado no novo controle remoto
    • (isso foi esquecido em todas as soluções que tentei)
  • Todas as tags são criadas no novo controle remoto
  • A fonte se move (um determinado)
  • Não destrutivo (dando uma pausa na opção --mirror)

O principal problema que eu estava vendo era que todas as ramificações remotas não foram recriadas no novo controle remoto. Se um comando o fez, o novo controle remoto não tinha o histórico da ramificação (por exemplo, fazer um git checkout branch; git lognão mostraria as confirmações esperadas da ramificação).

Notei que git checkout -b branchnameNÃO é o mesmo que git checkout branchname(sendo este último o que eu precisava). Percebo git checkout --track branchnameque não parece ter puxado o histórico do ramo.

Minha solução (baseada em PowerShell):

Function Git-FetchRemoteBranches {
$originalbranch = (git symbolic-ref HEAD).split("/")[-1]

Foreach ($entry in (git branch -r)) {

If ($entry -like "*->*") {
  $branch = $entry.split("->")[2].split("/")[1]
}
  else {$branch = $entry.split("/")[1]}

Write-Host "--Trying git checkout " -NoNewline
Write-Host "$branch" -Foreground Yellow

git checkout $branch

Remove-Variable branch -Force

""}

#Switch back to original branch, if needed
If ( ((git symbolic-ref HEAD).split("/")[-1]) -ne $originalbranch) {
"Switching back to original branch"
git checkout $originalbranch
Remove-Variable originalbranch -Force
}
}

git clone http://remoterepo
cd remoterepo
Git-FetchRemoteBranches
git remote add newremote
git push newremote --all
git push newremote --tags #Not sure if neeeded, but added for good measure

1

O comando abaixo empurrará todos os ramos ( incluindo aqueles que você nunca efetuou check-out, mas que estão presentes no seu repositório git, você pode vê-losgit branch -a )

git push origin '*:*'

NOTA: Este comando é útil quando você está migrando o serviço de controle de versão ( ou seja, migrando do Gitlab para o GitHub )


1
Migrando entre os serviços de controle de versão e é exatamente isso que estou procurando, felicidades!
Luka Špoljarić 14/04

1

Eu estava no processo de alternar de um serviço de controle de versão para outro e precisava clonar todos os repositórios, incluindo todos os ramos, tags e histórico.

Para alcançar acima, eu fiz a seguir:

  • fazer check-out manual de todas as ramificações para o repositório local (script para check-out, tudo mostrado abaixo),
  • git push origin '*:*'

Script .sh usado para fazer check-out de todas as ramificações no repositório local:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.