معظم التصحيحات (patches) المتداولة في مراجعة الكود وبلاغات المشكلات والبريد الإلكتروني بصيغة unified diff. تستخدم هذه الصيغة كل من git diff وdiff -u و«raw diff» في GitHub. قد تبدو الرموز كثيرة في البداية، لكن القواعد بسيطة.
الشكل العام
@@ -1,5 +1,6 @@ def greet(name):- print("Hello " + name)+ message = f"Hello, {name}!"+ print(message) def main(): greet("world")
من الأعلى إلى الأسفل تأتي ترويسات git الموسّعة، ثم ترويسات الملف (--- و+++)، ثم الكتل (hunks، أي المقاطع التي تبدأ بـ @@). قد يحتوي الملف الواحد على عدة كتل، وقد يحتوي التصحيح الواحد على عدة ملفات.
ترويسات الملف: --- و+++
--- a/greet.pyهو الملف قبل التغيير، و+++ b/greet.pyهو الملف بعد التغيير.- يضيف git البادئتين
a/وb/قبل المسار. لذلك عند التطبيق بالأمرpatchيُزال أول مكوّن من المسار بالخيار-p1. - يُشار إلى الملف الجديد بـ
--- /dev/nullوإلى الملف المحذوف بـ+++ /dev/null. - قد يضيف GNU diff وقت التعديل بعد اسم الملف.
ترويسة الكتلة @@ -a,b +c,d @@
@@ -1,5 +1,6 @@ تعني أن الكتلة تعرض «5 أسطر من الملف قبل التغيير بدءًا من السطر 1، و6 أسطر من الملف بعد التغيير بدءًا من السطر 1».
- الرقم الأول هو رقم سطر البداية، والرقم بعد الفاصلة هو عدد الأسطر التي تشغلها الكتلة (بما فيها أسطر السياق).
- إذا كان عدد الأسطر 1 يُحذف مع الفاصلة.
@@ -7 +7 @@كتلة من سطر واحد هو السطر 7. - إذا كان عدد الأسطر 0 فلا توجد أسطر في تلك الجهة.
@@ -3,0 +4,2 @@تعني أن سطرين جديدين أُدرجا بعد السطر 3 من الأصل. وعند المقارنة مع ملف فارغ يظهر-0,0. - قد يأتي بعد
@@الثانية نص مثل اسم دالة (@@ -40,7 +40,8 @@ def main():). هذه معلومة مرجعية تبيّن الدالة التي تقع فيها الكتلة، وتُتجاهل عند التطبيق.
لنعدّ بأنفسنا: أسطر السياق (التي تبدأ بمسافة) في المثال أعلاه أربعة: def greet(name): وسطر فارغ وdef main(): وgreet("world"). عدد الأسطر قبل التغيير هو 4 أسطر سياق مع سطر - واحد، أي 5، وبعد التغيير 4 أسطر سياق مع سطري +، أي 6، ولذلك تكون الترويسة -1,5 +1,6.
ثلاثة أنواع من الأسطر في المتن
| الحرف الأول | المعنى |
|---|---|
| مسافة | سطر سياق موجود بالشكل نفسه في الجهتين |
- | سطر موجود قبل التغيير فقط (محذوف) |
+ | سطر موجود بعد التغيير فقط (مضاف) |
السياق الافتراضي 3 أسطر قبل التغيير وبعده (يمكن تغييره، مثل git diff -U5). تُستخدم أسطر السياق لإيجاد الموضع الصحيح عند تطبيق التصحيح. إذا انزاحت أرقام الأسطر قليلًا لكن السياق مطابق، يطبّق patch التغيير مع إزاحة (offset).
تعديل سطر واحد يظهر على شكل زوج: سطر - يليه سطر +. لا يوجد في صيغة unified رمز خاص بـ«التعديل»، لذا فالحيلة هي قراءة مجموعة أسطر - ومجموعة أسطر + المتتاليتين مقابل بعضهما من الأعلى إلى الأسفل.
\ No newline at end of file
@@ -1,2 +1,2 @@ host=example.com-port=8080\ No newline at end of file+port=8080
تعني هذه العلامة أن السطر الذي فوقها مباشرة هو آخر سطر في الملف ولا يوجد في نهايته حرف سطر جديد. في المثال أعلاه المحتوى واحد، وأُضيف السطر الجديد الأخير في الملف بعد التغيير فقط. التفاصيل في مقال نهايات الأسطر والفروق غير المرئية.
ترويسات git الموسّعة
الأسطر التي تلي diff --git a/path b/path معلومات إضافية خاصة بـ git.
index 3b18e51..a6f4c2d 100644— بداية تجزئة (hash) محتوى الملف قبل التغيير وبعده، ونمط الملف (100644 ملف عادي، و100755 ملف تنفيذي)new file mode 100644/deleted file mode 100644— إنشاء ملف أو حذفهold mode 100644/new mode 100755— تغيّرت صلاحية التنفيذ فقط (قد تظهر دون كتل محتوى)similarity index 90%وrename from old-pathوrename to new-path— إعادة تسمية (المحتوى متطابق بنسبة 90%)Binary files a/logo.png and b/logo.png differ— للملفات الثنائية يظهر هذا السطر وحده بدلًا من المحتوى
حيل مفيدة عند المراجعة
- انظر أولًا إلى الفرق في عدد الأسطر في ترويسة الكتلة لتقدّر حجم التغيير.
-10,7 +10,30يعني أن 23 سطرًا أُضيفت. - لاستبعاد الكتل التي لم تتغير فيها إلا المسافات استخدم
git diff -w. هذا مفيد خصوصًا عند مراجعة commit اختلط فيه ترتيب المسافات البادئة بتغييرات فعلية (خيارات تجاهل المسافات). - لمعرفة ما تغيّر داخل السطر استخدم
git diff --word-diff، أو ضع الفرق في أداة تدعم الإبراز داخل السطر مثل هذا الموقع. - قبل تطبيق التصحيح تحقق أولًا بالأمر
git apply --check file.patchمن أنه يُطبَّق دون مشكلات. وخارج مستودع git استخدمpatch -p1 --dry-run < file.patch.
جرّبها في هذه الأداة
يعرض العرض الموحّد في مقارنة النصوص مجموعة - ثم مجموعة + بالترتيب نفسه الذي تتبعه هذه الصيغة، ويُبرز الكلمات المتغيرة داخل السطر مرة أخرى. عند الضغط على زر patch في شريط النتيجة يُنسخ نص unified diff قياسي، ويُنزّل زر الحفظ المجاور ملف diff.patch. يمكن تطبيق patch الذي أُنشئ مع إيقاف كل خيارات التجاهل على الأصل باستخدام patch -p1 أو git apply.