Por Anónimo (no verificado) , 29 Abril 2026

Introducción

git clone parece una operación pero en realidad compone varias. Entender los pasos ayuda al solucionar problemas con clones parciales, clones lentos o predeterminados sorprendentes.

La secuencia

  1. Crear el directorio destino.
  2. Ejecutar git init dentro de él.
  3. Añadir origin como un remoto con la URL fuente.
  4. Configurar el refspec predeterminado +refs/heads/*:refs/remotes/origin/*.
  5. Ejecutar git fetch origin para descargar objetos y refs.
  6. Determinar el branch predeterminado (el HEAD del remoto).
  7. Crear un branch local que lo rastree.
  8. Hacer checkout de ese branch al árbol de trabajo.

Viéndolo pasar

GIT_TRACE=1 GIT_TRACE_PACKET=1 git clone https://github.com/example/widget.git 2>&1 | head -50

Verás negociación de capacidades, anuncio de refs, negociación want/have y recepción de pack.

Protocolo de cable

Git moderno soporta el protocolo v2 (git config protocol.version 2 o predeterminado en 2.26+). El servidor anuncia solo las refs solicitadas en lugar de la lista completa de refs, lo que mejora dramáticamente los tiempos de clone para repos con muchas refs.

Variantes

git clone --bare                       # sin árbol de trabajo
git clone --mirror                     # bare + todas las refs, configurado para mirroring
git clone --depth 1                    # shallow
git clone --filter=blob:none           # clon parcial, saltar blobs hasta necesitarlos
git clone --filter=tree:0              # incluso menos datos, trees bajo demanda
git clone --single-branch              # historial de un solo branch
git clone --branch v1.2.3              # checkout de un branch/tag específico
git clone --recurse-submodules         # clonar submódulos también
git clone --no-checkout                # saltar populación del árbol de trabajo

Clones parciales

Los clones parciales (--filter) aplazan la descarga de objetos hasta que se necesiten. Requieren soporte del servidor (la mayoría de hosts modernos lo tienen):

git clone --filter=blob:none https://github.com/example/big.git
cd big
git log --oneline                  # barato; solo se descargan objetos commit y tree
git show HEAD:src/main.c           # esto dispara una descarga de blob

Qué va a dónde

Después de un clone exitoso:

  • .git/objects/pack/: el archivo pack recibido del servidor.
  • .git/refs/remotes/origin/: cada branch del servidor como una ref de seguimiento remoto.
  • .git/HEAD: ref simbólica al nuevo branch local.
  • .git/config: sección [remote "origin"] con URL y refspec.

Anuncio del lado del servidor

Lo primero que el servidor envía en cualquier clone es el anuncio de refs. Bajo el protocolo v0/v1 esto lista cada ref, incluso si solo quieres una; en repos enormes con millones de refs solo el anuncio podría tomar segundos. El protocolo v2 cambia esto: el cliente envía una solicitud ls-refs especificando patrones, y el servidor solo anuncia refs que coincidan:

git -c protocol.version=2 ls-remote origin 'refs/heads/main'
GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote origin 2>&1 | head

Para clones del día a día la aceleración es invisible; para servidores de hosting es dramática.

Errores comunes

Clonar un repo enorme en una red inestable y empezar de cero; git clone en 2.30+ soporta clonado reanudable sobre el protocolo HTTP smart, pero solo si el servidor lo soporta. De lo contrario --depth 1 primero, luego git fetch --unshallow después. Clonar en ~/Dropbox u otra carpeta de sincronización; el cliente de sincronización peleará con Git por el control de .git/index. Clonar un repo con submódulos y olvidar --recurse-submodules, terminando con directorios de submódulos vacíos. Finalmente, clonar por HTTPS sin un asistente de credenciales y que te pidan credenciales en cada fetch; configura uno una vez.