Schieben Sie das lokale Git-Repo auf eine neue Fernbedienung, einschließlich aller Zweige und Tags

551

Ich habe ein lokales Git-Repo, das ich auf ein neues Remote-Repo übertragen möchte (brandneues Repo, das auf Beanstalk eingerichtet wurde, falls dies wichtig ist).
Mein lokales Repo hat einige Filialen und Tags, und ich möchte meine gesamte Geschichte behalten.

Es sieht so aus, als müsste ich im Grunde nur eine machen git push, aber das lädt nur den masterZweig hoch .

Wie kann ich alles pushen, damit ich eine vollständige Kopie meines lokalen Repos auf der Fernbedienung erhalte?

Cory Imdieke
quelle
Kürzeste und einfachste Antwort - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Antworten:

898

Verwenden Sie eine der folgenden Optionen, um alle Ihre Zweige zu verschieben (ersetzen Sie REMOTE durch den Namen der Fernbedienung, z. B. "Ursprung"):

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

So pushen Sie alle Ihre Tags :

git push REMOTE --tags

Schließlich denke ich, dass Sie dies alles in einem Befehl tun können mit:

git push REMOTE --mirror

--mirrorDarüber hinaus werden jedoch auch Ihre Fernbedienungen gepusht, sodass dies möglicherweise nicht genau das ist, was Sie möchten.

cmcginty
quelle
53
--allstatt *:*scheint freundlicher
Idan K
56
Mein Gott ............. Ich habe das gesamte Internet zerrissen und herausgefunden, dass der Schalter "--all" AAAAALLLLLLLLLLLLLL ist, den ich brauchte!
Rakib
21
Nur zu bemerken, dass git push REMOTE --allzurückgegeben No refs in common and none specified;nichts zu tun., Während git push REMOTE "*:*tatsächlich alle Zweige auf Remote geschoben.
Im0rtality
10
Verwenden Sie --dry-run zu inspizieren , was passieren wird, falls Sie haben „tmp“ oder „Feature“ Filialen vor Ort , dass Sie nicht wirklich zu aktualisierenden in REMOTE
Jonno
55
Wenn die Originalfernbedienung noch verfügbar ist, ist dies eine gute Idee git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron
157

In dem Fall wie mir, dass Sie ein Repo erworben haben und jetzt den Remote-Ursprung auf ein anderes Repo umstellen, ein neues leeres ...

Sie haben also Ihr Repo und alle Zweige im Inneren, aber Sie müssen diese Zweige noch auschecken, damit der git push --allBefehl diese auch tatsächlich pusht.

Sie sollten dies tun, bevor Sie drücken:

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

gefolgt von

git push --all
Daniel
quelle
4
Dies ist auch sehr hilfreich, da ich alle Zweige manuell auschecken musste. Dies wird für das nächste Mal gut sein.
Cory Imdieke
10
Seltsamerweise git push '*:*'schob alle Äste. git push -allschob nur den Meister. Ich transportierte Repo vom Github zum Bitbucket.
Jerrymouse
3
Anstatt jeden einzelnen Zweig auszuchecken, sollten Sie einfach "git branch --track $ remote" ausführen. In riesigen Repos dauert das Auschecken einer alten Filiale
einige Zeit
2
Ich musste eine kleine Änderung vornehmen, damit dies funktionierte: --track remotes/$remotestatt --track $remote. Hier ist die komplette Befehlszeile:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T
Danke, es funktioniert bei mir, die obige Antwort funktioniert nicht so gut.
Benyamin Jafari
90

Hier ist eine weitere Einstellung derselben Sache, die für die Situation, in der ich mich befand, besser funktioniert hat. Sie löst das Problem, wenn Sie mehr als eine Fernbedienung haben und alle Zweige in Fernbedienung sourcezu Fernbedienung klonen möchten destination, ohne sie jedoch alle vorher überprüfen zu müssen.

(Das Problem, das ich mit Daniels Lösung hatte, war, dass es sich weigerte, einen Tracking-Zweig von der sourceFernbedienung auszuchecken, wenn ich ihn zuvor bereits ausgecheckt hatte, dh, dass mein lokaler Zweig vor dem Push nicht aktualisiert wurde.)

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

Hinweis: Wenn Sie keine direkte CLI verwenden, müssen Sie die Sternchen maskieren:

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

Dadurch werden alle Zweige in der Ferne sourcezu einem Hauptzweig hineingeschoben destination, möglicherweise wird ein nicht schneller Vorlauf ausgeführt. Sie müssen Tags immer noch separat pushen.

Pieter Breed
quelle
8
+1 Das hat bei mir funktioniert und von einem remotezum anderen geklont . Vielen Dank!
Laurence
4
Ich musste den Sternchen entkommen:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr
2
Für mich hat dies dazu geführt, dass ein Zweig namens HEAD geschoben wurde, was ich in diesem Szenario nicht für beabsichtigt halte.
Maxwellb
1
Diese Antwort war unglaublich nützlich für mich. Die einzige Erwähnung in der git-push (1) -Manpage dieser Verwendung von Sternchen ist in einem winzigen Beispiel für die --pruneOption.
Laindir
4
Hervorragende Antwort, die sich stark von den üblichen --mirrorParametern unterscheidet, die jeder empfiehlt. Funktioniert perfekt für Szenarien, in denen Sie nur zwei Fernbedienungen für Automatisierungs- oder Überwachungszwecke synchronisieren möchten.
Vinicius Xavier
15

Dies ist der prägnanteste Weg, den ich gefunden habe, vorausgesetzt, das Ziel ist leer. Wechseln Sie in einen leeren Ordner und dann:

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

Ersatz https://...für file:///your/repousw. als angemessen.

ta.speot.is
quelle
13

Die Manpage für git-pushist eine Lektüre wert. In Kombination mit dieser Website habe ich Folgendes in meine geschrieben .git/config:

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

Die push = :Mittel „drücken jede‚Matching‘Äste (dh Zweige , die bereits in dem entfernten Repository vorhanden und haben eine lokale Gegenstück)“ bezeichnet , während push = refs/tags/*bedeutet „alle Tags Push“.

Jetzt muss ich nur noch laufen git push, um alle passenden Zweige und alle Tags zu pushen.

Ja, dies ist nicht ganz das, was das OP wollte (alle zu schiebenden Zweige müssen bereits auf der Remote-Seite vorhanden sein), könnte aber für diejenigen hilfreich sein, die diese Frage finden, während sie nach "Wie schiebe ich Zweige und Tags gleichzeitig?" Zeit".

schüchtern
quelle
13

In meinem Fall hat was funktioniert.

git push origin --all
nomulex
quelle
4
Simpel und einfach. Es klappt! originist ein Alias ​​für das Remote-URL-Git-Repository.
Do Nhu Vy
8

Ein Repository spiegeln

Erstellen Sie einen nackten Klon des Repositorys.

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

Mirror-Push in das neue Repository.

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

Entfernen Sie das temporäre lokale Repository, das Sie in Schritt 1 erstellt haben.

cd ..
rm -rf old-repository.git

Spiegeln eines Repositorys, das Git Large File Storage-Objekte enthält

Erstellen Sie einen nackten Klon des Repositorys. Ersetzen Sie den Beispielbenutzernamen durch den Namen der Person oder Organisation, der das Repository gehört, und ersetzen Sie den Beispielrepository-Namen durch den Namen des Repositorys, das Sie duplizieren möchten.

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

Navigieren Sie zu dem gerade geklonten Repository.

cd old-repository.git

Ziehen Sie die Git Large File Storage-Objekte des Repositorys ein.

git lfs fetch --all

Mirror-Push in das neue Repository.

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

Schieben Sie die Git Large File Storage-Objekte des Repositorys auf Ihren Spiegel.

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

Entfernen Sie das temporäre lokale Repository, das Sie in Schritt 1 erstellt haben.

cd ..
rm -rf old-repository.git

Die obigen Anweisungen stammen aus der Github-Hilfe: https://help.github.com/articles/duplicating-a-repository/

Michał Zalewski
quelle
1
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Sehen Sie hier für Anweisungen , wie man schreibt besser „Link-basierte“ Antworten. Vielen Dank!
GhostCat
5

Ich fand oben Antworten haben noch einige unklare Dinge, die Benutzer irreführen werden. Erstens, es ist sicher , dass git push new_origin --allund git push new_origin --mirrornicht alle Zweige der Herkunft duplizieren, duplizieren nur Ihre lokale existierten Zweige zu Ihrem new_origin.

Im Folgenden sind zwei nützliche Methoden aufgeführt, die ich getestet habe:

1, durch Klon Bare Repo duplizieren. Geben Sie git clone --bare origin_urldann den Ordner ein, und. git push new_origin_url --mirrorAuf diese Weise können Sie auch git clone --mirror origin_urlbeide verwenden --bareund --mirrorein nacktes Repo ohne Arbeitsbereich herunterladen. Bitte beziehen Sie sich darauf

2, Wenn Sie ein Git-Repo haben, indem Sie verwenden git clone, was bedeutet, dass Sie nackten Repo und Git-Arbeitsbereich haben, können Sie git remote add new_origin new_origin_urlund dann git push new_origin +refs/remotes/origin/\*:refs/heads/\*und dann verwendengit push new_origin --tags

Auf diese Weise erhalten Sie einen zusätzlichen Kopfast, der keinen Sinn ergibt.

yanzi1225627
quelle
2

So verschieben Sie Zweige und Tags (aber keine Fernbedienungen):

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

Dies wäre gleichbedeutend mit der Kombination von --tagsund --allOptionen für git push, was Git nicht zuzulassen scheint.

CEL
quelle
Gibt es eine zusätzliche Option zum Pushen von einer anderen Fernbedienung? Zum Beispiel mit+refs/remotes/source/*
Yves Martin
2

Basierend auf @ Daniel Antwort habe ich getan:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done
Arthur Julião
quelle
2
Noch besser, | grep -v masterkann ersetzt werden durch | sed 's/\*//'(ich gehe davon aus, dass Sie ausgeschlossen haben master, um das böse Wenige zu vermeiden *, das dem aktuell ausgewählten Zweig vorangestellt ist), wodurch Sie masterProbleme einschließen und vermeiden können, wenn masteres sich nicht um Ihren aktuell ausgewählten Zweig handelt. Es tut mir auch leid für die Nekropostierung, es ist nur so, dass diese Antwort mir heute geholfen hat und ich wollte meine Modifikation teilen, wenn sie anderen in meiner Position helfen kann ...
ToVine
1

Ich stellte fest, dass keines davon für mich richtig zu funktionieren schien. Fühlen Sie sich frei, dies zu Tode zu flammen, aber aus irgendeinem Grund konnten die anderen Optionen nicht richtig funktionieren.

Das erwartete Ergebnis war ein Repo, das auf eine andere Fernbedienung "geklont" wurde (dh von Github zu einem anderen Anbieter):

  • Alle Zweige werden auf einer neuen Fernbedienung erstellt
  • Der gesamte Zweigverlauf wird auf einer neuen Fernbedienung erstellt
    • (Dies wurde bei jeder Lösung, die ich versuchte, übersehen)
  • Alle Tags werden auf einer neuen Fernbedienung erstellt
  • Quelle bewegt sich über (eine gegebene)
  • Zerstörungsfrei (Pause für die Option --mirror)

Das Hauptproblem, das ich sah, war, dass entweder nicht alle Remote-Zweige in der neuen Remote neu erstellt wurden. Wenn dies der Fall war, verfügte die neue Fernbedienung nicht über den Verzweigungsverlauf (dh, bei einem Befehl werden git checkout branch; git logdie erwarteten Verzweigungs-Commits nicht angezeigt).

Mir ist aufgefallen, dass git checkout -b branchnamees NICHT dasselbe ist wie git checkout branchname(letzteres ist das, was ich brauchte). Mir ist aufgefallen git checkout --track branchname, dass der Zweigverlauf nicht angezeigt wurde.

Meine Lösung (Powershell-basiert):

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
Kartoffelbauer
quelle
1

Mit dem folgenden Befehl werden alle Zweige verschoben ( einschließlich derjenigen, die Sie noch nie ausgecheckt haben, die aber in Ihrem Git-Repo vorhanden sind. Sie können sie sehen, indem Siegit branch -a )

git push origin '*:*'

HINWEIS: Dieser Befehl ist praktisch, wenn Sie den Versionskontrolldienst migrieren ( dh von Gitlab zu GitHub migrieren ).

Pratik Patel
quelle
1
Die Migration zwischen Versionskontrolldiensten und genau dem, wonach ich suche, Prost!
Luka Špoljarić
1

Ich war gerade dabei, von einem Versionskontrolldienst zu einem anderen zu wechseln, und musste alle Repositorys einschließlich aller Zweige, Tags und des Verlaufs klonen.

Um oben zu erreichen, tat ich als nächstes:

  • Manuelles Auschecken aller Zweige in das lokale Repository (Skript zum Auschecken aller unten gezeigten),
  • git push origin '*:*'

.sh-Skript zum Auschecken aller Zweige in das lokale Repository:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Luka Špoljarić
quelle