git shallow clone (clone --depth) manque les branches distantes

99

Après le clonage d'un référentiel distant, il n'affiche aucune branche distante par l'option -a. Quel pourrait être le problème? Comment le déboguer? Dans cet extrait de code, deux des branches distantes ne sont pas affichées:

$ 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

J'ai essayé la même commande sur une autre machine, cela fonctionne bien:

$ 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

J'ai également essayé de cloner un autre repo, cela fonctionne bien. Bien que je puisse l'essayer à nouveau sur cette machine, il serait préférable de savoir ce qui ne va pas.

Toutes suggestions ou astuces seront les bienvenues.

Edit: Résumé de la réponse: Depuis la version 1.8.3.2 de git, les "--depth" et "--no-single-branch" doivent être utilisés ensemble pour obtenir le même comportement qu'avant. Ceci est considéré comme une correction de bogue.

minghua
la source
3
masterest votre succursale locale. remotes/origin/masterest la branche distante correspondante. Quelle est exactement la question?
michas
1
Avez-vous peut-être oublié la verbosité? Essayezgit branch -avv
jthill
À michas etc: nous ne référons généralement pas master comme une branche, désolé pour la confusion. ajouté "deux branches distantes ne sont pas affichées". Pour jthill: merci pour le rappel, vous avez raison.
minghua
1
Merci d'avoir présenté git clone --depth=1 --no-single-branch, c'est ce dont j'ai besoin dans la plupart des cas.
Alireza Mohamadi

Réponses:

62

Le comportement est correct, après la dernière révision, la branche master est (puisqu'il s'agit de la HEAD de la télécommande principale) la seule branche distante du référentiel:

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

Le clone complet offre de nouvelles (toutes) branches:

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

Clones peu profonds

En raison de la description superficielle de la documentation technique, un " git-clone --depth 20 repo[...] résultat [s dans] des chaînes de validation d'une longueur d'au plus 20". Un clone peu profond doit donc contenir la profondeur de commits demandée, à partir de l'extrémité d'une branche.

Comme - en plus - la documentation de git clonepour l' --single-branchoption -décrit:

"Clonez uniquement l'historique menant à la pointe d'une seule branche, soit spécifié par l' --branchoption , soit par la branche principale pointée par la télécommande HEAD. Lors de la création d'un clone superficiel avec l' --depthoption, il s'agit de la valeur par défaut, à moins --no-single-branchque vous ne demandiez de récupérer les historiques près de bouts de toutes les branches. "

Par conséquent, un clone peu profond ( avec l' option de profondeur ) ne récupère qu'une seule branche (à la profondeur demandée).


Malheureusement, les deux options ( --depthet --single-branch) ont été défectueuses dans le passé et l'utilisation de clones peu profonds implique des problèmes non résolus (comme vous pouvez le lire dans le lien que j'ai posté ci-dessus), qui sont causés par la réécriture d'historique donnée. Cela conduit globalement à un comportement quelque peu compliqué dans des cas particuliers.

Florian Neumann
la source
1
florianb: quelle est ta version git? merci de l'avoir essayé. J'ai fait le --depth 1 sur 1.7.1 tout à l'heure, il montre toutes les branches distantes. a mis à jour la question avec ceci. +1 pour vérifier le problème.
minghua
1
@minghua: J'utilise la version 1.8.4 - je vais faire une petite enquête s'il y avait un correctif sur ce problème.
Florian Neumann
1
@minghua: j'ai édité pour refléter les nouvelles découvertes sur les "clones superficiels".
Florian Neumann
1
C'est presque parfait, sauf une chose: qu'est-ce que cela signifie en disant "le propriétaire du repo a décidé de couper les autres branches"? Je pense que ces succursales sont toujours là.
minghua
2
--no-single-branch clone également toutes les balises. Nous pouvons éviter cela en créant un nouveau dépôt, en utilisant la même configuration pour récupérer toutes les télécommandes, c'est fetch = +refs/heads/*:refs/remotes/origin/*-à- dire et en exécutant git fetch --depth 1(sans --tags). Nous pouvons également ajouter des balises spécifiques à récupérer, en utilisant une configuration similaire à fetch = +refs/tags/v2.0.0:refs/tags/v2.0.0.
Sam Watkins
208

Après avoir fait un clone superficiel, pour pouvoir vérifier d'autres branches à distance ,

  1. Exécutez (merci @jthill):

    git remote set-branches origin '*'
    
  2. Après cela, faites un git fetch -v

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


L'étape 1 peut également être effectuée manuellement en éditant .git/config.

Par exemple, modifiez la ligne suivante de:

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

à (remplacer masterpar *):

fetch = +refs/heads/*:refs/remotes/origin/*
Marlo
la source
57
Vous pouvez également utiliser git remote set-branches origin '*'pour toutes les branches, remplacer le *par un nom de branche pour une.
jthill
Je vous remercie! Cela m'a sauvé la journée.
Steven Xu
Que -vvvsignifie dans git fetch -vvv? Je n'ai trouvé aucune information à ce sujet dans git-fetch doc
guo
@guo c'est pour le niveau de journalisation verbosityou debugde git. Ce n'est pas par fetchméthode.
marlo
1
@ kawing-chiu c'est utile si vous avez tant de branches et que la taille est trop grande pour la «connexion Internet» avant et que vous pourriez maintenant vous permettre d'obtenir toutes ces branches. :)
marlo
62

Après avoir lu les réponses et le commentaire de @jthill, la chose qui fonctionnait le mieux pour moi était d'utiliser l' set-branchesoption sur la git remotecommande:

$ 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

Cela modifie la liste des branches suivies par la télécommande nommée afin que nous puissions récupérer et extraire uniquement la branche requise.

alejandrodnm
la source
15
Il peut être préférable de l'utiliser git remote set-branches --add origin 'remote_branch_name'pour que la nouvelle branche soit en plus de celles existantes, plutôt que de les remplacer dans la liste des branches distantes (ou des modèles de branche) à récupérer dans le fichier .git / config.
dumbledad
2
OMG, le guillemet simple 'est important dansgit remote set-branches --add origin 'remote_branch_name'
Week
@Weekend Je ne pouvais pas faire fonctionner cela jusqu'à ce que j'aie laissé les guillemets simples
PandaWood
@PandaWood Vous êtes probablement sous Windows. Le signe "$" dans la réponse implique Bash (sous Unix ou Cygwin / MSYS).
Yongwei Wu
Je ne vois rien sur les guillemets simples nécessaires dans la documentation et cela semble fonctionner correctement sans un sur macOS au moins.
Nickolay