Preskoči na vsebino

Protokoli

Pitmaster podpira več omrežnih prenosnih protokolov za komunikacijo s strežniki git. Primarni prenos je pametni protokol HTTP. Na voljo so tudi dodatni protokoli za širšo združljivost.

Pametni HTTP (primarni)

Priporočeni prenos. Deluje prek HTTPS in je najpogosteje uporabljen protokol. Za glave po meri ali poverilnice ni na voljo API; poverilnice je mogoče posredovati le v URL (https://user:token@host/repo.git), ki jih PHP pošlje kot osnovno preverjanje pristnosti. clone() shrani URL, vključno s poverilnicami, kot remote.origin.url v .git/config. Zahteve uporabljajo ovojnike tokov PHP, zato mora biti omogočen allow_url_fopen.

PHP
use Pitmaster\Protocol\SmartHttpClient;

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

Za vse podrobnosti glejte Pametni HTTP.

Protokol v1

Tradicionalni pametni protokol HTTP. Med odkrivanjem se pošljejo vse reference, dogovarjanje pa uporablja vrstice want/have/done.

PHP
use Pitmaster\Protocol\ProtocolV1;

Protokol v2

Novejši protokol s strukturiranimi ukazi (ls-refs, fetch). Učinkovitejši je za repozitorije z veliko referencami, saj lahko odjemalec filtrira seznam referenc.

clone() in fetch() vedno uporabljata protokol v1. Protokol v2 je na voljo izrecno prek pametnega protokola HTTP prek SmartHttpClient::discoverRefsV2() in UploadPackClient::fetchV2().

Preprosti HTTP

Nadomestna možnost za strežnike, ki ne podpirajo pametnega protokola HTTP. Preprosti protokol pridobiva objekte in pakete posamično z navadnimi zahtevami GET prek HTTP.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Omejitve preprostega HTTP:

  • Brez dogovarjanja (odjemalec mora prenesti vse)
  • Med prenosom ni stiskanja delt
  • Precej počasnejši od pametnega protokola HTTP
  • Nekateri strežniki (GitHub, GitLab) ga ne podpirajo

Preprosti protokol pridobi:

  1. GET /info/refs (navadno besedilo, brez pkt-line)

  2. GET /HEAD (privzeta veja)

  3. GET /objects/info/packs (seznam razpoložljivih paketov)

  4. GET /objects/pack/pack-<hash>.pack in .idx (vsak navedeni paket in njegov indeks)

  5. GET /objects/<xx>/<rest> (posamezne proste objekte, ki jih poišče od vrhov referenc naprej)

  6. korak se izvede samo, kadar strežnik ne navede nobenega paketa. Če navede pakete, se objekti, ki na strežniku obstajajo samo kot ohlapne datoteke, ne prenesejo (#18). Preprost odjemalec sprejema samo 40-mestne ID-je objektov (SHA-1). clone() in fetch() preklopita na preprost HTTP, kadar izmenjava s pametnim HTTP ne uspe.

SSH

Prenos SSH uporablja razširitev ssh2 PHP, če je naložena. Sicer zažene sistemski odjemalec ssh prek proc_open(). V obeh primerih na oddaljenem gostitelju zažene git-upload-pack ali git-receive-pack.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

URL-ji SSH:

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

Razširitev ni potrebna. Obe poti delujeta različno:

Sistemski odjemalec ssh (uporabi se, kadar ssh2 ni naložen). Pitmaster zažene ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, zato preverjanje pristnosti in gostiteljskega ključa sledita konfiguraciji SSH in agentu. Te spremenljivke okolja prilagodijo ukaz:

Spremenljivka Učinek
PITMASTER_SSH_COMMAND Izvedljiva datoteka, ki se zažene namesto ssh
PITMASTER_SSH_IDENTITY_FILE Posredovana kot -i <file>
PITMASTER_SSH_KNOWN_HOSTS Posredovana kot -o UserKnownHostsFile=<file>
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING Posredovana kot -o StrictHostKeyChecking=<value>

Ta pot zažene proces, zato ni na voljo pri povezavah, odprtih z ['processes' => false].

Razširitev ssh2 (vedno ima prednost, kadar je naložena). Pitmaster se najprej preveri pristnost z ~/.ssh/id_rsa, nato z ~/.ssh/id_ed25519, če je ključ RSA na voljo, vendar zavrnjen, sicer pa z agentom SSH. Spremenljivke PITMASTER_SSH_* se prezrejo, gostiteljski ključ strežnika pa se na tej poti ne preveri (#22).

Prenos SSH izvede git-upload-pack ali git-receive-pack kot oddaljeni ukaz in komunicira prek kanala SSH z istim protokolom pkt-line kot pametni protokol HTTP.

Protokol Git (TCP)

Izvorni protokol git komunicira prek vrat TCP 9418 z uporabo vtičnic PHP. GitProtocolClient implementira odkrivanje referenc in upload-pack (pridobivanje); pošiljanje ni mogoče. clone() in fetch() URL-jev git:// ne usmerjata nanj, zato uporabite odjemalca neposredno.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

URL-ji Git:

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

Značilnosti:

  • Brez preverjanja pristnosti (v praksi samo za branje)
  • Brez šifriranja
  • Večina ponudnikov gostovanja protokol opušča
  • Uporablja enako uokvirjanje pkt-line kot pametni protokol HTTP

Protokol git v začetni zahtevi pošlje ime storitve in pot do repozitorija, nato pa nadaljuje s standardnim odkrivanjem referenc pkt-line in dogovarjanjem o paketih.

Paketi

Paketi Git so datoteke paketov za uporabo brez povezave, ki vsebujejo podatke o referencah. Omogočajo prenos podatkov repozitorija brez omrežne povezave.

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 bere glavi paketov v2 in v3. Za uvoz paketa ni na voljo metode Repository: zapišite packData() v .git/objects/pack/, ustvarite njegov indeks z PackIndexer::writeIndex() in sami posodobite reference.

Oblika paketa:

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

Paketi so uporabni za:

  • Prenose s fizičnimi mediji (pogon USB)
  • Postopne varnostne kopije
  • Pripravo klonov v okoljih brez omrežne povezave

Plitvi kloni

Pitmaster podpira plitve klone, pri katerih se prenese le omejena globina zgodovine objav.

PHP
use Pitmaster\Protocol\ShallowClone;

Podajte globino za Pitmaster::clone($url, $path, $depth) ali $repo->fetch($remote, $depth). Zahteva doda zmožnost shallow in vrstico deepen:

Koda
want <hash>
deepen <depth>

Strežnik odgovori z vrsticami shallow <hash>, ki kažejo, kje je bila zgodovina skrajšana. Pitmaster izračuna plitvo mejo na podlagi same globine in uporabi strežniške vrstice shallow, kadar izračun ne vrne ničesar; rezultat shrani v .git/shallow. ShallowClone::readShallow(), writeShallow() in isShallow() neposredno delajo s to datoteko.

Primerjava protokolov

Protokol Preverjanje pristnosti Šifriranje Potiskanje Običajna uporaba
Smart HTTP Poverilnice v URL HTTPS Da Primarni prenos
Dumb HTTP Poverilnice v URL HTTPS Ne Združljivostna možnost za starejše sisteme
SSH Ključi SSH ali posrednik SSH Da Zasebni repozitoriji, CI
Git (TCP) Brez Brez Ne Zrcalni strežniki samo za branje
Paket Ni na voljo Ni na voljo Ni na voljo Prenos brez povezave

Izbira prenosa

Pitmaster::clone(), $repo->fetch() in $repo->push() izberejo način prenosa iz URL:

Vzorec URL Prenos
ssh://... SSH
user@host:path SSH
Vse drugo (https://..., http://...) Smart HTTP; pri kloniranju in pridobivanju se uporabi Dumb HTTP kot nadomestna možnost

Metode git:// ne podpirajo URL-jev in lokalnih poti: poslane so odjemalcu smart HTTP, kjer ne delujejo. Za git:// uporabite neposredno GitProtocolClient. HTTPS URL, ki vsebuje uporabnika in vrata (https://user@host:8443/repo.git), je trenutno napačno prepoznan kot SSH URL (#17).