Poussez le dépôt Git local vers une nouvelle télécommande, y compris toutes les branches et tous les tags


551

J'ai un dépôt Git local que j'aimerais pousser vers un nouveau dépôt distant (tout nouveau dépôt mis en place sur Beanstalk, si cela importe).
Mon repo local a quelques branches et tags, et je voudrais garder toute mon histoire.

Il semble que je dois simplement faire un git push, mais cela ne télécharge que la masterbranche.

Comment puis-je tout pousser pour obtenir une réplique complète de mon dépôt local sur la télécommande?


Réponse la plus courte et la plus simple - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Réponses:


898

Pour pousser toutes vos branches , utilisez l'une ou l'autre (remplacez REMOTE par le nom de la télécommande, par exemple "origine"):

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

Pour pousser tous vos tags :

git push REMOTE --tags

Enfin, je pense que vous pouvez faire tout cela en une seule commande avec:

git push REMOTE --mirror

Cependant, en plus --mirror, poussera également vos télécommandes, donc ce n'est peut-être pas exactement ce que vous voulez.


53
--allau lieu de *:*semble plus convivial
Idan K

56
mon dieu ............. j'ai déchiré tout Internet et j'ai découvert que le commutateur `--all` est AAAAALLLLLLLLLLLLLL dont j'avais besoin!
Rakib

21
Il suffit de noter que cela git push REMOTE --allest revenu No refs in common and none specified;sans rien faire, tout git push REMOTE "*:*en poussant toutes les branches à distance.
Im0rtality

10
Utilisez --dry-run pour inspecter ce qui se passera, au cas où vous auriez des branches "tmp" ou "feature" localement que vous ne voudriez pas vraiment mettre à jour dans REMOTE
Jonno

55
Si la télécommande d'origine est toujours disponible, c'est une bonne idée à faire git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron

157

Dans le cas comme moi où vous avez acquis un repo et que vous changez maintenant l'origine distante vers un autre repo, un nouveau vide ...

Vous avez donc votre dépôt et toutes les branches à l'intérieur, mais vous devez toujours vérifier ces branches pour que la git push --allcommande les pousse également.

Vous devez le faire avant de pousser:

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

Suivi par

git push --all

4
C'est aussi très utile, car j'ai dû vérifier toutes les succursales manuellement. Ce sera bon pour la prochaine fois.
Cory Imdieke

10
Étrangement, git push '*:*'poussé toutes les branches. git push -allvient de pousser le maître. Je transportais un dépôt de github à bitbucket.
jerrymouse

3
Au lieu de vérifier chaque branche, vous devez simplement faire "git branch --track $ remote". Dans un énorme repos, vérifier une ancienne branche prend du temps
Moataz Elmasry

2
J'ai dû faire un petit changement pour que cela fonctionne: --track remotes/$remoteau lieu de --track $remote. Voici la ligne de commande complète:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

Merci, cela fonctionne pour moi, la réponse ci-dessus ne fonctionne pas aussi bien.
Benyamin Jafari

90

Voici une autre version de la même chose qui a mieux fonctionné dans la situation dans laquelle je me trouvais. Cela résout le problème où vous avez plusieurs télécommandes, souhaitez cloner toutes les branches de télécommande sourceen télécommande destinationmais sans avoir à toutes les vérifier au préalable.

(Le problème que j'avais avec la solution de Daniel était qu'elle refusait de retirer une branche de suivi à sourcedistance si je l'avais déjà vérifiée, c'est-à-dire qu'elle ne mettrait pas à jour ma branche locale avant le push)

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

Remarque: Si vous n'utilisez pas l'interface CLI directe, vous devez échapper aux astérisques:

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

cela poussera toutes les branches distantes sourcevers une branche principale destination, en effectuant éventuellement une poussée non rapide. Vous devez toujours pousser les balises séparément.


8
+1 Cela a fonctionné pour moi, le clonage de l'un remoteà l'autre. Merci!
Laurence

4
J'ai dû échapper aux astérisques:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr

2
Pour moi, cela a poussé une branche appelée HEAD, ce qui, je pense, n'est pas intentionnel dans ce scénario.
maxwellb

1
Cette réponse m'a été incroyablement utile. La seule mention dans la page de manuel git-push (1) de cette utilisation des astérisques se trouve dans un petit exemple pour l' --pruneoption.
laindir

4
Excellente réponse, bien différente du --mirrorparamètre habituel que tout le monde recommande. Fonctionne parfaitement pour les scénarios où vous souhaitez simplement synchroniser deux télécommandes à des fins d'automatisation ou d'audit.
Vinicius Xavier

15

C'est la manière la plus concise que j'ai trouvée, à condition que la destination soit vide. Basculez vers un dossier vide puis:

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

Remplacer https://...par file:///your/repoetc., le cas échéant.


13

La page de manuel de git-pushvaut le détour. Combiné avec ce site Web, j'ai écrit ce qui suit dans mon .git/config:

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

Les push = :moyens "poussent toutes les branches" correspondantes "(c'est-à-dire les branches qui existent déjà dans le référentiel distant et ont une contrepartie locale)", tandis que les push = refs/tags/*moyens "poussent toutes les balises".

Alors maintenant, je n'ai plus qu'à courir git pushpour pousser toutes les branches correspondantes et toutes les balises.

Oui, ce n'est pas tout à fait ce que l'OP voulait (toutes les branches à pousser doivent déjà exister du côté distant), mais cela pourrait être utile pour ceux qui trouvent cette question en recherchant "comment puis-je pousser les branches et les balises en même temps" temps".


13

Dans mon cas, ce qui a fonctionné était.

git push origin --all

4
Simple et facile. Ça marche! originest un alias pour le référentiel Git d'URL distant.
Do Nhu Vy

8

Mise en miroir d'un référentiel

Créez un clone nu du référentiel.

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

Pousser en miroir vers le nouveau référentiel.

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

Supprimez le référentiel local temporaire que vous avez créé à l'étape 1.

cd ..
rm -rf old-repository.git

Mise en miroir d'un référentiel contenant des objets de stockage de fichiers volumineux Git

Créez un clone nu du référentiel. Remplacez l'exemple de nom d'utilisateur par le nom de la personne ou de l'organisation propriétaire du référentiel et remplacez l'exemple de nom de référentiel par le nom du référentiel que vous souhaitez dupliquer.

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

Accédez au référentiel que vous venez de cloner.

cd old-repository.git

Récupérez les objets Git Large File Storage du référentiel.

git lfs fetch --all

Pousser en miroir vers le nouveau référentiel.

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

Poussez les objets Git Large File Storage du référentiel dans votre miroir.

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

Supprimez le référentiel local temporaire que vous avez créé à l'étape 1.

cd ..
rm -rf old-repository.git

L'instruction ci-dessus provient de l'aide de Github: https://help.github.com/articles/duplicating-a-repository/


1
Bien que cela puisse théoriquement répondre à la question, il serait préférable d'inclure ici les parties essentielles de la réponse et de fournir le lien de référence. Voir ici pour obtenir des instructions comment écrire de meilleures réponses « fondées sur les liens ». Merci!
GhostCat

5

J'ai trouvé que les réponses ci-dessus ont encore des choses peu claires, ce qui pourrait induire les utilisateurs en erreur. Tout d'abord, il est sûr que git push new_origin --allet git push new_origin --mirrorne peut pas dupliquer toutes les branches d'origine, il suffit de dupliquer vos branches locales existantes vers votre nouvelle_origine.

Voici deux méthodes utiles que j'ai testées:

1, dupliquer par clone repo nu. git clone --bare origin_url, puis entrez dans le dossier, et. git push new_origin_url --mirrorDe cette façon, vous pouvez également utiliser les git clone --mirror origin_urldeux --bareet --mirrortélécharger un dépôt nu, sans compter l'espace de travail. veuillez vous référer à ceci

2, Si vous avez un dépôt git en utilisant git clone, ce qui signifie que vous avez un dépôt nu et un espace de travail git, vous pouvez utiliser git remote add new_origin new_origin_url, puis git push new_origin +refs/remotes/origin/\*:refs/heads/\*, puisgit push new_origin --tags

De cette façon, vous obtiendrez une branche de tête supplémentaire, ce qui n'a aucun sens.


2

Pour pousser des branches et des balises (mais pas des télécommandes):

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

Cela équivaudrait à combiner les options --tagset --allpour git push, ce que git ne semble pas autoriser.


Existe-t-il une option supplémentaire pour pousser depuis une autre télécommande? Par exemple avec+refs/remotes/source/*
Yves Martin

2

D' après la réponse de @Daniel, j'ai fait:

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

2
Encore mieux, | grep -v masterpeut être remplacé par | sed 's/\*//'(je suppose que vous avez exclu masterpour éviter le petit méchant *ajouté à la branche actuellement sélectionnée) qui vous permet d'inclure masteret d'éviter tout problème lorsque ce mastern'est pas votre branche actuellement sélectionnée. Désolé également pour la nécropostage, c'est juste que cette réponse m'a aidé aujourd'hui et je voulais partager ma modification si elle peut aider les autres dans ma position ...
ToVine

1

J'ai constaté qu'aucun de ces éléments ne semblait fonctionner correctement pour moi. N'hésitez pas à enflammer cela à mort, mais pour une raison quelconque, vous ne pouviez pas faire fonctionner correctement les autres options.

Le résultat escompté était un dépôt "cloné" sur une autre télécommande (c'est-à-dire de Github à un autre fournisseur):

  • Toutes les branches sont créées sur une nouvelle télécommande
  • Tout l'historique des succursales est créé sur une nouvelle télécommande
    • (cela a été manqué pour chaque solution que j'ai essayée)
  • Tous les tags sont créés sur la nouvelle télécommande
  • La source se déplace (une donnée)
  • Non destructif (donnant une pause à l'option --mirror)

Le problème majeur que je voyais était que toutes les succursales distantes n'étaient pas recréées dans la nouvelle télécommande. Si une commande le faisait, la nouvelle télécommande n'avait pas l'historique de la branche (c'est-à-dire que faire un git checkout branch; git logne montrerait pas les validations de branche attendues).

J'ai remarqué que ce git checkout -b branchnamen'est PAS la même chose git checkout branchname(ce dernier étant ce dont j'avais besoin). Je remarque git checkout --track branchnamequ'il ne semble pas tirer l'historique de la branche.

Ma solution (basée sur 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

La commande ci-dessous poussera toutes les branches ( y compris celles que vous n'avez jamais extraites mais présentes dans votre dépôt git, vous pouvez les voir pargit branch -a )

git push origin '*:*'

REMARQUE: cette commande est pratique lorsque vous migrez un service de contrôle de version ( c'est-à-dire une migration de Gitlab vers GitHub )


1
Migrer entre les services de contrôle de version et c'est exactement ce que je recherche, bravo!
Luka Špoljarić

1

J'étais en train de passer d'un service de contrôle de version à un autre et j'avais besoin de cloner tous les référentiels, y compris toutes les branches, les balises et l'historique.

Pour réaliser ci-dessus, j'ai fait ensuite:

  • extraire manuellement toutes les branches vers le référentiel local (script pour extraire toutes les illustrations ci-dessous),
  • git push origin '*:*'

Script .sh utilisé pour extraire toutes les branches du référentiel local:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.