البروتوكولات
يدعم Pitmaster بروتوكولات نقل متعددة للاتصال بخوادم git. يُعد HTTP الذكي وسيلة النقل الأساسية، وتتوفر بروتوكولات إضافية لضمان توافق أوسع.
HTTP الذكي (أساسي)
وسيلة النقل الموصى بها. تعمل عبر HTTPS وهي البروتوكول الأكثر انتشارًا. لا يتوفر API للعناوين المخصصة أو بيانات الاعتماد؛ ولا يمكن تمرير بيانات الاعتماد إلا في URL (https://user:token@host/repo.git)، التي يرسلها PHP على هيئة مصادقة Basic. يخزّن clone() قيمة URL، بما فيها بيانات الاعتماد، بوصفها remote.origin.url في .git/config. تستخدم الطلبات أغلفة تدفق PHP، لذا يجب تفعيل allow_url_fopen.
use Pitmaster\Protocol\SmartHttpClient;
$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');
راجع HTTP الذكي للاطلاع على التفاصيل كاملة.
البروتوكول v1
بروتوكول HTTP الذكي التقليدي. تُرسل كل المراجع أثناء الاكتشاف، ويستخدم التفاوض أسطر المطلوب والمتاح والانتهاء.
use Pitmaster\Protocol\ProtocolV1;
البروتوكول v2
بروتوكول أحدث بأوامر منظمة (ls-refs، fetch). أكثر كفاءة للمستودعات التي تضم مراجع كثيرة، إذ يمكن للعميل تصفية قائمة المراجع.
يستخدم clone() وfetch() البروتوكول v1 دائمًا. يتوفر البروتوكول v2 صراحةً عبر HTTP الذكي من خلال SmartHttpClient::discoverRefsV2() وUploadPackClient::fetchV2().
HTTP غير الذكي
خيار احتياطي للخوادم التي لا تدعم بروتوكول HTTP الذكي. يجلب البروتوكول غير الذكي الكائنات والحزم كلًا على حدة عبر طلبات GET عادية باستخدام HTTP.
use Pitmaster\Protocol\DumbHttpClient;
$client = new DumbHttpClient();
قيود HTTP غير الذكي:
- لا يوجد تفاوض (على العميل تنزيل كل شيء)
- لا يوجد ضغط دلتا أثناء النقل
- أبطأ بكثير من HTTP الذكي
- بعض الخوادم (GitHub وGitLab) لا تدعمه
يجلب البروتوكول غير الذكي ما يلي:
GET /info/refs(نص عادي، بلا pkt-line)GET /HEAD(الفرع الافتراضي)GET /objects/info/packs(قائمة بالحزم المتاحة)GET /objects/pack/pack-<hash>.packو.idx(كل حزمة مدرجة وفهرسها)GET /objects/<xx>/<rest>(الكائنات المنفردة غير المعبأة، بدءًا من رؤوس المراجع)
تُنفّذ الخطوة 5 فقط عندما لا يسرد الخادم أي حزم. وعند إدراج حزم، لا تُنزّل الكائنات الموجودة كملفات منفردة على الخادم (#18). يقبل العميل غير الذكي معرّفات الكائنات ذات 40 محرفًا (SHA-1) فقط. يعود clone() وfetch() إلى HTTP غير الذكي إذا فشل التبادل عبر HTTP الذكي.
SSH
يستخدم نقل SSH الامتداد ssh2 PHP عند تحميله. وإلا فيبدأ عميل ssh النظام عبر proc_open(). وفي الحالتين يشغّل git-upload-pack أو git-receive-pack على المستودع البعيد.
use Pitmaster\Protocol\SshClient;
$client = new SshClient();
عناوين SSH:
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git
لا يلزم أي امتداد. يختلف سلوك المسارين:
عميل ssh النظام (يُستخدم عند عدم تحميل ssh2). يشغّل Pitmaster الأمر ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>، لذا تتبع المصادقة والتحقق من مفتاح المضيف إعدادات SSH والوكيل لديك. تضبط متغيرات البيئة التالية الأمر:
| المتغير | التأثير |
|---|---|
PITMASTER_SSH_COMMAND |
الملف التنفيذي الذي سيُشغّل بدلًا من ssh |
PITMASTER_SSH_IDENTITY_FILE |
يُمرّر بوصفه -i <file> |
PITMASTER_SSH_KNOWN_HOSTS |
يُمرّر بوصفه -o UserKnownHostsFile=<file> |
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING |
يُمرّر بوصفه -o StrictHostKeyChecking=<value> |
يبدأ هذا المسار عملية، لذا فهو غير متاح للمقابض المفتوحة باستخدام ['processes' => false].
امتداد ssh2 (يُفضّل دائمًا عند تحميله). يصادق Pitmaster باستخدام ~/.ssh/id_rsa، ثم ~/.ssh/id_ed25519 إذا كان مفتاح RSA موجودًا لكن رُفض، وإلا فيستخدم وكيل SSH. تُتجاهل متغيرات PITMASTER_SSH_*، ولا يُتحقق من مفتاح مضيف الخادم في هذا المسار (#22).
يشغّل نقل SSH الأمر git-upload-pack أو git-receive-pack على المستودع البعيد، ويتواصل عبر قناة SSH باستخدام بروتوكول pkt-line نفسه الذي يستخدمه HTTP الذكي.
بروتوكول Git (TCP)
يتواصل بروتوكول git الأصلي عبر منافذ TCP رقم 9418 باستخدام مقابس PHP. ينفّذ GitProtocolClient اكتشاف المراجع وupload-pack (الجلب)، لكنه لا يدعم الدفع. لا يوجّه clone() وfetch() عناوين git:// إليه، لذا استخدم العميل مباشرةً.
use Pitmaster\Protocol\GitProtocolClient;
$client = new GitProtocolClient();
عناوين Git:
git://github.com/user/repo.git
الخصائص:
- لا توجد مصادقة (للقراءة فقط عمليًا)
- لا يوجد تشفير
- أوقف معظم مزودي الاستضافة استخدامه
- يستخدم تأطير pkt-line نفسه الذي يستخدمه HTTP الذكي
يرسل بروتوكول git اسم الخدمة ومسار المستودع في الطلب الأولي، ثم يتابع باكتشاف المراجع والتفاوض على الحزم باستخدام pkt-line القياسي.
الحزم المجمّعة
حزم Git المجمّعة ملفات حزم للاستخدام دون اتصال، تتضمن معلومات المراجع. وتتيح نقل بيانات المستودع دون اتصال بالشبكة.
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 وv3. لا توجد طريقة Repository لاستيراد حزمة مجمّعة: اكتب packData() إلى .git/objects/pack/، وأنشئ فهرسها باستخدام PackIndexer::writeIndex()، ثم حدّث المراجع بنفسك.
تنسيق الحزم المجمّعة:
# v2 git bundle\n
-<prerequisite hash>\n (zero or more)
<hash> <refname>\n (one or more)
\n
<pack data> (standard pack file format)
تفيد الحزم المجمّعة في:
- النقل دون شبكة (محركات USB)
- النسخ الاحتياطية التدريجية
- تهيئة نسخ المستودعات في بيئات معزولة عن الشبكة
الاستنساخ السطحي
يدعم Pitmaster الاستنساخ السطحي، حيث لا يُجلب سوى عمق محدود من سجل الالتزامات.
use Pitmaster\Protocol\ShallowClone;
مرّر عمقًا إلى Pitmaster::clone($url, $path, $depth) أو $repo->fetch($remote, $depth). يضيف الطلب إمكانية shallow وسطر deepen:
want <hash>
deepen <depth>
يرد الخادم بأسطر shallow <hash> تشير إلى الموضع الذي اقتُطع عنده السجل. يحسب Pitmaster الحد السطحي من العمق نفسه، ويستخدم أسطر shallow من الخادم إذا لم يُفضِ هذا الحساب إلى نتيجة؛ وتُخزّن النتيجة في .git/shallow. يتعامل كل من ShallowClone::readShallow() وwriteShallow() وisShallow() مع هذا الملف مباشرةً.
مقارنة البروتوكولات
| البروتوكول | المصادقة | التشفير | الدفع | الاستخدام المعتاد |
|---|---|---|---|---|
| HTTP الذكي | بيانات اعتماد في URL | HTTPS | نعم | وسيلة النقل الأساسية |
| HTTP غير الذكي | بيانات اعتماد في URL | HTTPS | لا | خيار احتياطي قديم |
| SSH | مفاتيح SSH أو وكيل | SSH | نعم | المستودعات الخاصة وCI |
| Git (TCP) | لا شيء | لا شيء | لا | نسخ مطابقة للقراءة فقط |
| حزمة مجمّعة | لا ينطبق | لا ينطبق | لا ينطبق | النقل دون اتصال |
اختيار وسيلة النقل
يختار كل من Pitmaster::clone() و$repo->fetch() و$repo->push() وسيلة النقل من URL:
| نمط URL | وسيلة النقل |
|---|---|
ssh://... |
SSH |
user@host:path |
SSH |
أي شيء آخر (https://...، http://...) |
HTTP ذكي؛ يعود الاستنساخ والجلب إلى HTTP غير الذكي |
لا تدعم هذه الأساليب عناوين git:// والمسارات المحلية؛ إذ تُرسل إلى عميل HTTP الذكي وتفشل. استخدم GitProtocolClient مباشرةً من أجل git://. ويُخلط حاليًا بين HTTPS URL الذي يحتوي على مستخدم ومنفذ (https://user@host:8443/repo.git) وبين URL SSH (#17).