Treci la conținut

Protocoale

Pitmaster acceptă mai multe protocoale de transport de rețea pentru comunicarea cu serverele git. Smart HTTP este transportul principal. Sunt disponibile protocoale suplimentare pentru compatibilitate extinsă.

Smart HTTP (principal)

Transportul recomandat. Funcționează prin HTTPS și este protocolul cel mai răspândit. Nu există API pentru antete sau acreditări personalizate; acreditările pot fi transmise numai în URL (https://user:token@host/repo.git), pe care PHP îl trimite ca autentificare Basic. clone() stochează URL, inclusiv acreditările, ca remote.origin.url în .git/config. Cererile folosesc fluxurile PHP, așadar allow_url_fopen trebuie să fie activată.

PHP
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');

Consultați Smart HTTP pentru detalii complete.

v1 protocol

Protocolul smart HTTP tradițional. Toate referințele sunt trimise în timpul descoperirii, iar negocierea folosește liniile want/have/done.

PHP
use Pitmaster\Protocol\ProtocolV1;

v2 protocol

Protocolul mai nou, cu comenzi structurate (ls-refs, fetch). Este mai eficient pentru depozitele cu multe referințe, deoarece clientul poate filtra lista acestora.

clone() și fetch() folosesc întotdeauna protocolul v1. Protocolul v2 este disponibil explicit prin smart HTTP, prin intermediul SmartHttpClient::discoverRefsV2() și UploadPackClient::fetchV2().

Dumb HTTP

Opțiune de rezervă pentru serverele care nu acceptă protocolul smart HTTP. Protocolul dumb preia obiectele și fișierele pack individual, prin cereri GET simple HTTP.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Limitările protocolului dumb HTTP:

  • Fără negociere (clientul trebuie să descarce totul)
  • Fără comprimare delta în timpul transferului
  • Semnificativ mai lent decât smart HTTP
  • Unele servere (GitHub, GitLab) nu îl acceptă

Protocolul dumb preia:

  1. GET /info/refs (text simplu, fără pkt-line)
  2. GET /HEAD (ramura implicită)
  3. GET /objects/info/packs (lista fișierelor pack disponibile)
  4. GET /objects/pack/pack-<hash>.pack și .idx (fiecare fișier pack listat și indexul său)
  5. GET /objects/<xx>/<rest> (obiecte libere individuale, parcurse pornind de la vârfurile referințelor)

Pasul 5 rulează numai când serverul nu listează niciun fișier pack. Dacă listează fișiere pack, obiectele care există doar ca fișiere libere pe server nu sunt descărcate (#18). Clientul dumb acceptă numai ID-uri de obiecte cu 40 de caractere (SHA-1). clone() și fetch() revin la dumb HTTP dacă schimbul smart HTTP eșuează.

SSH

Transportul SSH folosește extensia ssh2 PHP când aceasta este încărcată. În caz contrar, pornește clientul de sistem ssh prin proc_open(). În ambele cazuri rulează git-upload-pack sau git-receive-pack pe serverul la distanță.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

URL-uri SSH:

Cod
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

Nu este necesară nicio extensie. Cele două căi se comportă diferit:

Clientul ssh de sistem (folosit când ssh2 nu este încărcat). Pitmaster rulează ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, așadar autentificarea și verificarea cheii gazdei urmează configurația SSH și agentul dvs. Aceste variabile de mediu modifică comanda:

Variabilă Efect
PITMASTER_SSH_COMMAND Executabilul rulat în locul lui ssh
PITMASTER_SSH_IDENTITY_FILE Transmis ca -i <file>
PITMASTER_SSH_KNOWN_HOSTS Transmis ca -o UserKnownHostsFile=<file>
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING Transmis ca -o StrictHostKeyChecking=<value>

Această cale pornește un proces, așadar nu este disponibilă pentru instanțele deschise cu ['processes' => false].

Extensia ssh2 (este întotdeauna preferată când este încărcată). Pitmaster se autentifică folosind ~/.ssh/id_rsa, apoi ~/.ssh/id_ed25519 dacă cheia RSA există, dar este respinsă; în caz contrar, folosește agentul SSH. Variabilele PITMASTER_SSH_* sunt ignorate, iar pe această cale cheia gazdei serverului nu este verificată (#22).

Transportul SSH rulează git-upload-pack sau git-receive-pack ca o comandă la distanță și comunică prin canalul SSH, folosind același protocol pkt-line ca smart HTTP.

Protocolul Git (TCP)

Protocolul nativ git comunică prin portul TCP 9418, folosind socket-uri PHP. GitProtocolClient implementează descoperirea referințelor și upload-pack (preluarea); nu poate trimite modificări. clone() și fetch() nu direcționează URL-uri git:// către acesta, așadar folosiți direct clientul.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

URL-uri Git:

Cod
git://github.com/user/repo.git

Caracteristici:

  • Fără autentificare (în practică, doar pentru citire)
  • Fără criptare
  • Învechit pentru majoritatea furnizorilor de găzduire
  • Folosește aceeași încadrare pkt-line ca smart HTTP

Protocolul git trimite numele serviciului și calea depozitului în cererea inițială, apoi continuă cu descoperirea standard a referințelor pkt-line și negocierea fișierelor pack.

Pachete bundle

Pachetele bundle Git sunt fișiere pack offline care conțin informații despre referințe. Acestea permit transferul datelor depozitului fără conexiune la rețea.

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 citește antetele pachetelor bundle v2 și v3. Nu există nicio metodă Repository pentru a importa un pachet bundle: scrieți packData() în .git/objects/pack/, creați-i indexul cu PackIndexer::writeIndex() și actualizați singuri referințele.

Formatul pachetelor bundle:

Cod
# v2 git bundle\n
-<prerequisite hash>\n    (zero or more)
<hash> <refname>\n        (one or more)
\n
<pack data>               (standard pack file format)

Pachetele bundle sunt utile pentru:

  • Transferuri sneaker-net (unități USB)
  • Copii de rezervă incrementale
  • Inițializarea clonelor în medii izolate de rețea

Clone superficiale

Pitmaster acceptă clone superficiale, în care se preia doar o parte limitată din istoricul commit-urilor.

PHP
use Pitmaster\Protocol\ShallowClone;

Transmiteți o adâncime către Pitmaster::clone($url, $path, $depth) sau $repo->fetch($remote, $depth). Cererea adaugă capabilitatea shallow și o linie deepen:

Cod
want <hash>
deepen <depth>

Serverul răspunde cu linii shallow <hash> care indică locul unde istoricul a fost trunchiat. Pitmaster calculează limita superficială pornind de la adâncime și folosește liniile shallow ale serverului când calculul nu găsește nimic; rezultatul este stocat în .git/shallow. ShallowClone::readShallow(), writeShallow() și isShallow() lucrează direct cu acel fișier.

Comparație între protocoale

Protocol Autentificare Criptare Push Utilizare tipică
Smart HTTP Date de autentificare în URL HTTPS Da Transport principal
Dumb HTTP Date de autentificare în URL HTTPS Nu Alternativă pentru compatibilitate veche
SSH Chei SSH sau agent SSH Da Depozite private, CI
Git (TCP) Niciuna Niciuna Nu Oglinzi doar pentru citire
Bundle N/A N/A N/A Transfer offline

Selectarea transportului

Pitmaster::clone(), $repo->fetch() și $repo->push() selectează transportul din URL:

Model URL Transport
ssh://... SSH
user@host:path SSH
Orice altceva (https://..., http://...) Smart HTTP; clone și fetch folosesc ca alternativă dumb HTTP

git:// URL-urile și căile locale nu sunt acceptate de aceste metode: sunt trimise către clientul smart HTTP și eșuează. Folosiți direct GitProtocolClient pentru git://. Un HTTPS URL care conține atât un utilizator, cât și un port (https://user@host:8443/repo.git) este interpretat în prezent greșit ca SSH URL (#17).