مقارنة النصوص
قارن نصين جنبًا إلى جنب أو كـ diff موحّد، مع تمييز على مستوى الكلمة، وخيارات للمسافات وحالة الأحرف، ورقعة (patch) قابلة للنسخ.
الصق نسختين من نص للمقارنة
ما الذي تفعله هذه الأداة
يجيب الـdiff بدقة عن سؤال واحد: ما الذي يجب أن يتغيّر لتحويل نص إلى آخر؟ الصق الأصل في لوحة «الأصل» والنسخة الجديدة في لوحة «المعدَّل»، وستعرض الأداة كل سطر محذوف وكل سطر مضاف — وداخل السطر المعدَّل الكلمات المختلفة بالضبط، مميّزة. إنه السؤال نفسه الذي يجيب عنه git في كل commit، محسوبًا بعائلة الخوارزميات نفسها، بالكامل في متصفحك.
هذا الجزء الأخير يهم في أداة diff أكثر من معظم الأدوات: ما يقارنه الناس يميل إلى أن يكون خاصًا — نسختان من إعدادات الإنتاج، استعلام قبل التحسين وبعده، جسم الاستجابة الذي عمل أمس مقابل الذي يفشل اليوم. هنا لا يغادران جهازك أبدًا.
جنبًا إلى جنب أو موحّد
يعرض الوضعان المقارنة نفسها بترتيب مختلف. جنبًا إلى جنب يضع الأصل والمعدَّل وجهًا لوجه — عمود الأصل تحت لوحة «الأصل» — مع محاذاة الأسطر المتطابقة: الطريقة الطبيعية لقراءة مراجعة مستند. الموحّد يضفرهما في عمود واحد: المحذوفات تسبقها علامة ناقص والإضافات علامة زائد — صيغة git log ومراجعات الكود، أكثر إيجازًا وأفضل عندما تكون التغييرات متفرقة. كلا الوضعين يعلّمان أرقام الأسطر الأصلية في الهوامش، فما تجده هنا يشير مباشرة إلى ملفك.
كيف يُحسب الـdiff
تنفّذ الأداة خوارزمية الفروق لمايرز (Myers)، المنشورة عام 1986 والتي ما زالت الافتراضية في git حتى اليوم. تجد أقصر سيناريو تحرير: العدد الأدنى من حذف الأسطر وإدراجها الذي يحوّل نصًا إلى آخر. هذه الحدّية الدنيا هي ما يجعل الـdiff قابلًا للقراءة — فمقارنة ساذجة تسيء إعادة التزامن بعد تغيير تُبلغ عن كتل كاملة كمستبدَلة، بينما تشير مايرز بالضبط إلى السطرين اللذين تغيّرا فعلًا.
تُقارَن الأسطر أولًا، ثم يُقارَن كل زوج من الأسطر المتغيّرة مرة أخرى على مستوى الكلمات لإنتاج التمييز. حدٌّ نقوله بصراحة: عندما لا يتشارك نصان شيئًا تقريبًا، كان بحث السيناريو الأدنى سيكلف ذاكرة أكثر مما ينبغي لتبويب متصفح؛ لذا بعد مسافة تحرير قدرها ألفان تتراجع الأداة إلى عرض كل شيء كمستبدَل — وتقول ذلك بإشعار بدل الصمت.
خيارا المسافات وحالة الأحرف
كثير من الفروق حقيقية لكنها غير مهمة. ملف أعيدت إزاحته من Tab إلى مسافات، مسافة نهائية أضافها محرر، كلمة مفتاحية بحالة أحرف مختلفة — كلها تغييرات أصيلة، وكلها ضجيج عندما يكون ما تريد معرفته هو: هل تغيّر المنطق؟ يغطي المربعان الحالتين الشائعتين: أحدهما يستبعد المسافات عند طرفي كل سطر، والآخر يستبعد حالة الأحرف. لا يؤثران إلا فيما يُحسب تغييرًا — العرض يُظهر كل سطر دائمًا كما لُصق بالضبط.
- تجاهل مسافات الأطراف — تُستبعد المسافات وTab في بداية كل سطر ونهايته قبل المقارنة: تغيير الإزاحة وحده يتوقف عن الظهور كسطر معدَّل. المسافات داخل السطر ما زالت تُحسب.
- تجاهل حالة الأحرف — الأسطر والكلمات التي لا تختلف إلا في حالة الأحرف تُعد متساوية. مفيد لكلمات SQL المفتاحية وأسماء ترويسات HTTP وسياقات أخرى غير حساسة لحالة الأحرف.
الرقعة التي يمكنك نسخها
ينتج زر النسخ المقارنة بصيغة unified diff — اللغة المشتركة لتغييرات الكود. كل كتلة تغيير (hunk) تبدأ بترويسة @@ تسمّي أرقام الأسطر التي تغطيها، الأسطر المحذوفة تبدأ بناقص والمضافة بزائد، وبضعة أسطر سياق غير متغيّرة تحيط بكل كتلة كي يمكن تحديد موضع التغيير حتى لو انزاح الملف قليلًا.
--- a +++ b @@ -1,3 +1,3 @@ server: - port: 8080 + port: 9090 timeout: 30
يمكن لصق هذا النص في تذكرة أو مراجعة كود، أو إرساله لزميل، أو تطبيقه آليًا: احفظه في ملف وسيعيد git apply أو أمر patch في يونكس تشغيل التغيير على الأصل. تفصيل يستحق المعرفة: الملف الذي لا ينتهي بسطر جديد يحصل في رقعته على العلامة \ No newline at end of file — والأداة تعيد إنتاج هذا السلوك، لأن السطر الجديد الأخير المفقود فرق حقيقي، والتظاهر بغير ذلك ينتج رقعًا لا تنطبق.
الأسئلة الشائعة
- لماذا يُبلَّغ عن تغيير مع أن النصين يبدوان متطابقين؟
- الفرق على الأرجح غير مرئي: مسافات في نهاية السطر، أو Tab مقابل مسافات، أو سطر جديد مفقود بعد السطر الأخير. فعّل «تجاهل مسافات الأطراف» لاستبعاد الحالتين الأوليين. فرق السطر الجديد الأخير يظل مُبلَّغًا عنه — وgit يبلغ عنه أيضًا بعلامته no-newline — لأن الفرق على مستوى البايتات حقيقي حتى عندما لا يُظهره أي حرف.
- لماذا تظهر النصوص شديدة الاختلاف كاستبدال واحد كبير؟
- إيجاد الـdiff الأدنى يكلف ذاكرة تتناسب مع مربع مدى اختلاف النصين. بعد مسافة تحرير تقارب ألفي سطر متغيّر تتحول الأداة إلى عرض خشن «استُبدل كل شيء» وتُظهر إشعارًا. مع نسختين من المستند نفسه لن تصل إلى ذلك أبدًا؛ عند مقارنة ملفين لا صلة بينهما — نعم.
- كيف أطبّق الرقعة المنسوخة؟
- احفظها في ملف ثم نفّذ git apply file.patch داخل المستودع، أو patch original.txt file.patch بأداة يونكس الكلاسيكية. أُنشئت الرقعة مقابل النص الأصلي بالضبط، لذا تنطبق نظيفة ما دام الهدف لم ينحرف.
- هل يُرفَع شيء من نصي إلى أي مكان؟
- لا. تجري المقارنة بالكامل في متصفحك — لا يوجد خادم يمكنه رؤية النصين. هذا هو مغزى الحساب في جهة العميل: الإعدادات وبيانات الاعتماد وبيانات الإنتاج تُقارن من دون أن تغادر جهازك.