لماذا جيت معقد جدا؟
لم يكن جيت ليجعلك تشعر أنه بسيط.
تعتقد أن جيت هو مجرد add، commit، push؟ هذا يعني أنك كنت تلعب في “وضع اللاعب الفردي” طوال الوقت، في أحسن الأحوال تعاون عبر الشبكة المحلية. هذا ليس استخداما لجيت — هذا استخدام لجيت كقرص سحابي بايدو (Baidu Netdisk) بمزامنة يدوية.
تعقيد جيت نابع من المشكلة القصوى التي بني لحلها: كيف يمكن لمجموعة من المبرمجين الذين لا يثقون ببعضهم، ولديهم جداول زمنية متعاكسة، وقد يختفون في أي لحظة، أن يتعاونوا على نفس المشروع دون أن ينزلق الجميع إلى الفوضى؟
انظر، أي شخص يستطيع عمل clone و push. ولكن بمجرد أن تبدأ العمل ضمن فريق — تسحب pull فتجد كل شيء مليئا بالتعارضات، الشاشة مغطاة بـ <<<<< HEAD و >>>>>> some-random-hash — هنا تبدأ الكابوس.
لقد مررت بهذا بنفسي. كان هناك مطور backend جديد في فريقنا، موهوب لكنه لا يتقن جيت. في إحدى المرات كان يحتاج دمج (merge) تحديث عاجل، قضى ساعات دون أن ينجح وجاء يطلب مساعدتي. نظرت إلى رسم فروع (branch graph) الخاص به — يا إلهي، كان تشابكا يستحق مجسات كاثولو (Cthulhu): تفرعات ودمج وتفرعات ودمج، تتخللها عدة commits لا معنى لها من نوع merge branch 'master' into master. سألته ماذا فعل. قال: “لم أستطع سحب pull، فقمت بعمل fetch، ثم rebase، rebase لم يعمل فقمت بدمج merge، والدمج كان لا يزال به تعارضات فقمت بإعادة تعيين reset…”
ارتفع ضغط دمي في الحال. كان يعامل جيت كبئر أمنيات — أي أمر يبدو مناسبا يرميه ويأمل أن القوة العمياء تصنع معجزة. المفاجأة: لم تحدث معجزة، بل كدنا نسبب حادثة.
وهذا مجرد غيض من فيض. أعمق من ذلك تجد “التقنيات المحرمة” للتلاعب الذري بالتاريخ: rebase -i، cherry-pick، filter-branch. لما هي؟ ببساطة، هي “آلة الزمن” لعالم الأكواد — تسمح لك بالعودة إلى الماضي وتعديل التاريخ. ولكن كما نعرف جميعا من الأفلام، تسعة من كل عشرة مسافرين عبر الزمن يدمّرون الكون. git reflog هو دواء الندم، لكن في معظم الأحيان لا تدري متى تسممت.
فلسفة تصميم جيت هي أنه لا يثق بأي سلطة مركزية. يعتبر كل كمبيوتر مطور “كونا موازيا” كاملا (repository). كل commit تقوم به يخلق لقطة تاريخية جديدة في ذلك الكون. الفروع (branches) تسمح لك بإنشاء أعداد لا حصر لها من الأكوان الموازية. merge و rebase هما محاولتان للتوفيق بين “خطين زمنيين” مختلفين — فكر في مدى تعقيد هذا! حتى الفيزيائيون لم يفهموه!
منطقة التخزين المؤقت (staging area) موجودة لتتحكم بدقة في محتوى commitsك. الفروع تعزل عملك لئلا تتداخل مع الآخرين. merge يعالج المنتج الحتمي للتعاون: الاختلاف. كل هذا يخدم هدفا “موزعا” عظيما. جيت يمنحك حرية لا نهائية — وطرقا لا نهائية لتخريب الأمور.
فالسؤال هو: هل جيت ميؤوس منه؟ هل لا يستطيع الناس العاديون تعلمه أبدا؟
ليس تماما. المشكلة ليست في جيت — بل في طريقة تعلمنا له. معظم الدروس إما قوائم أوامر كالقواميس أو شروحات مبعثرة لسيناريوهات. الوثائق الرسمية مثل قاموس Xinhua بألف صفحة — ممتاز للبحث عن كلمة، لكنك لا تتعلم كتابة الروايات من قاموس. الأدلة على الإنترنت متناثرة هنا وهناك، مثل كومة من قطع Lego المبعثرة دون دليل يريك كيف تبني Millenium Falcon.
لهذا أوصي بشدة بالدروس التي لا تحاول تغطية كل شيء بل تركز على السيناريوهات العملية عالية التكرار. أعتقد أن “الدليل العملي لجيت من الصفر إلى الاحتراف” من فريق Bytedance جيد جدا.
فهو يشرح لك الفرق بين git pull و git pull --rebase ومتى تستخدم كل واحد، بدلا من أن يجعلك تحفظ عن ظهر قلب. يرشدك خطوة بخطوة خلال حالة تعارض حقيقية، ويريك كيف تحلها بأناقة بدلا من مجرد حذف كود الآخرين. يشرح عندما تتخلف فرع الميزات (feature branch) عن الرئيسي كثيرا، هل تستخدم merge أم rebase للمزامنة، وما إيجابيات وسلبيات كل خيار.
في النهاية، فلسفة جيت هي: “أعطك حرية لا نهائية، وأعطك أيضا الحبل لتشنق نفسك.” الدليل الجيد يعلمك كيف تستخدم هذا الحبل لنسج شبكة أو لتسلق جرف — لا لربط حبل المشنقة حول عنقك عن طريق الخطأ. هدفنا ليس أن نصبح عالم آثار في جيت يستطيع تلاوة كل الأوامر من ذاكرته. بل أن نصبح حرفيا في جيت يتنقل بسلاسة في الفريق، لا يخذل زملاءه أبدا، ويمكنه إنقاذ الموقف عندما يحين الوقت.