Preskočiť na obsah

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.

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

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

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

  1. GET /info/refs (obyčajný text bez pkt-line)
  2. GET /HEAD (predvolená vetva)
  3. GET /objects/info/packs (zoznam dostupných balíkov)
  4. GET /objects/pack/pack-<hash>.pack a .idx (každý uvedený balík a jeho index)
  5. 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.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

Adresy URL SSH:

Kód
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.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

Adresy URL Git:

Kód
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.

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

Kód
# 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.

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

Kód
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).