Pular para o conteúdo

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.

PHP
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.

PHP
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.

PHP
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:

  1. GET /info/refs (texto simples, sem pkt-line)
  2. GET /HEAD (branch padrão)
  3. GET /objects/info/packs (lista de packs disponíveis)
  4. GET /objects/pack/pack-<hash>.pack e .idx (cada pack listado e seu índice)
  5. 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.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

URLs SSH:

Código
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.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

URLs Git:

Código
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.

PHP
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:

Código
# 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.

PHP
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:

Código
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).