Protocolos
Pitmaster é compatível com vários protocolos de transporte de rede para comunicação com servidores git. Smart HTTP é o transporte principal. Há protocolos adicionais para maior compatibilidade.
Smart HTTP (principal)
O transporte recomendado. Funciona por HTTPS e é o protocolo mais amplamente implantado. Não há API para cabeçalhos ou credenciais personalizados; as credenciais só podem ser passadas em URL (https://user:token@host/repo.git), que PHP envia como autenticação Basic. clone() armazena URL, incluindo as credenciais, como remote.origin.url em .git/config. As solicitações usam os wrappers de stream de PHP, portanto allow_url_fopen precisa estar habilitado.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Consulte Smart HTTP para ver todos os detalhes.
Protocolo v1
O protocolo smart HTTP tradicional. Todas as refs são enviadas durante a descoberta, e a negociação usa linhas want/have/done.
use Pitmaster\Protocol\ProtocolV1;
Protocolo v2
O protocolo mais novo, com comandos estruturados (ls-refs, fetch). É mais eficiente para repositórios com muitas refs, pois o cliente pode filtrar a lista de refs.
clone() e fetch() sempre usam o protocolo v1. O protocolo v2 está disponível explicitamente por smart HTTP via SmartHttpClient::discoverRefsV2() e UploadPackClient::fetchV2().
Dumb HTTP
Alternativa para servidores que não são compatíveis com o protocolo smart HTTP. O protocolo dumb busca objetos e packs individualmente por solicitações GET simples de HTTP.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Limitações do dumb HTTP:
- Sem negociação (o cliente precisa baixar tudo)
- Sem compressão delta durante a transferência
- Significativamente mais lento que smart HTTP
- Alguns servidores (GitHub, GitLab) não são compatíveis
O protocolo dumb busca:
GET /info/refs(texto simples, sem pkt-line)GET /HEAD(branch padrão)GET /objects/info/packs(lista de packs disponíveis)GET /objects/pack/pack-<hash>.packe.idx(cada pack listado e seu índice)GET /objects/<xx>/<rest>(objetos soltos individuais, percorridos a partir das pontas das refs)
A etapa 5 só é executada quando o servidor não lista nenhum pack. Quando há packs listados, objetos que existem apenas como arquivos soltos no servidor não são baixados (#18). O cliente dumb aceita apenas IDs de objeto de 40 caracteres (SHA-1). clone() e fetch() recorrem ao dumb HTTP quando a troca pelo smart HTTP falha.
SSH
O transporte SSH usa a extensão ssh2 PHP quando ela está carregada. Caso contrário, inicia o cliente ssh do sistema por meio de proc_open(). Em ambos os casos, executa git-upload-pack ou git-receive-pack no remoto.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URLs SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
Nenhuma extensão é necessária. Os dois caminhos se comportam de forma diferente:
Cliente ssh do sistema (usado quando ssh2 não está carregado). Pitmaster executa ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, então a autenticação e a verificação da chave do host seguem a configuração de SSH e o agente. Estas variáveis de ambiente ajustam o comando:
| Variável | Efeito |
|---|---|
PITMASTER_SSH_COMMAND |
Executável a ser usado em vez de ssh |
PITMASTER_SSH_IDENTITY_FILE |
Passado como -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
Passado como -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
Passado como -o StrictHostKeyChecking=<value> |
Este caminho inicia um processo, portanto não está disponível em handles abertos com ['processes' => false].
Extensão ssh2 (sempre preferida quando carregada). Pitmaster autentica com ~/.ssh/id_rsa, depois com ~/.ssh/id_ed25519 se a chave RSA estiver presente, mas for rejeitada, e caso contrário com o agente SSH. As variáveis PITMASTER_SSH_* são ignoradas, e a chave do host do servidor não é verificada neste caminho (#22).
O transporte SSH executa git-upload-pack ou git-receive-pack como comando remoto e se comunica pelo canal SSH usando o mesmo protocolo pkt-line do smart HTTP.
Protocolo Git (TCP)
O protocolo nativo git se comunica pela porta TCP 9418 usando sockets PHP. GitProtocolClient implementa a descoberta de refs e upload-pack (fetch); não pode fazer push. clone() e fetch() não encaminham URLs git:// para esse protocolo, então use o cliente diretamente.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URLs Git:
git://github.com/user/repo.git
Características:
- Sem autenticação (na prática, somente leitura)
- Sem criptografia
- Descontinuado pela maioria dos provedores de hospedagem
- Usa o mesmo enquadramento pkt-line do smart HTTP
O protocolo git envia o nome do serviço e o caminho do repositório como solicitação inicial e, em seguida, prossegue com a descoberta de refs padrão pkt-line e a negociação do pack.
Bundles
Os bundles Git são arquivos de pack off-line com informações de refs. Eles permitem transferir dados do repositório sem uma conexão de rede.
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 lê cabeçalhos de bundle v2 e v3. Não há um método Repository para importar um bundle: grave packData() em .git/objects/pack/, crie seu índice com PackIndexer::writeIndex() e atualize as refs por conta própria.
Formato do bundle:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
Os bundles são úteis para:
- Transferências por sneaker net (unidades USB)
- Backups incrementais
- Preparar clones em ambientes isolados de redes
Clones rasos
Pitmaster oferece suporte a clones rasos, que buscam apenas uma profundidade limitada do histórico de commits.
use Pitmaster\Protocol\ShallowClone;
Passe uma profundidade para Pitmaster::clone($url, $path, $depth) ou $repo->fetch($remote, $depth). A solicitação adiciona o recurso shallow e uma linha deepen:
want <hash>
deepen <depth>
O servidor responde com linhas shallow <hash> que indicam onde o histórico foi truncado. Pitmaster calcula o limite superficial com base na própria profundidade e usa as linhas shallow do servidor quando esse cálculo não encontra nada; o resultado é armazenado em .git/shallow. ShallowClone::readShallow(), writeShallow() e isShallow() trabalham diretamente com esse arquivo.
Comparação de protocolos
| Protocolo | Autenticação | Criptografia | Push | Uso típico |
|---|---|---|---|---|
| Smart HTTP | Credenciais em URL | HTTPS | Sim | Transporte principal |
| Dumb HTTP | Credenciais em URL | HTTPS | Não | Alternativa legada |
| SSH | chaves ou agente SSH | SSH | Sim | Repositórios privados, CI |
| Git (TCP) | Nenhuma | Nenhuma | Não | Espelhos somente leitura |
| Bundle | N/A | N/A | N/A | Transferência off-line |
Seleção de transporte
Pitmaster::clone(), $repo->fetch() e $repo->push() selecionam o transporte a partir de URL:
| Padrão URL | Transporte |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Qualquer outro (https://..., http://...) |
Smart HTTP; clone e fetch recorrem ao dumb HTTP |
URLs git:// e caminhos locais não são compatíveis com esses métodos: eles são enviados ao cliente smart HTTP e falham. Use GitProtocolClient diretamente para git://. Um HTTPS URL que contém usuário e porta (https://user@host:8443/repo.git) é atualmente confundido com um SSH URL (#17).