Come clonare tutti i rami remoti in Git?


4129

Ho un mastere un developmentramo, entrambi inviati a GitHub . L'ho fatto clone, ho pulled fetched, ma non riesco a riavere altro che il masterramo.

Sono sicuro che mi manca qualcosa di ovvio, ma ho letto il manuale e non provo affatto gioia.


133
La risposta accettata qui ( git branch -a) mostra i rami nel telecomando, ma se provi a controllarne uno, sarai in uno stato di "HEAD distaccato". La risposta successiva verso il basso (la seconda più votata) risponde a una domanda diversa (vale a dire: come estrarre tutti i rami e, di nuovo, questo funziona solo per quelli che stai monitorando localmente). Molti dei commenti sottolineano che è possibile analizzare i git branch -arisultati con uno script di shell che traccia localmente tutti i rami remoti. Riepilogo: Non esiste un modo nativo git per fare ciò che vuoi e potrebbe non essere comunque un'idea così grande.
Giorno Davis Waterbury,

5
Forse basta copiare l'intera cartella alla vecchia maniera? scp some_user@example.com:/home/some_user/project_folder ~Non sono sicuro che questa soluzione
funzioni per Github

19
Piuttosto che dire "Ho clonato, tirato e recuperato", molto meglio per mostrarci gli esatti comandi che hai eseguito.
Bob Gilmore,

57
Mi sorprende sempre il motivo per cui "clone" non è nel senso di una copia esatta. Se si tratta di un clone esatto, tutti i rami non dovrebbero far parte del repository locale? Voglio dire, non è quello del punto di essere distribuito? Quindi, quando qualcosa non è più disponibile, hai ancora una copia completa di tutto. Oppure il cosiddetto "remoto" fa già parte del repository locale?
Huggie,

21
Vedendo tutti i voti positivi, le risposte, i commenti sulle risposte e il numero incredibile di visualizzazioni, penso che sia ora che Git abbia aggiunto un comando per farlo. E proprio tu sei @huggie, i miei pensieri esattamente.
Sнаđошƒаӽ,

Risposte:


4557

Innanzitutto, clona un repository Git remoto e cd in esso:

$ git clone git://example.com/myproject
$ cd myproject

Quindi, guarda le filiali locali nel tuo repository:

$ git branch
* master

Ma ci sono altri rami nascosti nel tuo repository! Puoi vederli usando la -abandiera:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

Se vuoi solo dare una rapida occhiata a una filiale a monte, puoi verificarlo direttamente:

$ git checkout origin/experimental

Ma se vuoi lavorare su quel ramo, dovrai creare un ramo di tracciamento locale che viene fatto automaticamente da:

$ git checkout experimental

e vedrai

Branch experimental set up to track remote branch experimental from origin.
Switched to a new branch 'experimental'

L'ultima riga genera alcune persone: "Nuovo ramo" - eh? Ciò che significa veramente è che il ramo è preso dall'indice e creato localmente per te. La riga precedente è in realtà più informativa in quanto ti dice che il ramo è stato impostato per tenere traccia del ramo remoto, che di solito significa il ramo origin / branch_name

Ora, se guardi le tue filiali locali, questo è ciò che vedrai:

$ git branch
* experimental
  master

Puoi effettivamente tenere traccia di più di un repository remoto usando git remote.

$ git remote add win32 git://example.com/users/joe/myproject-win32-port
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental
  remotes/win32/master
  remotes/win32/new-widgets

A questo punto, le cose stanno diventando piuttosto pazze, quindi corri gitka vedere cosa sta succedendo:

$ gitk --all &

119
Come si può creare automaticamente tutti i rami remoti, ad esempio sperimentale per origine / sperimentale?
Cristian Ciupitu,

54
Cristian: creavo sempre un ramo 'foo' per ogni ramo 'origine / foo', ma questo portava a due problemi: (1) Mi sono ritrovato con un sacco di rami di localizzazione davvero stantii che erano molti commit dietro il corrispondente ramo remoto e (2) nelle versioni precedenti di git, l'esecuzione di 'git push' avrebbe tentato di spingere tutti i miei rami locali su un telecomando, anche quando quei rami erano stantii. Quindi ora tengo filiali locali solo per cose che sto attivamente sviluppando e accedo direttamente alle filiali origin / * se ho bisogno di informazioni su di esse. (Detto questo, potresti usare uno script di shell per analizzare 'git branch -a'.)
emk,

49
"git fetch <nome-origine> <brnome>" porta il ramo in locale per te.

137
Buona risposta, ma un po 'manca la domanda. Stavo cercando un one-liner per controllare tutti i rami remoti.
cmcginty,

32
La domanda riguardava la clonazione di tutti i rami remoti, non il loro controllo. E, come ho notato sopra, non vuoi davvero creare più rami di localizzazione locali del necessario, perché quando diventano veramente stantii possono causare mal di testa.
emk,

822

Se hai molti rami remoti che vuoi recuperare contemporaneamente, fai:

$ git pull --all

Ora puoi effettuare il checkout di qualsiasi ramo come ti serve, senza colpire il repository remoto.


12
Se eseguo git clone, ho il ramo master localmente e 10 rami "remoti". Quindi QUESTA risposta di Gabe è stata molto utile e risponde alla domanda.
basZero,

38
questo recupera solo i rami remoti che sono stati aggiunti localmente, nessun ramo remoto
giujule

33
Il primo comando è ridondante. Semplicemente git pull --allfarà lo stesso - semplicemente non recupererà due volte. E infosec812 ha ragione nel dire che questo non risponde alla domanda comunque. Mi chiedo come questo abbia ottenuto così tanti voti.
Sven Marnach,

6
Dopo averlo fatto git remote update, poi provato git branch, vedo solo filiali locali. Ma se lo faccio git branch -aora posso vedere i rami remoti e posso fare un git pull <branchname>per ottenere il ramo che voglio. - Sono arrivato a questa domanda da una ricerca su Google e questa risposta risolve il mio problema.
WNRosenberg,

38
Questo non è affatto utile, non estrae alcun ramo remoto diverso da quello esistente.
Avinash R

446

Questo script di Bash mi ha aiutato:

#!/bin/bash
for branch in $(git branch --all | grep '^\s*remotes' | egrep --invert-match '(:?HEAD|master)$'); do
    git branch --track "${branch##*/}" "$branch"
done

Creerà rami di tracciamento per tutti i rami remoti, tranne master (che probabilmente hai ottenuto dal comando clone originale). Penso che potresti ancora aver bisogno di fare un

git fetch --all
git pull --all

per essere sicuro.

One liner : git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs
Come al solito: prova nella tua configurazione prima di copiare l'universo rm -rf come lo conosciamo

I crediti per un liner vanno all'utente cfi


19
Questo è molto vicino all'essere una soluzione perfetta .. L'unica cosa che lo renderebbe migliore è se questa funzionalità fosse integrata come opzione in Git.
Deven Phillips,

51
"One liner": git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs come al solito: prova nella tua configurazione prima di copiarerm -rf universe as we know it
cfi

4
Questo comando crea i rami delle funzionalità da remoto come rami normali (non i rami delle caratteristiche) - come risolvere questo problema?
Alex2php,

4
se riscontri problemi con "/" nei nomi delle filiali c'è una soluzione sotto usando un alias git. vedi risposta da "nessuno" on "rispose 15 maggio '13 alle 11:02"
WEMU

8
Sto tagliando solo remotes/origin/per preservare gli spazi dei nomi:for BRANCH in $(git branch -a | grep remotes | grep -v HEAD | grep -v master); do git branch --track "${BRANCH#remotes/origin/}" "${BRANCH}"; done
kgadek,

348

L'uso --mirrordell'opzione sembra copiare remotecorrettamente i rami di tracciamento. Tuttavia, configura il repository come repository nudo, quindi successivamente è necessario ripristinarlo in un repository normale.

git clone --mirror path/to/original path/to/dest/.git
cd path/to/dest
git config --bool core.bare false
git checkout anybranch

Riferimento: Domande frequenti su Git: come posso clonare un repository con tutti i rami monitorati da remoto?


7
Sai che in realtà sembra essere una risposta abbastanza buona anche se non ha voti. Ci sono delle insidie ​​nel farlo in quel modo? Ho dovuto verificare esplicitamente un ramo dopo aver eseguito quei comandi.
loop

27
Questo, combinato con git push --mirror, è esattamente ciò di cui avevo bisogno per creare un duplicato esatto di un repository git remoto quando ci si spostava da github.com a un'installazione aziendale di github. Grazie!
Jacob Fike,

3
@Dave: aggiungi un ultimo git checkoutcome ultimo comando per estrarre finalmente la testa del ramo corrente sul repository clonato. Questa è un'ottima risposta, di gran lunga la migliore. Sii coraggioso, alla fine ti porteremo in cima :-)
cfi,

3
@Dave: Hm. Sto ripensandoci: --mirror fa molto di più che impostare tutti i rami come tracciati. Copia tutti i riferimenti dall'origine e successivamente git remote updatelo farà di nuovo. Comportamento del pull pull. Sono tornato a credere che la copia completa richieda uno script di una riga.
cfi,

5
git clone --mirrorè ottimo per il backup dei repository git ^ _ ^
TrinitronX,

220

Puoi passare facilmente a un ramo senza usare la sintassi "git checkout -b somebranch origin / somebranch". Puoi semplicemente fare:

git checkout somebranch

Git farà automaticamente la cosa giusta:

$ git checkout somebranch
Branch somebranch set up to track remote branch somebranch from origin.
Switched to a new branch 'somebranch'

Git verificherà se un ramo con lo stesso nome esiste esattamente in un solo telecomando e, in caso affermativo, lo traccia allo stesso modo di se si fosse specificato esplicitamente che si tratta di un ramo remoto. Dalla pagina man di git-checkout di Git 1.8.2.1:

Se <branch> non viene trovato ma esiste un ramo di tracciamento esattamente in un telecomando (chiamalo <remote>) con un nome corrispondente, trattalo come equivalente a

$ git checkout -b <branch> --track <remote>/<branch>

1
Quindi, se il nome del ramo checkoutè identico al nome del ramo remoto, tutto dopo "/", allora git creerà un ramo con lo stesso nome, tutto dopo "/", "tracking" quel telecomando ? E per il monitoraggio, si intende: git push, git pull, ecc sarà fatto su quella distanza? Se questo è corretto, espandi la tua risposta con ulteriori informazioni, poiché sono d'accordo con @Daniel, questa risposta merita più rep.
Gerard Roche,

5
@BullfrogBlues, la risposta a tutte le tue domande sembra essere sì (sto usando git v1.7.7.4). Sono d'accordo che questo comportamento dovrebbe essere meglio conosciuto. (Non è nel manuale per questa versione di git.) In realtà non mi piace questo comportamento, preferirei ricevere un errore e devo dire git checkout --track origin/somebranchesplicitamente.
dubiousjim,

3
@dubiousjim: In realtà, questo è nel manuale. git-checkout (1) dice: "Se <branch> non viene trovato ma esiste un ramo di tracciamento esattamente in un telecomando (chiamalo <remote>) con un nome corrispondente, trattalo come equivalente a 'git checkout -b <ramo > --track <remote> / <branch> '"(Git V.1.8.1.1).
sleske,

Ciò di cui abbiamo bisogno è $ git pull * <remote> / * - dove "*" è un carattere jolly, quindi estrae tutti i rami, inclusi quelli non ancora presenti sul sistema locale. Come fare questo? Dobbiamo davvero effettuare il checkout / pull di ogni ramo solo per ottenere il codice trasferito al nostro sistema locale?
JosephK,

98

Per quanto riguarda,

$ git checkout -b origine sperimentale / sperimentale

utilizzando

$ git checkout -t origin/experimental

o più prolisso ma più facile da ricordare

$ git checkout --track origin/experimental

potrebbe essere migliore, in termini di tracciamento di un repository remoto.


Quindi vuoi dire che la seconda forma è solo più facile da ricordare e non c'è altra differenza?
aderchox,

79

Il recupero che stai facendo dovrebbe ottenere tutti i rami remoti, ma non creerà rami locali per loro. Se usi gitk, dovresti vedere i rami remoti descritti come "telecomandi / origine / dev" o qualcosa di simile.

Per creare un ramo locale basato su un ramo remoto, fare qualcosa del tipo:

git checkout -b ref ref / telecomandi / origine / dev

Che dovrebbe restituire qualcosa di simile:

Sviluppo del ramo impostato per tenere traccia dei riferimenti / telecomandi / origine / sviluppo del ramo remoto.
Passato a un nuovo ramo "dev"

Ora, quando ti trovi sul ramo di sviluppo, "git pull" aggiornerà il tuo sviluppatore locale allo stesso punto del ramo di sviluppo remoto. Nota che prenderà tutti i rami, ma tira solo quello su cui ti trovi in ​​cima all'albero.


14
Non hai bisogno di riferimenti / telecomandi qui. git checkout -b dev origin / dev funzionerà bene.
emk,

3
Questo funziona sempre: git checkout -b newlocaldev --track origin/dev. Se si desidera che il ramo locale abbia lo stesso nome di quello remoto e quello remoto non abbia un nome complicato, è possibile omettere il -b newlocaldev. Con l'impostazione di branch.autosetupmergeconfigurazione predefinita , e supponendo che tu non abbia un ramo locale chiamato dev, questi due comandi possono fare la stessa cosa: git checkout -b dev origin/deve semplicemente git checkout dev. Infine, git checkout origin/devnon crea un nuovo ramo, ma ti mette semplicemente nello stato HEAD distaccato.
dubiousjim,

Cosa succede quando il telecomando non esiste più ma Git è troppo stupido per riconoscere che è stato eliminato? Ciò presuppone che sia stato aggiornato e git branch -acontinua a elencarlo come ramo remoto.
1616

E lo facciamo per dozzine di rami?
JosephK,

59

Quando fai "git clone git: // location", vengono recuperati tutti i rami e i tag.

Per lavorare su uno specifico ramo remoto, supponendo che sia l'origine remota:

git checkout -b branch origin/branchname

2
Apprezzo la tua nota "tutti i rami e i tag vengono recuperati". Stavo per commentare la tua risposta sbagliata, ma poi l'ho verificato e ho scoperto che hai perfettamente ragione. Quindi, in un certo senso, hai fornito la risposta più breve: se hai clonato, ce l'hai già. Bello. Si potrebbe provare ad aggiungere: provare $ git branch -aad imparare quali rami remoti sono già disponibili.
Jan Vlcinsky,

Dai un'occhiata anche alla risposta che ho pubblicato. Questo potrebbe essere utile se sai che vorrai lavorare localmente su molti dei rami remoti e non doverli controllare uno per uno.
lacostenycoder

Puoi spiegarmi qual è la differenza tra git checkout -b master origin/mastere per git checkout --track origin/masterfavore?
aderchox,

1
@aderchox Al giorno d'oggi, penso che nessuno.
elmarco,

58

Usa alias. Anche se non ci sono battute singole Git native, puoi definirne una come

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

e poi usalo come

git clone-branches

Grazie. Questo in realtà clona tutti i rami remoti a differenza di molte altre risposte
FearlessHyena

50

Perché vedi solo "maestro"

git clonescarica tutti i rami remoti ma li considera comunque "remoti", anche se i file si trovano nel nuovo repository. C'è un'eccezione a questo, che è che il processo di clonazione crea un ramo locale chiamato "master" dal ramo remoto chiamato "master". Per impostazione predefinita, git branchmostra solo le filiali locali, motivo per cui vedi solo "master".

git branch -amostra tutti i rami, inclusi i rami remoti .


Come ottenere filiali locali

Se vuoi davvero lavorare su un ramo, probabilmente vorrai una versione "locale" di esso. Per creare semplicemente filiali locali da filiali remote (senza estrarle e quindi modificare il contenuto della directory di lavoro) , puoi farlo in questo modo:

git branch branchone origin/branchone
git branch branchtwo origin/branchtwo
git branch branchthree origin/branchthree

In questo esempio, branchoneè il nome di un ramo locale su cui stai creando origin/branchone; se invece vuoi creare filiali locali con nomi diversi, puoi farlo:

git branch localbranchname origin/branchone

Una volta creato un ramo locale, puoi vederlo con git branch(ricorda, non è necessario -avedere i rami locali).


Se origin/branchoneesiste, puoi anche semplicemente usare git checkout branchoneper creare un ramo locale con lo stesso nome e impostarlo per tenere traccia del telecomando.
Evan,

47

Questo non è troppo complicato, i passaggi molto semplici e diretti sono i seguenti;

git fetch origin Questo porterà tutte le filiali remote al tuo locale.

git branch -a Questo ti mostrerà tutti i rami remoti.

git checkout --track origin/<branch you want to checkout>

Verifica se sei nel ramo desiderato con il seguente comando;

git branch

L'output piacerà a questo;

*your current branch 
some branch2
some branch3 

Notare il segno * che indica il ramo corrente.


1
Grazie suraj. Il motivo perché non è stato votato molto. E la risposta non è accettata dall'interrogante.
Sam,

"Git fetch origin" non ha portato alcun ramo remoto nel mio locale - o sono nascosti da qualche parte? Leggere tutte le risposte sopra mi ha fatto venire il mal di testa. Stiamo cercando "git fetch tutti i rami in locale". Ci deve essere un modo diverso da bash-script per farlo.
JosephK,

1
Subito dopo aver eseguito "git fetch origin", mostrerà l'output in questo modo nel tuo terminale - "* [new branch] branch_name -> origin / branch_name", ma quando esegui "git branch" ti mostrerà solo il tuo locale rami invece, quindi per vedere tutti i rami che puoi fare "git branch -a" e poi per passare al ramo remoto devi eseguire "git checkout --track origin / <branch che vuoi verificare>". Spero che sia di aiuto. :-)
Sam,

4
Suraj, perché la domanda era: come "clonare tutti i rami remoti", non come aggiornarne uno alla volta manualmente. Sembra che non ci sia una risposta alla domanda reale - solo modi per fare un sacco di digitazione se si hanno molti rami.
JosephK,

47

Meglio tardi che mai, ma ecco il modo migliore per farlo:

mkdir repo
cd repo
git clone --bare path/to/repo.git .git
git config --unset core.bare
git reset --hard

A questo punto hai una copia completa del repository remoto con tutti i suoi rami (verifica con git branch). È possibile utilizzare --mirrorinvece --barese il proprio repository remoto ha telecomandi propri.


Qualcosa è andato storto durante le modifiche qui. Ora questa risposta non ha senso. Il " --bare" menzionato nell'ultima frase non esiste nell'elenco dei comandi indicato.
Cerran,

prendendo dalla risposta di Dave qui sotto. L'uso di 'git config --bool core.bare false' invece di 'git config unset core.bare' sembra fare il lavoro.
Confuso Vorlon,

Ho il error: key does not contain a section: unset. La risposta del Dave funziona meglio.
olibre,

In git config --unset core.barerealtà è ... Per me, questa sembra la soluzione più pulita di tutte presentate nelle risposte qui. Un vero peccato che abbia così pochi voti ...
Dirk Hillbrecht

1
Grazie @ChrisSim sono d'accordo git config --bool core.bare false. Questo è il motivo per cui raccomando invece la risposta di Dave . Cosa ne pensi della risposta di Dave ? Cin cin
olibre

39

Basta fare questo:

$ git clone git://example.com/myproject
$ cd myproject
$ git checkout branchxyz
Branch branchxyz set up to track remote branch branchxyz from origin.
Switched to a new branch 'branchxyz'
$ git pull
Already up-to-date.
$ git branch
* branchxyz
  master
$ git branch -a
* branchxyz
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchxyz
  remotes/origin/branch123

Vedi, 'git clone git: //example.com/myprojectt' recupera tutto, anche i rami, devi solo verificarli, quindi verrà creato il tuo ramo locale.


25

Devi solo usare "git clone" per ottenere tutti i rami.

git clone <your_http_url>

Anche se vedi solo il ramo master, puoi usare "git branch -a" per vedere tutti i rami.

git branch -a

E puoi passare a qualsiasi ramo che hai già.

git checkout <your_branch_name>

Non preoccuparti che dopo aver "git clone", non è necessario connettersi con il repository remoto, "git branch -a" e "git checkout" possono essere eseguiti correttamente quando si chiude il wifi. Quindi è dimostrato che quando si esegue "git clone", ha già copiato tutti i rami dal repository remoto. Successivamente, non è necessario il repository remoto, il tuo locale ha già tutti i codici delle filiali.


Risposta molto chiara qui. Molte persone confuse su questo argomento.
XMAN,

Vorrei secondare la tua affermazione "può essere eseguito correttamente quando chiudi il tuo wifi". "git clone" si traduce davvero in un repository contenente tutti i rami.
bvgheluwe,

Una risposta chiara e chiara.
Amr

24

A git clonedovrebbe copiare l'intero repository. Prova a clonarlo, quindi esegui git branch -a. Dovrebbe elencare tutti i rami. Se poi vuoi passare al ramo "pippo" invece di "master", usa git checkout foo.


1
Puoi eseguire i comandi git con o senza il trattino. Sia "git-branch" che "git branch" funzioneranno.
Peter Boughton,

21
Forse questa risposta è stata data molto tempo fa quando git ha funzionato diversamente, ma penso che sia fuorviante oggi. git clonescarica tutti i rami remoti, ma crea solo un ramo locale del master. Dal momento git branchche mostra solo le filiali locali, è necessario git branch -avedere anche le filiali remote.
Cerran,

Grazie. Questo è un tipo di strano comportamento predefinito IMO. Lo segnerò solo con un testimone più enigmatico. Se ha scaricato i rami, perché li nasconderebbe quando si chiama git branch?
Adam Hughes,

1
@Cerran, grazie; Ho aggiornato la mia risposta di conseguenza.
MattoxBeckman,

"scarica tutti i rami remoti, ma crea solo un ramo locale del master". Ho bisogno di aiuto per capirlo. Sembra che git clone NON cloni alcun ramo tranne master, poiché quando si fa "git branch -a" mostra che il ramo "sviluppo" è solo su "telecomandi / origine / sviluppo". Questo deve dire che non hai questo ramo ovunque a livello locale, esiste attualmente solo sull'origine giusto?
John Little,

19

Usa il mio strumento git_remote_branch (hai bisogno che Ruby sia installato sul tuo computer). È stato progettato appositamente per semplificare la manipolazione di filiali remote.

Ogni volta che esegue un'operazione per tuo conto, la stampa in rosso sulla console. Nel corso del tempo, finalmente si attaccano al tuo cervello :-)

Se non vuoi che grb esegua comandi per tuo conto, usa semplicemente la funzione "Spiega". I comandi verranno stampati sulla tua console anziché eseguiti per te.

Infine, tutti i comandi hanno alias, per facilitare la memorizzazione.

Nota che questo è un software alfa ;-)

Ecco l'aiuto quando esegui grb help:

git_remote_branch versione 0.2.6

  Uso:

  grb create branch_name [server_origine] 

  grb publishing branch_name [server_origine] 

  grb rinomina branch_name [server_origine] 

  grb delete branch_name [server_origine] 

  traccia grb branch_name [server_origine] 



  Appunti:
  - Se non viene specificato origin_server, viene assunto il nome "origine" 
    (impostazione predefinita di git)
  - La funzionalità di rinomina rinomina il ramo corrente

  Il meta-comando esplicativo: puoi anche anteporre qualsiasi comando con il 
parola chiave "spiegare". Invece di eseguire il comando, git_remote_branch
visualizzerà semplicemente l'elenco dei comandi che è necessario eseguire per eseguire 
quell'obiettivo.

  Esempio: 
    grb spiega create
    grb spiega creare my_branch github

  Tutti i comandi hanno anche alias:
  creare: creare, nuovo
  elimina: elimina, distruggi, uccidi, rimuovi, rm
  pubblica: pubblica, remotizza
  rinomina: rinomina, rn, mv, sposta
  traccia: traccia, segui, prendi, recupera

6
Parola al saggio: sembra che questo progetto sia stato abbandonato nel periodo in cui questa risposta è stata pubblicata. Non riesco a trovare alcun aggiornamento dopo il 2008. Caveat emptor e tutto il resto. Se sbaglio, spero che qualcuno modificherà e fornirà un puntatore corrente, perché mi piacerebbe avere uno strumento come questo a portata di mano.
bradheintz,

@bradheintz controllare questa risposta, esso imposta un alias di git: stackoverflow.com/a/16563327/151841
user151841

19

tutte le risposte che ho visto qui sono valide ma esiste un modo molto più pulito per clonare un repository e estrarre tutti i rami contemporaneamente.

Quando si clona un repository, tutte le informazioni sui rami vengono effettivamente scaricate ma i rami vengono nascosti. Con il comando

$ git branch -a

puoi mostrare tutti i rami del repository e con il comando

$ git checkout -b branchname origin/branchname

è quindi possibile "scaricarli" manualmente uno alla volta.


Tuttavia, quando si desidera clonare un repository con molti rami, tutti i modi illustrati sopra sono lunghi e noiosi rispetto a un modo molto più pulito e rapido che ho intenzione di mostrare, anche se è un po 'complicato. Sono necessari tre passaggi per ottenere questo risultato:

  1. Primo passo

crea una nuova cartella vuota sul tuo computer e clona una copia speculare della cartella .git dal repository:

$ cd ~/Desktop && mkdir my_repo_folder && cd my_repo_folder
$ git clone --mirror https://github.com/planetoftheweb/responsivebootstrap.git .git

il repository locale all'interno della cartella my_repo_folder è ancora vuoto, ora c'è solo una cartella nascosta .git che puoi vedere con un comando "ls -alt" dal terminale.

  1. Secondo passo

cambia questo repository da un repository vuoto (bare) a un repository regolare impostando il valore booleano "bare" delle configurazioni git su false:

$ git config --bool core.bare false
  1. Terzo passo

Prendi tutto ciò che si trova nella cartella corrente e crea tutti i rami sul computer locale, rendendolo quindi un normale repository.

$ git reset --hard

Quindi ora puoi semplicemente digitare il comando "git branch" e puoi vedere che tutti i rami vengono scaricati.

Questo è il modo rapido in cui puoi clonare un repository git con tutti i rami contemporaneamente, ma non è qualcosa che vuoi fare per ogni singolo progetto in questo modo.


Non mi piace il tuo uso della parola "download" in ... "download" manualmente uno alla volta . Tutte le informazioni sono, infatti, già scaricate dopo aver clonato il repository. L'unica cosa che bisogna fare è creare filiali di localizzazione locali (che è anche possibile quando si è offline, il che dimostra che tutte le informazioni sono nel repository).
bvgheluwe,

@bvgheluwe ecco perché è tra virgolette.
Federico

15

La clonazione da un repository locale non funzionerà con git clone e git fetch: molti rami / tag rimarranno non recuperati.

Per ottenere un clone con tutti i rami e tutti i tag.

git clone --mirror git://example.com/myproject myproject-local-bare-repo.git

Per ottenere un clone con tutti i rami e tutti i tag ma anche con una copia funzionante:

git clone --mirror git://example.com/myproject myproject/.git
cd myproject
git config --unset core.bare
git config receive.denyCurrentBranch updateInstead
git checkout master

13

OK, quando cloni il tuo repository, hai tutti i rami lì ...

Se lo fai git branch, sono un po 'nascosti ...

Quindi, se desideri vedere il nome di tutti i rami, aggiungi semplicemente --allflag in questo modo:

git branch --all o git branch -a

Se fai il checkout alla filiale, otterrai tutto ciò di cui hai bisogno.

E se il ramo creato da qualcun altro dopo aver clonato?

In questo caso, basta fare:

git fetch

e controlla di nuovo tutti i rami ...

Se ti piace recuperare e fare il checkout allo stesso tempo, puoi fare:

git fetch && git checkout your_branch_name

Ho anche creato l'immagine qui sotto per semplificare ciò che ho detto:

git branch - tutti per ottenere tutti i rami


3
C'è una differenza tra "ce l'hai" e "lo vedi". git branch -all NON elencherà più i rami remoti quando si rimuove il repository remoto.
Gustave

12

Guardando una delle risposte alla domanda ho notato che è possibile accorciarla:

for branch in  `git branch -r | grep -v 'HEAD\|master'`; do  
 git branch --track ${branch##*/} $branch;
done

Ma attenzione, se uno dei rami remoti viene chiamato ad esempio admin_master, non verrà scaricato!

Grazie a bigfish per l'idea originale


Puoi migliorare la regex, o forse usare Awk invece di grep, per migliorare il filtro per evitare falsi positivi.
Tripleee,

tutti i rami sono 'origin \ my_branch_name', che non è sicuramente quello che voglio.
Sнаđошƒаӽ,

Non ho mai visto il costrutto $ {branch ## * /} prima - sembra davvero utile - hai idea di dove posso saperne di più? non riesco a trovare sotto bash da nessuna parte. Grazie.
SaminOz,


10

Per copiare e incollare nella riga di comando:

git checkout master ; remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch -D $brname ; git checkout -b $brname $remote/$brname ; done ; git checkout master

Per maggiore leggibilità:

git checkout master ;
remote=origin ;
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do
    git branch -D $brname ;
    git checkout -b $brname $remote/$brname ;
done ;
git checkout master


Questo sarà:

  1. controlla master (in modo che possiamo eliminare il ramo in cui ci troviamo)
  2. seleziona il telecomando per effettuare il checkout (modificalo in qualsiasi telecomando tu abbia)
  3. scorrere tutti i rami del telecomando tranne master e HEAD
    1. elimina la filiale locale (in modo da poter verificare le filiali con aggiornamento forzato)
    2. controlla la filiale dal telecomando
  4. controlla il master (per il gusto di farlo)

Basato sulla risposta di VonC .


10

Ho scritto queste piccole funzioni di Powershell per essere in grado di fare il checkout di tutti i miei rami git, che sono in remoto di origine.

Function git-GetAllRemoteBranches {
     iex "git branch -r"                       <# get all remote branches #> `
     | % { $_ -Match "origin\/(?'name'\S+)" }  <# select only names of the branches #> `
     | % { Out-Null; $matches['name'] }        <# write does names #>
}


Function git-CheckoutAllBranches {
    git-GetAllRemoteBranches `
        | % { iex "git checkout $_" }          <# execute ' git checkout <branch>' #>
}

Altre funzioni git sono disponibili nel repository delle mie impostazioni git


9

Ecco una risposta che usa awk. Questo metodo dovrebbe essere sufficiente se utilizzato su un nuovo repository.

git branch -r | awk -F/ '{ system("git checkout " $NF) }'

Le filiali esistenti verranno semplicemente estratte o dichiarate come già presenti, ma è possibile aggiungere filtri per evitare conflitti.

Può anche essere modificato in modo da chiamare un git checkout -b <branch> -t <remote>/<branch>comando esplicito .

Questa risposta segue Nikos C. s' idea .


In alternativa possiamo invece specificare il ramo remoto. Questo si basa su murphytalk 's risposta .

git branch -r | awk '{ system("git checkout -t " $NF) }'

Genera messaggi di errore fatali sui conflitti ma li vedo innocui.


Entrambi i comandi possono essere modificati.

Usando la risposta di nessuno come riferimento, possiamo creare i seguenti comandi per creare gli alias:

git config --global alias.clone-branches '! git branch -r | awk -F/ "{ system(\"git checkout \" \$NF) }"'
git config --global alias.clone-branches '! git branch -r | awk "{ system(\"git checkout -t \" \$NF) }"'

Personalmente userei track-allo track-all-branches.


Volevo solo ringraziarti. Funzionava perfettamente e non soffriva di vari problemi legati alla clonazione di un repository nudo come alcuni cambi di comportamento, ecc.
Mahonya,

8

Dovevo fare esattamente lo stesso. Ecco la mia sceneggiatura di Ruby .

#!/usr/bin/env ruby

local = []
remote = {}

# Prepare
%x[git reset --hard HEAD]
%x[git checkout master] # Makes sure that * is on master.
%x[git branch -a].each_line do |line|
  line.strip!
  if /origin\//.match(line)
     remote[line.gsub(/origin\//, '')] = line
   else
     local << line
   end
end
# Update 
remote.each_pair do |loc, rem|
  next if local.include?(loc)
  %x[git checkout --track -b #{loc} #{rem}]
end
%x[git fetch]

Vedi la risposta che ho postato più in basso per evitare di dover eseguire questo script.
lacostenycoder

8

Nessuna di queste risposte lo taglia, tranne l'utente nessuno è sulla strada giusta.

Ho avuto problemi con lo spostamento di un repository da un server / sistema a un altro. Quando ho clonato il repository, ha creato solo un ramo locale per il master, quindi quando ho spinto sul nuovo telecomando, è stato inviato solo il ramo master.

Quindi ho trovato questi due metodi MOLTO utili. Spero che aiutino qualcun altro.

Metodo 1:

git clone --mirror OLD_REPO_URL
cd new-cloned-project
mkdir .git
mv * .git
git config --local --bool core.bare false
git reset --hard HEAD
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

Metodo 2:

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
git clone OLD_REPO_URL
cd new-cloned-project
git clone-branches
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

8

git clone --mirror sul repository originale funziona bene per questo.

git clone --mirror /path/to/original.git
git remote set-url origin /path/to/new-repo.git
git push -u origin

7

Git di solito (quando non specificato) recupera tutti i rami e / o tag (rif, vedi:) git ls-refsda uno o più altri repository insieme agli oggetti necessari per completare la loro cronologia. In altre parole, recupera gli oggetti che sono raggiungibili dagli oggetti già scaricati. Vedi: cosa fa git fetchveramente?

A volte potresti avere rami / tag che non sono direttamente collegati a quello attuale, quindi git pull --all/ git fetch --allnon ti aiuteranno in quel caso, ma puoi elencarli per:

git ls-remote -h -t origin

e recuperarli manualmente conoscendo i nomi di riferimento.

Quindi, per recuperarli tutti , prova:

git fetch origin --depth=10000 $(git ls-remote -h -t origin)

Il --depth=10000parametro può essere utile se il repository è superficiale.

Quindi controlla di nuovo tutti i tuoi rami:

git branch -avv

Se sopra non aiuta, è necessario aggiungere manualmente i rami mancanti all'elenco monitorato (poiché in qualche modo si sono persi):

$ git remote -v show origin
...
  Remote branches:
    master      tracked

da git remote set-branchescome:

git remote set-branches --add origin missing_branch

quindi potrebbe apparire sotto remotes/origindopo il recupero:

$ git remote -v show origin
...
  Remote branches:
    missing_branch new (next fetch will store in remotes/origin)
$ git fetch
From github.com:Foo/Bar
 * [new branch]      missing_branch -> origin/missing_branch

Risoluzione dei problemi

Se non riesci ancora a ottenere qualcosa di diverso dal ramo principale, controlla quanto segue:

  • Controlla nuovamente i telecomandi ( git remote -v), ad es
    • Convalida che git config branch.master.remoteè origin.
    • Controlla se originpunta all'URL giusto tramite: git remote show origin(vedi questo post ).

7

All'inizio del 2017, la risposta in questo commento funziona:

git fetch <origin-name> <branch-name>porta il ramo per te. Anche se questo non estrae tutti i rami contemporaneamente, puoi eseguire singolarmente questo ramo per ramo.


Ciò richiede di recuperare ogni ramo uno alla volta. Non molto bene se hai molti rami.
lacostenycoder

6

Ecco un altro breve comando one-liner che crea rami locali per tutti i rami remoti:

(git branch -r | sed -n '/->/!s#^  origin/##p' && echo master) | xargs -L1 git checkout

Funziona correttamente anche se sono già state create le filiali locali di tracciamento. Puoi chiamarlo dopo la prima git cloneo in qualsiasi momento successivo.

Se non è necessario che il masterramo venga estratto dopo la clonazione, utilizzare

git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout
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.