guide/diff-algorithms.md

Myers وPatience وHistogram — مقارنة خوارزميات diff

كيف يعمل كل خيار من خيارات --diff-algorithm في git diff (myers وminimal وpatience وhistogram)، ولماذا تختلف نتائجها، مع أمثلة.

آخر تحديث: 2026-09-23

حتى عند مقارنة الملفين أنفسهم، قد تختلف النتيجة باختلاف خوارزمية diff. كل النتائج «صحيحة»، لكنها تختلف في الأسطر التي تعدّها متطابقة، ولذلك تختلف سهولة قراءتها. يوفّر git أربعة خيارات عبر --diff-algorithm.

القيمةالوصف في وثائق gitالخصائص
myers (default)الخوارزمية الجشعة (greedy) الأساسية، وهي الافتراضية حاليًاسريعة ونتيجتها غالبًا قريبة من الأصغرية
minimalتقضي وقتًا إضافيًا لإنتاج أصغر diff ممكنأصغرية دائمًا، وقد تكون بطيئة مع المدخلات الكبيرة
patienceخوارزمية patience diffتتخذ الأسطر الفريدة نقاط ارتكاز
histogramتوسّع patience لتدعم العناصر المشتركة النادرةتتخذ الأسطر النادرة نقاط ارتكاز

توجد أيضًا صيغ مختصرة مثل git diff --patience وgit diff --histogram، ويمكن تغيير القيمة الافتراضية بالأمر git config diff.algorithm histogram.

Myers: القيمة الافتراضية التي تبحث عن أقل تحرير

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

تغيير واحد ونتيجتان

لنفترض أنك أضفت دالة جديدة h بين الدالتين f وg. في كلا الـ diff أدناه 4 أسطر مضافة، أي أن عدد التعديلات متساوٍ.

@@ -1,6 +1,10 @@ int f() {     return 1; }++int h() {+    return 3;+}  int g() {     return 2;
@@ -1,5 +1,9 @@ int f() {     return 1;+}++int h() {+    return 3; }  int g() {

في الأول تظهر الدالة الجديدة كاملة، أما في الثاني فقد عُدّ قوس الإغلاق الخاص بالدالة القائمة f قوسًا للدالة الجديدة، فانقطع الجزء المضاف بشكل غير طبيعي. ينشأ هذا الشكل بسبب ترتيب البحث، ويصحّح git الحديث جزءًا كبيرًا منه باستدلال ينقل حدود المقطع المتغير بالنظر إلى المسافات البادئة ليصبح أسهل قراءة (--indent-heuristic، مفعّل افتراضيًا).

Patience: مطابقة الأسطر الفريدة أولًا

اقترح برام كوهين (Bram Cohen) خوارزمية patience diff، وهي تبحث أولًا عن الأسطر التي تظهر مرة واحدة بالضبط في كل ملف، لأن السطر الفريد مثل تعريف الدالة int h() { يكون قرينه مؤكدًا. من بين هذه الأسطر الفريدة تُختار أطول قائمة متسقة الترتيب (أطول متتالية جزئية متزايدة) لتكون نقاط ارتكاز، ثم تُعاد مقارنة المقاطع الصغيرة الواقعة بينها فقط.

Histogram: الأولوية للأسطر النادرة

طُوّرت خوارزمية histogram في JGit (تطبيق git بلغة جافا) ثم أُدخلت في git. وعلى عكس patience التي لا تنظر إلا إلى «الأسطر التي تظهر مرة واحدة بالضبط»، فإن histogram تحصي عدد مرات ظهور كل سطر وتختار الأقل ظهورًا نقاطًا للارتكاز. لذلك يمكنها الارتكاز على أسطر نادرة نسبيًا حتى لو لم توجد أسطر فريدة. تصفها وثائق git بأنها «توسّع خوارزمية patience لتدعم العناصر المشتركة قليلة الظهور». وفي الممارسة العملية كثيرًا ما تنتج مثل patience نتيجة تحافظ على بنية الكود جيدًا.

أيّها تستخدم؟

أيًّا كانت الخوارزمية، يُستعاد الملف الناتج بالشكل نفسه. الذي يختلف هو الشكل الذي يقرؤه الإنسان فقط.

في هذه الأداة

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

انتقل إلى مقارنة النصوص