Invia il repository Git locale al nuovo telecomando, inclusi tutti i rami e i tag


551

Ho un repository Git locale che vorrei spingere in un nuovo repository remoto (repository nuovissimo impostato su Beanstalk, se questo è importante).
Il mio repository locale ha alcuni rami e tag e vorrei conservare tutta la mia cronologia.

Sembra che in pratica devo solo fare un git push, ma che carica solo il masterramo.

Come posso inviare tutto in modo da ottenere una replica completa del mio repository locale sul telecomando?


Risposta più breve e più semplice - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Risposte:


898

Per spingere tutti i tuoi rami , usa uno dei due (sostituisci REMOTO con il nome del telecomando, ad esempio "origine"):

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

Per inviare tutti i tag :

git push REMOTE --tags

Infine, penso che puoi farlo tutto in un solo comando con:

git push REMOTE --mirror

Tuttavia, inoltre --mirror, spingerai anche i tuoi telecomandi, quindi questo potrebbe non essere esattamente quello che vuoi.


53
--allinvece di *:*sembra più amichevole
Idan K

56
mio dio ............. ho strappato l'intera rete e ho scoperto che l'interruttore `--all` è AAAAALLLLLLLLLLLLLLLL di cui avevo bisogno!
Rakib,

21
Solo notando che è git push REMOTE --alltornato senza No refs in common and none specified;fare nulla, mentre in git push REMOTE "*:*realtà ha spinto tutti i rami in remoto.
Im0rtality,

10
Usa --dry-run per ispezionare ciò che accadrà, nel caso in cui tu abbia "tmp" o "feature" rami localmente che non vuoi veramente aggiornare in REMOTE
Jonno

55
Se il telecomando originale è ancora disponibile, è una buona idea farlo git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron,

157

Nel caso come me, hai acquistato un repository e ora stai passando l'origine remota a un repository diverso, uno nuovo vuoto ...

Quindi hai il tuo repository e tutti i rami all'interno, ma devi comunque controllare quei rami perché il git push --allcomando spinga effettivamente anche quelli.

Dovresti farlo prima di spingere:

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

Seguito da

git push --all

4
Anche questo è molto utile, poiché ho dovuto controllare manualmente tutti i rami. Questo andrà bene per la prossima volta.
Cory Imdieke,

10
Stranamente, ha git push '*:*'spinto tutti i rami. git push -allho appena spinto il maestro. Stavo trasportando un repo da Github a Bitbucket.
jerrymouse,

3
Invece di controllare ogni singolo ramo dovresti semplicemente fare "git branch --track $ remote". In enormi repo il check-out richiede una vecchia filiale
Moataz Elmasry,

2
Ho dovuto apportare una piccola modifica affinché questo funzionasse: --track remotes/$remoteinvece di --track $remote. Ecco la riga di comando completa:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

Grazie, funziona per me, la risposta sopra non funziona altrettanto bene.
Benyamin Jafari,

90

Ecco un'altra versione della stessa cosa che ha funzionato meglio per la situazione in cui mi trovavo. Risolve il problema in cui hai più di un telecomando, vorrebbe clonare tutti i rami da remoto sourcea remoto destinationma senza doverli controllare tutti in anticipo.

(Il problema che ho avuto con la soluzione di Daniel era che si sarebbe rifiutato di effettuare il checkout di un ramo di monitoraggio dal sourcetelecomando se lo avessi già verificato in precedenza, ovvero, non aggiornerebbe il mio ramo locale prima del push)

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

Nota: se non si utilizza l'interfaccia della riga di comando diretta, è necessario uscire dagli asterischi:

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

questo spingerà tutti i rami in remoto sourceverso un ramo principale destination, eventualmente facendo una spinta non in avanti veloce. Devi ancora inviare i tag separatamente.


8
+1 Questo ha funzionato per me, clonando l'uno remotedall'altro. Grazie!
Laurence,

4
Ho dovuto sfuggire agli asterischi:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr,

2
Per me, questo è finito spingendo un ramo chiamato HEAD, che non credo sia intenzionale in questo scenario.
maxwellb,

1
Questa risposta mi è stata incredibilmente utile. L'unica menzione nella pagina man git-push (1) di questo uso di asterischi è in un piccolo esempio --prunedell'opzione.
Laindir,

4
Risposta eccellente, molto diversa dal solito --mirrorparametro che tutti raccomandano. Funziona perfettamente per scenari in cui si desidera solo mantenere sincronizzati due telecomandi per scopi di automazione o di controllo.
Vinicius Xavier

15

Questo è il modo più conciso che ho trovato, a condizione che la destinazione sia vuota. Passare a una cartella vuota e quindi:

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

Sostituire https://...per file:///your/repoecc a seconda dei casi.


13

La manpage di git-pushmerita una lettura. In combinazione con questo sito web ho scritto quanto segue nel mio .git/config:

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

Il push = :mezzo "invia qualsiasi ramo" corrispondente "(ovvero rami che già esistono nel repository remoto e hanno una controparte locale)", mentre push = refs/tags/*significa "invia tutti i tag".

Quindi ora devo solo correre git pushper spingere tutti i rami corrispondenti e tutti i tag.

Sì, questo non è esattamente ciò che l'OP voleva (tutti i rami da spingere devono già esistere sul lato remoto), ma potrebbe essere utile per coloro che trovano questa domanda mentre cercano su Google "come faccio a spingere rami e tag allo stesso tempo".


13

Nel mio caso ciò che ha funzionato è stato.

git push origin --all

4
Semplice e facile. Funziona! originè un alias per il repository Git di URL remoto.
Fai Nhu Vy il

8

Mirroring di un repository

Crea un clone nudo del repository.

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

Mirror-push nel nuovo repository.

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

Rimuovere il repository locale temporaneo creato nel passaggio 1.

cd ..
rm -rf old-repository.git

Mirroring di un repository che contiene oggetti Git Large File Storage

Crea un clone nudo del repository. Sostituisci il nome utente di esempio con il nome della persona o dell'organizzazione proprietaria del repository e sostituisci il nome del repository di esempio con il nome del repository che desideri duplicare.

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

Passare al repository appena clonato.

cd old-repository.git

Estrai gli oggetti Git Large File Storage del repository.

git lfs fetch --all

Mirror-push nel nuovo repository.

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

Invia gli oggetti Git Large File Storage del repository al tuo mirror.

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

Rimuovere il repository locale temporaneo creato nel passaggio 1.

cd ..
rm -rf old-repository.git

Le istruzioni sopra riportate provengono dalla Guida di Github: https://help.github.com/articles/duplicating-a-repository/


1
Sebbene ciò possa teoricamente rispondere alla domanda, sarebbe preferibile includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Vedi qui per istruzioni su come scrivere risposte "basate sul link" migliori . Grazie!
GhostCat,

5

Ho trovato sopra le risposte hanno ancora alcune cose poco chiare, che fuorviano gli utenti. Innanzitutto, è sicuro che git push new_origin --alle git push new_origin --mirrornon può duplicare tutti i rami di origine, ma duplica solo i tuoi rami esistenti locali sul tuo new_origin.

Di seguito sono riportati due metodi utili che ho testato:

1, duplicato dal clone repo nudo. git clone --bare origin_url, quindi inserisci la cartella e, in git push new_origin_url --mirrorquesto modo, puoi anche utilizzare git clone --mirror origin_urlentrambi --baree --mirrorscaricare un repository nudo, escluso lo spazio di lavoro. si prega di fare riferimento a questo

2, Se hai un repository git usando git clone, il che significa che hai un repository nudo e un'area di lavoro git, puoi usare git remote add new_origin new_origin_url, e poi git push new_origin +refs/remotes/origin/\*:refs/heads/\*, e poigit push new_origin --tags

In questo modo, otterrai un ramo di testa in più, che non ha senso.


2

Per inviare rami e tag (ma non telecomandi):

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

Ciò equivarrebbe a combinare le opzioni --tagse --allper git push, che git non sembra consentire.


C'è un'opzione aggiuntiva per spingere da un altro telecomando? Ad esempio con+refs/remotes/source/*
Yves Martin il

2

Basato sulla risposta di @Daniel, ho fatto:

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

2
Ancora meglio, | grep -v masterpuò essere sostituito con | sed 's/\*//'(suppongo che tu sia escluso masterper evitare il brutto poco *che è anteposto al ramo attualmente selezionato) che ti consente di includere mastered evitare eventuali problemi quando masternon è il ramo attualmente selezionato. Mi dispiace anche per il necropostaggio, è solo che questa risposta mi ha aiutato oggi e volevo condividere la mia modifica se può aiutare gli altri nella mia posizione ...
ToVine

1

Ho scoperto che nessuno di questi sembrava funzionare correttamente per me. Sentiti libero di infiammarlo a morte, ma per qualche motivo non è riuscito a far funzionare correttamente le altre opzioni.

Il risultato atteso era un repository "clonato" su un altro telecomando (ovvero da Github a un altro provider):

  • Tutti i rami vengono creati sul nuovo telecomando
  • Tutta la cronologia delle filiali viene creata sul nuovo telecomando
    • (questo è mancato su ogni soluzione che ho provato)
  • Tutti i tag vengono creati sul nuovo telecomando
  • La fonte si sposta (un dato)
  • Non distruttivo (dando una pausa all'opzione --mirror)

Il problema principale che stavo vedendo era che tutti i rami remoti non venivano ricreati nel nuovo telecomando. Se un comando ha funzionato, il nuovo telecomando non aveva la cronologia del ramo (ovvero facendo un comando git checkout branch; git lognon mostrava i commit del ramo previsti).

Ho notato che git checkout -b branchnameNON è lo stesso di git checkout branchname(essendo quest'ultimo ciò di cui avevo bisogno). Ho notato git checkout --track branchnameche non sembra estrarre la storia del ramo.

La mia soluzione (basata su 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

Il comando seguente spingerà tutti i rami ( inclusi quelli che non hai mai estratto ma presenti nel tuo repository git, li puoi vederegit branch -a )

git push origin '*:*'

NOTA: questo comando è utile quando si esegue la migrazione del servizio di controllo versione ( ovvero la migrazione da Gitlab a GitHub )


1
Migrare tra i servizi di controllo versione e questo è esattamente quello che sto cercando, evviva!
Luka Špoljarić,

1

Stavo passando da un servizio di controllo versione a un altro e avevo bisogno di clonare tutti i repository, inclusi tutti i rami, i tag e la cronologia.

Per ottenere sopra ho fatto il prossimo:

  • checkout manuale di tutti i rami nel repository locale (script per il checkout di tutti mostrati di seguito),
  • git push origin '*:*'

Script .sh utilizzato per il checkout di tutti i rami nel repository locale:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.