git shallow clone (clon --depth) pierde ramas remotas

99

Después de clonar un repositorio remoto, no muestra ninguna rama remota mediante la opción -a. ¿Cual podría ser el problema? ¿Cómo depurarlo? En este fragmento no se muestran dos de las ramas remotas:

$ 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

Probé el mismo comando en otra máquina, funciona 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

Intenté también clonar otro repositorio, funciona bien. Aunque puedo volver a intentarlo en esta máquina, pero sería mejor saber qué está mal.

Cualquier sugerencia o sugerencia será más que bienvenida.

Editar: Resumen de la respuesta: desde la versión 1.8.3.2 de git, es necesario usar "--depth" y "--no-single-branch" juntos para obtener el mismo comportamiento que antes. Esto se considera una corrección de errores.

minghua
fuente
3
masteres su sucursal local. remotes/origin/masteres la rama remota correspondiente. Cuál es exactamente la pregunta?
michas
1
¿Quizás olvidaste la verbosidad? Pruebagit branch -avv
hasta
Para michas, etc.: generalmente no nos referimos a master como una rama, perdón por la confusión. agregó "no se muestran dos sucursales remotas". Para jthill: gracias por recordárselo, tienes razón.
minghua
1
Gracias por presentarme git clone --depth=1 --no-single-branch, esto es lo que necesito en la mayoría de los casos.
Alireza Mohamadi

Respuestas:

62

El comportamiento es correcto, después de la última revisión, la rama maestra es (ya que esta es la HEAD del control remoto primario) la única rama remota en el repositorio:

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

El clon completo ofrece nuevas (todas) ramas:

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

Clones superficiales

Debido a la descripción superficial en la documentación técnica, un " git-clone --depth 20 repo[...] resultado [s en] cadenas de compromiso con una longitud máxima de 20." Por lo tanto, un clon superficial debe contener la profundidad solicitada de confirmaciones, desde la punta de una rama.

Como, además, la documentación de git clonela --single-branchopción-describe:

"Clonar solo el historial que conduce a la punta de una sola rama, ya sea especificado por la --branchopción o los HEADpuntos del control remoto de la rama principal en. Cuando se crea un clon superficial con la --depthopción, este es el valor predeterminado, a menos que --no-single-branchse proporcione para recuperar los historiales cerca del puntas de todas las ramas " .

Por lo tanto un poco profunda clon ( con la profundidad -option) sólo se obtiene solamente una sola rama (a su profundidad requerida).


Desafortunadamente, ambas opciones ( --depthy --single-branch) han tenido fallas en el pasado y el uso de clones superficiales implica problemas no resueltos (como puede leer en el enlace que publiqué arriba), que es causado por la reescritura del historial dada. En general, esto conduce a un comportamiento algo complicado en casos especiales.

Florian Neumann
fuente
1
florianb: ¿cuál es tu versión de git? Gracias por intentarlo. Hice el --depth 1 en 1.7.1 justo ahora muestra todas las ramas remotas. actualizó la pregunta con esto. +1 para verificar el problema.
minghua
1
@minghua: Estoy usando 1.8.4; investigaré un poco si hubo un parche sobre ese problema.
Florian Neumann
1
@minghua: edité para reflejar nuevos hallazgos sobre "clones superficiales".
Florian Neumann
1
Es casi perfecto, excepto por una sola cosa: ¿qué significa decir "el propietario del repositorio decidió cortar las otras ramas"? Creo que esas ramas todavía están ahí.
minghua
2
--no-single-branch también clona todas las etiquetas. Podemos evitar eso creando un nuevo repositorio, usando la misma configuración para buscar todos los controles remotos, es decir fetch = +refs/heads/*:refs/remotes/origin/*, y ejecutándose git fetch --depth 1(sin --tags). También podemos agregar etiquetas específicas para ser recuperadas, usando config como fetch = +refs/tags/v2.0.0:refs/tags/v2.0.0.
Sam Watkins
208

Después de hacer un clon superficial, para poder verificar otras ramas desde el control remoto ,

  1. Ejecutar (gracias @jthill):

    git remote set-branches origin '*'
    
  2. Después de eso, haz un git fetch -v

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


El paso 1 también se puede realizar manualmente editando .git/config.

Por ejemplo, cambie la siguiente línea de:

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

para (reemplazar mastercon *):

fetch = +refs/heads/*:refs/remotes/origin/*
marlo
fuente
57
También puede usar git remote set-branches origin '*'para todas las ramas, reemplace el *con un nombre de rama para uno.
hasta el
¡Gracias! Esto me salvó el día.
Steven Xu
¿Qué -vvvsignifica en git fetch -vvv? No encuentro ninguna información al respecto en git-fetch doc
guo
@guo es para el nivel de registro verbosityo debugde git. No es por fetchmétodo.
marlo
1
@ kawing-chiu, esto es útil si tiene tantas sucursales y el tamaño es demasiado grande para la 'conexión a Internet' antes y ahora puede permitirse el lujo de obtener todas esas sucursales. :)
marlo
62

Después de leer las respuestas y el comentario de @jthill, lo que mejor me funcionó fue usar la set-branchesopción en el 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

Esto cambia la lista de ramas rastreadas por el control remoto nombrado para que podamos buscar y pagar solo la rama requerida.

alejandrodnm
fuente
15
Podría ser mejor usarlo git remote set-branches --add origin 'remote_branch_name'para que la nueva rama sea adicional a las existentes, en lugar de reemplazarlas en la lista de ramas del control remoto (o patrones de rama) para buscar en el archivo .git / config.
dumbledad
2
Dios mío, la comilla simple 'es importante engit remote set-branches --add origin 'remote_branch_name'
Fin de semana
@Weekend No pude hacer que esto funcionara hasta que dejé las comillas simples fuera
PandaWood
@PandaWood Probablemente esté en Windows. El signo "$" en la respuesta implica Bash (en Unix o Cygwin / MSYS).
Yongwei Wu
No veo nada sobre que las comillas simples sean necesarias en los documentos y parece funcionar bien sin una en macOS al menos.
Nickolay