انتقل إلى المحتوى

البروتوكولات

يدعم 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.

PHP
use Pitmaster\Protocol\SmartHttpClient;

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

راجع HTTP الذكي للاطلاع على التفاصيل كاملة.

البروتوكول v1

بروتوكول HTTP الذكي التقليدي. تُرسل كل المراجع أثناء الاكتشاف، ويستخدم التفاوض أسطر المطلوب والمتاح والانتهاء.

PHP
use Pitmaster\Protocol\ProtocolV1;

البروتوكول v2

بروتوكول أحدث بأوامر منظمة (ls-refs، fetch). أكثر كفاءة للمستودعات التي تضم مراجع كثيرة، إذ يمكن للعميل تصفية قائمة المراجع.

يستخدم clone() وfetch() البروتوكول v1 دائمًا. يتوفر البروتوكول v2 صراحةً عبر HTTP الذكي من خلال SmartHttpClient::discoverRefsV2() وUploadPackClient::fetchV2().

HTTP غير الذكي

خيار احتياطي للخوادم التي لا تدعم بروتوكول HTTP الذكي. يجلب البروتوكول غير الذكي الكائنات والحزم كلًا على حدة عبر طلبات GET عادية باستخدام HTTP.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

قيود HTTP غير الذكي:

  • لا يوجد تفاوض (على العميل تنزيل كل شيء)
  • لا يوجد ضغط دلتا أثناء النقل
  • أبطأ بكثير من HTTP الذكي
  • بعض الخوادم (GitHub وGitLab) لا تدعمه

يجلب البروتوكول غير الذكي ما يلي:

  1. GET /info/refs (نص عادي، بلا pkt-line)
  2. GET /HEAD (الفرع الافتراضي)
  3. GET /objects/info/packs (قائمة بالحزم المتاحة)
  4. GET /objects/pack/pack-<hash>.pack و.idx (كل حزمة مدرجة وفهرسها)
  5. 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 على المستودع البعيد.

PHP
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:// إليه، لذا استخدم العميل مباشرةً.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

عناوين Git:

الكود
git://github.com/user/repo.git

الخصائص:

  • لا توجد مصادقة (للقراءة فقط عمليًا)
  • لا يوجد تشفير
  • أوقف معظم مزودي الاستضافة استخدامه
  • يستخدم تأطير pkt-line نفسه الذي يستخدمه HTTP الذكي

يرسل بروتوكول git اسم الخدمة ومسار المستودع في الطلب الأولي، ثم يتابع باكتشاف المراجع والتفاوض على الحزم باستخدام pkt-line القياسي.

الحزم المجمّعة

حزم Git المجمّعة ملفات حزم للاستخدام دون اتصال، تتضمن معلومات المراجع. وتتيح نقل بيانات المستودع دون اتصال بالشبكة.

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 ترويسات الحزم المجمّعة 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 الاستنساخ السطحي، حيث لا يُجلب سوى عمق محدود من سجل الالتزامات.

PHP
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).