git bisect إيجاد التغيير الذي أدى إلى التوقف دون قراءة 500 سطر من السجل
توقف عن تصفح سجل git للبحث عن الـ Commit الذي أدى إلى توقف الإنتاج. يُستخدم git bisect لبحث ثنائي في التاريخ بحوالي 9 خطوات بغض النظر عن عدد الـ commits في الفترة. إليك العملية الكاملة، جلسة واقعية مُعلّمة، والمشكلات التي يجب مراقبتها.
أرسلت 50 تغييرًا خلال أسبوعين. في مكان ما، توقف شيء. الاختبار الذي كان يمرر منذ ثلاثة أسابيع الآن يفشل. git log --oneline يعرض 200 سطر لا ترغب في قراءتها.
لديك خيارات: النظر إلى التغييرات حتى ينزف عينيك، git checkout أو تحقق من التغييرات عشوائيًا وتشغيلها يدويًا، أو استخدام الأداة التي كانت موجودة في git منذ 2007 وتم تضمينها مع كل تثبيت.
git bisect يقوم ببحث ثنائي في تاريخ التغييرات. تُحدد إحدى التغييرات كمُتضررة، وواحدة كمُستقر، ثم يُعرض التغييرات بينهما — ويقلّ مساحة البحث إلى نصفها كل مرة. العثور على السبب في 500 تغيير يستغرق حوالي 9 خطوات. لا يستخدم معظم المطورين هذه الأداة.
كيف تعمل
يُعدّ التدفق الكامل بثلاث أوامر لبدء العمل:
git bisect start
git bisect bad # current state is broken
git bisect good v2.4.0 # last known-good tag or commit hash
يُخرج git تغييرًا من منتصف النطاق بين النقطتين. تُختبر وجود المشكلة، ثم تُبلغ بالنتيجة:
git bisect good # bug is NOT present here
# or
git bisect bad # bug IS present here
يُقلّل git النطاق ويختار النقطة التالية من منتصفه. تكرر حتى يخبرك abc1234 is the first bad commit. عندما تنتهي:
git bisect reset # returns you to your original branch
لا توجد علامات خاصة، ولا إعدادات، ولا إضافات. يعمل على أي مخزن، على أي إصدار من git من المرجح أن تمتلكه.
جلسة حقيقية لـ bisect (مُشفرة)
إليك جلسة كاملة. بدأت دالة تُرجع بيانات JSON صحيحة تُرجع قيمة null بعد بعض التحسينات الأخيرة — لا يوجد سبب واضح في التغييرات الأخيرة:
$ git bisect start
$ git bisect bad HEAD # current commit is broken
$ git bisect good 3f8a12b # commit from 2 weeks ago, worked fine
Bisecting: 24 revisions left to test after this (roughly 5 steps)
[c9e41f0] Refactor: extract auth middleware
$ npm test -- --grep "parseResponse" # ← run your check here
# FAIL
$ git bisect bad
Bisecting: 12 revisions left to test after this (roughly 4 steps)
[a77b2d1] Fix: update retry logic in fetch wrapper
$ npm test -- --grep "parseResponse"
# PASS
$ git bisect good
Bisecting: 6 revisions left to test after this (roughly 3 steps)
[91e0bc3] Refactor: consolidate response handlers
$ npm test -- --grep "parseResponse"
# FAIL
$ git bisect bad
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[b44c19f] Chore: remove deprecated serialization helpers
$ npm test -- --grep "parseResponse"
# FAIL
$ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[8d3e77a] Fix: normalize response envelope for new API version
$ npm test -- --grep "parseResponse"
# PASS
$ git bisect good
91e0bc3e1f4d is the first bad commit
commit 91e0bc3e1f4d
Author: Dev <dev@example.com>
Date: Mon Apr 14 11:23:07 2026
Refactor: consolidate response handlers
src/http/response.js | 14 +++---
$ git bisect reset # ← always do this when done
5 خطوات عبر نطاق 50 تغييرًا. التغيير "إعادة تجميع معالجات الاستجابة" أزالت تدفقًا للتحويل الذي يعتمد عليه شيء ما في الطرف السفلي. بدون bisect، كنت ستقرأ التغييرات لمدة ساعة.
التشغيل التلقائي
إذا كان بإمكانك التعبير عن التحقق كمُخطط — يخرج 0 للحالة الجيدة، وعدد غير صفر للحالة السيئة — يمكن لـ git bisect أن يعمل بدون تدخل:
git bisect start
git bisect bad HEAD
git bisect good v2.4.0
git bisect run npm test -- --grep "parseResponse"
يُخرج git كل نقطة من منتصف النطاق، ويُنفذ المخطط، ويُبلغ عن أول تغيير سيء. بالنسبة للاختبارات التي تُنفذ في أقل من 10 ثوانٍ، فإن هذا السرعة كافية لترك المكان وعودة لاستلام النتيجة.
مُفهوم الرمز عند تشغيل المخطط:
- 0 — التغيير جيد
- 1–124 — التغيير سيء
- 125 — تخطي هذا التغيير (بناء مُكسور، لا يمكن التحقق منه)
استخدم 125 عندما لا يُمكن تجميع التغيير أو تُعطل البنية التحتية للاختبارات في تلك النقطة — يُتجاهل bisect ويُنتقل إلى التغيير التالي.
عندما يتفوق bisect على git blame
git blame يُخبرك من أين أُخِذت السطر الأخير. مفيد عندما تعرف بالفعل السطر الخاطئ. git bisect مُخصص عندما لا تعرف — عندما يكون السبب سلوكًا وربما يكون في أي مكان.
استخدم bisect عندما:
- يمكنك تكرار التدهور ولكن لا يمكنك تتبعه إلى ملف معين
- تغير سلوك الإنتاج ولكن لا يوجد مُحتمل واضح في التاريخ الأخير
- "كان يعمل في v2.3، وانكسر في v2.5" مع أكثر من 80 تغييرًا بينهما
- بدأ الاختبار بالفشل بشكل متسق حول تاريخ معين
عند مقارنة النتائج بين تغييرين خلال bisect، نسخ كلا النتائج إلى أداة مقارنة النصوص غالبًا ما تكون أسرع من قراءة التغييرات المُوحّدة في الطرفية — خاصةً عندما تكون النتيجة مُكوّنة من JSON أو مُسلسلة.
Trampas comunes
لا تنسَ git bisect reset. يُخرج bisect تغييرات في حالة رأس منفصل. إذا قمت بتحويل الفروع أثناء الجلسة دون إعادة تعيين، فإن حالة bisect ستكون مُتضررة وستُشعرك بالارتباك. يجب إعادة التعيين عند الانتهاء، حتى بعد إيجاد الحل.
يمكن أن تؤثر التغييرات المدمجة على النطاق. إذا كان النطاق يشمل فرعًا مُستمرًا تم دمجه، فقد يُدخل bisect داخل تغييرات هذا الفرع بترتيب غير واضح. قم بتشغيل git log --oneline --no-merges good..bad أولًا لفهم ما هو موجود في النطاق.
القابلية للإعادة هي كل شيء. إذا كان التحقق غير موثوق — مرتبط بالوقت، أو يعتمد على البيئة، أو يُصل إلى خدمة خارجية — فإن bisect سيُعطي نتائج غير صحيحة. تأكد من أن التحقق مُحدد قبل تلقائيته.
التغيير الذي يُحدد بواسطة bisect هو حيث تغير السلوك، وليس بالضرورة حيث يقع السبب. في بعض الأحيان، تُظهر تحسينات صحيحة عيوب موجودة سابقًا في أماكن أخرى. اعتبر النتيجة كـ "ابدأ من هنا"، وليس كـ "أعد التغيير وانتهت."
إذا كنت تُحلّل التاريخ المُجمّع بشكل متكرر، فإن جيت ورقة الغش على IO Tools يحتوي على bisect، blame، علامات log، وسجل الإرجاع كلها على صفحة واحدة — يستحق التخزين كمُفضل عند حدوث شيء غريب.
تثبيت ملحقاتنا
أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع
恵 وصلت لوحة النتائج!
لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!
