Start free
Andrew Hanna

Andrew Hanna

كيفية إعداد merge driver في git واعٍ بـSalesforce

كيفية إعداد merge driver في git واعٍ بـSalesforce

باختصار: الـmerge driver برنامج يستدعيه git بدل الدمج القائم على الأسطر، لأنماط الملفات التي تحددها أنت. وجّه واحدًا إلى ميتاداتا Salesforce عبر .gitattributes، وسجّله في إعدادات git لكل clone، فتُدمج تغييرات عُقد الـXML المستقلة تلقائيًا بدل أن تصلك كعلامات تعارض. الإعداد يخص كل clone على حدة، فيحتاج خطوة تهيئة، وهو لا يعمل أبدًا مع زر الدمج على منصة الاستضافة.

هذا دليل الإعداد، لا دليل الحل. إن كانت علامات التعارض مفتوحة أمامك الآن، اقرأ أولًا كيف تحل تعارضات ميتاداتا Salesforce من غير ما تضيّع شغل حد، ثم عد إلى هنا لمنع الدفعة التالية من الوصول إليك أصلًا.

ماذا يفعل الـmerge driver فعليًا؟

حين ينفّذ git دمجًا ثلاثي الاتجاه، يحتاج ثلاث نسخ من الملف: النسخة الأصل المشتركة، ونسختك، والنسخة الواردة. افتراضيًا يوفّق بينها سطرًا بسطر. الـmerge driver يستبدل هذه الخطوة بأمر من اختيارك، ويسلّمه git النسخ الثلاث كملفات مؤقتة.

العقد بينهما بسيط. يعوّض git العناصر النائبة في سطر الأمر:

  • %O نسخة الأصل المشتركة
  • %A نسختك، وهي الملف الذي يجب أن يكتب فيه الـdriver النتيجة
  • %B النسخة الواردة
  • %P المسار الحقيقي للملف الجاري دمجه
  • %L حجم علامة التعارض

الخروج بالقيمة 0 يجعل git يعتمد محتوى %A كدمج نظيف. والخروج بقيمة غير صفرية يجعله يعدّه تعارضًا ويترك %A لإنسان. هذه كل الواجهة، ولهذا يمكن أن يكون الـdriver الواعي بـSalesforce بسيطًا كسكربت يقرأ الطرفين كـXML، ويوحّد العُقد الفرعية تحت كل عقدة أب، ولا ينسحب إلا حين يحمل العنصر المفتاحي نفسه قيمًا مختلفة في الطرفين.

كيف تعدّه في git؟

ملفان، واحد منهما فقط داخل نظام الإصدارات.

أولًا، سجّل الـdriver في إعدادات git. مكانها .git/config، وهي محلية لكل clone:

git config merge.sfxml.name "Salesforce metadata XML merge"
git config merge.sfxml.driver "sf-xml-merge %O %A %B %P"

ثانيًا، أخبر git بالملفات التي يملكها، في .gitattributes في جذر الريبو. هذا الملف يُرفع بالفعل، فيصل إلى كل زميل:

force-app/**/*.profile-meta.xml      merge=sfxml
force-app/**/*.permissionset-meta.xml merge=sfxml
force-app/**/*.layout-meta.xml       merge=sfxml
force-app/**/*.translation-meta.xml  merge=sfxml

ابدأ ضيقًا. أضف نوعين أو ثلاثة من الميتاداتا تولّد أكثر التعارضات، وعِش معها سبرنتًا كاملًا، ثم وسّع الأنماط. الـdriver الذي يسيء التعامل بصمت مع نوع لم تختبره أسوأ من التعارض الذي حلّ محله.

لماذا يحتاج كل clone إعدادًا، وكيف تؤتمته؟

.gitattributes داخل نظام الإصدارات، أما merge.sfxml.driver فلا، وgit يرفض تشغيل أمر عرفه من ملف مستنسخ فقط. هذا الفصل تصميم أمني مقصود: الريبو الذي تستنسخه لا يستطيع أن يجعل جهازك ينفّذ أوامر عشوائية.

والنتيجة العملية أن الزميل الذي يتخطى الإعداد لا يرى أي خطأ. يعود git بصمت إلى الدمج النصي المدمج فيرى هو علامات تعارض بينما يرى الجميع دمجًا نظيفًا. عالج ذلك بخطوة تهيئة لا يحتاج أحد لتذكّرها: ارفع scripts/setup-merge-driver.sh ينفّذ أمري git config، واستدعِه من خطاف ما بعد التثبيت في مدير الحزم لديك، واجعله يفشل بصوت عالٍ إذا كان الـdriver غير موجود.

أي عمليات دمج لا يراها الـdriver أبدًا؟

ثلاث ثغرات تستحق المعرفة قبل الاعتماد عليه:

  • الدمج على الخادم. زر الدمج في GitHub أو GitLab أو Bitbucket يعمل على بنيتهم التحتية، بلا وصول إلى .git/config عندك. فقد يبلّغ pull request عن تعارضات هناك رغم أنه سيُدمج نظيفًا على جهازك. الحل المعتاد: ادمج الفرع الهدف في فرع الميزة محليًا، حيث يعمل الـdriver، وادفع الحل.
  • التغييرات من طرف واحد. لا يستدعي git الـdriver إلا حين يلمس الطرفان الملف. فإن غيّره طرف واحد فقط، أخذ git ذلك الطرف ولم يبدأ الـdriver إطلاقًا.
  • الـXML المولَّد آليًا. يستطيع الـdriver توحيد العُقد، لكنه لا يعرف أن نسختي Flow تصفان منطقًا غير متوافق. أبقِ *.flow-meta.xml خارج أنماطك وحلّه في Flow Builder.

هل توجد نسخة بلا تثبيت؟

نعم، للحالات الإضافية البحتة. يأتي git بـdriver مدمج اسمه union يحتفظ بكل الأسطر من الطرفين، ولا يحتاج أي مدخل في الإعدادات:

force-app/**/labels/*.labels-meta.xml merge=union

لكنه فظ. دمج union يلصق ولا يزيل التكرار، فالعقدة التي أضافها الفرعان تهبط مرتين وقد يعود الملف غير صالح. استخدمه فقط على القوائم المسطّحة الإضافية البحتة مثل custom labels، وأبقِ تحقق نشر في الـCI يلتقط ما يخطئ فيه. عدّه حلًا مؤقتًا ريثما تقيّم driver حقيقيًا، لا محطة نهائية.

driver أم منصة أم حل على الـpull request؟

الـmerge driver أرخص الطبقات وأضيقها: يزيل التعارضات الزائفة على طبقة git، على أجهزة المطورين، ولا يفعل شيئًا للتحقق أو النشر. أما منصات DevOps فتبني الدمج الدلالي داخل خط الأنابيب بلوحة ثلاثية الاتجاه مرئية، وهو ما يسد ثغرة الخادم لكنه يربط الحل بأدواتها.

ويسلك Serpent الطريق الثالث فيحل على الـpull request نفسه: يقرأ Serpent AI التعارض، ويقترح حلًا، وينتظر مراجعتك قبل تطبيقه، فيهبط الإصلاح حيث يقع الدمج فعلًا بدل أن يعتمد على الجهاز المضبوط صدفة. اطّلع على Serpent AI، أو تصفح المزيد من أدلة Salesforce DevOps الدائمة في أدلة Serpent.

الأسئلة الشائعة

هل يجب أن أكتب الـmerge driver بنفسي؟

ليس بالضرورة. توجد merge drivers مفتوحة المصدر لـXML الخاص بـSalesforce، وأي أداة دمج واعية بالـXML يمكن تغليفها في سكربت شِل من سطرين يلتزم بعقد %O %A %B. وكتابة واحد بنفسك عمل معقول لبعد ظهر واحد إذا كانت ميتاداتاك ذات شكل غير معتاد.

هل يغيّر الـmerge driver ملفات مرفوعة بالفعل؟

لا. يعمل أثناء الدمج فقط، على ناتج الدمج. التاريخ يبقى كما هو، فيمكنك إضافته ثم إزالته دون إعادة كتابة أي شيء.

ماذا يحدث إذا انهار الـdriver؟

يعامل git الخروج بقيمة غير صفرية كتعارض غير محلول ويترك العلامات مكانها، فالـdriver المعطوب يعود بك إلى السلوك الذي كان لديك من قبل. اجعل الخاص بك يخرج بقيمة غير صفرية عند أي شيء لا يفهمه بدل التخمين.

هل يغني هذا عن تطبيع الميتاداتا عند الـretrieve؟

لا، والاثنان يتكاملان. تطبيع ترتيب العناصر يصغّر الـdiff قبل أن يراه git، والـdriver يتولى ما يتبقى. شغّل الاثنين إن استطعت.

مقالات ذات صلة

هل تريد معرفة كيف يمكنكم الشحن أسرع قبل البدء؟ لنتحدث

بدون التزام.