Protokoller
Pitmaster, git sunucularıyla iletişim kurmak için birden fazla ağ aktarım protokolünü destekler. Akıllı HTTP birincil aktarımdır. Daha geniş uyumluluk için ek protokoller de kullanılabilir.
Akıllı HTTP (birincil)
Önerilen aktarım yöntemidir. HTTPS üzerinden çalışır ve en yaygın kullanılan protokoldür. Özel başlıklar veya kimlik bilgileri için API yoktur; kimlik bilgileri yalnızca URL içinde (https://user:token@host/repo.git) geçirilebilir ve PHP bunları Basic kimlik doğrulaması olarak gönderir. clone(), kimlik bilgileri dahil URL değerini .git/config içinde remote.origin.url olarak saklar. İsteklerde PHP'nin akış sarmalayıcıları kullanılır; bu nedenle allow_url_fopen etkin olmalıdır.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
Tüm ayrıntılar için Akıllı HTTP bölümüne bakın.
v1 protokolü
Geleneksel akıllı HTTP protokolüdür. Keşif sırasında tüm ref'ler gönderilir; uzlaşmada istenenler/mevcutlar/tamamlandı satırları kullanılır.
use Pitmaster\Protocol\ProtocolV1;
v2 protokolü
Yapılandırılmış komutlara sahip daha yeni protokoldür (ls-refs, fetch). İstemci ref listesini filtreleyebildiği için çok sayıda ref içeren depolarda daha verimlidir.
clone() ve fetch() her zaman v1 protokolünü kullanır. v2 protokolü, HTTP akıllı aktarımı üzerinden SmartHttpClient::discoverRefsV2() ve UploadPackClient::fetchV2() aracılığıyla açıkça kullanılabilir.
Basit HTTP
Akıllı HTTP protokolünü desteklemeyen sunucular için yedek yöntemdir. Basit protokol, nesneleri ve pack'leri tek tek, düz HTTP GET istekleriyle getirir.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
Basit HTTP sınırlamaları:
- Uzlaşma yoktur (istemci her şeyi indirmelidir)
- Aktarım sırasında delta sıkıştırması yapılmaz
- Akıllı HTTP yönteminden çok daha yavaştır
- Bazı sunucular (GitHub, GitLab) bunu desteklemez
Basit protokol şunları getirir:
-
GET /info/refs(düz metin, pkt-line yok) -
GET /HEAD(varsayılan dal) -
GET /objects/info/packs(kullanılabilir pack'lerin listesi) -
GET /objects/pack/pack-<hash>.packve.idx(listelenen her pack ve indeksi) -
GET /objects/<xx>/<rest>(ref uçlarından başlayarak dolaşılan tek tek gevşek nesneler) -
adım yalnızca sunucu hiçbir pack listelemediğinde çalışır. Pack listelendiğinde, sunucuda yalnızca gevşek dosyalar olarak bulunan nesneler indirilmez (#18). Basit istemci yalnızca 40 karakterlik (SHA-1) nesne kimliklerini kabul eder. Akıllı HTTP alışverişi başarısız olursa
clone()vefetch()basit HTTP yöntemine geçer.
SSH
SSH aktarımı yüklüyse ssh2 PHP uzantısını kullanır. Aksi durumda sistemin ssh istemcisini proc_open() üzerinden başlatır. Her iki durumda da uzak sunucuda uzaktan komut olarak git-upload-pack veya git-receive-pack çalıştırır.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
SSH URL'leri:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
Uzantı gerekmez. İki yol farklı şekilde çalışır:
Sistem ssh istemcisi (ssh2 yüklü olmadığında kullanılır). Pitmaster, ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command> çalıştırır; bu nedenle kimlik doğrulama ve ana makine anahtarı denetimi, SSH yapılandırmanıza ve aracınıza göre yapılır. Bu ortam değişkenleri komutu ayarlar:
| Değişken | Etki |
|---|---|
PITMASTER_SSH_COMMAND |
ssh yerine çalıştırılacak yürütülebilir dosya |
PITMASTER_SSH_IDENTITY_FILE |
-i <file> olarak geçirilir |
PITMASTER_SSH_KNOWN_HOSTS |
-o UserKnownHostsFile=<file> olarak geçirilir |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
-o StrictHostKeyChecking=<value> olarak geçirilir |
Bu yol bir süreç başlatır; bu nedenle ['processes' => false] ile açılan tanıtıcılarda kullanılamaz.
ssh2 uzantısı (yüklüyse her zaman tercih edilir). Pitmaster, ~/.ssh/id_rsa ile kimlik doğrular; RSA anahtarı varsa ancak reddedilmişse ~/.ssh/id_ed25519 ile dener, aksi durumda SSH aracısını kullanır. PITMASTER_SSH_* değişkenleri yok sayılır ve bu yolda sunucunun ana makine anahtarı doğrulanmaz (#22).
SSH aktarımı, uzak komut olarak git-upload-pack veya git-receive-pack çalıştırır ve akıllı HTTP ile aynı pkt-line protokolünü kullanarak SSH kanalı üzerinden iletişim kurar.
Git protokolü (TCP)
Yerel git protokolü, TCP portu 9418 üzerinden PHP soketleri kullanarak iletişim kurar. GitProtocolClient ref keşfini ve upload-pack (getirme) işlemini uygular; push yapamaz. clone() ve fetch(), git:// URL'lerini bu protokole yönlendirmez; bu nedenle istemciyi doğrudan kullanın.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
Git URL'leri:
git://github.com/user/repo.git
Özellikler:
- Kimlik doğrulama yoktur (uygulamada salt okunur)
- Şifreleme yoktur
- Çoğu barındırma sağlayıcısı tarafından kullanımdan kaldırılmıştır
- Akıllı HTTP ile aynı pkt-line çerçevelemesini kullanır
git protokolü, ilk istekte hizmet adını ve depo yolunu gönderir; ardından standart pkt-line ref keşfi ve pack uzlaşmasıyla devam eder.
Paketler
Git paketleri, ref bilgisi içeren çevrimdışı pack dosyalarıdır. Depo verilerinin ağ bağlantısı olmadan aktarılmasını sağlar.
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, v2 ve v3 paket başlıklarını okur. Paketi içe aktarmak için Repository yöntemi yoktur: packData() dosyasını .git/objects/pack/ konumuna yazın, PackIndexer::writeIndex() ile indeksini oluşturun ve ref'leri kendiniz güncelleyin.
Paket biçimi:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
Paketler şu durumlarda kullanışlıdır:
- Sneakernet aktarımları (USB sürücüler)
- Artımlı yedeklemeler
- Ağdan yalıtılmış ortamlarda clone'ları başlatma
Sığ klonlar
Pitmaster, commit geçmişinin yalnızca sınırlı bir derinliğinin getirildiği sığ klonları destekler.
use Pitmaster\Protocol\ShallowClone;
Pitmaster::clone($url, $path, $depth) veya $repo->fetch($remote, $depth) için bir derinlik belirtin. İstek, shallow yeteneğini ve bir deepen satırını ekler:
want <hash>
deepen <depth>
Sunucu, geçmişin nerede kesildiğini gösteren shallow <hash> satırlarıyla yanıt verir. Pitmaster, sığ sınırı doğrudan derinlikten hesaplar; bu hesaplama sonuç vermezse sunucunun shallow satırlarını kullanır. Sonuç .git/shallow içinde saklanır. ShallowClone::readShallow(), writeShallow() ve isShallow() bu dosyayla doğrudan çalışır.
Protokol karşılaştırması
| Protokol | Kimlik doğrulama | Şifreleme | Gönderme | Yaygın kullanım |
|---|---|---|---|---|
| Akıllı HTTP | URL içinde kimlik bilgileri | HTTPS | Evet | Birincil aktarım |
| Aptal HTTP | URL içinde kimlik bilgileri | HTTPS | Hayır | Eski sistemler için yedek |
| SSH | SSH anahtarları veya aracı | SSH | Evet | Özel depolar, CI |
| Git (TCP) | Yok | Yok | Hayır | Salt okunur yansılar |
| Paket | Uygulanamaz | Uygulanamaz | Uygulanamaz | Çevrimdışı aktarım |
Aktarım seçimi
Pitmaster::clone(), $repo->fetch() ve $repo->push() aktarımı URL üzerinden seçer:
| URL deseni | Aktarım |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
Diğer her şey (https://..., http://...) |
Akıllı HTTP; clone ve fetch, aptal HTTP yöntemine geri döner |
Bu yöntemler git:// URL'lerini ve yerel yolları desteklemez: bunlar akıllı HTTP istemcisine gönderilir ve başarısız olur. git:// için doğrudan GitProtocolClient kullanın. Hem kullanıcı hem de bağlantı noktası içeren bir HTTPS URL (https://user@host:8443/repo.git), şu anda yanlışlıkla bir SSH URL olarak algılanıyor (#17).