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ă.
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.
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.
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:
GET /info/refs(text simplu, fără pkt-line)GET /HEAD(ramura implicită)GET /objects/info/packs(lista fișierelor pack disponibile)GET /objects/pack/pack-<hash>.packși.idx(fiecare fișier pack listat și indexul său)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ță.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URL-uri SSH:
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.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URL-uri Git:
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.
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:
# 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.
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:
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).