Přejít k obsahu

Protokoly

Pitmaster podporuje několik síťových transportních protokolů pro komunikaci se servery git. Hlavním transportním protokolem je Smart HTTP. Pro širší kompatibilitu jsou k dispozici i další protokoly.

Smart HTTP (hlavní)

Doporučený transport. Funguje přes HTTPS a jde o nejrozšířenější protokol. Pro vlastní hlavičky nebo přihlašovací údaje není k dispozici API; přihlašovací údaje lze předat pouze v URL (https://user:token@host/repo.git), které PHP odesílá jako základní ověření. clone() ukládá URL, včetně přihlašovacích údajů, jako remote.origin.url v .git/config. Požadavky používají proudové obaly PHP, proto musí být povoleno allow_url_fopen.

PHP
use Pitmaster\Protocol\SmartHttpClient;

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

Podrobnosti najdete v části Smart HTTP.

Protokol v1

Tradiční protokol smart HTTP. Při zjišťování se odešlou všechny reference a vyjednávání používá řádky want/have/done.

PHP
use Pitmaster\Protocol\ProtocolV1;

Protokol v2

Novější protokol se strukturovanými příkazy (ls-refs, fetch). Je efektivnější pro repozitáře s mnoha referencemi, protože klient může seznam referencí filtrovat.

clone() a fetch() vždy používají protokol v1. Protokol v2 je dostupný výslovně přes smart HTTP prostřednictvím SmartHttpClient::discoverRefsV2() a UploadPackClient::fetchV2().

Hloupý HTTP

Záložní řešení pro servery, které nepodporují protokol smart HTTP. Hloupý protokol stahuje objekty a packy jednotlivě pomocí běžných požadavků HTTP GET.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Omezení hloupého HTTP:

  • Bez vyjednávání (klient musí stáhnout vše)
  • Během přenosu se nepoužívá delta komprese
  • Výrazně pomalejší než smart HTTP
  • Některé servery (GitHub, GitLab) ho nepodporují

Hloupý protokol stahuje:

  1. GET /info/refs (prostý text, bez pkt-line)
  2. GET /HEAD (výchozí větev)
  3. GET /objects/info/packs (seznam dostupných packů)
  4. GET /objects/pack/pack-<hash>.pack a .idx (každý uvedený pack a jeho index)
  5. GET /objects/<xx>/<rest> (jednotlivé volné objekty procházené od špiček referencí)

Krok 5 se provede pouze tehdy, když server neuvede žádné packy. Pokud packy uvede, objekty, které na serveru existují pouze jako volné soubory, se nestáhnou (#18). Hloupý klient přijímá pouze ID objektů o délce 40 znaků (SHA-1). clone() a fetch() přejdou na hloupý HTTP, pokud výměna přes smart HTTP selže.

SSH

Transport SSH používá rozšíření ssh2 PHP, pokud je načtené. Jinak spustí systémového klienta ssh prostřednictvím proc_open(). V obou případech na vzdáleném serveru spustí git-upload-pack nebo git-receive-pack.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

URL SSH:

Kód
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

Není potřeba žádné rozšíření. Obě cesty se chovají odlišně:

Systémový klient ssh (používá se, když není načteno ssh2). Pitmaster spouští ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, takže ověřování a kontrola hostitelského klíče se řídí konfigurací a agentem SSH. Tyto proměnné prostředí upravují příkaz:

Proměnná Účinek
PITMASTER_SSH_COMMAND Spustitelný soubor, který se spustí místo ssh
PITMASTER_SSH_IDENTITY_FILE Předává se jako -i <file>
PITMASTER_SSH_KNOWN_HOSTS Předává se jako -o UserKnownHostsFile=<file>
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING Předává se jako -o StrictHostKeyChecking=<value>

Tato cesta spouští proces, takže není dostupná pro handly otevřené pomocí ['processes' => false].

Rozšíření ssh2 (po načtení má vždy přednost). Pitmaster se ověří pomocí ~/.ssh/id_rsa, poté pomocí ~/.ssh/id_ed25519, pokud je klíč RSA přítomen, ale odmítnut, a jinak pomocí agenta SSH. Proměnné PITMASTER_SSH_* se ignorují a hostitelský klíč serveru se touto cestou neověřuje (#22).

Transport SSH spouští git-upload-pack nebo git-receive-pack jako vzdálený příkaz a komunikuje přes kanál SSH za použití stejného protokolu pkt-line jako smart HTTP.

Protokol Git (TCP)

Nativní protokol git komunikuje přes port TCP 9418 pomocí soketů PHP. GitProtocolClient zajišťuje zjišťování odkazů a upload-pack (načítání); odesílat neumí. clone() ani fetch() k němu nesměrují adresy URL git://, proto použijte klienta přímo.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

URL Git:

Kód
git://github.com/user/repo.git

Vlastnosti:

  • Bez ověřování (v praxi pouze pro čtení)
  • Bez šifrování
  • Většina poskytovatelů hostingu jej označila za zastaralý
  • Používá stejné rámování pkt-line jako smart HTTP

Protokol git odešle název služby a cestu k repozitáři jako úvodní požadavek a poté pokračuje standardním zjišťováním odkazů a vyjednáváním o balíčku pomocí pkt-line.

Balíčky

Balíčky Git jsou offline soubory packů s informacemi o referencích. Umožňují přenášet data repozitáře bez síťového připojení.

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 čte hlavičky balíčků v2 a v3. Neexistuje žádná metoda Repository pro import balíčku: zapište packData() do .git/objects/pack/, vytvořte jeho index pomocí PackIndexer::writeIndex() a reference aktualizujte sami.

Formát balíčku:

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 se hodí pro:

  • Přenosy pomocí „sneakernetu“ (USB disky)
  • Přírůstkové zálohy
  • Předání klonů do prostředí bez síťového připojení

Mělké klony

Pitmaster podporuje mělké klony, které stahují pouze omezenou hloubku historie commitů.

PHP
use Pitmaster\Protocol\ShallowClone;

Předejte hloubku do Pitmaster::clone($url, $path, $depth) nebo $repo->fetch($remote, $depth). Požadavek přidá schopnost shallow a řádek deepen:

Kód
want <hash>
deepen <depth>

Server odpovídá řádky shallow <hash>, které označují místo zkrácení historie. Pitmaster vypočítá hranici mělké historie ze samotné hloubky a použije řádky shallow ze serveru, pokud výpočet nic nenajde; výsledek se uloží do .git/shallow. ShallowClone::readShallow(), writeShallow() a isShallow() pracují přímo s tímto souborem.

Porovnání protokolů

Protokol Ověření Šifrování Push Typické použití
Smart HTTP Přihlašovací údaje v URL HTTPS Ano Hlavní transport
Hloupý HTTP Přihlašovací údaje v URL HTTPS Ne Záložní řešení pro starší systémy
SSH Klíče SSH nebo agent SSH Ano Soukromé repozitáře, CI
Git (TCP) Žádné Žádné Ne Zrcadla pouze pro čtení
Balíček N/A N/A N/A Offline přenos

Výběr transportu

Pitmaster::clone(), $repo->fetch() a $repo->push() vybírají transport podle URL:

Vzor URL Transport
ssh://... SSH
user@host:path SSH
Cokoli jiného (https://..., http://...) Smart HTTP; clone a fetch přejdou na hloupý HTTP

Metody nepodporují URL git:// ani místní cesty: předají se klientovi smart HTTP a selžou. Pro git:// použijte přímo GitProtocolClient. HTTPS URL obsahující uživatele i port (https://user@host:8443/repo.git) je v současnosti chybně považováno za SSH URL (#17).