المشكلة
اكتشفت خطأً في مشروعك اليوم، لكنك لا تعرف متى ظهر بالضبط — قد يكون أي commit من آخر 200 commit. مراجعتها واحدًا واحدًا تستغرق وقتًا طويلًا.
الفكرة: بحث ثنائي بدل بحث خطّي
بدل فحص كل commit بالترتيب، git bisect يستخدم بحث ثنائي (binary search): يقسّم النطاق إلى نصفين في كل خطوة. بين 200 commit، تحتاج فقط ~8 خطوات (log₂ 200 ≈ 8) بدل 200 محاولة.
سير العمل
git bisect start
git bisect bad # الوضع الحالي فيه الخطأ
git bisect good v1.5.0 # هذا الإصدار كان سليمًا
Git ينقلك تلقائيًا إلى commit في منتصف النطاق:
Bisecting: 97 revisions left to test after this (roughly 7 steps)
اختبر مشروعك عند هذا الـ commit، ثم أخبر Git بالنتيجة:
git bisect good # إذا لم يظهر الخطأ هنا
git bisect bad # إذا ظهر الخطأ هنا
يكرّر Git العملية، ويضيّق النطاق للنصف في كل مرّة، حتى يحدّد أول commit سيّئ بالضبط:
a3f5c21 is the first bad commit
إنهاء الجلسة
git bisect reset # يعيدك للفرع والـ commit اللذين كنت عليهما قبل البدء
⚠️ لا تنسَ
git bisect reset— بدونه تبقى في حالة "detached HEAD" في منتصف عملية البحث.
أتمتة البحث بسكربت
بدل اختبار كل commit يدويًا، أعطِ Git سكربتًا يرجع 0 إذا كان الـ commit سليمًا وأي رقم آخر (غير 125) إذا كان فيه الخطأ:
git bisect start HEAD v1.5.0
git bisect run npm test
- 0 يعني "جيّد".
- 1 حتى 127 (باستثناء 125) يعني "سيّئ".
- 125 يعني "لا يمكن اختباره" (مثلًا فشل البناء نفسه) — Git يتخطّى هذا الـ commit.
Git يشغّل السكربت تلقائيًا على كل commit مرشّح حتى يجد الـ commit المسبّب للخطأ، دون أي تدخّل يدوي.
💡 استخدم
git bisectعندما تعرف أن الخطأ "جديد" (لم يكن موجودًا سابقًا) لكن لا تعرف أي commit بالتحديد سبّبه.
🎯 التالي: المستودعات الفرعية (Submodules).