Ga naar de inhoud

Protocollen

Pitmaster ondersteunt meerdere netwerktransportprotocollen voor communicatie met git-servers. Smart HTTP is het primaire transportprotocol. Er zijn aanvullende protocollen beschikbaar voor bredere compatibiliteit.

Smart HTTP (primair)

Het aanbevolen transport. Werkt via HTTPS en is het meest gebruikte protocol. Er is geen API voor aangepaste headers of inloggegevens; inloggegevens kunnen alleen worden doorgegeven in de URL (https://user:token@host/repo.git), die PHP verstuurt als Basic-authenticatie. clone() slaat de URL, inclusief inloggegevens, op als remote.origin.url in .git/config. Verzoeken gebruiken de stream wrappers van PHP, dus allow_url_fopen moet zijn ingeschakeld.

PHP
use Pitmaster\Protocol\SmartHttpClient;

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

Zie Smart HTTP voor alle details.

Protocol v1

Het traditionele smart HTTP-protocol. Alle refs worden tijdens de discovery verstuurd en de onderhandeling gebruikt want/have/done-regels.

PHP
use Pitmaster\Protocol\ProtocolV1;

Protocol v2

Het nieuwere protocol met gestructureerde opdrachten (ls-refs, fetch). Efficiënter voor repositories met veel refs, omdat de client de lijst met refs kan filteren.

clone() en fetch() gebruiken altijd protocol v1. Protocol v2 is expliciet beschikbaar via smart HTTP met SmartHttpClient::discoverRefsV2() en UploadPackClient::fetchV2().

Dumb HTTP

Terugvaloptie voor servers die het smart HTTP-protocol niet ondersteunen. Het dumb-protocol haalt objecten en packs afzonderlijk op via gewone HTTP GET-verzoeken.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Beperkingen van Dumb HTTP:

  • Geen onderhandeling (de client moet alles downloaden)
  • Geen deltacompressie tijdens de overdracht
  • Aanzienlijk trager dan smart HTTP
  • Sommige servers (GitHub, GitLab) ondersteunen het niet

Het dumb-protocol haalt het volgende op:

  1. GET /info/refs (platte tekst, geen pkt-line)
  2. GET /HEAD (standaardbranch)
  3. GET /objects/info/packs (lijst met beschikbare packs)
  4. GET /objects/pack/pack-<hash>.pack en .idx (elke vermelde pack en de bijbehorende index)
  5. GET /objects/<xx>/<rest> (afzonderlijke losse objecten, doorlopen vanaf de ref-tips)

Stap 5 wordt alleen uitgevoerd wanneer de server geen packs vermeldt. Wanneer de server wel packs vermeldt, worden objecten die alleen als losse bestanden op de server bestaan niet gedownload (#18). De dumb-client accepteert alleen object-ID's van 40 tekens (SHA-1). clone() en fetch() vallen terug op dumb HTTP wanneer de smart HTTP-uitwisseling mislukt.

SSH

Het transport SSH gebruikt de extensie ssh2 PHP wanneer die is geladen. Anders start het de systeemclient ssh via proc_open(). In beide gevallen voert het git-upload-pack of git-receive-pack uit op de remote.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

SSH-URL's:

Code
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

Er is geen extensie vereist. De twee routes werken verschillend:

Systeemclient ssh (gebruikt wanneer ssh2 niet is geladen). Pitmaster voert ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command> uit, dus authenticatie en controle van host keys volgen uw configuratie van SSH en agent. Met deze omgevingsvariabelen past u de opdracht aan:

Variabele Effect
PITMASTER_SSH_COMMAND Uitvoerbaar bestand dat wordt uitgevoerd in plaats van ssh
PITMASTER_SSH_IDENTITY_FILE Doorgegeven als -i <file>
PITMASTER_SSH_KNOWN_HOSTS Doorgegeven als -o UserKnownHostsFile=<file>
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING Doorgegeven als -o StrictHostKeyChecking=<value>

Deze route start een proces en is daarom niet beschikbaar voor handles die zijn geopend met ['processes' => false].

Extensie ssh2 (altijd de voorkeur wanneer geladen). Pitmaster authenticeert met ~/.ssh/id_rsa, daarna met ~/.ssh/id_ed25519 als de RSA-sleutel aanwezig maar geweigerd is, en anders met de agent SSH. De variabelen PITMASTER_SSH_* worden genegeerd en de host key van de server wordt langs deze route niet geverifieerd (#22).

Het transport SSH voert git-upload-pack of git-receive-pack als remote opdracht uit en communiceert via het kanaal SSH, met hetzelfde pkt-line-protocol als smart HTTP.

Protocol Git (TCP)

Het native git-protocol communiceert via TCP-poort 9418 met PHP-sockets. GitProtocolClient implementeert het ontdekken van refs en upload-pack (ophalen); pushen is niet mogelijk. clone() en fetch() sturen git://-URL's er niet naartoe door, dus gebruik de client rechtstreeks.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

Git-URL's:

Code
git://github.com/user/repo.git

Kenmerken:

  • Geen authenticatie (in de praktijk alleen-lezen)
  • Geen versleuteling
  • Door de meeste hostingproviders verouderd verklaard
  • Gebruikt dezelfde pkt-line-framing als smart HTTP

Het git-protocol verstuurt de servicenaam en het repositorypad als eerste verzoek en gaat daarna verder met standaard pkt-line-refdetectie en pack-onderhandeling.

Bundels

Git-bundels zijn offline pack-bestanden met ref-informatie. Hiermee kunt u repositorygegevens overdragen zonder netwerkverbinding.

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 leest de bundelheaders v2 en v3. Er is geen Repository-methode om een bundel te importeren: schrijf packData() naar .git/objects/pack/, bouw de index met PackIndexer::writeIndex() en werk de refs zelf bij.

Bundelformaat:

Code
# v2 git bundle\n
-<prerequisite hash>\n    (zero or more)
<hash> <refname>\n        (one or more)
\n
<pack data>               (standard pack file format)

Bundels zijn handig voor:

  • Overdrachten via USB-sticks
  • Incrementele back-ups
  • Clones klaarzetten in omgevingen zonder netwerkverbinding

Shallow clones

Pitmaster ondersteunt shallow clones, waarbij slechts een beperkte diepte van de commitgeschiedenis wordt opgehaald.

PHP
use Pitmaster\Protocol\ShallowClone;

Geef een diepte door aan Pitmaster::clone($url, $path, $depth) of $repo->fetch($remote, $depth). Het verzoek voegt de capability shallow en een deepen-regel toe:

Code
want <hash>
deepen <depth>

De server reageert met shallow <hash>-regels die aangeven waar de geschiedenis is afgekapt. Pitmaster berekent de shallow-grens op basis van de diepte zelf en gebruikt de shallow-regels van de server wanneer die berekening niets oplevert; het resultaat wordt opgeslagen in .git/shallow. ShallowClone::readShallow(), writeShallow() en isShallow() werken rechtstreeks met dat bestand.

Protocolvergelijking

Protocol Authenticatie Versleuteling Push Typisch gebruik
Smart HTTP Inloggegevens in de URL HTTPS Ja Primair transport
Dumb HTTP Inloggegevens in de URL HTTPS Nee Terugvaloptie voor oudere systemen
SSH Sleutels SSH of agent SSH Ja Privérepositories, CI
Git (TCP) Geen Geen Nee Mirrors met alleen-leestoegang
Bundel N.v.t. N.v.t. N.v.t. Offlineoverdracht

Transport selecteren

Pitmaster::clone(), $repo->fetch() en $repo->push() selecteren het transport op basis van de URL:

Patroon van URL Transport
ssh://... SSH
user@host:path SSH
Al het andere (https://..., http://...) Smart HTTP; clone en fetch vallen terug op dumb HTTP

git://-URL's en lokale paden worden niet ondersteund door deze methoden: ze worden naar de smart HTTP-client gestuurd en mislukken. Gebruik GitProtocolClient rechtstreeks voor git://. Een HTTPS URL met zowel een gebruiker als een poort (https://user@host:8443/repo.git) wordt momenteel ten onrechte herkend als een SSH URL (#17).