Protokol
Pitmaster mendukung beberapa protokol transport jaringan untuk berkomunikasi dengan server git. Smart HTTP adalah transport utama. Protokol tambahan tersedia untuk kompatibilitas yang lebih luas.
Smart HTTP (utama)
Transport yang direkomendasikan. Berfungsi melalui HTTPS dan merupakan protokol yang paling banyak digunakan. Tidak ada API untuk header atau kredensial kustom; kredensial hanya dapat dikirim di URL (https://user:token@host/repo.git), yang dikirim PHP sebagai autentikasi Basic. clone() menyimpan URL, termasuk kredensial, sebagai remote.origin.url di .git/config. Permintaan menggunakan pembungkus stream milik PHP, jadi allow_url_fopen harus diaktifkan.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Lihat Smart HTTP untuk detail lengkap.
Protokol v1
Protokol smart HTTP tradisional. Semua ref dikirim saat discovery, dan negosiasi menggunakan baris want/have/done.
use Pitmaster\Protocol\ProtocolV1;
Protokol v2
Protokol yang lebih baru dengan perintah terstruktur (ls-refs, fetch). Lebih efisien untuk repositori dengan banyak ref karena klien dapat memfilter daftar ref.
clone() dan fetch() selalu menggunakan protokol v1. Protokol v2 tersedia secara eksplisit melalui smart HTTP menggunakan SmartHttpClient::discoverRefsV2() dan UploadPackClient::fetchV2().
Dumb HTTP
Fallback untuk server yang tidak mendukung protokol smart HTTP. Protokol dumb mengambil objek dan pack satu per satu melalui permintaan GET HTTP biasa.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Keterbatasan dumb HTTP:
- Tidak ada negosiasi (klien harus mengunduh semuanya)
- Tidak ada kompresi delta selama transfer
- Jauh lebih lambat daripada smart HTTP
- Beberapa server (GitHub, GitLab) tidak mendukungnya
Protokol dumb mengambil:
GET /info/refs(teks biasa, tanpa pkt-line)GET /HEAD(cabang default)GET /objects/info/packs(daftar pack yang tersedia)GET /objects/pack/pack-<hash>.packdan.idx(setiap pack yang tercantum dan indeksnya)GET /objects/<xx>/<rest>(objek lepas satu per satu, ditelusuri dari tip ref)
Langkah 5 hanya dijalankan jika server tidak mencantumkan pack. Jika server mencantumkan pack, objek yang hanya tersedia sebagai file lepas di server tidak diunduh (#18). Klien dumb hanya menerima ID objek 40 karakter (SHA-1). clone() dan fetch() beralih ke dumb HTTP jika pertukaran smart HTTP gagal.
SSH
Transport SSH menggunakan ekstensi ssh2 PHP jika ekstensi tersebut dimuat. Jika tidak, transport ini menjalankan klien ssh sistem melalui proc_open(). Keduanya menjalankan git-upload-pack atau git-receive-pack pada remote.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
URL SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
Tidak diperlukan ekstensi. Kedua jalur bekerja secara berbeda:
Klien ssh sistem (digunakan saat ssh2 tidak dimuat). Pitmaster menjalankan ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, sehingga autentikasi dan pemeriksaan kunci host mengikuti konfigurasi SSH dan agent Anda. Variabel lingkungan ini menyesuaikan perintah:
| Variabel | Efek |
|---|---|
PITMASTER_SSH_COMMAND |
Executable yang dijalankan sebagai pengganti ssh |
PITMASTER_SSH_IDENTITY_FILE |
Dikirim sebagai -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
Dikirim sebagai -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
Dikirim sebagai -o StrictHostKeyChecking=<value> |
Jalur ini memulai proses, jadi tidak tersedia pada handle yang dibuka dengan ['processes' => false].
Ekstensi ssh2 (selalu diprioritaskan jika dimuat). Pitmaster melakukan autentikasi dengan ~/.ssh/id_rsa, lalu ~/.ssh/id_ed25519 jika kunci RSA tersedia tetapi ditolak, dan jika tidak, menggunakan agent SSH. Variabel PITMASTER_SSH_* diabaikan, dan kunci host server tidak diverifikasi pada jalur ini (#22).
Transport SSH menjalankan git-upload-pack atau git-receive-pack sebagai perintah remote dan berkomunikasi melalui kanal SSH menggunakan protokol pkt-line yang sama dengan smart HTTP.
Protokol Git (TCP)
Protokol git native berkomunikasi melalui port TCP 9418 menggunakan socket PHP. GitProtocolClient menerapkan discovery ref dan upload-pack (pengambilan); protokol ini tidak dapat melakukan push. clone() dan fetch() tidak mengarahkan URL git:// ke protokol ini, jadi gunakan kliennya secara langsung.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
URL Git:
git://github.com/user/repo.git
Karakteristik:
- Tidak ada autentikasi (dalam praktiknya hanya baca)
- Tidak ada enkripsi
- Tidak digunakan lagi oleh sebagian besar penyedia hosting
- Menggunakan framing pkt-line yang sama dengan smart HTTP
Protokol git mengirim nama layanan dan jalur repositori sebagai permintaan awal, lalu melanjutkan dengan discovery ref pkt-line standar dan negosiasi pack.
Bundle
Bundle Git adalah file pack offline yang berisi informasi ref. Bundle memungkinkan transfer data repositori tanpa koneksi jaringan.
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 membaca header bundle v2 dan v3. Tidak ada metode Repository untuk mengimpor bundle: tulis packData() ke .git/objects/pack/, buat indeksnya dengan PackIndexer::writeIndex(), lalu perbarui ref sendiri.
Format bundle:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
Bundle berguna untuk:
- Transfer sneakernet (drive USB)
- Cadangan inkremental
- Menyiapkan clone di lingkungan terisolasi dari jaringan
Clone dangkal
Pitmaster mendukung clone dangkal, yaitu hanya mengambil riwayat commit hingga kedalaman tertentu.
use Pitmaster\Protocol\ShallowClone;
Berikan kedalaman ke Pitmaster::clone($url, $path, $depth) atau $repo->fetch($remote, $depth). Permintaan menambahkan kapabilitas shallow dan baris deepen:
want <hash>
deepen <depth>
Server merespons dengan baris shallow <hash> yang menunjukkan di mana riwayat dipotong. Pitmaster menghitung batas kedalaman dari kedalaman itu sendiri dan menggunakan baris shallow server jika perhitungan tersebut tidak menemukan apa pun; hasilnya disimpan di .git/shallow. ShallowClone::readShallow(), writeShallow(), dan isShallow() bekerja langsung dengan file itu.
Perbandingan protokol
| Protokol | Autentikasi | Enkripsi | Push | Penggunaan umum |
|---|---|---|---|---|
| Smart HTTP | Kredensial di URL | HTTPS | Ya | Transport utama |
| Dumb HTTP | Kredensial di URL | HTTPS | Tidak | Fallback lama |
| SSH | Kunci atau agent SSH | SSH | Ya | Repo privat, CI |
| Git (TCP) | Tidak ada | Tidak ada | Tidak | Mirror hanya-baca |
| Bundle | N/A | N/A | N/A | Transfer offline |
Pemilihan transport
Pitmaster::clone(), $repo->fetch(), dan $repo->push() memilih transport dari URL:
| Pola URL | Transport |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Apa pun lainnya (https://..., http://...) |
Smart HTTP; clone dan fetch beralih ke dumb HTTP |
URL git:// dan jalur lokal tidak didukung oleh metode ini: keduanya dikirim ke klien smart HTTP dan gagal. Gunakan GitProtocolClient secara langsung untuk git://. HTTPS URL yang berisi pengguna dan port (https://user@host:8443/repo.git) saat ini keliru dianggap sebagai SSH URL (#17).