
# Protokollid

Pitmaster toetab git-serveritega suhtlemiseks mitut võrgutranspordi protokolli. Peamine transport on nutikas HTTP. Laiema ühilduvuse jaoks on saadaval lisaprotokollid.

## Nutikas HTTP (peamine)

Soovitatav transport. Töötab üle HTTPS ja on kõige laiemalt kasutatav protokoll. Kohandatud päiste ega mandaadi jaoks pole API-i; mandaati saab edastada ainult URL-is (`https://user:token@host/repo.git`), mille PHP saadab Basic-autentimisena. `clone()` salvestab URL-i koos mandaatidega kujul `remote.origin.url` asukohas `.git/config`. Päringud kasutavad PHP vooümbriseid, seega peab `allow_url_fopen` olema lubatud.

```php
use Pitmaster\Protocol\SmartHttpClient;

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

Üksikasju vt jaotisest [Nutikas HTTP](https://pitmaster.inline0.dev/et/docs/network/smart-http).

### Protokoll v1

Traditsiooniline nutikas HTTP-protokoll. Tuvastamisel saadetakse kõik viited ning läbirääkimisel kasutatakse ridu want/have/done.

```php
use Pitmaster\Protocol\ProtocolV1;
```

### Protokoll v2

Uuem protokoll struktureeritud käskudega (`ls-refs`, `fetch`). See on tõhusam paljude viidetega hoidlates, sest klient saab viidete loendit filtreerida.

`clone()` ja `fetch()` kasutavad alati protokolli v1. Protokoll v2 on nutika HTTP kaudu selgesõnaliselt saadaval transpordiga `SmartHttpClient::discoverRefsV2()` ja `UploadPackClient::fetchV2()`.

## Lihtsustatud HTTP

Varuvariant serveritele, mis ei toeta nutikat HTTP-protokolli. Lihtsustatud protokoll hangib objektid ja pakifailid ükshaaval tavaliste HTTP GET-päringutega.

```php
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();
```

Lihtsustatud HTTP-i piirangud:
- Läbirääkimisi pole (klient peab kõik alla laadima)
- Edastuse ajal delta-tihendust ei kasutata
- Oluliselt aeglasem kui nutikas HTTP
- Mõned serverid (GitHub, GitLab) ei toeta seda

Lihtsustatud protokoll hangib:
1. `GET /info/refs` (lihttekst, pkt-line-vorminguta)
2. `GET /HEAD` (vaikimisi haru)
3. `GET /objects/info/packs` (saadaolevate pakifailide loend)
4. `GET /objects/pack/pack-<hash>.pack` ja `.idx` (iga loendis oleva pakifaili ja selle indeks)
5. `GET /objects/<xx>/<rest>` (üksikud lahtised objektid, mida läbitakse viidete tippude põhjal)

5. sammu tehakse ainult siis, kui server ei loetle pakifaile. Kui server loetleb pakifaile, ei laadita alla objekte, mis on serveris olemas ainult lahtiste failidena ([#18](https://github.com/inline0/pitmaster/issues/18)). Lihtsustatud klient aktsepteerib ainult 40-kohalisi (SHA-1) objektitunnuseid. `clone()` ja `fetch()` lähevad nutika HTTP andmevahetuse nurjumisel üle lihtsustatud HTTP-ile.

## SSH

Transport SSH kasutab laiendust `ssh2` PHP, kui see on laaditud. Muul juhul käivitab see süsteemi `ssh` kliendi programmi `proc_open()` kaudu. Mõlemal juhul käivitatakse kaugserveris `git-upload-pack` või `git-receive-pack`.

```php
use Pitmaster\Protocol\SshClient;

$client = new SshClient();
```

SSH URL-id:
```
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
```

Laiendust pole vaja. Need kaks teed toimivad erinevalt:

**Süsteemi klient `ssh`** (kasutatakse siis, kui `ssh2` pole laaditud). Pitmaster käivitab käsu `ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>`, seega järgivad autentimine ja hostivõtme kontroll teie SSH seadistust ja agenti. Käsku saab muuta järgmiste keskkonnamuutujatega:

| Muutuja | Mõju |
|----------|--------|
| `PITMASTER_SSH_COMMAND` | Käivitatav fail, mida kasutada `ssh` asemel |
| `PITMASTER_SSH_IDENTITY_FILE` | Edastatakse väärtusena `-i <file>` |
| `PITMASTER_SSH_KNOWN_HOSTS` | Edastatakse väärtusena `-o UserKnownHostsFile=<file>` |
| `PITMASTER_SSH_STRICT_HOST_KEY_CHECKING` | Edastatakse väärtusena `-o StrictHostKeyChecking=<value>` |

See tee käivitab protsessi, seega pole see saadaval käepidemetel, mis avati valikuga `['processes' => false]`.

**Laiendus `ssh2`** (laadimise korral alati eelistatud). Pitmaster autendib `~/.ssh/id_rsa` abil ja proovib siis `~/.ssh/id_ed25519`-i, kui RSA-võti on olemas, kuid tagasi lükatud; muul juhul kasutab see agenti SSH. Muutujaid `PITMASTER_SSH_*` eiratakse ja selle tee puhul serveri hostivõtit ei kontrollita ([#22](https://github.com/inline0/pitmaster/issues/22)).

Transport SSH käivitab kaugkäsklusena programmi `git-upload-pack` või `git-receive-pack` ning suhtleb SSH kanali kaudu, kasutades sama pkt-line-protokolli mis nutikas HTTP.

## Protokoll Git (TCP)

Algne git-protokoll suhtleb TCP-pordi 9418 kaudu, kasutades sokleid PHP. `GitProtocolClient` teostab viidete tuvastamise ja `upload-pack` (toomise); sellega ei saa muudatusi saata. `clone()` ja `fetch()` ei suuna URL-e `git://` selle protokollini, seega kasutage seda kliendilt otse.

```php
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();
```

Git URL-id:
```
git://github.com/user/repo.git
```

Omadused:
- Autentimine puudub (praktikas kirjutuskaitstud)
- Krüpteerimine puudub
- Enamik majutusteenuse pakkujaid on selle kasutusest kõrvaldanud
- Kasutab sama pkt-line-vormingut mis nutikas HTTP

git-protokoll saadab teenuse nime ja hoidla tee algse päringuna, seejärel jätkub töö tavalise pkt-line-vormingus viidete tuvastamise ja pakifaili läbirääkimisega.

## Paketid

Git-paketid on viiteteabega võrguühenduseta pakifailid. Need võimaldavad hoidlaandmeid edastada võrguühenduseta.

```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 loeb pakettide päiseid v2 ja v3. Paketi importimiseks pole meetodit `Repository`: kirjutage `packData()` asukohta `.git/objects/pack/`, koostage selle register käsuga `PackIndexer::writeIndex()` ja uuendage viited ise.

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

Pakettidest on kasu järgmistes olukordades:
- Andmete edastamine eemaldatava andmekandjaga (USB-draivid)
- Järk-järgulised varukoopiad
- Kloonide ettevalmistamine internetita keskkondades

## Madala ajaloosügavusega kloonid

Pitmaster toetab madala ajaloosügavusega kloone, mille puhul tuuakse ainult piiratud sügavusega sissekannete ajalugu.

```php
use Pitmaster\Protocol\ShallowClone;
```

Edastage sügavus argumendina funktsioonile `Pitmaster::clone($url, $path, $depth)` või `$repo->fetch($remote, $depth)`. Päring lisab võimaluse `shallow` ja rea `deepen`:
```
want <hash>
deepen <depth>
```

Server vastab ridadega `shallow <hash>`, mis näitavad, kus ajalugu kärbiti. Pitmaster arvutab pinnapealse piiri sügavuse põhjal ja kasutab serveri ridu `shallow`, kui arvutus tulemust ei anna; tulemus salvestatakse faili `.git/shallow`. `ShallowClone::readShallow()`, `writeShallow()` ja `isShallow()` töötavad selle failiga otse.

## Protokollide võrdlus

| Protokoll | Autentimine | Krüpteerimine | Tõuketeavitus | Tüüpiline kasutus |
|----------|------|-----------|------|-------------|
| Nutikas HTTP | Mandaadid failis URL | HTTPS | Jah | Peamine edastusviis |
| Rumal HTTP | Mandaadid failis URL | HTTPS | Ei | Pärandvaruvariant |
| SSH | SSH võtmed või agent | SSH | Jah | Privaatsed repositooriumid, CI |
| Git (TCP) | Puudub | Puudub | Ei | Ainult lugemiseks peeglid |
| Bundle | Pole kohaldatav | Pole kohaldatav | Pole kohaldatav | Võrguühenduseta edastus |

## Edastusviisi valik

`Pitmaster::clone()`, `$repo->fetch()` ja `$repo->push()` valivad edastusviisi URL põhjal:

| URL muster | Edastusviis |
|------------|-----------|
| `ssh://...` | SSH |
| `user@host:path` | SSH |
| Kõik muu (`https://...`, `http://...`) | Nutikas HTTP; kloonimine ja toomine kasutavad varuvariandina rumalat HTTP |

`git://` URL-id ja kohalikud teed pole nende meetoditega toetatud: need edastatakse nutikale HTTP kliendile ja toiming nurjub. Kasutage `GitProtocolClient` otse `git://` jaoks. HTTPS URL, mis sisaldab nii kasutajat kui porti (`https://user@host:8443/repo.git`), peetakse praegu ekslikult SSH URL-ks ([#17](https://github.com/inline0/pitmaster/issues/17)).
