يا جماعة الخير، السلام عليكم ورحمة الله. اسمي أبو عمر، مبرمج فلسطيني قضيت سنين عمري بين الأكواد والخوارزميات، وشفت العجب العجاب في عالم التقنية. اليوم بدي أحكيلكم قصة من قلب المعاناة، قصة كانت تتكرر مع كل إصدار جديد للبرنامج، قصة كانت نهايتها دائماً دموع وإحباط… لحد ما لقينا الحل.
بتذكرها زي كأنها مبارح. ليلة خميس، الساعة وحدة بعد نص الليل، وكنا بنجهز لإطلاق نسخة جديدة من نظام كبير بنشتغل عليه. الأكواد جاهزة، الاختبارات (Tests) كلها ناجحة، والكل متحمس… إلا من شغلة وحدة: كتابة سجل التغييرات (Changelog). المدير التقني بطلع فيي وبحكيلي: “أبو عمر، جهّز النا الـ Release Notes عشان نبعتها للعملاء بكرة الصبح”.
وقتها حسيت كأن حدا كبّ عليّ مي باردة. فتحت الـ git log عشان أشوف شو التغييرات اللي صارت خلال الأسبوعين الماضيين، وكانت الصدمة. الشاشة قدامي مليانة برسائل زي هيك:
- “fix”
- “update code”
- “WIP”
- “stuff”
- “แก้บั๊ก” (حتى واحد من الزملاء كتب بلغة ما حدا فينا بفهمها!)
- “merge branch ‘dev'”
يا زلمة شو هاد؟ جحيم! كيف بدي أعرف من هاي “الطلاسم” شو الميزات الجديدة اللي انضافت؟ شو الأخطاء اللي تصلحت؟ مين عمل شو؟ ولعت بيني وبين باقي الفريق، وكل واحد يرمي المسؤولية على الثاني. قضينا ساعتين زيادة بس وإحنا بنحاول “ننبش” في التاريخ تبع Git ونفتح كل commit عشان نفهم شو قصته. كانت عملية يدوية، مملة، ومليانة أخطاء. في هذيك الليلة، سجل التغييرات انكتب فعلاً بالدموع والتعب. وقتها حلفت يمين إننا لازم نلاقي طريقة أفضل.
الفوضى المنظمة: ليش رسائل الـ Commit مهمة أصلاً؟
قبل ما نحكي عن الحل، خلينا نتفق على المشكلة. رسالة الـ commit مش مجرد “توثيق” للي عملته وخلص. هي حجر الأساس للتواصل داخل فريق التطوير، وهي السجل التاريخي لمشروعك. لما تكون رسائل الـ commit فوضوية، إنت مش بس بتصعّب كتابة سجل التغييرات، إنت بتخلق مشاكل أكبر:
- صعوبة تتبع الأخطاء (Debugging): لما يظهر bug جديد، أول إشي بنعمله هو استخدام
git bisectأو بنرجع لتاريخ الملف عشان نشوف مين آخر واحد عدّل عليه وليش. إذا كانت الرسالة “update”، الله يعينك. - صعوبة مراجعة الكود (Code Review): المراجع (reviewer) بيحتاج يفهم “ليش” التغيير هاد صار، مش بس “شو” هو التغيير. رسالة commit واضحة بتعطي سياق وتوفر وقت طويل في النقاش.
- فقدان المعرفة: المبرمجين بييجوا وبروحوا، لكن الكود بضل. رسائل الـ commit هي اللي بتحفظ “ذاكرة” المشروع وبتشرح القرارات اللي اتاخدت في الماضي.
باختصار، تاريخ Git الفوضوي هو دين تقني (Technical Debt) عالي الفائدة. كل يوم بتتركه بدون حل، كل يوم بتدفع الثمن غالي من وقتك وجهدك وصحتك النفسية.
المنقذ وصل: ما هي “الالتزامات التقليدية” (Conventional Commits)؟
بعد ليلة الجحيم هذيك، قعدت أبحث ولقيت كنز اسمه Conventional Commits. هي مش أداة سحرية أو مكتبة برمجية معقدة، هي ببساطة عبارة عن “اتفاقية” أو “مواصفات” خفيفة لكتابة رسائل Git بطريقة منظمة وموحدة يفهمها البشر والآلات على حد سواء.
الفكرة بسيطة جداً. كل رسالة commit لازم تتبع هاد الشكل:
<type>[optional scope]: <description>
[optional body]
[optional footer]
خلينا نفصّلها حبة حبة…
تشريح الالتزام التقليدي
1. النوع (Type)
هاي أهم جزئية. هي كلمة مفتاحية بتوصف “نوع” التغيير اللي عملته. أشهر الأنواع هي:
feat: اختصار لـ “Feature”. بتستخدمها لما تضيف ميزة جديدة للمستخدم النهائي. (هذا النوع هو اللي بيظهر في سجل التغييرات كـ “New Features”).fix: لما تصلح خطأ أو bug في الكود. (هذا النوع بيظهر كـ “Bug Fixes”).docs: أي تغييرات على ملفات التوثيق (زي ملف README).style: تغييرات ما بتأثر على معنى الكود، زي تنسيق، فواصل منقوطة، مسافات…إلخ.refactor: إعادة صياغة للكود بدون تغيير وظيفته الظاهرية. مثلاً تحسين الأداء أو تبسيط الكود.perf: تغيير في الكود يحسن الأداء (Performance).test: إضافة اختبارات جديدة أو تعديل الاختبارات الموجودة.build: تغييرات بتأثر على نظام البناء (Build system) أو الاعتماديات الخارجية (مثل npm).ci: تغييرات على ملفات وإعدادات الـ CI/CD (مثل Github Actions).chore: مهام أخرى ما بتدخل ضمن التصنيفات اللي فوق، زي تحديث ملف.gitignore.
2. النطاق (Scope) – اختياري
كلمة اختيارية بتحطها بين قوسين عشان تحدد أي جزء من المشروع تأثر بهذا التغيير. مفيدة جداً في المشاريع الكبيرة أو الـ Monorepos. مثلاً: api, auth, ui.
3. الوصف (Description)
جملة قصيرة وواضحة بتوصف التغيير. القاعدة الذهبية هون: اكتبها بصيغة الأمر (Imperative mood)، كأنك بتعطي أمر لـ Git. مثلاً: “Add login functionality” مش “Added login functionality”.
4. الجسم (Body) – اختياري
فقرة أو أكتر بتشرح فيها “السبب” وراء التغيير. شو كانت المشكلة؟ وكيف حليتها؟ هون المكان اللي بتفصّل فيه.
5. التذييل (Footer) – اختياري
هون بنحط معلومات إضافية مهمة. أهم استخدامين إله:
- التغييرات الكاسرة (BREAKING CHANGE): لو التغيير تبعك رح يكسر إشي عند الناس اللي بتستخدم الكود تبعك (مثلاً غيرت اسم endpoint في الـ API)، لازم تكتب
BREAKING CHANGE:وتوضح شو هو التغيير. هاي أهم معلومة للأتمتة. - إغلاق تذاكر (Issues): عشان تربط الـ commit مع تذكرة على GitHub أو Jira، بتكتب مثلاً:
Closes #123.
أمثلة من الميدان
طيب، خلينا نشوف الفرق على أرض الواقع:
❌ سيء:
git commit -m "fixed profile page"✅ ممتاز:
git commit -m "fix(profile): correct user avatar not displaying on mobile"
❌ سيء:
git commit -m "new api"✅ ممتاز (مع تفاصيل):
feat(api): add endpoint for user data export Users can now request a full export of their data in JSON format via the new GET /api/v2/users/export endpoint. This is part of our commitment to GDPR compliance. Closes #45
❌ سيء:
git commit -m "refactor user model"✅ ممتاز (مع تغيير كاسر):
refactor(auth): rename user ID field from 'uid' to 'userId' The previous field name 'uid' was ambiguous and caused confusion with other system IDs. 'userId' is more explicit. BREAKING CHANGE: The 'uid' field in the user object returned from the API has been renamed to 'userId'. All clients must be updated to use the new field name.
من الدموع إلى الأتمتة: السحر الحقيقي!
لما صار كل الفريق يلتزم بهاي الطريقة، الـ git log تبعنا تحول من خرابيش دجاج إلى رواية منظمة ومقروءة. لكن الجمال الحقيقي مش هون. الجمال الحقيقي هو لما خلينا الآلات تقرأ هاي الرواية وتشتغل لحالها.
1. توليد سجل التغييرات (Changelog) بضغطة زر
وداعاً للساعات الضايعة! باستخدام أدوات مثل standard-version أو semantic-release، صرنا نقدر نولّد ملف CHANGELOG.md كامل ومفصّل بشكل تلقائي. الأداة بتقرأ كل الـ commits من آخر إصدار، وبتصنفهم حسب النوع:
- كل شي
featبينزل تحت قسم Features. - كل شي
fixبينزل تحت قسم Bug Fixes. - أي شي فيه
BREAKING CHANGEبينزل تحت قسم خاص وواضح عشان الكل ينتبه.
الأمر صار بسيط زي هيك:
# شغل هذا الأمر في مشروعك
npx standard-version
والنتيجة؟ ملف CHANGELOG.md مرتب وجميل، جاهز للنشر. ✨
2. الترقيم الدلالي (Semantic Versioning) على الطيار الآلي
هل عمرك دخلت في نقاش مع فريقك: “هل هذا التغيير يستاهل نرفع الإصدار من 1.1 لـ 1.2، ولا بس لـ 1.1.1؟”. مع الالتزامات التقليدية، هذا النقاش بطل إله وجود.
الأدوات بتفهم العلاقة بين أنواع الـ commits والترقيم الدلالي (Major.Minor.Patch):
- إذا كان أجدد commit هو
fix: يتم زيادة رقم الـ PATCH (e.g., 1.0.0 -> 1.0.1). - إذا كان أجدد commit هو
feat: يتم زيادة رقم الـ MINOR (e.g., 1.0.1 -> 1.1.0). - إذا كان أي commit يحتوي على
BREAKING CHANGE: يتم زيادة رقم الـ MAJOR (e.g., 1.1.0 -> 2.0.0).
الآلة هي اللي بتقرر رقم الإصدار الجديد بناءً على الكود اللي انكتب. ما في أروع من هيك!
3. التكامل مع الـ CI/CD
الخطوة الأخيرة كانت ربط كل هاد بسلسلة التكامل والنشر المستمر (CI/CD). الآن، لما نعمل merge لفرع على الـ main، السيرفر بيعمل التالي بشكل تلقائي:
- يحلل الـ commits الجديدة.
- يحدد رقم الإصدار الجديد.
- يولّد سجل التغييرات.
- يعمل Git Tag بالإصدار الجديد.
- ينشئ Release على GitHub/GitLab ويحط فيه سجل التغييرات.
- ينشر الحزمة (Package) على npm أو أي سجل آخر.
تحولنا من عملية يدوية بتاخد ساعات وإحباط، إلى عملية مؤتمتة بالكامل بتصير في دقايق وبدون أي تدخل بشري.
نصائح أبو عمر (الزبدة)
خبرتي علمتني شوية شغلات عملية بتساعد في تبني هاي الطريقة:
- ابدأوا بالتدريج: ما في داعي تفرضوا النظام على كل الشركة من أول يوم. جربوه على مشروع جديد أو مع فريق صغير ومتحمس. لما يشوفوا باقي الفرق الفوائد، رح يجوا يركضوا وراكم.
- استعينوا بالأدوات المساعدة: عشان تسهلوا على الفريق كتابة الـ commit بالطريقة الصحيحة، استخدموا أدوات مثل
commitizen. هاي الأداة بتسألك أسئلة (شو نوع التغيير؟ شو النطاق؟ …) وبتكتبلك رسالة الـ commit لحالها. - المدقق (Linter) هو صديقك: استخدموا أدوات مثل
commitlintمعhusky(Git hooks). هاي الأداة بتمنع أي commit ما بتبع المواصفات إنه يدخل على الـ repository أصلاً. “لا تسمح للغلط يفوت من الأساس”. - المرونة مطلوبة: تذكروا إنها مجرد “إرشادات” مش “قرآن”. الهدف هو الوضوح والأتمتة، مش إنك تكون شرطي commits. إذا في حالة استثنائية، استخدموا المنطق.
الخلاصة: من الفوضى إلى النظام
يا جماعة الخير، التحول إلى الالتزامات التقليدية (Conventional Commits) كان واحد من أفضل القرارات التقنية اللي أخذناها في فريقنا. هو مش مجرد تغيير في طريقة كتابة رسالة Git، هو تغيير في العقلية. هو انتقال من العمل اليدوي الفوضوي إلى الوضوح والنظام والأتمتة.
صحيح، في البداية بتحتاج شوية تعويد، لكن الثمرة اللي رح تقطفها بتسوى كل التعب. رح توفر ساعات من وقت فريقك، ورح تحسن التواصل بينهم، ورح تخلي عملية إطلاق الإصدارات الجديدة شغلة ممتعة بدل ما تكون كابوس.
نصيحتي الأخيرة: جربوها، ومش رح تندموا. وعد من أبو عمر. ✅