كثير من الحالات التي يكون فيها «المحتوى واحدًا» بين ملفين ومع ذلك يُظهر diff فروقًا كثيرة سببها المسافات: حذف المحرر المسافات في نهاية الأسطر، أو حوّل علامات الجدولة إلى مسافات، أو غيّر عرض المسافة البادئة. توفّر أدوات diff خيارات لتجاهل هذه الفروق، لكن كل خيار يتجاهل نطاقًا مختلفًا، فيجب أن تعرف بالضبط ما الذي يفعله.
خيارات GNU diff المتعلقة بالمسافات
| الخيار | الاسم الطويل | ما يتجاهله |
|---|---|---|
-Z | --ignore-trailing-space | المسافات في نهاية السطر |
-E | --ignore-tab-expansion | الفرق الناتج عن تحويل علامة الجدولة إلى مسافات |
-b | --ignore-space-change | تغيّر عدد المسافات، والمسافات في نهاية السطر |
-w | --ignore-all-space | كل المسافات |
-B | --ignore-blank-lines | التغييرات التي أُضيفت أو حُذفت فيها أسطر فارغة فقط |
-i | --ignore-case | حالة الأحرف |
--strip-trailing-cr | حرف CR في نهاية أسطر المدخلات |
ما يقابلها في git diff
تصفها وثائق git على النحو التالي.
--ignore-cr-at-eol: يتجاهل حرف الإرجاع (CR) في نهاية السطر عند المقارنة.--ignore-space-at-eol: يتجاهل تغيّر المسافات في نهاية السطر.-bو--ignore-space-change: يتجاهل تغيّر عدد المسافات. يتجاهل المسافات في نهاية السطر، ويعدّ كل تتابع من مسافة واحدة أو أكثر متطابقًا في غير ذلك.-wو--ignore-all-space: يتجاهل المسافات عند مقارنة الأسطر. ويتجاهل الفرق حتى عندما توجد مسافة في جهة ولا توجد في الأخرى.--ignore-blank-lines: يتجاهل التغييرات التي تكون كل أسطرها فارغة.
الفرق الحاسم بين -b و-w
يخلط كثيرون بين هذين الخيارين. الجوهر هو هل يميّز الخيار بين وجود المسافة وعدم وجودها.
| اليسار | اليمين | -b (تجاهل عدد المسافات) | -w (تجاهل كل المسافات) |
|---|---|---|---|
a b | a b | متطابقان | متطابقان |
a b | ab | مختلفان | متطابقان |
x = 1 | x=1 | مختلفان | متطابقان |
if (a) + مسافة في نهاية السطر | if (a) | متطابقان | متطابقان |
| مسافة بادئة بعلامة جدولة واحدة | مسافة بادئة بأربع مسافات | متطابقان | متطابقان |
-b يختصر كل كتلة مسافات إلى مسافة واحدة، أما -w فيحذف المسافات كلها. لذلك يعدّ -w السطرين x = 1 وx=1 متطابقين، بل يعدّ int a وinta متطابقين أيضًا.
الخطر عندما تكون المسافات البادئة ذات معنى
في الملفات التي تكون المسافة البادئة فيها جزءًا من الصياغة مثل بايثون وYAML وMakefile، قد تُخفي خيارات تجاهل المسافات تغييرًا حقيقيًا.
if ready:
start()
notify()
if ready:
start()
notify()
في الثاني خرج notify() من جملة if فتغيّر السلوك، لكن عند المقارنة بـ -w تُحذف المسافات كلها فيختفي الفرق. أما -b فيلتقط الفرق لأن المسافة في بداية السطر تحولت من «موجودة» إلى «غير موجودة». لكن إذا تغيّرت المسافة البادئة من 4 إلى 8 مسافات ودخل الكود كتلة داخلية أعمق، فالذي تغيّر هو عدد المسافات فقط، فلن يظهر الفرق مع -b أيضًا.
الطريقة المضمونة هي مقارنة الملفات ذات المسافات البادئة المهمة دون خيارات المسافات. العادة الآمنة أن تستخدم خيارات المسافات للتحقق من أن «التغيير مجرد ترتيب»، ثم تُجري الفحص النهائي دون خيارات.
نطاق تجاهل الأسطر الفارغة (-B)
يُخفي -B و--ignore-blank-lines في git التغييرات المكوّنة من أسطر فارغة فقط. إذا اختلط سطر فارغ مضاف بتغيير حقيقي في الكتلة نفسها فقد يظل ذلك السطر الفارغ ظاهرًا. هذا الخيار مفيد في المستندات التي تغيّر فيها عدد الأسطر الفارغة بين الفقرات، أو عندما يعدّل منسّق الكود الأسطر الفارغة بين الدوال.
خيارات هذا الموقع وما يقابلها
| هذا الموقع | الأقرب في GNU diff | الأقرب في git diff |
|---|---|---|
| المسافات: مقارنة كما هي | (دون خيار) | (دون خيار) |
| المسافات: تجاهل المسافات في نهاية السطر | -Z | --ignore-space-at-eol |
| المسافات: تجاهل عدد المسافات | -b | -b |
| المسافات: تجاهل كل المسافات | -w | -w |
| تجاهل حالة الأحرف | -i | (لا يوجد مقابل) |
| تجاهل الأسطر الفارغة | يشبه -B (تُستبعد الأسطر الفارغة من المقارنة) | يشبه --ignore-blank-lines |
| توحيد نهايات الأسطر | --strip-trailing-cr + تجاهل السطر الجديد الأخير | يشبه --ignore-cr-at-eol |
خيار «تجاهل الأسطر الفارغة» في هذا الموقع يستبعد الأسطر الفارغة من المقارنة تمامًا ويعرضها بلون باهت فقط. كما تنطبق خيارات التجاهل على الإبراز داخل السطر أيضًا؛ فإذا فعّلت تجاهل عدد المسافات فلن تُبرز المواضع التي يختلف فيها عدد المسافات فقط.
جرّبها في هذه الأداة
أدخل أمثلة الجدول أعلاه في مقارنة النصوص وغيّر خيارات المسافات واحدًا تلو الآخر، وسترى الفرق فورًا. أما «الفروق غير المرئية» مثل CR في نهاية السطر أو السطر الجديد في نهاية الملف فتجدها في مقال نهايات الأسطر والفروق غير المرئية، وطريقة قراءة النتيجة كـ patch في مقال كيف تقرأ unified diff.