أدوات مساحة العمل

خصائص الملفات

.gitattributes هو أعلى ملفات git قيمةً وأقلّها كتابةً. إنه الطريقة التي يعلّم بها المستودع git عن محتوياته: أي الملفات ثنائي، وأيها ينبغي أن يُلحَق بعضه ببعض بدل أن يتعارض، وأيها لا يخرج أبدًا في أرشيف، وأي نهايات أسطر يحصل عليها الجميع.

الجزء المهم: إنه ملف ملتزَم به. القاعدة التي تضيفها تُصلح المشكلة لكل من يستنسخ المستودع، على كل نظام تشغيل، إلى الأبد — بخلاف إعداد في تهيئتك الخاصة، الذي يُصلحها لك وحدك ويترك زملاءك يكتشفونها بالطريقة الصعبة.

⌘K ← خصائص الملفات.

القواعد التي يحملها المستودع أصلًا، والقوالب الجاهزة، وفاحص المسارات، ومحرّكات الفروق

ما الذي تفعله القواعد

الخاصية تُصلح
text=auto eol=lf نهايات أسطر تتقلّب تبعًا لمن سحب الملف
binary محاولة git أن يقارن أو يدمج ثلاثيًا ملف PSD أو DOCX أو أصلًا مُصرَّفًا
merge=union سجل تغييرات يُلحق به الجميع، ويتعارض عليه الجميع
-merge ملفات ينتج فيها الدمج الثلاثي هراءً — ملفات القفل، الشيفرة المولَّدة
export-ignore تهيئة التكامل المستمر والتجهيزات المشحونة داخل أرشيف إصدار
diff=<driver> فروق غير مقروءة لصيغ هي مقروءة، متى توفّر محوِّل
filter=lfs ملفات كبيرة مخزَّنة عبر LFS
linguist-vendored شيفرة مستوردة تُحسب لك في إحصاءات اللغات

binary اختصار لـ -diff -merge -text، أي ثلاث إجابات عن «كفّ عن التخمين بشأن هذا الملف» في كلمة واحدة.

التحرير

تملأ القوالب الجاهزة النمط وخصائصه؛ حرّر النمط قبل الإضافة — فـ CHANGELOG.md اقتراح، لا قاعدة عن مشروعك.

التعديلات جراحية. إضافة قاعدة لنمط له قاعدة أصلًا تعيد كتابة ذلك السطر في مكانه، بدل إلحاق قاعدة ثانية تفوز لكونها متأخرة. التعليقات في الملف تبقى كما هي، لأن «لماذا» المكتوبة بجانب القاعدة تساوي عادةً أكثر من القاعدة نفسها.

كل حفظ هو إجراء عادي في Gitcito: يُظهر إشعارًا، والتراجع يعيد الملف كما كان تمامًا.

يمكن أن يحمل المستودع عدة ملفات خصائص. واحد في الجذر، وواحد في أي مجلد فرعي، وملف خاص .git/info/attributes لا يُلتزم به أبدًا ولا ينطبق إلا على جهازك — وهو المكان الصحيح لقاعدة تخصّك أنت، لا المشروع. يسردها Gitcito جميعًا ويبيّن أيّها أيّ.

ما الذي ينطبق على مسار؟

تأتي القواعد من عدة ملفات، والأكثر تحديدًا هو الذي يفوز، وقراءتها لاستنتاج الجواب تخمين. ما الذي ينطبق على مسار؟ يشغّل git check-attr ويعرض ما يستنتجه git نفسه — وهو الجواب الوحيد الذي يُعتدّ به.

محرّكات الفروق: جعل مستند Word مقروءًا

ملف .docx هو ملف مضغوط. وملف .pdf رسم كائنات مضغوط. يقارنهما git كما هما — ضجيجًا — فيصبح سجل المستند غير مقروء رغم أن المستند نفسه مقروء.

يُصلح محرّك الفروق هذا عبر textconv: أمر يحوّل الملف إلى نص لأغراض المقارنة فقط. الملف في شجرة عملك يبقى دون مساس؛ كل ما يفعله git هو مقارنة النص المحوَّل.

نصفان، وكلاهما لازم:

  1. diff.<name>.textconv في تهيئة git — أمر التحويل.
  2. *.docx diff=<name> في .gitattributes — الملفات التي ينطبق عليها.

الأزرار هنا تفعل الأمرين معًا. لملفات Word وExcel وJSON و.strings، يشحن Gitcito المحوِّل بنفسه — وهو نفس تحليل المستندات الذي تستخدمه معايناته، مكشوفًا كأمر صغير باسم gitcito-textconv داخل التطبيق — لذا تعمل هذه الأربعة دون تثبيت أي شيء. أما البقية فما زالت تحتاج أداة حقيقية في مسار PATH لديك: يفحص Gitcito ذلك ويطفئ ما هو مفقود بدل أن يكتب محرّكًا يفشل عند أول فرق.

المحرّك يحتاج يمنحك
word لا شيء — يأتي مع Gitcito فروقًا نصية لملفات .docx
excel لا شيء — يأتي مع Gitcito فروق صفوف (CSV لكل ورقة) لملفات .xlsx/.xls
json لا شيء — يأتي مع Gitcito فروق JSON مرتّبة بالمفاتيح وثابتة
strings لا شيء — يأتي مع Gitcito فروق سطرية لملف .strings بترميز UTF-16 الذي يعدّه git ثنائيًا
pdf pdftotext (poppler) فروقًا نصية لملفات .pdf
exif exiftool ما الذي تغيّر في صورة، حين تكون البكسلات معتمة

الملف الذي يعضّ مشاريع iOS فعلًا

ملف Localizable.strings بترميز UTF-16 طوال معظم تاريخ Xcode، وUTF-16 مليء ببايتات NUL، فيعدّه git ثنائيًا ولا يعرض شيئًا:

diff --git a/Localizable.strings b/Localizable.strings
Binary files a/Localizable.strings and b/Localizable.strings differ

وهو بالضبط الملف الذي تهمّك فيه رؤية أي نص حرّكه أحدهم أكثر من أي ملف آخر. مشغّل strings يفكّ ترميزه لغرض المقارنة فقط — قارئًا علامة ترتيب البايتات بدل افتراضها، فيمرّ ملف .strings الحديث بترميز UTF-8 سليمًا بدل أن يتحول إلى طلاسم.

وكتالوجات النصوص (.xcstrings، من Xcode 15 فصاعدًا) ملفات JSON يغطيها مشغّل json: فهو يرتّب المفاتيح، فتتوقف ترجمة مضافة في الأعلى عن إعادة كتابة الملف كله في الفروق.

حدود المحوِّل المرفق، بصراحة: صيغة .doc (صيغة Word الثنائية القديمة) غير مفهومة، فقط .docx؛ وملفات PDF غير مشمولة — يعاين Gitcito ملفات PDF بعارض المتصفح وليس لديه مستخرج نصوص يعيد استخدامه؛ وكل فرق لمستند يدفع كلفة بدء تشغيل قصيرة للمحوِّل. ضبط git config diff.<name>.cachetextconv true يجعل git يخزّن الناتج مؤقتًا لكل blob.

النصف الخاص بالمحوِّل يعيش في تهيئتك أنت، لا في المستودع — فـ git لن يشغّل أوامر يسلّمها لك استنساخ، وهذه خاصية أمنية تستحق الحفاظ عليها. كما أن المحرّكات المرفقة تشير إلى مسار تثبيت Gitcito لديك أنت، لذا فالزميل الذي يستنسخ المستودع يحصل على قاعدة diff=word وعلى الفرق القديم غير المقروء، إلى أن يوصّل محوِّله الخاص (Gitcito أو غيره). قل ذلك في ملف README.

مرشّحات clean/smudge — بتشغيل تجريبي أولًا

المرشّح يعيد كتابة المحتوى في طريقه إلى المستودع ومنه: clean يعمل عند التجهيز (شجرة العمل ← المستودع)، وsmudge عند السحب (المستودع ← شجرة العمل). هكذا يعمل git-lfs، وهكذا تزيل الفرق بيانات الاعتماد أو الضجيج المولَّد مما يُلتزم به.

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

  1. يعمل أمر clean على نسخة من كل ملف مطابق (حتى خمسة ملفات) — دون مساس بأي شيء في المستودع أو تهيئته.
  2. إن أُعطي أمر smudge، فإنه يعمل على الناتج المنظَّف وتُقارن نتيجته بايتًا ببايت مع الأصل — فحص الذهاب والإياب. المرشّح الذي لا يجتاز هذا الفحص يعني أن السحب لن يعيد ما كان لديك.
  3. لا يُفعَّل زر الحفظ إلا بعد تشغيل تجريبي على القيم ذاتها التي تحفظها. والتشغيل التجريبي الذي فشل — خطأ في الأمر، أو لا شيء مطابق، أو ذهاب وإياب مختلف — يظل قابلًا للحفظ، لكن عبر تحذير صريح يقول ما الذي قد يُفقد.

الحفظ يكتب filter.<name>.clean/smudge في تهيئة git المحلية لديك وقاعدة filter=<name> في ملف الخصائص، ويترك مدخل تراجع يعيد ما كانت التهيئة تحمله من قبل. مفتاح required يضبط filter.<name>.required، مما يجعل git يُفشل العملية بدل أن يمرّر الملفات بصمت دون تغيير حين يتعطل المرشّح.

الحدود، بصراحة: التشغيل التجريبي يأخذ عيّنة حتى خمسة ملفات مطابقة بحجم أقصاه 5 MB لكل ملف، بمهلة 10 ثوانٍ لكل أمر — والمرشّح الذي يحسن التصرف على العيّنة قد يسيء التصرف على ملف فاتته العيّنة. الأوامر تعيش في تهيئتك أنت، لذا فالزميل الذي يستنسخ يحصل على قاعدة filter=<name> دون الأوامر؛ وبدونها (وبدون required) تمرّ ملفاته دون تغيير.

حدود يجدر معرفتها

  • text=auto يغيّر ما الذي يُلتزم به، إذ يوحّد نهايات الأسطر عند الدخول. في مستودع قائم، أضفه ثم شغّل git add --renormalize . عن قصد، في التزام مستقل خاص به.
  • الخصائص لا تنطبق بأثر رجعي. وسم ملف بـ binary اليوم لا يغيّر كيف خُزّنت فروقه الماضية؛ بل يغيّر كيف يعامله git من الآن فصاعدًا.
  • القواعد لا تسري إلا حيث يكون الملف مرئيًا. قاعدة في design/.gitattributes لا تقول شيئًا عن src/.
  • يكتب Gitcito ملفات كاملة، لذا يعود الملف المنسَّق يدويًا بتنسيقه — لكن القاعدة التي يعيد Gitcito كتابتها يُعاد تنسيقها إلى تباعد git المعياري pattern attr attr.

انظر أيضًا: LFS والسحب الجزئي · الحزم والأرشيفات · خيارات الدمج · الخطافات

حسّن هذه الترجمة على GitHub