Protokoly
Pitmaster podporuje viacero protokolov sieťového prenosu na komunikáciu so servermi git. Hlavným prenosom je inteligentný HTTP. Na zaistenie širšej kompatibility sú k dispozícii aj ďalšie protokoly.
Inteligentný HTTP (hlavný)
Odporúčaný prenos. Funguje cez HTTPS a je najrozšírenejším protokolom. Pre vlastné hlavičky alebo prihlasovacie údaje nie je k dispozícii API; prihlasovacie údaje možno odovzdať iba v URL (https://user:token@host/repo.git), ktoré PHP odosiela ako základné overenie totožnosti. clone() ukladá URL vrátane prihlasovacích údajov ako remote.origin.url v .git/config. Požiadavky používajú obaly prúdov PHP, preto musí byť povolené allow_url_fopen.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Podrobnosti nájdete na stránke Inteligentné HTTP.
Protokol v1
Tradičný protokol inteligentného HTTP. Počas zisťovania sa odošlú všetky odkazy a pri dohadovaní sa používajú riadky want/have/done.
use Pitmaster\Protocol\ProtocolV1;
Protokol v2
Novší protokol so štruktúrovanými príkazmi (ls-refs, fetch). Je efektívnejší pri repozitároch s mnohými odkazmi, pretože klient môže filtrovať ich zoznam.
clone() a fetch() vždy používajú protokol v1. Protokol v2 je dostupný výslovne cez inteligentný HTTP prostredníctvom SmartHttpClient::discoverRefsV2() a UploadPackClient::fetchV2().
Jednoduchý HTTP
Záložné riešenie pre servery, ktoré nepodporujú protokol inteligentného HTTP. Jednoduchý protokol načítava objekty a balíky jednotlivo prostredníctvom bežných požiadaviek HTTP GET.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Obmedzenia jednoduchého HTTP:
- Bez dohadovania (klient musí stiahnuť všetko)
- Bez kompresie delta počas prenosu
- Výrazne pomalší než inteligentný HTTP
- Niektoré servery (GitHub, GitLab) ho nepodporujú
Jednoduchý protokol načítava:
GET /info/refs(obyčajný text bez pkt-line)GET /HEAD(predvolená vetva)GET /objects/info/packs(zoznam dostupných balíkov)GET /objects/pack/pack-<hash>.packa.idx(každý uvedený balík a jeho index)GET /objects/<xx>/<rest>(jednotlivé voľné objekty, prechádzané od vrcholových odkazov)
Krok 5 sa vykoná iba vtedy, keď server neuvádza žiadne balíky. Ak ich uvádza, objekty, ktoré existujú na serveri iba ako voľné súbory, sa nestiahnu (#18). Jednoduchý klient prijíma iba ID objektov so 40 znakmi (SHA-1). clone() a fetch() pri zlyhaní inteligentnej výmeny HTTP prejdú na jednoduchý HTTP.
SSH
Prenos SSH používa rozšírenie ssh2 PHP, keď je načítané. Inak spustí systémového klienta ssh prostredníctvom proc_open(). V oboch prípadoch na vzdialenom zariadení spustí git-upload-pack alebo git-receive-pack.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
Adresy URL SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
Nevyžaduje sa žiadne rozšírenie. Tieto dva postupy sa líšia:
Systémový klient ssh (používa sa, keď ssh2 nie je načítané). Pitmaster spúšťa ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, takže overenie totožnosti a kontrola kľúča hostiteľa sa riadia konfiguráciou a agentom SSH. Tieto premenné prostredia upravujú príkaz:
| Premenná | Účinok |
|---|---|
PITMASTER_SSH_COMMAND |
Spustiteľný súbor namiesto ssh |
PITMASTER_SSH_IDENTITY_FILE |
Odovzdáva sa ako -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
Odovzdáva sa ako -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
Odovzdáva sa ako -o StrictHostKeyChecking=<value> |
Táto cesta spúšťa proces, preto nie je dostupná pri rukovätiach otvorených pomocou ['processes' => false].
Rozšírenie ssh2 (pri načítaní má vždy prednosť). Pitmaster sa overuje pomocou ~/.ssh/id_rsa, potom pomocou ~/.ssh/id_ed25519, ak je kľúč RSA prítomný, ale zamietnutý, a v opačnom prípade pomocou agenta SSH. Premenné PITMASTER_SSH_* sa ignorujú a hostiteľský kľúč servera sa pri tomto postupe neoveruje (#22).
Prenos SSH spúšťa git-upload-pack alebo git-receive-pack ako vzdialený príkaz a komunikuje cez kanál SSH pomocou rovnakého protokolu pkt-line ako inteligentný HTTP.
Protokol Git (TCP)
Natívny protokol git komunikuje cez port TCP 9418 pomocou soketov PHP. GitProtocolClient implementuje zisťovanie referencií a upload-pack (načítanie); nedokáže odosielať zmeny. clone() ani fetch() naň nesmerujú adresy URL git://, preto použite klienta priamo.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
Adresy URL Git:
git://github.com/user/repo.git
Charakteristiky:
- Bez overenia (v praxi iba na čítanie)
- Bez šifrovania
- Väčšina poskytovateľov hostingu ho už nepodporuje
- Používa rovnaké rámcovanie pkt-line ako inteligentný HTTP
Protokol git odosiela názov služby a cestu k úložisku ako počiatočnú požiadavku a potom pokračuje štandardným zisťovaním referencií pkt-line a dohodou o balíku.
Balíky
Balíky Git sú offline súbory pack s informáciami o referenciách. Umožňujú prenášať údaje úložiska bez sieťového pripojenia.
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 číta hlavičky balíkov v2 a v3. Neexistuje metóda Repository na import balíka: zapíšte packData() do .git/objects/pack/, vytvorte jeho index pomocou PackIndexer::writeIndex() a referencie aktualizujte sami.
Formát balíka:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
Balíky sú užitočné na:
- Prenos dát na USB kľúčoch
- Prírastkové zálohy
- Prípravu klonov v prostrediach bez sieťového pripojenia
Plytké klony
Pitmaster podporuje plytké klony, pri ktorých sa načíta iba obmedzená hĺbka histórie commitov.
use Pitmaster\Protocol\ShallowClone;
Zadajte hĺbku pre Pitmaster::clone($url, $path, $depth) alebo $repo->fetch($remote, $depth). Požiadavka pridá schopnosť shallow a riadok deepen:
want <hash>
deepen <depth>
Server odpovie riadkami shallow <hash>, ktoré označujú, kde sa história skrátila. Pitmaster vypočíta hranicu plytkej histórie podľa samotnej hĺbky a použije riadky shallow zo servera, ak výpočet nič nenájde; výsledok sa uloží do .git/shallow. ShallowClone::readShallow(), writeShallow() a isShallow() pracujú priamo s týmto súborom.
Porovnanie protokolov
| Protokol | Overenie | Šifrovanie | Odosielanie zmien | Typické použitie |
|---|---|---|---|---|
| Inteligentný HTTP | Prihlasovacie údaje v URL | HTTPS | Áno | Hlavný prenos |
| Jednoduchý HTTP | Prihlasovacie údaje v URL | HTTPS | Nie | Náhradné riešenie pre staršie systémy |
| SSH | Kľúče SSH alebo agent | SSH | Áno | Súkromné úložiská, CI |
| Git (TCP) | Žiadne | Žiadne | Nie | Zrkadlá iba na čítanie |
| Balík | Nevzťahuje sa | Nevzťahuje sa | Nevzťahuje sa | Offline prenos |
Výber prenosu
Pitmaster::clone(), $repo->fetch() a $repo->push() vyberajú prenos podľa URL:
| Vzor URL | Prenos |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Čokoľvek iné (https://..., http://...) |
Inteligentný HTTP; pri klonovaní a načítaní sa použije jednoduchý HTTP |
Adresy URL git:// a lokálne cesty tieto metódy nepodporujú: odosielajú sa klientovi inteligentného HTTP a zlyhajú. Pre git:// použite priamo GitProtocolClient. HTTPS URL, ktorá obsahuje používateľa aj port (https://user@host:8443/repo.git), sa momentálne nesprávne považuje za SSH URL (#17).