git shallow clone (clone --depth) manca i rami remoti


98

Dopo la clonazione di un repository remoto, non mostra alcun ramo remoto con l'opzione -a. Quale potrebbe essere il problema? Come eseguirne il debug? In questo frammento non vengono mostrati due dei rami remoti:

$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
$ cd pythonwebkit
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
$ git --version
git version 1.8.3.1

Ho provato lo stesso comando su un'altra macchina, funziona bene:

$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
Receiving objects: 100% (186886/186886), 818.91 MiB | 3.44 MiB/s, done.
$ cd pythonwebkit/
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/debian
  remotes/origin/master
  remotes/origin/python_codegen
$ git --version
git version 1.7.1

Ho provato anche a clonare un altro repo, funziona bene. Anche se posso provarlo di nuovo su questa macchina, ma sarebbe meglio sapere cosa c'è che non va.

Eventuali suggerimenti o suggerimenti saranno più che benvenuti.

Modifica: Riepilogo della risposta: dalla versione 1.8.3.2 di git, "--depth" e "--no-single-branch" devono essere usati insieme per ottenere lo stesso comportamento di prima. Questa è considerata una correzione di bug.


3
masterè la tua filiale locale. remotes/origin/masterè il ramo remoto corrispondente. Qual è esattamente la domanda?
michas

1
Hai forse dimenticato la verbosità? Provagit branch -avv
jthill

A michas ecc: di solito non ci riferiamo al master come a un ramo, ci scusiamo per la confusione. aggiunto "due rami remoti non vengono visualizzati". A jthill: grazie per il ricordo, hai ragione.
minghua

1
Grazie per git clone --depth=1 --no-single-branchaverlo presentato , questo è ciò di cui ho bisogno nella maggior parte dei casi.
Alireza Mohamadi

Risposte:


63

Il comportamento è corretto, dopo l'ultima revisione il ramo principale è (poiché questo è l'HEAD del telecomando primario) l'unico ramo remoto nel repository:

florianb$ git branch -a
        * master
          remotes/origin/HEAD -> origin/master
          remotes/origin/master

Il clone completo offre nuovi (tutti) rami:

florianb$ git branch -a
        * master
          remotes/origin/HEAD -> origin/master
          remotes/origin/debian
          remotes/origin/master
          remotes/origin/python_codegen

Cloni poco profondi

A causa della descrizione superficiale nella documentazione tecnica, un " git-clone --depth 20 repo[...] risultato [s in] catene di commit con una lunghezza massima di 20." Un clone superficiale quindi dovrebbe contenere la profondità di commit richiesta, dalla punta di un ramo.

Come - inoltre - la documentazione di git cloneper l' --single-branchopzione descrive:

"Clona solo la cronologia che porta alla punta di un singolo ramo, specificata --branchdall'opzione o dai HEADpunti del telecomando del ramo primario in. Quando si crea un clone superficiale con l' --depthopzione, questa è l'impostazione predefinita, a meno che non --no-single-branchvenga fornito per recuperare le cronologie vicino al punte di tutti i rami. "

Pertanto un clone superficiale ( con l' opzione di profondità ) recupera solo un singolo ramo (alla profondità richiesta).


Sfortunatamente entrambe le opzioni ( --depthe --single-branch) sono state difettose in passato e l'uso di cloni superficiali implica problemi irrisolti (come puoi leggere nel link che ho postato sopra), che sono causati dalla data riscrittura della cronologia. Ciò porta in generale a comportamenti alquanto complicati in casi speciali.


1
florianb: qual è la tua versione di git? Grazie per averci provato. Ho fatto --depth 1 su 1.7.1 proprio ora che mostra tutti i rami remoti. aggiornato la domanda con questo. +1 per aver verificato il problema.
minghua

1
@minghua: Sto usando 1.8.4 - farò una piccola indagine se ci fosse una patch su quel problema.
Florian Breisch

1
@minghua: ho modificato per riflettere le nuove scoperte sui "cloni poco profondi".
Florian Breisch

1
È quasi perfetto tranne una cosa: cosa vuol dire "il proprietario del repo ha deciso di tagliare gli altri rami"? Penso che quei rami siano ancora lì.
minghua

2
--no-single-branch clona anche tutti i tag. Possiamo evitarlo creando un nuovo repository, usando la stessa configurazione per recuperare tutti i telecomandi, cioè fetch = +refs/heads/*:refs/remotes/origin/*, e in esecuzione git fetch --depth 1(senza --tags). Possiamo anche aggiungere tag specifici da recuperare, usando config like fetch = +refs/tags/v2.0.0:refs/tags/v2.0.0.
Sam Watkins,

205

Dopo aver eseguito un clone superficiale, per poter controllare altri rami da remoto ,

  1. Corri (grazie @jthill):

    git remote set-branches origin '*'
    
  2. Dopodiché, fai un file git fetch -v

  3. Finalmente git checkout the-branch-i-ve-been-looking-for


Il passaggio 1 può essere eseguito anche manualmente modificando .git/config.

Ad esempio, cambia la riga seguente da:

fetch = +refs/heads/master:refs/remotes/origin/master

a (sostituire mastercon *):

fetch = +refs/heads/*:refs/remotes/origin/*

57
Puoi anche usare git remote set-branches origin '*'per tutti i rami, sostituire il *con un nome di ramo per uno.
jthill

Grazie! Questo mi ha salvato la giornata.
Steven Xu

Cosa -vvvsignifica in git fetch -vvv? Non ho trovato alcuna informazione al riguardo in git-fetch doc
guo

@guo è per il livello di registrazione verbosityo debugdi git. Non è di fetchmetodo.
marlo

1
@ kawing-chiu questo è utile se hai così tanti rami e la dimensione è troppo grande per la "connessione Internet" prima e ora potresti permetterti di ottenere tutti quei rami. :)
marlo

61

Dalla lettura delle risposte e del commento di @jthill, la cosa che ha funzionato meglio per me è stata utilizzare l' set-branchesopzione sul git remotecomando:

$ git clone --depth 1 https://github.com/dogescript/dogescript.git
$ git remote set-branches origin 'remote_branch_name'
$ git fetch --depth 1 origin remote_branch_name
$ git checkout remote_branch_name

Questo cambia l'elenco dei rami tracciati dal telecomando denominato in modo che possiamo recuperare ed estrarre solo il ramo richiesto.


15
Potrebbe essere meglio usare in git remote set-branches --add origin 'remote_branch_name'modo che il nuovo ramo sia in aggiunta a quelli esistenti, piuttosto che sostituirli nell'elenco dei rami del telecomando (o schemi di ramo) da recuperare nel file .git / config.
Dumbledad

2
OMG, la citazione singola 'è importante ingit remote set-branches --add origin 'remote_branch_name'
Weekend

@Weekend Non sono riuscito a farlo funzionare finché non ho lasciato fuori le virgolette singole
PandaWood,

@PandaWood Probabilmente sei su Windows. Il segno "$" nella risposta implica Bash (su Unix o Cygwin / MSYS).
Yongwei Wu

Non vedo nulla sulle virgolette singole necessarie nei documenti e sembra funzionare bene senza almeno uno su macOS.
Nickolay
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.