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.
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.
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.
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:
GET /info/refs(prostý text, bez pkt-line)GET /HEAD(výchozí větev)GET /objects/info/packs(seznam dostupných packů)GET /objects/pack/pack-<hash>.packa.idx(každý uvedený pack a jeho index)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.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URL SSH:
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.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URL Git:
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í.
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:
# 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ů.
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:
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).