Protocolli
Pitmaster supporta diversi protocolli di trasporto di rete per comunicare con i server git. Smart HTTP è il trasporto principale. Sono disponibili protocolli aggiuntivi per una compatibilità più ampia.
Smart HTTP (principale)
Il trasporto consigliato. Funziona su HTTPS ed è il protocollo più diffuso. Non esiste API per intestazioni personalizzate o credenziali; le credenziali possono essere passate solo in URL (https://user:token@host/repo.git), che PHP invia come autenticazione Basic. clone() memorizza URL, credenziali incluse, come remote.origin.url in .git/config. Le richieste usano i wrapper di stream di PHP, quindi allow_url_fopen deve essere abilitato.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Per tutti i dettagli, consultate Smart HTTP.
Protocollo v1
Il protocollo smart HTTP tradizionale. Durante il rilevamento vengono inviati tutti i riferimenti e la negoziazione usa le righe want/have/done.
use Pitmaster\Protocol\ProtocolV1;
Protocollo v2
Il protocollo più recente, con comandi strutturati (ls-refs, fetch). Più efficiente per i repository con molti riferimenti, perché il client può filtrare l'elenco.
clone() e fetch() usano sempre il protocollo v1. Il protocollo v2 è disponibile esplicitamente tramite smart HTTP con SmartHttpClient::discoverRefsV2() e UploadPackClient::fetchV2().
HTTP non smart
Alternativa per i server che non supportano il protocollo smart HTTP. Il protocollo non smart recupera singolarmente oggetti e pack tramite semplici richieste GET HTTP.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Limitazioni di HTTP non smart:
- Nessuna negoziazione (il client deve scaricare tutto)
- Nessuna compressione delta durante il trasferimento
- Notevolmente più lento di HTTP smart
- Alcuni server (GitHub, GitLab) non lo supportano
Il protocollo non smart recupera:
GET /info/refs(testo semplice, senza pkt-line)GET /HEAD(branch predefinito)GET /objects/info/packs(elenco dei pack disponibili)GET /objects/pack/pack-<hash>.packe.idx(ogni pack elencato e il relativo indice)GET /objects/<xx>/<rest>(singoli oggetti sciolti, a partire dalle estremità dei riferimenti)
Il passaggio 5 viene eseguito solo quando il server non elenca pack. Se invece ne elenca, gli oggetti presenti solo come file sciolti sul server non vengono scaricati (#18). Il client non smart accetta solo ID oggetto di 40 caratteri (SHA-1). clone() e fetch() passano al protocollo HTTP non smart quando lo scambio smart HTTP fallisce.
SSH
Il trasporto SSH usa l'estensione ssh2 PHP quando è caricata. Altrimenti avvia il client di sistema ssh tramite proc_open(). In entrambi i casi esegue git-upload-pack o git-receive-pack sul remote.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URL SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
Non è necessaria alcuna estensione. I due percorsi funzionano in modo diverso:
Client di sistema ssh (usato quando ssh2 non è caricato). Pitmaster esegue ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, quindi l'autenticazione e la verifica della chiave host seguono la configurazione SSH e l'agent in uso. Queste variabili d'ambiente modificano il comando:
| Variabile | Effetto |
|---|---|
PITMASTER_SSH_COMMAND |
Eseguibile da usare al posto di ssh |
PITMASTER_SSH_IDENTITY_FILE |
Passato come -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
Passato come -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
Passato come -o StrictHostKeyChecking=<value> |
Questo percorso avvia un processo, quindi non è disponibile sugli handle aperti con ['processes' => false].
Estensione ssh2 (sempre preferita quando è caricata). Pitmaster esegue l'autenticazione con ~/.ssh/id_rsa, poi con ~/.ssh/id_ed25519 se la chiave RSA è presente ma viene rifiutata, e in caso contrario con l'agent SSH. Le variabili PITMASTER_SSH_* vengono ignorate e, in questo percorso, la chiave host del server non viene verificata (#22).
Il trasporto SSH esegue git-upload-pack o git-receive-pack come comando remoto e comunica sul canale SSH usando lo stesso protocollo pkt-line di HTTP smart.
Protocollo Git (TCP)
Il protocollo nativo git comunica sulla porta TCP 9418 usando socket PHP. GitProtocolClient implementa il rilevamento dei riferimenti e upload-pack (fetch); non può eseguire push. clone() e fetch() non instradano gli URL git:// verso di esso, quindi usate direttamente il client.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URL Git:
git://github.com/user/repo.git
Caratteristiche:
- Nessuna autenticazione (in pratica, sola lettura)
- Nessuna crittografia
- Dichiarato obsoleto dalla maggior parte dei provider di hosting
- Usa la stessa struttura pkt-line di HTTP smart
Il protocollo git invia il nome del servizio e il percorso del repository come richiesta iniziale, quindi procede con il rilevamento dei riferimenti e la negoziazione del pack standard basati su pkt-line.
Bundle
I bundle Git sono file pack offline contenenti informazioni sui riferimenti. Permettono di trasferire i dati di un repository senza una connessione di rete.
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 legge le intestazioni dei bundle v2 e v3. Non esiste un metodo Repository per importare un bundle: scrivete packData() in .git/objects/pack/, create l'indice con PackIndexer::writeIndex() e aggiornate i riferimenti manualmente.
Formato dei bundle:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
I bundle sono utili per:
- Trasferimenti tramite supporti fisici (unità USB)
- Backup incrementali
- Preparare cloni in ambienti isolati dalla rete
Cloni superficiali
Pitmaster supporta i cloni superficiali, che recuperano solo un numero limitato di commit nella cronologia.
use Pitmaster\Protocol\ShallowClone;
Passate una profondità a Pitmaster::clone($url, $path, $depth) o $repo->fetch($remote, $depth). La richiesta aggiunge la funzionalità shallow e una riga deepen:
want <hash>
deepen <depth>
Il server risponde con righe shallow <hash> che indicano dove è stata troncata la cronologia. Pitmaster calcola il limite della cronologia a partire dalla profondità e usa le righe shallow del server quando il calcolo non produce risultati; il risultato viene salvato in .git/shallow. ShallowClone::readShallow(), writeShallow() e isShallow() lavorano direttamente con quel file.
Confronto dei protocolli
| Protocollo | Autenticazione | Crittografia | Push | Uso tipico |
|---|---|---|---|---|
| HTTP smart | Credenziali in URL | HTTPS | Sì | Trasporto principale |
| HTTP non smart | Credenziali in URL | HTTPS | No | Alternativa legacy |
| SSH | Chiavi SSH o agent | SSH | Sì | Repository privati, CI |
| Git (TCP) | Nessuna | Nessuna | No | Mirror in sola lettura |
| Bundle | N/D | N/D | N/D | Trasferimento offline |
Selezione del trasporto
Pitmaster::clone(), $repo->fetch() e $repo->push() selezionano il trasporto in base a URL:
| Schema URL | Trasporto |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Qualsiasi altro (https://..., http://...) |
HTTP smart; clone e fetch passano a HTTP non smart |
Gli URL git:// e i percorsi locali non sono supportati da questi metodi: vengono inviati al client HTTP smart e falliscono. Per git:// usate direttamente GitProtocolClient. Un HTTPS URL che contiene sia un utente sia una porta (https://user@host:8443/repo.git) viene attualmente interpretato erroneamente come SSH URL (#17).