
# Protokoly

Pitmaster podporuje viacero protokolov sieťového prenosu na komunikáciu so servermi git. Hlavným prenosom je inteligentný HTTP. Na zaistenie širšej kompatibility sú k dispozícii aj ďalšie protokoly.

## Inteligentný HTTP (hlavný)

Odporúčaný prenos. Funguje cez HTTPS a je najrozšírenejším protokolom. Pre vlastné hlavičky alebo prihlasovacie údaje nie je k dispozícii API; prihlasovacie údaje možno odovzdať iba v URL (`https://user:token@host/repo.git`), ktoré PHP odosiela ako základné overenie totožnosti. `clone()` ukladá URL vrátane prihlasovacích údajov ako `remote.origin.url` v `.git/config`. Požiadavky používajú obaly prúdov PHP, preto musí byť povolené `allow_url_fopen`.

```php
use Pitmaster\Protocol\SmartHttpClient;

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

Podrobnosti nájdete na stránke [Inteligentné HTTP](https://pitmaster.inline0.dev/sk/docs/network/smart-http).

### Protokol v1

Tradičný protokol inteligentného HTTP. Počas zisťovania sa odošlú všetky odkazy a pri dohadovaní sa používajú riadky want/have/done.

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

### Protokol v2

Novší protokol so štruktúrovanými príkazmi (`ls-refs`, `fetch`). Je efektívnejší pri repozitároch s mnohými odkazmi, pretože klient môže filtrovať ich zoznam.

`clone()` a `fetch()` vždy používajú protokol v1. Protokol v2 je dostupný výslovne cez inteligentný HTTP prostredníctvom `SmartHttpClient::discoverRefsV2()` a `UploadPackClient::fetchV2()`.

## Jednoduchý HTTP

Záložné riešenie pre servery, ktoré nepodporujú protokol inteligentného HTTP. Jednoduchý protokol načítava objekty a balíky jednotlivo prostredníctvom bežných požiadaviek HTTP GET.

```php
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();
```

Obmedzenia jednoduchého HTTP:
- Bez dohadovania (klient musí stiahnuť všetko)
- Bez kompresie delta počas prenosu
- Výrazne pomalší než inteligentný HTTP
- Niektoré servery (GitHub, GitLab) ho nepodporujú

Jednoduchý protokol načítava:
1. `GET /info/refs` (obyčajný text bez pkt-line)
2. `GET /HEAD` (predvolená vetva)
3. `GET /objects/info/packs` (zoznam dostupných balíkov)
4. `GET /objects/pack/pack-<hash>.pack` a `.idx` (každý uvedený balík a jeho index)
5. `GET /objects/<xx>/<rest>` (jednotlivé voľné objekty, prechádzané od vrcholových odkazov)

Krok 5 sa vykoná iba vtedy, keď server neuvádza žiadne balíky. Ak ich uvádza, objekty, ktoré existujú na serveri iba ako voľné súbory, sa nestiahnu ([#18](https://github.com/inline0/pitmaster/issues/18)). Jednoduchý klient prijíma iba ID objektov so 40 znakmi (SHA-1). `clone()` a `fetch()` pri zlyhaní inteligentnej výmeny HTTP prejdú na jednoduchý HTTP.

## SSH

Prenos SSH používa rozšírenie `ssh2` PHP, keď je načítané. Inak spustí systémového klienta `ssh` prostredníctvom `proc_open()`. V oboch prípadoch na vzdialenom zariadení spustí `git-upload-pack` alebo `git-receive-pack`.

```php
use Pitmaster\Protocol\SshClient;

$client = new SshClient();
```

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

Nevyžaduje sa žiadne rozšírenie. Tieto dva postupy sa líšia:

**Systémový klient `ssh`** (používa sa, keď `ssh2` nie je načítané). Pitmaster spúšťa `ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>`, takže overenie totožnosti a kontrola kľúča hostiteľa sa riadia konfiguráciou a agentom SSH. Tieto premenné prostredia upravujú príkaz:

| Premenná | Účinok |
|----------|--------|
| `PITMASTER_SSH_COMMAND` | Spustiteľný súbor namiesto `ssh` |
| `PITMASTER_SSH_IDENTITY_FILE` | Odovzdáva sa ako `-i <file>` |
| `PITMASTER_SSH_KNOWN_HOSTS` | Odovzdáva sa ako `-o UserKnownHostsFile=<file>` |
| `PITMASTER_SSH_STRICT_HOST_KEY_CHECKING` | Odovzdáva sa ako `-o StrictHostKeyChecking=<value>` |

Táto cesta spúšťa proces, preto nie je dostupná pri rukovätiach otvorených pomocou `['processes' => false]`.

**Rozšírenie `ssh2`** (pri načítaní má vždy prednosť). Pitmaster sa overuje pomocou `~/.ssh/id_rsa`, potom pomocou `~/.ssh/id_ed25519`, ak je kľúč RSA prítomný, ale zamietnutý, a v opačnom prípade pomocou agenta SSH. Premenné `PITMASTER_SSH_*` sa ignorujú a hostiteľský kľúč servera sa pri tomto postupe neoveruje ([#22](https://github.com/inline0/pitmaster/issues/22)).

Prenos SSH spúšťa `git-upload-pack` alebo `git-receive-pack` ako vzdialený príkaz a komunikuje cez kanál SSH pomocou rovnakého protokolu pkt-line ako inteligentný HTTP.

## Protokol Git (TCP)

Natívny protokol git komunikuje cez port TCP 9418 pomocou soketov PHP. `GitProtocolClient` implementuje zisťovanie referencií a `upload-pack` (načítanie); nedokáže odosielať zmeny. `clone()` ani `fetch()` naň nesmerujú adresy URL `git://`, preto použite klienta priamo.

```php
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();
```

Adresy URL Git:
```
git://github.com/user/repo.git
```

Charakteristiky:
- Bez overenia (v praxi iba na čítanie)
- Bez šifrovania
- Väčšina poskytovateľov hostingu ho už nepodporuje
- Používa rovnaké rámcovanie pkt-line ako inteligentný HTTP

Protokol git odosiela názov služby a cestu k úložisku ako počiatočnú požiadavku a potom pokračuje štandardným zisťovaním referencií pkt-line a dohodou o balíku.

## Balíky

Balíky Git sú offline súbory pack s informáciami o referenciách. Umožňujú prenášať údaje úložiska bez sieťového pripojenia.

```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 číta hlavičky balíkov v2 a v3. Neexistuje metóda `Repository` na import balíka: zapíšte `packData()` do `.git/objects/pack/`, vytvorte jeho index pomocou `PackIndexer::writeIndex()` a referencie aktualizujte sami.

Formát balíka:
```
# 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 sú užitočné na:
- Prenos dát na USB kľúčoch
- Prírastkové zálohy
- Prípravu klonov v prostrediach bez sieťového pripojenia

## Plytké klony

Pitmaster podporuje plytké klony, pri ktorých sa načíta iba obmedzená hĺbka histórie commitov.

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

Zadajte hĺbku pre `Pitmaster::clone($url, $path, $depth)` alebo `$repo->fetch($remote, $depth)`. Požiadavka pridá schopnosť `shallow` a riadok `deepen`:
```
want <hash>
deepen <depth>
```

Server odpovie riadkami `shallow <hash>`, ktoré označujú, kde sa história skrátila. Pitmaster vypočíta hranicu plytkej histórie podľa samotnej hĺbky a použije riadky `shallow` zo servera, ak výpočet nič nenájde; výsledok sa uloží do `.git/shallow`. `ShallowClone::readShallow()`, `writeShallow()` a `isShallow()` pracujú priamo s týmto súborom.

## Porovnanie protokolov

| Protokol | Overenie | Šifrovanie | Odosielanie zmien | Typické použitie |
|----------|------|-----------|-------------|-------------|
| Inteligentný HTTP | Prihlasovacie údaje v URL | HTTPS | Áno | Hlavný prenos |
| Jednoduchý HTTP | Prihlasovacie údaje v URL | HTTPS | Nie | Náhradné riešenie pre staršie systémy |
| SSH | Kľúče SSH alebo agent | SSH | Áno | Súkromné úložiská, CI |
| Git (TCP) | Žiadne | Žiadne | Nie | Zrkadlá iba na čítanie |
| Balík | Nevzťahuje sa | Nevzťahuje sa | Nevzťahuje sa | Offline prenos |

## Výber prenosu

`Pitmaster::clone()`, `$repo->fetch()` a `$repo->push()` vyberajú prenos podľa URL:

| Vzor URL | Prenos |
|------------|-----------|
| `ssh://...` | SSH |
| `user@host:path` | SSH |
| Čokoľvek iné (`https://...`, `http://...`) | Inteligentný HTTP; pri klonovaní a načítaní sa použije jednoduchý HTTP |

Adresy URL `git://` a lokálne cesty tieto metódy nepodporujú: odosielajú sa klientovi inteligentného HTTP a zlyhajú. Pre `git://` použite priamo `GitProtocolClient`. HTTPS URL, ktorá obsahuje používateľa aj port (`https://user@host:8443/repo.git`), sa momentálne nesprávne považuje za SSH URL ([#17](https://github.com/inline0/pitmaster/issues/17)).
