Vai al contenuto

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.

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

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

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

  1. GET /info/refs (testo semplice, senza pkt-line)
  2. GET /HEAD (branch predefinito)
  3. GET /objects/info/packs (elenco dei pack disponibili)
  4. GET /objects/pack/pack-<hash>.pack e .idx (ogni pack elencato e il relativo indice)
  5. 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.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

URL SSH:

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

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

URL Git:

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

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

Codice
# 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.

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

Codice
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).