شعار أوسكار أوسكار كل المقالات

أساسيات Git: تحكّم في كودك بثقة

هل سبق أن سمّيت ملفاً final_v2_final_real.html؟ هذه بالضبط المشكلة التي يحلّها Git: نظام تحكّم بالإصدارات يحفظ تاريخ مشروعك لقطةً بلقطة، فتعود لأي نقطة بثقة، وتجرّب أفكاراً دون خوف، وتتعاون مع غيرك دون فوضى. قد يبدو مربكاً في البداية، لكنّ تسعة أوامر تكفيك لتعمل بثقة يومياً.

لماذا Git أصلاً؟

ثلاث فوائد تختصر قيمته: سِجلّ كامل لكل تغيير ومن أجراه ومتى؛ أمان للتجربة عبر الفروع فتعدّل بحرّية وتتراجع إن لزم؛ وتعاون منظّم يدمج عمل عدّة أشخاص دون أن يطمس أحدهم عمل الآخر. وحتى لو كنت تعمل وحدك، Git شبكة أمان لا غنى عنها.

1. ابدأ مستودعاً

داخل مجلّد مشروعك:

git init

هذا ينشئ مستودعاً (repository) يبدأ بتتبّع المجلّد. أضِف ملف .gitignore لاستثناء ما لا يجب تتبّعه (مثل node_modules أو ملفّات الإعدادات السرّية) — خطوة يتجاهلها المبتدئون فتمتلئ مستودعاتهم بفوضى.

2. الحالة والإضافة والالتزام

دورة العمل اليومية ثلاث خطوات:

git status — ماذا تغيّر؟
git add . — جهّز التغييرات للحفظ.
git commit -m "إضافة نموذج التواصل" — احفظ لقطة برسالة تصفها.

الـcommit هو الوحدة الأساسية في Git: لقطة دائمة يمكنك العودة إليها متى شئت. التزِم كثيراً وبخطوات صغيرة منطقية، لا مرّة واحدة في نهاية اليوم.

3. اكتب رسائل commit واضحة

الرسالة الجيّدة تشرح لماذا لا ماذا فقط. «إصلاح» رسالة سيّئة؛ «إصلاح تكرار فتح البريد في نموذج التواصل» رسالة تفهمها بعد ستّة أشهر. ابدأ بفعل أمر مختصر، وأبقِ السطر الأول تحت 50 حرفاً. مستقبلُك سيشكرك حين تبحث في السِّجل.

قاعدة: الـcommit الواحد = فكرة واحدة. لا تخلط إصلاح خطأ مع إعادة تنسيق مع ميزة جديدة في commit واحد — يصبح السِّجل عديم الفائدة عند المراجعة أو التراجع.

4. الفروع (Branches)

الفرع نسخة موازية تجرّب فيها بأمان دون المساس بالنسخة الأساسية:

git checkout -b feature/contact-form

تعمل على الفرع، تلتزم فيه، وحين تكتمل الميزة تدمجها في الفرع الرئيسي. هكذا يبقى main مستقرّاً دائماً، وتختبر أفكارك في عزلة. هذه عادة أساسية في أي عمل احترافي أو جماعي.

5. الربط مع منصّة بعيدة (GitHub)

لحفظ نسخة سحابية وللتعاون، اربط مستودعك بمنصّة مثل GitHub:

git remote add origin <url>
git push -u origin main

بعدها git push يرفع التزاماتك، وgit pull يجلب تغييرات الآخرين. مستودعك السحابي هو أيضاً نسخة احتياطية: لو تعطّل جهازك، كودك بأمان.

6. حلّ التعارضات (Conflicts)

يحدث التعارض حين يعدّل شخصان السطر نفسه. لا تَفزع — Git يضع علامات واضحة (<<<<<<< و>>>>>>>) حول النسختين. مهمّتك: اختر النصّ الصحيح، احذف العلامات، ثم add وcommit. التعارضات طبيعية في العمل الجماعي، ومع التعوّد تصبح حلّها روتيناً بسيطاً.

7. التراجع بأمان

أخطأت؟ Git يحميك. لإلغاء تعديلات لم تلتزمها بعد: git checkout -- <file>. ولإلغاء آخر commit مع إبقاء التغييرات: git reset --soft HEAD~1. تعلّم الفرق بين الأوامر الآمنة والمدمّرة (مثل reset --hard) قبل استعمالها على عمل مهمّ.

8. ملف .gitignore: القرار الذي لا رجعة فيه

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

السبب أن Git يحفظ التاريخ كاملاً. الملف الذي دخل المستودع مرّة يبقى فيه إلى الأبد ولو حذفته في التزام تالٍ — يستطيع أي شخص لديه وصول للمستودع أن يقرأه من أي لقطة قديمة بأمر واحد. لهذا حذف مفتاح مسرَّب ليس إصلاحاً؛ الإصلاح الوحيد هو تدوير السرّ نفسه: أنشئ مفتاحاً جديداً وألغِ القديم. أمّا تنظيف التاريخ فيمكن نظرياً لكنه يعيد كتابة كل الالتزامات ويكسر كل نسخة موجودة عند غيرك.

ما يُستثنى دائماً في مشاريعنا:

  • مجلّدات الاعتماديات — تُعاد بناءً من ملف الاعتماديات، وتتبّعها يضيف آلاف الملفّات بلا فائدة.
  • مخرجات البناء — تُولَّد في كل نشر. إبقاؤها متتبَّعة يُنتج تعارضاً في كل التزام لأنها تتغيّر بالكامل مع كل بناء.
  • ملفّات المفاتيح والأسرار — مفاتيح توقيع التطبيقات، وملفّات حسابات الخدمة، وملفّات متغيّرات البيئة، ومفاتيح واجهات الخدمات المدفوعة.
تحذير: ملف .gitignore لا يُخرج ملفّاً سبق تتبّعه. إن التزمت ملفاً ثم أضفته للاستثناء فسيبقى متتبَّعاً — يحتاج إخراجاً صريحاً من الفهرس. تحقّق بعد كل إضافة، ولا تفترض.

9. المستودع كنسخة احتياطية معتمدة

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

القرار الذي اتّخذناه في أحد المشاريع: إلغاء النسخ المحلّية بالكامل واعتماد المستودع البعيد نسخةً احتياطية وحيدة. المستودع يحفظ كل حالة مرّ بها المشروع بلا تكرار، ويمكن الرجوع لأي لحظة بدقّة.

لكنّ هذا القرار آمن بشرطين لا ثالث لهما: أن يكون الرفع تلقائياً لا يدوياً (وإلّا صار عملك محفوظاً على جهازك وحده)، وأن تكون الأسرار مستثناة فعلاً قبل أول التزام. بلا الشرطين يصبح القرار مخاطرة لا تبسيطاً.

10. الأتمتة بالخطّافات: لأن الذاكرة تُخطئ

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

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

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

11. سكربت مزامنة واحد بدل ثلاثة أوامر

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

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

12. قرار موثّق مقابل سهو

ليست كل مخالفة للقاعدة خطأً — بشرط أن تكون قراراً واعياً مكتوباً. في مستودع خاصّ قد نُبقي ملف إعداد يحمل قيماً حسّاسة متتبَّعاً لتسهيل إعادة تجهيز بيئة البناء، مع استثناء ملف المفتاح نفسه دائماً.

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

ومع مستودع عام فلا استثناء ولا نقاش: لا سرّ يدخل المستودع أبداً.

13. رسائل الالتزام كوثائق تُقرأ بعد أشهر

عدنا إلى موضوع الرسائل بعد التجربة، لأنّ القاعدة «اشرح لماذا» ناقصة. الرسالة التي تنفع فعلاً بعد ستّة أشهر تحمل ثلاثة أشياء: ما تغيّر، ولماذا، وما تحقّقتَ منه.

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

أسئلة شائعة

ما الفرق بين Git وGitHub؟ Git هو الأداة التي تعمل على جهازك، وGitHub منصّة سحابية لاستضافة المستودعات والتعاون. يمكنك استعمال Git دون GitHub، لكنّ الجمع بينهما هو المعتاد.

هل أحتاج سطر الأوامر؟ تساعدك واجهات رسومية (مثل الموجودة في المحرّرات)، لكن فهم الأوامر الأساسية يجعلك أقوى وأقلّ عجزاً حين تختلف الأمور عن المتوقّع.

كم مرّة ألتزم (commit)؟ كلّما أنجزت خطوة منطقية مكتملة. الالتزامات الصغيرة المتكرّرة أسهل في الفهم والتراجع من الالتزامات الضخمة النادرة.

سرّبتُ مفتاحاً في التزام — ماذا أفعل؟ بالترتيب: ألغِ المفتاح وأنشئ بديلاً فوراً (هذه الخطوة الوحيدة التي تُصلح شيئاً)، ثم أضِف الملف للاستثناء، ثم أخرجه من الفهرس. لا تكتفِ بحذفه — فهو باقٍ في تاريخ المستودع، والسرّ الذي وصل مكاناً لا تسيطر عليه يُعتبر مكشوفاً.

هل أرفع ملفّات البناء المصغَّرة؟ لا. ولّدها في كل نشر واستثنِ مجلّد المخرجات. تتبّعها يعني تعارضاً في كل التزام لأنها تتغيّر بالكامل مع كل بناء، ويضاعف حجم المستودع بلا فائدة.

مستودع خاصّ أم عام؟ ابدأ خاصّاً دائماً. تحويله إلى عام لاحقاً قرار واعٍ تراجع قبله التاريخ كلّه؛ أمّا العكس فلا يُصلح شيئاً — ما نُشر مرّة يُعتبر منشوراً.

خلاصة

Git ليس عقبة بل حرّية: init للبدء، ودورة status → add → commit اليومية، وفروع للتجربة الآمنة، وpush/pull للتعاون والنسخ الاحتياطي. أتقن هذه الأساسيات وستتعامل مع كودك بثقة مطوّر محترف — وتنسى إلى الأبد ملفّات «final_v2».

وثلاثة دروس دفعنا ثمنها بعد سنوات من الاستخدام: الأسرار تُستثنى قبل أول التزام لأن التاريخ لا يُنسى وحذف السرّ لا يُصلحه؛ والأتمتة تسبق الانضباط فأي خطوة أمان تعتمد على ذاكرتك ستُنسى في اليوم الذي تحتاجها؛ والقرار غير الموثّق لا يُميَّز عن الغفلة فاكتب لماذا خالفت القاعدة أو لا تخالفها.

تتحكّم في كودك؟ تعلّم الآن أن تكتبه نظيفاً: أساسيات JavaScript الحديثة →
والأسرار في مشاريع الجوّال لها حساسية إضافية — مفتاح توقيع واحد يفصل بين تطبيق قابل للتحديث وتطبيق ضائع: النشر على Google Play →