rdc repo diff
يُبلّغ rdc repo diff عن الملفات التي تغيّرت بين مستودعَين مترابطَين: نسخة متشعبة وأصلها، أو أي مستودعَين يتشاركان سلفًا مشتركًا من نوع نسخ-عند-الكتابة. مرّر --name <fork> لمقارنة نسخة متشعبة مع أصلها المسجَّل في الإعداد المحلي، أو أضف --base <repo> للمقارنة مع أي مستودع مترابط آخر، حيث يُمثّل --base الجانب الأساسي (القديم) ويُمثّل --name الجانب الهدف (الجديد). الأمر للقراءة فقط ولا يفك تشفير الصور قط. يُجري المقارنة على مستوى الكتل في الجهاز البعيد، لذا تتناسب التكلفة مع عدد الكتل المتغيّرة لا مع حجم المستودع: مستودع بحجم 1 GB ومستودع بحجم 100 GB يستغرقان الوقت ذاته طالما أن التعديلات متماثلة. إذا تغيّر المستودع بالكامل، فإن عدد الكتل يتناسب مع الحجم وتتناسب التكلفة معه بالتبعية.
متى تستخدمها
الخلاصة: الجأ إلى repo diff قبل ترقية أي نسخة متشعبة. إذا شغّل وكيل ذكاء اصطناعي بحرية داخل نسخة متشعبة من بيئة الإنتاج وأردت معرفة الملفات التي لمسها تحديدًا قبل دمج التغيير: يمنحك repo diff --name <fork> -m <machine> قائمة الملفات في ثوانٍ. ثوانٍ. بعد استعادة الكوارث، قارن النسخة المستعادة باللقطة التي كان من المفترض أن تُعيد إنتاجها للتأكد من عودة مجموعة الملفات المتوقعة دون أي انحراف. أما النسخة المتشعبة طويلة الأمد التي عملت جنبًا إلى جنب مع أصلها لأسابيع، فإن الفرق يُظهر التباين المتراكم (تعديلات الإعداد، تراكم السجلات، ترحيل المخطط) دون الحاجة إلى تحميل الشجرتين وتصفحهما يدويًا.
لا تستخدم هذه الأداة بين مستودعات غير مترابطة. يجب أن يتشارك الطرفان سلفًا مشتركًا من نوع نسخ-عند-الكتابة، لأن المقارنة تعتمد على تاريخ الكتل المشترك. كما أنها ليست أداة مقارنة ثنائية: يُنتج --content مخرجات على مستوى السطر للملفات النصية فقط، وتُبلّغ الملفات الثنائية بـ Binary files differ.
مرجع الأوامر
الصيغة العامة
rdc repo diff --name <fork> -m <machine> # diff a fork against its parent
rdc repo diff --name <fork> --base <repo> -m <machine> # diff against an arbitrary related repo
الخيارات
| الخيار | الوصف | الافتراضي |
|---|---|---|
--name <name> | المستودع المراد فحصه (الجانب الهدف، الجديد). مطلوب. | مطلوب |
--base <name> | المستودع المراد المقارنة معه (الجانب الأساسي، القديم). يُعيّن افتراضيًا إلى أصل --name المحلول من الإعداد المحلي. | أصل --name |
| (بدون علامة تنسيق) | مخرجات الاسم والحالة: حرف ملوّن A/M/D/R لكل ملف متغيّر مع سطر ملخص. | مفعّل |
--name-only | مسار واحد لكل سطر دون حرف الحالة. مناسب للتمرير عبر الأنابيب. | معطّل |
--stat | حجم التغيير لكل ملف (دلتا البايتات والكتل) مع تذييل يحتوي الإجماليات. | معطّل |
--content <path> | فرق نصي موحّد لملف نصي واحد. للنصوص فقط؛ تُبلّغ الملفات الثنائية بـ Binary files differ. | معطّل |
--json | مخرجات منظّمة للوكلاء والسكريبتات. | معطّل |
--fast | تخطي خطوة تأكيد تجزئة المحتوى والوثوق بفلتر الكتل. أسرع، لكنه قد يُبالغ في الإبلاغ عن ملفات على أنها معدّلة. | معطّل |
-m, --machine <name> | الجهاز الهدف. مطلوب. | مطلوب |
--debug | تشخيصات مفصّلة على stderr. | معطّل |
--skip-router-restart | تخطي خطوة إعادة تشغيل الموجّه. | معطّل |
أمثلة
مقارنة الاسم والحالة الافتراضية مع الأصل
عند تمرير --name فقط، تُقارَن النسخة المتشعبة مع الأصل المسجّل في الإعداد المحلي. في المثال التالي، النسخة المتشعبة test-1gb:fork1 تحتوي على ملف واحد معدَّل:
$ rdc repo diff --name test-1gb:fork1 -m hostinger
M hello.txt
1 file changed: 0 added, 1 modified, 0 deleted, 0 renamed
المقارنة مع قاعدة محددة
مرّر --base للمقارنة مع أي مستودع مترابط. --base هو الجانب الأساسي (القديم)، و--name هو الجانب الهدف (الجديد):
$ rdc repo diff --name test-1gb:fork1 --base test-1gb:latest -m hostinger
M hello.txt
1 file changed: 0 added, 1 modified, 0 deleted, 0 renamed
حجم التغيير مع --stat
يُضيف --stat دلتا البايتات والكتل لكل ملف مع تذييل يحتوي الإجماليات:
$ rdc repo diff --name test-1gb:fork1 --stat -m hostinger
hello.txt | +8 bytes, 1 block
1 file changed, 4096 bytes touched
المسارات فقط، ممررة إلى أداة
يطبع --name-only مسارًا واحدًا في كل سطر دون حرف الحالة، جاهزًا للتمرير إلى أمر آخر:
$ rdc repo diff --name test-1gb:fork1 --name-only -m hostinger | xargs -I{} echo "review: {}"
review: hello.txt
فرق على مستوى السطر لملف واحد
يُنتج --content فرقًا موحدًا لملف نصي واحد:
$ rdc repo diff --name test-1gb:fork1 --content hello.txt -m hostinger
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-the original line of text in the parent
+the original line of text in the parent, now edited
تصفية JSON باستخدام jq
يُرسل --json الغلاف المنظّم إلى stdout، مما يجعله مناسبًا للتمرير مباشرةً إلى jq:
$ rdc repo diff --name test-1gb:fork1 --json -m hostinger | jq '.data.entries[] | select(.status=="M")'
{
"status": "M",
"path": "/hello.txt",
"type": "file",
"old_size": 53,
"size": 61,
"bytes_changed": 4096,
"blocks_changed": 1,
"inode": 13,
"content_changed": true,
"mode_changed": false,
"uid_changed": false,
"gid_changed": false
}
صيغ الإخراج
الاسم والحالة (الافتراضي)
يحصل كل ملف متغيّر على حرف حالة ومساره. A يعني مضاف، M معدَّل، D محذوف، R مُعاد تسمية (مع عرض المسار القديم). يلي ذلك سطر ملخص يحتوي العدد لكل فئة.
--name-only
مسار واحد في كل سطر، بدون حرف حالة ولا ملخص. استخدمه حين يحتاج الأمر اللاحق قائمة ملفات نظيفة.
--stat
يحمل كل سطر دلتا البايتات ودلتا الكتل للملف. يُبلّغ التذييل عن إجمالي عدد الملفات وإجمالي البايتات التي طالها التغيير. يُظهر هذا أين يتمركز ثقل التغيير، لا الملفات التي تأثرت فحسب.
--content <path>
فرق موحّد قياسي (رأسا ---/+++ وفقرات @@) لملف نصي واحد. تُبلّغ الملفات الثنائية بـ Binary files differ دون إنتاج أي فقرات.
--json
النتيجة المنظّمة الكاملة. تذهب البيانات إلى stdout وتذهب التقدّم والتشخيصات إلى stderr، مما يتيح تمرير JSON بشكل نظيف إلى jq أو أي محلّل آخر حتى أثناء طباعة مؤشرات التقدّم.
مخطط JSON
يُغلّف CLI نتيجة renet في الغلاف القياسي (success، command، data، errors، warnings، metrics). تقع نتيجة الفرق داخل data بحقول بصيغة snake_case:
{
"success": true,
"command": "repo diff",
"data": {
"base": "<base-guid>",
"target": "<target-guid>",
"added": 0,
"modified": 1,
"deleted": 0,
"renamed": 0,
"strategy": "shared",
"fast": false,
"degraded": false,
"block_size": 4096,
"total_bytes_changed": 4096,
"entries": [
{
"status": "M",
"path": "/hello.txt",
"type": "file",
"old_size": 53,
"size": 61,
"bytes_changed": 4096,
"blocks_changed": 1,
"inode": 13,
"content_changed": true,
"mode_changed": false,
"uid_changed": false,
"gid_changed": false
}
]
}
}
كل كائن في entries[] يصف مسارًا واحدًا متغيّرًا:
| الحقل | النوع | الوصف |
|---|---|---|
status | A | M | D | R | مضاف أو معدَّل أو محذوف أو مُعاد تسمية. |
path | string | المسار على الجانب الهدف (أو الجانب الأساسي عند الحذف). |
old_path | string | المسار السابق. موجود عند إعادة التسمية فقط. |
type | file | dir | symlink | other | نوع المدخلة. |
old_size | number | الحجم بالبايت على الجانب الأساسي. |
size | number | الحجم بالبايت على الجانب الهدف. |
bytes_changed | number | البايتات المختلفة، مقرَّبة للأعلى إلى كتل كاملة. |
blocks_changed | number | عدد الكتل المتغيّرة. |
inode | number | رقم inode، يُستخدم لاكتشاف إعادة التسمية. |
content_changed | boolean | ما إذا تغيّر محتوى الملف (لا البيانات الوصفية فقط). |
mode_changed | boolean | ما إذا تغيّر وضع الملف. يظهر old_mode/new_mode عندما تكون القيمة true. |
uid_changed | boolean | ما إذا تغيّر المالك. يظهر old_uid/new_uid عندما تكون القيمة true. |
gid_changed | boolean | ما إذا تغيّرت المجموعة. يظهر old_gid/new_gid عندما تكون القيمة true. |
old_target / new_target | string | وجهات الروابط الرمزية. موجودة للروابط الرمزية المتغيّرة. |
لحقول الغلاف وقواعد الاكتشاف التلقائي التي تُصدر JSON في البيئات غير الطرفية، راجع مرجع مخرجات JSON.
آلية العمل
المستودع عبارة عن ملف صورة LUKS2 على مجموعة btrfs، والنسخة المتشعبة هي reflink ثابت الوقت لتلك الصورة. يقارن repo diff الصورتَين المشفَّرتَين على مستوى الكتل عبر FIEMAP، يقرأ البيانات الوصفية لنظام الملفات فقط دون فك تشفير أي شيء. يُحوّل إزاحات النص المشفّر المتغيّرة بإزاحة بيانات LUKS للحصول على إزاحات جهاز ext4، ثم يُعيد ربط تلك الإزاحات بأسماء الملفات عبر خريطة الامتدادات ext4 لكل ملف. يُتبع ذلك بجولة تعريف inode على كلتا التحميلتين تُوفّق النتيجة في مدخلات مضافة ومعدَّلة ومحذوفة ومُعادة التسمية. نظرًا لأن العمل محدود بعدد الكتل المتغيّرة، يستقل الفرق عن حجم المستودع، ولأنه يُعيد استخدام تحميل قائم في مكانه، لا يُزعزع استقرار أي مستودع قيد التشغيل. الآلية الكاملة موصوفة في Git diff for encrypted disk images.
القيود
- النسخ المتشعبة المترابطة فقط. يجب أن يتشارك الطرفان سلفًا مشتركًا من نوع نسخ-عند-الكتابة. لا توجد مقارنة ذات معنى على مستوى الكتل بين مستودعات غير مترابطة.
- اكتشاف إعادة التسمية يعتمد على inode. يُبلَّغ عن ملف بوصفه مُعادًا تسميته حين يظهر inode ذاته في مسار جديد. الحذف ثم إعادة الإنشاء (inode جديد) يظهر كمدخلة محذوفة ومدخلة مضافة، لا كإعادة تسمية.
--contentللنصوص فقط. يُنتج فقرات على مستوى السطر للملفات النصية. تُبلّغ الملفات الثنائية بـBinary files differ.- قد يُبالغ
--fastفي الإبلاغ عن التعديلات. يثق بفلتر الكتل ويتخطى تأكيد تجزئة المحتوى، لذا قد يظهر ملف انتقلت كتله دون تغيير محتواه على أنه معدَّل. - وقت جولة الامتدادات يتناسب مع التجزئة لا مع الحجم. نظام الملفات المُجزَّأ بشدة يحتوي على امتدادات أكثر للتعيين، مما يُطيل الجولة حتى حين يكون حجم التغييرات بالبايت صغيرًا.
انظر أيضًا
- rdc repo fork. إنشاء النسخة المتشعبة بنسخ-عند-الكتابة التي يقارنها هذا الأمر.
- rdc repo status. الحالة الراهنة لمستودع واحد.
- rdc repo cat. قراءة ملف واحد من مستودع.