٨، ٣، خطاطيف جت

لدى جت، مثل أنظمة إدارة نسخ كثيرة أخرى، طريقة لتشغيل بُرَيْمِجات (scripts) مخصصة عند أحداث معينة مهمة. وتسمى الخطاطيف، وتقسم نوعين: خطاطيف عند العميل، وخطاطيف على الخادوم. تستثير خطاطيفَ العميل عملياتٌ مثل الإيداع والدمج، أما خطاطيفَ الخادوم فالعملياتُ الشبكية مثل استقبال الإيداعات المدفوعة. ويمكنك استخدام الخطاطيف لأسباب عديدة مختلفة.

تركيب خطاف

تحفظ جميع الخطاطيف في مجلد hooks داخل مجلد جت. أي في .git/hooks في معظم المستودعات. وعندما تبتدئ مستودعًا جديدًا بأمر الابتداء git init، فإن جت يملأ مجلد الخطاطيف بأمثلة بُريمجات (التي قد يفيد بعضها بلا تغيير)، وفيها شرح مدخلات كل بريمج. أكثر الأمثلة مكتوبة بلغة الصدَفة (shell)، والبعض بلغة Perl. ولكن أي ملف تنفيذي بالاسم المناسب سيعمل؛ اكتبه بـ Python أو بـ Ruby أو بما تشاء. وإذا أردت استعمال بُريمجات الخطاطيف المرفقة مع جت، عليك تغيير أسمائها، فأسماؤها جميعًا تنتهي بالامتداد .sample.

لتفعيل بُريمج خطاف، ضع ملفًا تنفيذيًّا بالاسم المناسب (بغير امتداد) في مجلد hooks في مجلد .git في مستودعك، ومن وقتئذٍ فصاعدًا سيُنفّذ. نمرّ الآن على أهم الخطاطيف ونسرد أسماءها.

خطاطيف العميل

خطاطيف كثيرة تُنفّذ عند العميل. يقسمهم هذا الفصل إلى أقسام ثلاثة لتيسير الشرح: خطاطيف الإيداع، وخطاطيف البريد، والخطاطيف الأخرى.

مهم جدا أن تعلم أن خطاطيف العميل ليست تُنسخ عند استنساخ المستودع. فإذا كان مرادك من هذه البُريمجات أن تفرض سياسات معينة، فربما تفضّل فعل هذا على الخادوم؛ انظر المثال في فصل مثال لفرض السياسات في جت.

خطاطيف الإيداع

الخطاطيف الأربعة الأولى تخص عملية الإيداع.

يعمل خطاف ما قبل الإيداع (pre-commit) أولا، حتى قبل أن تكتب رسالة الإيداع. ويُستعمل لفحص اللقطة التي ستودعها للتأكد من أنك لم تنسَ شيئًا، أو للتأكد من أنك نفّذت الاختبارات، أو للتأكد مما تريد التأكد منه عمومًا. وإنهاء تنفيذ هذا البُريمج بقيمة خروج غير الصفر يوقف الإيداع، على أنك تستطيع تخطيه بالأمر git commit --no-verify. يمكّنك هذا من تنسيق المصدر البرمجي (مثل تنفيذ lint أو ما يكافئه)، أو التأكد من عدم انتهاء السطور بمسافات زائدة (وهذا ما يفعله المثال الآتي مع جت)، أو فحص وجود التوثيق المناسب للدوال الجديدة.

أما خطاف تجهيز رسالة الإيداع (prepare-commit-msg) فيعمل قبل فتح محرر رسالة الإيداع ولكن بعد إنشاء الرسالة المبدئية، حتى يتيح لك تعديل الرسالة المبدئية قبل أن يراها صانع الإيداع. ويُرسل إلى هذا الخطاف ثلاثة معاملات: مسار الملف المؤقت الذي فيه رسالة الإيداع، ونوع الإيداع، وبصمة SHA-1 للإيداع إذا كان إيداعًا مصحّحًا (أي مودَع بالخيار --amend). وعمومًا ليس هذا الخطاف كبير النفع للإيداعات العادية، لكنه يفيد الإيداعات التي رسالتها المبدئية مولدة آليًّا، مثل قوالب رسائل الإيداع، وإيداعات الدمج، والإيداعات المهروسة (‪“squashed”‬)، والإيداعات المصححة (‪“amended”‬). وقد تستخدمه مع قالب رسالة إيداع لإدراج معلومات فيها برمجيًّا.

وأما خطاف رسالة الإيداع (commit-msg) فيقبل معاملًا واحدًا، وهو كذلك مسار الملف المؤقت الذي فيه رسالة الإيداع التي كتبها المطوّر. وإن أنهى تنفيذه بقيمة خروج غير الصفر فإن جت يوقف الإيداع. فيمكنك إذًا استخدامه لتحقق حالة مشروعك أو رسالة الإيداع قبل السماح للإيداع بأن يتم. وسنرى في الفصل الأخير من هذا الباب شرح مثال لاستعمال هذا الخطاف لتحقُّق موافقة رسائل الإيداع لنمط محدد.

أما خطاف ما بعد الإيداع (post-commit) فيعمل بعد تمام عملية الإيداع بكاملها. ولا يقبل أي معاملات. لكن يمكن جلب الإيداع الأخير بسهولة بالأمر git log -1 HEAD. وعموما يُستعمل هذا البُريمج للإعلامات أو ما يشابهها.

خطاطيف البريد

يمكنك إعداد خطاطيف ثلاثة لأساليب التطوير المعتمدة على البريد. جميعها يناديها أمر تطبيق الرقع البريدية git am، فإذا لم يكن هذا الأم‍ر في أسلوب التطوير الذي تتبعه فانتقل إلى الفصل التالي. أما إذا كنت تقبل الرقع المُعدَّة بالأمر git format-patch عبر البريد الشابكي، فقد يفيدك بعضها.

أول خطاف ينفّذ هو خطاف رسالة الرقعة (applypatch-msg). ويقبل معاملًا واحدًا هو مسار الملف المؤقت الذي فيه رسالة الإيداع المقترحة. وإنهاء تنفيذه بقيمة خروج غير الصفر يوقف الرقعة. فيمكنك استعماله للتأكد من أن رسالة الإيداع صحيحة التنسيق، أو لاستنظام (normalize) الرسالة بتعديلها في مكانها.

والتالي هو خطاف ما قبل إيداع الرقعة (pre-applypatch). وقد يسبب اللبس أنه، خلافًا لاسمه الأصلي بالإنجليزية، يعمل بعد تطبيق الرقعة ولكن قبل صنع الإيداع، فيمكنك استعماله لفحص اللقطة قبل إيداعها. فيمكنك فيه تنفيذ الاختبارات أو فحص شجرة العمل أو غير ذلك. وإن افتقدت شيئًا أو فشل اختبار، فإن إنهاء تنفيذ هذا البُريمج بقيمة خروج غير الصفر يوقف أمر git am بغير إيداع الرقعة.

أما خطاف ما بعد إيداع الرقعة (post-applypatch) فهو الخطاف الأخير الذي ينفَّذ عند تطبيق رقعة بريدية بالأمر git am، وينفَّذ بعد صنع الإيداع. فيمكنك استعماله لإعلام صاحب الرقعة أو غيره بإتمام إيداعها. ولا يمكنك إيقاف الرقعة بهذا البُريمج.

خطاطيف العميل الأخرى

ينفَّذ خطاف ما قبل إعادة التأسيس (pre-rebase) قبل إعادة تأسيس أي شيء، ويمكنه إيقاف العملية بإنهاء تنفيذه بقيمة خروج غير الصفر. فيمكنك استعماله لمنع إعادة تأسيس أي إيداعات قد دُفعت. البُريمج المثال المرفق مع جت يفعل هذا، إلا أنه يفترض بعض الأمور التي قد لا توافق أسلوب عملك.

أما خطاف ما بعد التحرير (post-rewrite) فتنفِّذه الأوامر التي تبدّل الإيداعات، مثل أم‍ر تصحيح الإيداع git commit --amend وأم‍ر إعادة التأسيس git rebase (لكن ليس أم‍ر معالجة الفروع git filter-branch). مُعامِله الوحيد هو الأمر الذي سبّب التحرير، ويستقبل قائمة بالتحريرات على المَدخل المعياري (stdin). معظم استعمالات هذا الخطاف مثل خطافَيْ post-checkout و post-merge التاليين.

بعد نجاح أمر السحب، ينفّذ خطاف ما بعد السحب (post-checkout). يمكنك استعماله لإعداد مجلد عملك ليناسب بيئة مشروعك. قد يعني هذا مثلا أن تنقل إليه ملفات رقْمية كبيرة لا تريدها في تاريخ المستودع، أو أن توّلد الوثائق، أو شيئًا من هذا القبيل.

أما خطاف ما بعد الدمج (post-merge) فينفَّذ بعد نجاح أمر الدمج. فيمكنك استعماله لكي تستعيد إلى مجلد العمل البيانات التي لا يسجلها جت، مثل أذونات الملفات. ويمكنه كذلك تحقّق وجود ملفات معينة يتجاهلها جت وتريدها عندما يتبدّل مجلد العمل.

ويعمل خطاف ما قبل الدفع (pre-push) عند تنفيذ أمر الدفع، بعد تحديث الإشارات البعيدة لكن قبل نقل أي كائن. يستقبل مُعامِلين هما اسم البعيد المدفوع إليه، ورابطه، ويستقبل من المدخل المعياري قائمة من الإشارات التي ستُحدَّث. يمكنك استعماله لتحقق تحديثات الإشارات قبل إتمام الدفع، فإن إنهاء تنفيذه بقيمة خروج غير الصفر يوقف الدفع.

خلال عمل جت أحيانا يحتاج تنظيف سجلاته الخاصة بالمستودع، فينفّذ جت أمر التنظيف الآلي git gc --auto، الذي ينظّم الملفات الداخلية للمستودع ويحذف المهملات. (gc اختصار ‪“garbage collection”‬ («جمع المهملات»).) ينفَّذ خطاف ما قبل التنظيف الآلي (pre-auto-gc) قُبَيل بدء التنظيف الآلي، ليُخبرك مثلًا بحدوثه، أو ليمنعه إن لم يمكن الوقت مناسبًا لذلك.

خطاطيف الخادوم

بالإضافة إلى الخطاطيف التي تنفّذ عند العميل، يمكنك استخدام الخطاطيف التي تنفّذ على الخادوم، إذا كنت مدير أنظمة، حتى تنْفِذ سياسات مشروعك المختارة. وتعمل هذه البُريمجات قبل الدفع إلى خادومك وبعده. فتستطيع الخطاطيف «القَبْلية» رفض الدفع بأن تنهي تنفيذها بقيمة خروج غير الصفر في أي وقت، ثم تطبع رسالة خطأ إلى العميل. ويمكنك إعداد سياسة دفع سهلة أو معقدة كما تشاء.

خطاف ما قبل الاستلام pre-receive

أول بُريمج يعمل عند استقبال دفع من عميل هو خطاف ما قبل الاستلام (pre-receive). ويقرأ من المَدخل المعياري (stdin) قائمةَ الإشارات التي تُدفع. فإذا أنهى تنفيذه بقيمة خروج غير الصفر، لم تُقبل أيٌّ منهم. فيمكنك استعماله مثلًا للتحقُّق أن الإشارات المحدّثة جميعها إيداعات تسريع، أو لتحقُّق صلاحيات الوصول للإشارات والملفات التي تعدلها إيداعات هذا الدفع.

خطاف التحديث update

خطاف التحديث (update) يشبه كثيرا خطاف ما قبل الاستلام (pre-receive)، إلا أنه ينفّذ مرة لكل فرع يريد تحديثه الذي يدفع. فإن كان يدفع إلى عدة فروع، فإن خطاف ما قبل الاستلام (pre-receive) سينفّذ مرة واحدة فقط، أما خطاف التحديث (update) سينفّذ م‍رة لكل فرع يدفع إليه. وبدلًا من القراءة من المدخل المعياري، فإنه يقبل ثلاثة معاملات: اسم الإشارة (الفرع)، وبصمة SHA-1 التي كانت تشير إليها الإشارة قبل الدفع، وبصمة SHA-1 التي يريد المستخدم دفعها. فإذا أنهي البُريمج تنفيذه بقيمة خروج غير الصفر، فستُرفض هذه الإشارة وحدها. أما الإشارات الأخرى فلن تتأثر به وقد تقبل.

خطاف ما بعد الاستلام post-receive

أما خطاف ما بعد الاستلام (post-receive) فيعمل بعد تمام العملية بكاملها، ويُستعمل لتحديث الخدمات الأخرى أو إعلام المستخدمين. ويقرأ المعطيات نفسها من المدخل المعياري مثل خطاف ما قبل الاستلام (pre-receive) تماما. يمكن استعماله لإرسال بريد شابكي إلى قائمة بريدية، أو تنبيه خادوم دمج مستمر (CI)، أو تحديث نظام متابعة مسائل. فيمكنك تحليل رسائل الإيداع برمجيًّا لتعلم إن كانت مسألةٌ ما تحتاج إلى الفتح أو التعديل أو الغلق. لن يُوقف هذا البريمج عمليةَ الدفع، لكن لن يقطع العميل اتصاله إلا عندما يتنهي، فاحذر أن تفعل شيئًا قد يستغرق وقتًا طويلًا.

إذا كنت تكتب بُريمج خطاف سيقرؤه الآخرون، فعليك بالخيارات الطويلة للأوامر؛ سوف تشكرنا بعد شهور من الآن.

البرشامة في الخطاطيف (Cheatsheet)

هذا مرجع موجز لجميع الخطاطيف المشروحة. (من إضافة المترجم.)

خطاطيف أمر الإيداع git commit

  1. خطاف ما قبل الإيداع pre-commit:
    قبل رسالة الإيداع، لفحص اللقطة المودعة. قد يوقف الإيداع.

  2. خطاف تجهيز رسالة الإيداع prepare-commit-msg:
    قبل فتح المحرر لكن بعد إنشاء الرسالة المبدئية، لتعديلها.

  3. خطاف رسالة الإيداع commit-msg:
    بعد الفراغ من تحرير رسالة الإيداع، لمراجعتها. قد يوقف الإيداع.

  4. خطاف ما بعد الإيداع post-commit:
    بعد إتمام عملية الإيداع بكاملها، للإعلامات وما يشابهها.

خطاطيف أمر تطبيق الرقع البريدية git am

  1. خطاف رسالة الرقعة applypatch-msg:
    عند البدء، لمراجعة رسالة الرقعة أو تعديلها. قد يوقف تطبيق الرقعة.

  2. خطاف ما قبل إيداع الرقعة pre-applypatch (اسمه الإنجليزي خادع):
    بعد تطبيق الرقعة وقبل إيداعها، لفحص اللقطة قبل إيداعها. قد يوقف الإيداع.

  3. خطاف ما بعد إيداع الرقعة post-applypatch:
    بعد الإيداع، للإعلامات وما يشابهها.

خطاطيف العميل الأخرى

  • خطاف ما قبل إعادة التأسيس pre-rebase:
    قبل إعادة تأسيس أي شيء. قد يوقف العملية.

  • خطاف ما بعد التحرير post-rewrite:
    بعد تحرير الإيداعات. يستعمل لتجهيز مجلد العمل.

  • خطاف ما بعد السحب post-checkout:
    بعد نجاح أمر السحب. يستعمل لتجهيز مجلد العمل.

  • خطاف ما بعد الدمج post-merge:
    بعد نجاح أمر الدمج. يستعمل لتجهيز مجلد العمل.

  • خطاف ما قبل الدفع pre-push:
    عند بدء تنفيذ أمر الدفع، بعد تحديث الإشارات وقبل نقل شيء. يستعمل لمراجعة ما سيُدفع. قد يوقف الدفع.

  • خطاف ما قبل التنظيف الآلي pre-auto-gc (تنظيم بيانات جت وجمع المهملات منها):
    قُبَيل بدء التنظيف الآلي، للإعلام به أو منعه عند الحاجة.

خطاطيف الخادوم

  1. خطاف ما قبل الاستلام pre-receive:
    عند الدفع إلى الخادوم، ينفّذ مرة واحدة للدفع كله، ليراجع جميع الإشارات المدفوعة. قد يوقف الدفع.

  2. خطاف التحديث update:
    عند الدفع إلى الخادوم، ينفّذ مرة لكل فرع مدفوع إليه، ليراجع جميع الإشارات المدفوعة إليه. قد يوقف الدفع إلى هذا الفرع وحده.

  3. خطاف ما بعد الاستلام post-receive:
    بعد نجاح الدفع إلى الخادوم، لتحديث الخدمات أو للإعلامات. يبقى العميل متصلًا حتى ينتهي هذا الخطاف.