Protocolos
Pitmaster admite varios protocolos de transporte de red para comunicarse con servidores git. HTTP inteligente es el transporte principal. Hay protocolos adicionales para ofrecer mayor compatibilidad.
HTTP inteligente (principal)
Es el transporte recomendado. Funciona sobre HTTPS y es el protocolo más extendido. No hay API para encabezados personalizados o credenciales; estas solo se pueden pasar en URL (https://user:token@host/repo.git), que PHP envía como autenticación básica. clone() almacena URL, incluidas las credenciales, como remote.origin.url en .git/config. Las solicitudes usan los contenedores de flujo de PHP, por lo que debe estar habilitado allow_url_fopen.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Consulte HTTP inteligente para obtener todos los detalles.
Protocolo v1
El protocolo tradicional HTTP inteligente. Todas las referencias se envían durante el descubrimiento y la negociación usa líneas want/have/done.
use Pitmaster\Protocol\ProtocolV1;
Protocolo v2
El protocolo más reciente, con comandos estructurados (ls-refs, fetch). Es más eficiente para repositorios con muchas referencias porque el cliente puede filtrar la lista.
clone() y fetch() siempre usan el protocolo v1. El protocolo v2 está disponible explícitamente sobre HTTP inteligente a través de SmartHttpClient::discoverRefsV2() y UploadPackClient::fetchV2().
HTTP simple
Alternativa para servidores que no admiten el protocolo HTTP inteligente. El protocolo simple obtiene objetos y paquetes individualmente mediante solicitudes GET de HTTP sin formato.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Limitaciones de HTTP simple:
- Sin negociación (el cliente debe descargarlo todo)
- Sin compresión delta durante la transferencia
- Mucho más lento que HTTP inteligente
- Algunos servidores (GitHub, GitLab) no lo admiten
El protocolo simple obtiene:
GET /info/refs(texto sin formato, sin pkt-line)GET /HEAD(rama predeterminada)GET /objects/info/packs(lista de paquetes disponibles)GET /objects/pack/pack-<hash>.packy.idx(cada paquete enumerado y su índice)GET /objects/<xx>/<rest>(objetos sueltos individuales, recorridos desde las puntas de las referencias)
El paso 5 solo se ejecuta cuando el servidor no enumera paquetes. Si enumera paquetes, no se descargan los objetos que solo existen como archivos sueltos en el servidor (#18). El cliente simple solo admite ID de objeto de 40 caracteres (SHA-1). clone() y fetch() recurren a HTTP simple cuando falla el intercambio HTTP inteligente.
SSH
El transporte SSH usa la extensión ssh2 PHP cuando está cargada. De lo contrario, inicia el cliente ssh del sistema mediante proc_open(). En ambos casos ejecuta git-upload-pack o git-receive-pack en el remoto.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URL SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
No se requiere ninguna extensión. Las dos vías funcionan de manera diferente:
Cliente ssh del sistema (se usa cuando ssh2 no está cargado). Pitmaster ejecuta ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, por lo que la autenticación y la comprobación de la clave del host siguen la configuración de SSH y su agente. Estas variables de entorno ajustan el comando:
| Variable | Efecto |
|---|---|
PITMASTER_SSH_COMMAND |
Ejecutable que se ejecutará en lugar de ssh |
PITMASTER_SSH_IDENTITY_FILE |
Se pasa como -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
Se pasa como -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
Se pasa como -o StrictHostKeyChecking=<value> |
Esta vía inicia un proceso, así que no está disponible en identificadores abiertos con ['processes' => false].
Extensión ssh2 (siempre se prefiere cuando está cargada). Pitmaster se autentica con ~/.ssh/id_rsa y, si la clave RSA está presente pero se rechaza, con ~/.ssh/id_ed25519; en los demás casos, usa el agente SSH. Se ignoran las variables PITMASTER_SSH_* y, por esta vía, no se verifica la clave del host del servidor (#22).
El transporte SSH ejecuta git-upload-pack o git-receive-pack como comando remoto y se comunica por el canal SSH mediante el mismo protocolo pkt-line que HTTP inteligente.
Protocolo Git (TCP)
El protocolo nativo de git se comunica por el puerto TCP 9418 mediante sockets PHP. GitProtocolClient implementa el descubrimiento de referencias y upload-pack (obtención); no puede enviar cambios. clone() y fetch() no dirigen las URL git:// hacia este protocolo, así que use el cliente directamente.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URL Git:
git://github.com/user/repo.git
Características:
- Sin autenticación (en la práctica, solo lectura)
- Sin cifrado
- La mayoría de los proveedores de alojamiento lo han desaprobado
- Usa el mismo encuadre pkt-line que HTTP inteligente
El protocolo git envía el nombre del servicio y la ruta del repositorio como solicitud inicial; luego continúa con el descubrimiento de referencias pkt-line estándar y la negociación del paquete.
Paquetes de transferencia
Los paquetes de transferencia Git son archivos de paquete sin conexión que contienen información de referencias. Permiten transferir datos del repositorio sin conexión de red.
use Pitmaster\Protocol\Bundle;
// Read a bundle file
$bundle = Bundle::open('/path/to/repo.bundle');
$refs = $bundle->refs();
$packData = $bundle->packData();
$prerequisites = $bundle->prerequisites();
// Create one
$bundle = Bundle::create(['refs/heads/main' => $commitId], $packData);
$bundle->writeTo('/path/to/out.bundle');
Pitmaster lee encabezados de paquetes de transferencia v2 y v3. No hay ningún método Repository para importar un paquete de transferencia: escriba packData() en .git/objects/pack/, cree su índice con PackIndexer::writeIndex() y actualice las referencias por su cuenta.
Formato de los paquetes de transferencia:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
Los paquetes de transferencia son útiles para:
- Transferencias mediante dispositivos físicos (unidades USB)
- Copias de seguridad incrementales
- Preparar clones en entornos aislados de la red
Clones superficiales
Pitmaster admite clones superficiales, que solo obtienen una parte limitada del historial de confirmaciones.
use Pitmaster\Protocol\ShallowClone;
Pase una profundidad a Pitmaster::clone($url, $path, $depth) o $repo->fetch($remote, $depth). La solicitud añade la capacidad shallow y una línea deepen:
want <hash>
deepen <depth>
El servidor responde con shallow <hash> líneas que indican dónde se truncó el historial. Pitmaster calcula el límite superficial a partir de la profundidad y usa las líneas shallow del servidor cuando el cálculo no encuentra ninguna; el resultado se almacena en .git/shallow. ShallowClone::readShallow(), writeShallow() y isShallow() trabajan directamente con ese archivo.
Comparación de protocolos
| Protocolo | Autenticación | Cifrado | Envío | Uso habitual |
|---|---|---|---|---|
| Smart HTTP | Credenciales en URL | HTTPS | Sí | Transporte principal |
| Dumb HTTP | Credenciales en URL | HTTPS | No | Alternativa heredada |
| SSH | Claves SSH o agente | SSH | Sí | Repositorios privados, CI |
| Git (TCP) | Ninguna | Ninguno | No | Réplicas de solo lectura |
| Bundle | N/A | N/A | N/A | Transferencia sin conexión |
Selección del transporte
Pitmaster::clone(), $repo->fetch() y $repo->push() seleccionan el transporte a partir de URL:
| Patrón URL | Transporte |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Cualquier otro (https://..., http://...) |
Smart HTTP; clone y fetch recurren a dumb HTTP |
git:// no admite URL ni rutas locales con estos métodos: se envían al cliente smart HTTP y fallan. Usa GitProtocolClient directamente para git://. Actualmente, un HTTPS URL que contiene tanto un usuario como un puerto (https://user@host:8443/repo.git) se confunde con un SSH URL (#17).