كانت ‘main’ branch مقبرة للأخطاء: كيف أنقذتنا خطافات Git (Git Hooks) من جحيم الإصلاحات التافهة؟

يا هلا بيكم يا جماعة الخير. اسمي أبو عمر، مطور برمجيات قضيت سنين عمري بين الأكواد والخوارزميات، وشفت من العجايب ما يكفي لكتابة مجلدات. اليوم بدي أحكيلكم قصة صارت معي ومع فريقي، قصة عن الإحباط واليأس، وكيف شعاع من نور الأتمتة أنقذنا من حفرة كنا نحفرها لأنفسنا كل يوم.

بتذكرها زي كأنه امبارح… كانت ليلة خميس، والكل بيستعد لعطلة نهاية الأسبوع. فجأة، رن جوالي. على الطرف الثاني كان صوت مدير المشروع، متوتر ومضغوط. “أبو عمر، الموقع واقع! في مشكلة كبيرة في الإنتاج والعملاء بشتكوا!”. يا ساتر! نزلت الكنافة من إيدي وركضت على اللابتوب. بعد ساعة من البحث والتحقيق والضغط النفسي، شو اكتشفنا؟

مطور جديد في الفريق، بحسن نية، كان بيعمل تعديل بسيط. لكنه نسي يمسح سطر console.log("test") من ملف JavaScript. هذا السطر، في بيئة الإنتاج مع متصفح قديم عند أحد العملاء الكبار، كان كفيل إنه يكسر الدنيا كلها ويعطل الموقع. المشكلة مش في المطور الجديد، كلنا بنغلط. المشكلة كانت فينا إحنا، في عمليتنا الهشة اللي سمحت لخطأ تافه زي هاد إنه يوصل للفرع الرئيسي (main branch) وينتشر للإنتاج.

في ذلك اليوم، بعد ما صلحنا المشكلة، عقدنا اجتماع طارئ. كان النقاش حاد: “لازم نراجع كل سطر كود!”، “لازم نعمل عشرين Pull Request review!”… كلها حلول بشرية، معرضة للخطأ والنسيان. وقتها، وقفت وحكيتلهم: “يا جماعة، الحل مش في زيادة الشغل اليدوي، الحل في أتمتة الدفاعات. لازم يكون عنا حارس بوابة يمنع هاي الأخطاء قبل ما تصير commit أصلاً”. ومن هنا، بدأت رحلتنا مع خطافات Git، أو الـ Git Hooks.

ما هي خطافات Git (Git Hooks) يا أبو عمر؟ وليش لازم نهتم؟

بكل بساطة، تخيل إن مستودع الكود (Git repository) تبعك هو بناية مهمة، والفرع الرئيسي main هو الخزنة اللي فيها كل الكنوز. خطافات Git هي الحراس اللي واقفين على كل باب وفي كل ممر. هم عبارة عن سكربتات (scripts) برمجية بتشتغل تلقائياً عند نقاط معينة في عملية Git.

عندما تحاول تعمل git commit، بيشتغل حارس. عندما تحاول تعمل git push، بيشتغل حارس ثاني. لو الحارس شاف إنه في إشي غلط (مثلاً، كود لا يتبع معايير الجودة، أو فيه أخطاء واضحة)، بيمنع العملية وبيقولك: “لو سمحت، ارجع صلح شغلك قبل ما تفوت!”.

هناك نوعان رئيسيان من الخطافات:

  • خطافات العميل (Client-Side Hooks): بتشتغل على جهازك الشخصي. هاي هي اللي رح نركز عليها اليوم، لأنها خط الدفاع الأول. أمثلتها: pre-commit, prepare-commit-msg, pre-push.
  • خطافات الخادم (Server-Side Hooks): بتشتغل على الخادم اللي مستضيف الـ repository (مثل GitHub أو GitLab). هاي مفيدة لفرض سياسات على مستوى الفريق كله، مثل منع الـ force push على فروع معينة.

بطل القصة: خطاف الـ pre-commit

من بين كل الخطافات، في واحد هو البطل الحقيقي لقصتنا: خطاف الـ pre-commit. هذا الخطاف هو الحارس اللي بيوقف على باب الـ commit. بيشتغل قبل ما Git يقوم بإنشاء الـ commit. إذا نجح السكربت تبع الخطاف، بتكمل عملية الـ commit. إذا فشل، بتتوقف العملية كلها، ولا يتم إنشاء أي commit، وبيعطيك رسالة بالخطأ.

طيب، شو ممكن نعمل فيه؟ (أمثلة عملية)

الجميل في الـ pre-commit هو إنه ممكن يعمل أي إشي بتقدر تبرمجه في سكربت. هاي بعض الاستخدامات اللي غيرت حياتنا:

  1. فحص جودة وتنسيق الكود (Linting & Formatting): هاي أهم شغلة. بنشغل أدوات مثل ESLint (لـ JavaScript) أو Flake8 (لـ Python) للتأكد من خلو الكود من الأخطاء الشائعة، وأدوات مثل Prettier أو Black لإعادة تنسيق الكود تلقائياً عشان كل الكود في المشروع يكون بنفس الشكل. وداعاً للنقاشات البيزنطية حول المسافات والفواصل!
  2. منع إضافة الأسرار (Secrets): كم مرة سمعت عن مطور بالغلط رفع مفتاح API أو كلمة سر على GitHub؟ باستخدام أدوات مثل trufflehog أو gitleaks في الـ pre-commit hook، بنقدر نعمل فحص تلقائي يمنع هاي الكارثة قبل وقوعها.
  3. تشغيل الاختبارات الوحدوية السريعة (Unit Tests): ممكن تشغل مجموعة من الاختبارات الأساسية للتأكد من إنك ما كسرت إشي موجود. (نصيحة: الاختبارات الطويلة خليها لخطاف الـ pre-push أو لـ CI/CD server).
  4. فحص صيغة رسائل الـ Commit: ممكن تفرض على الفريق يكتب رسائل commit واضحة وذات صيغة محددة (مثل Conventional Commits) عشان يكون تاريخ المشروع سهل القراءة والفهم.

يلا نشتغل: كيف نفعّل أول خطاف Git إلنا؟ (الطريقة اليدوية)

عشان تفهم المبدأ، خلينا نعمل أول خطاف بإيدينا. الموضوع أسهل مما بتتخيل.

في أي مستودع Git عندك، في مجلد مخفي اسمه .git. جواته في مجلد اسمه hooks. هذا المجلد بيحتوي على أمثلة لخطافات، كلها بتنتهي بـ .sample. عشان تفعّل أي واحد فيهم، كل اللي عليك تعمله هو إنك تشيل الـ .sample من اسمه.

خلينا نعمل خطاف pre-commit بسيط بيمنعنا من إضافة console.log في ملفات JavaScript.

  1. اذهب إلى مجلد المشروع في الـ terminal.
  2. أنشئ ملف جديد: touch .git/hooks/pre-commit
  3. اجعل الملف قابل للتنفيذ: chmod +x .git/hooks/pre-commit
  4. افتح الملف بأي محرر نصوص والصق الكود التالي:
#!/bin/sh

echo "تشغيل خطاف الـ pre-commit..."

# ابحث عن ملفات JavaScript المعدّلة (staged) التي تحتوي على "console.log"
# git diff --cached بيفحص فقط الملفات اللي أنت عملتلها "git add"
STAGED_JS_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".js$")

if [ -z "$STAGED_JS_FILES" ]; then
    exit 0 # لا يوجد ملفات JS، استمر
fi

# تحقق من وجود "console.log" في هذه الملفات
if grep -q "console.log" $STAGED_JS_FILES; then
    echo "🚫 خطأ: تم العثور على 'console.log' في أحد الملفات."
    echo "الرجاء إزالته قبل تنفيذ الـ commit."
    exit 1 # فشل الخطاف، أوقف الـ commit
fi

echo "✅ تمام، الأمور طيبة. استمر!"
exit 0 # نجاح الخطاف، اسمح بالـ commit

الآن، جرب تعدل أي ملف JavaScript، ضيف فيه سطر console.log("hello");، ثم نفذ git add . و git commit -m "test". رح تشوف كيف الخطاف رح يشتغل ويمنعك من إكمال العملية! سحر، مش هيك؟

الطريقة اليدوية منيحة، بس مش عملية… خلينا نصير محترفين!

الطريقة اليدوية ممتازة عشان نتعلم، لكنها بتعاني من مشكلة كبيرة: مجلد .git لا يتم إضافته لنظام إدارة الإصدارات. هذا يعني إن الخطافات اللي بتعملها رح تضل على جهازك فقط، وما رح تتشارك مع باقي الفريق. وهيك بنرجع لنفس المشكلة.

وهنا يأتي دور الأدوات الاحترافية اللي بتدير هاي العملية.

أهلاً وسهلاً في pre-commit: الأداة السحرية

pre-commit هي أداة مكتوبة بلغة Python (لكنها بتشتغل مع أي لغة برمجة) بتحل كل مشاكل الطريقة اليدوية. هي عبارة عن إطار عمل (framework) لإدارة الخطافات.

نصيحة أبو عمر: لا تخلط بين “خطاف الـ pre-commit” كحدث في Git، وبين “أداة pre-commit” كإطار عمل. الأداة بتساعدك تدير الحدث.

ليش هي سحرية؟

  • ملف إعدادات مركزي: كل إعدادات الخطافات بتنحط في ملف واحد اسمه .pre-commit-config.yaml. هذا الملف بتعمله commit وبترفعوا مع المشروع، فكل الفريق بيستخدم نفس الإعدادات.
  • إدارة تلقائية للأدوات: هل خطافك بيحتاج أداة Black (لـ Python) وخطاف ثاني بيحتاج Prettier (لـ JavaScript)؟ ما في مشكلة. أداة pre-commit بتنزل هاي الأدوات وبتديرها في بيئات معزولة بدون ما تلوث جهازك.
  • مكتبة ضخمة من الخطافات الجاهزة: في آلاف الخطافات الجاهزة اللي عملوها مطورين ثانيين. كل اللي عليك تعمله هو إنك تضيفها لملف الإعدادات.

كيف نستخدمها؟

  1. التثبيت: (تحتاج Python مثبت على جهازك)
    pip install pre-commit
  2. إنشاء ملف الإعدادات: في جذر مشروعك، أنشئ ملف اسمه .pre-commit-config.yaml.
  3. إضافة الخطافات: الصق هذا المثال كبداية في الملف. هذا المثال بيصلح المسافات الزائدة، وبيفحص ملفات YAML، وبيشغل فورماتر لـ Python و JavaScript.
    # .pre-commit-config.yaml
    repos:
    -   repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v4.5.0
        hooks:
        -   id: trailing-whitespace # يزيل المسافات في نهاية السطر
        -   id: end-of-file-fixer # يتأكد من وجود سطر فارغ في نهاية الملف
        -   id: check-yaml # يفحص صحة ملفات YAML
        -   id: check-added-large-files # يمنع إضافة ملفات كبيرة الحجم
        -   id: check-merge-conflict # يمنع عمل commit لملفات فيها conflict markers
    
    -   repo: https://github.com/psf/black
        rev: 24.4.2
        hooks:
        -   id: black # فورماتر للغة بايثون
    
    -   repo: https://github.com/prettier/prettier
        rev: 3.2.5
        hooks:
        -   id: prettier # فورماتر للويب (JS, HTML, CSS, JSON, ...)
    
  4. تثبيت الخطافات في مستودعك المحلي:
    pre-commit install

    هذا الأمر مرة واحدة لكل مشروع. هو اللي بيربط أداة pre-commit بحدث .git/hooks/pre-commit الفعلي.

وهيك خلصنا! الآن، في كل مرة أي مطور في الفريق (بعد ما ينفذ الخطوتين 1 و 4) بيحاول يعمل git commit، رح تشتغل هاي الخطافات تلقائياً. إذا الكود مش منسق، رح يتم تنسيقه تلقائياً. إذا في مشكلة، رح يتوقف الـ commit مع رسالة واضحة. يا سلام على الروقان!

الخلاصة: نصيحة من أخوك أبو عمر 👨‍💻

يا جماعة، البرمجة مش بس كتابة كود، البرمجة هي بناء أنظمة وعمليات مستدامة. قصة “الـ main branch مقبرة الأخطاء” انتهت في فريقنا من اليوم اللي اعتمدنا فيه خطافات Git بشكل جدي. تحولنا من فريق إطفاء حرائق إلى فريق بناء صواريخ.

الاستثمار في الأتمتة في البداية قد يبدو وكأنه عمل إضافي، لكن صدقني، الساعات القليلة اللي رح تقضيها في إعداد pre-commit رح توفر عليك وعلى فريقك مئات الساعات من تصحيح الأخطاء التافهة، والنقاشات غير المجدية، والإحباط. أنت بتبرمج جهازك عشان يحميك من نفسك ومن زلاتك البشرية.

نصيحتي الأخيرة: لا تنتظر حتى تحترق أصابعك. ابدأ اليوم. افتح مشروعك، طبق الخطوات اللي حكيناها، وشاركها مع فريقك. اجعلوا الجودة والأتمتة جزءاً لا يتجزأ من ثقافتكم. صدقني، رح تدعيلي. 😉

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

نصائح برمجية

كانت كل إعادة محاولة كارثة جديدة: كيف أنقذتنا مفاتيح عدم التكرار (Idempotency Keys) من جحيم العمليات المكررة؟

أشارككم قصة حقيقية من قلب المعركة البرمجية، حين كادت عمليات الدفع المكررة أن تدمر مشروعاً كاملاً. سنتعلم سوياً عن مفهوم "عدم التكرار" (Idempotency) وكيف يمكن...

3 يونيو، 2026 قراءة المزيد
تسويق رقمي

كانت نقرة العميل الأخيرة هي كل ما نراه: كيف أنقذنا بناء نموذج العزو الخاص بنا من جحيم إهدار الميزانية التسويقية؟

أشارككم قصة حقيقية من واقع عملي كمبرمج، عن اللحظة التي كاد فيها اعتمادنا الأعمى على نموذج "النقرة الأخيرة" أن يودي بميزانيتنا التسويقية إلى الهاوية. اكتشفوا...

3 يونيو، 2026 قراءة المزيد
تجربة المستخدم والابداع البصري

كان كل زر قصة مختلفة: كيف أنقذنا ‘نظام التصميم’ (Design System) من جحيم الفوضى البصرية؟

من الفوضى البصرية إلى الانسجام الرقمي، هذه قصتنا مع 'نظام التصميم'. أشارككم رحلتنا العملية، بالأمثلة والنصائح، لبناء نظام تصميم ينقذ مشاريعكم من جحيم عدم الاتساق...

3 يونيو، 2026 قراءة المزيد
برمجة وقواعد بيانات

كانت استعلاماتنا تزحف: كيف أنقذت الفهارس (Database Indexes) قاعدة بياناتنا من جحيم المسح الكامل للجداول؟

في هذه المقالة، أشارككم قصة حقيقية من الميدان حول كيف تحولت استعلاماتنا من بطء قاتل إلى سرعة البرق. سنغوص في عالم فهارس قواعد البيانات (Database...

3 يونيو، 2026 قراءة المزيد
البودكاست