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.
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.
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.
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:
GET /info/refs(platte tekst, geen pkt-line)GET /HEAD(standaardbranch)GET /objects/info/packs(lijst met beschikbare packs)GET /objects/pack/pack-<hash>.packen.idx(elke vermelde pack en de bijbehorende index)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.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
SSH-URL's:
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.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
Git-URL's:
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.
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:
# 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.
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:
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).