guide/line-endings.md

حروف نهاية السطر (CRLF وLF) والفروق غير المرئية — عندما تظهر كل الأسطر متغيرة

أسباب ظهور كل الأسطر مختلفة في diff مع أن الملفين متطابقان بالعين: فواصل الأسطر CRLF وLF، والسطر الجديد في نهاية الملف، وBOM، وعلامات الجدولة والمسافات، والمسافات الخاصة، وتوحيد يونيكود، وطرق الحل.

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

أحيانًا تفتح ملفين فلا تجد بينهما اختلافًا في حرف واحد، ومع ذلك يقول diff إن كل الأسطر تغيّرت، أو إن السطر الأول أو الأخير فقط مختلف. السبب في الغالب أحرف لا تظهر على الشاشة. يلخّص هذا المقال أنواع هذه «الفروق غير المرئية» وطرق حلها.

حروف فاصل السطر: CRLF وLF وCR

تختلف أعراف الانتقال إلى سطر جديد من نظام تشغيل إلى آخر.

الرمزالبايتاتأين يُستخدم غالبًا
LF0A (\n)Linux وmacOS ومعظم أدوات التطوير
CRLF0D 0A (\r\n)برامج كثيرة في Windows مثل المفكرة، وبروتوكولات الإنترنت مثل البريد الإلكتروني وHTTP
CR0D (\r)إصدارات Mac OS القديمة جدًا (قبل الإصدار 9)

إذا حُفظ ملف بـ CRLF وآخر بـ LF، ففي المقارنة سطرًا بسطر يُحتسب حرف \r غير المرئي في نهاية كل سطر فرقًا، فيبدو كأن الملف كله تغيّر. يمكن تجاهل هذا الفرق في GNU diff بالخيار --strip-trailing-cr، وفي git diff بالخيار --ignore-cr-at-eol.

السطر الجديد في نهاية الملف

وفق أعراف POSIX تنتهي أسطر الملف النصي بحرف سطر جديد. لذلك تضع أدوات كثيرة سطرًا جديدًا بعد السطر الأخير أيضًا، لكن بعض المحررات لا تفعل. يظهر هذا الفرق في unified diff على النحو التالي.

@@ -1,2 +1,2 @@ host=example.com-port=8080\ No newline at end of file+port=8080

\ No newline at end of file تعني أنه لا يوجد سطر جديد في نهاية السطر الذي فوقها مباشرة. في المثال أعلاه المحتوى واحد، وأُضيف السطر الجديد الأخير في الملف بعد التغيير فقط. تشترط أدلة أسلوب كتابة الكود كثيرًا وجود سطر جديد في نهاية الملف، ويمكن توحيد ذلك بإعداد «إدراج سطر جديد في نهاية الملف» في المحرر.

BOM: عندما يختلف السطر الأول فقط

قد تُضاف في بداية ملف UTF-8 ثلاثة بايتات هي EF BB BF. تُسمّى هذه علامة ترتيب البايتات (BOM). لا حاجة إلى ترتيب البايتات في UTF-8، لكن بعض البرامج تضيفها علامةً على أن «هذا الملف بترميز UTF-8». لا تظهر BOM على الشاشة، فإذا قيل إن السطر الأول فقط مختلف فاشتبه في BOM. يزيل هذا الموقع BOM من بداية الملف عند تحميله، وإذا فعّلت خيارات تجاهل المسافات فإنه يعامل BOM ‏(U+FEFF) داخل النص الملصوق كمسافة أيضًا.

علامات الجدولة والمسافات والمسافات الخاصة

تُستبعد معظم هذه الأحرف عند تفعيل خيارات تجاهل المسافات (لكن الأحرف التي لا تُصنَّف مسافات، مثل U+200B، قد تبقى حتى مع تفعيل الخيار). وإذا حوّلت المقارنة داخل السطر إلى أحرف، يُبيّن لك الإبراز موضع الحرف غير المرئي.

توحيد يونيكود: الحرف نفسه ببايتات مختلفة

يمكن كتابة الحرف «é» كحرف واحد (U+00E9)، أو كحرف e ‏(U+0065) تتبعه علامة النبر المركّبة (U+0301). وكذلك المقطع الكوري «가» قد يكون حرفًا واحدًا (U+AC00) أو تركيبًا من حرفين منفصلين (U+1100 وU+1161). يسمّي يونيكود الشكل الأول NFC والثاني NFD ‏(UAX #15). يبدو النصان متطابقين على الشاشة، لكنهما عند المقارنة أحرف مختلفة. ومن الأمثلة الشائعة أسماء الملفات التي أُنشئت على macOS، إذ تصل أحيانًا إلى أنظمة أخرى بالشكل المفكك فلا تتطابق مع أسماء تبدو مماثلة لها. الحل هو تحويل الجهتين إلى NFC قبل المقارنة.

توحيد فواصل الأسطر في git

إذا كان المستودع يُعمل عليه من أنظمة تشغيل مختلفة، فيمكن توحيد فواصل الأسطر بإعدادات git.

* text=auto
*.sh text eol=lf
*.bat text eol=crlf

يوحّد text=auto فواصل الأسطر إلى LF داخل المستودع للملفات التي يعدّها git نصية، ويحدد eol=lf وeol=crlf فاصل السطر عند إخراج الملفات إلى مجلد العمل.

جرّبها في هذه الأداة

خيار توحيد نهايات الأسطر في مقارنة النصوص مفعّل افتراضيًا، فيعدّ CRLF وCR وLF فاصل سطر واحدًا ويتجاهل وجود السطر الجديد في نهاية الملف من عدمه. إذا أوقفته يظهر CR في نهاية السطر على هيئة ، والسطر الذي ليس بعده سطر جديد على هيئة ، فتستطيع رؤية الفروق التي كانت مخفية. خيارات المسافات مشروحة في خيارات تجاهل المسافات، ومعاني رموز النتيجة في كيف تقرأ unified diff.

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