كيفية إصلاح خطأ “would clobber existing tag” في Git.
يعرض Git الخطأ “would clobber existing tag” عندما تحاول عملية fetch استبدال وسم محلي موجود بكائن مختلف. قارن مرجعَي الوسم، واحفظ المرجع المحلي. لا تحدّث إلا ذلك الوسم، وفقط بعد التأكد من أن النسخة البعيدة هي النسخة الصحيحة.
خطوات المعالجة الآمنة
حدد الوسم المذكور في الخطأ. قارن معرّفات الكائنات المحلية والبعيدة، وأنشئ نسخة احتياطية محلية. إذا كانت النسخة البعيدة صحيحة، اجلب ذلك الوسم الذي تحققت منه وحده مع السماح باستبداله. لا تفرض تحديث جميع الوسوم ولا تدفع وسماً بديلاً إلى المستودع البعيد.
للوسوم المشروحة معرّفات كائنات خاصة بها. قد يشير كائنان لوسمين إلى الالتزام نفسه مع اختلاف الرسالة أو التوقيع. قارن مراجع الوسوم والكائنات التي تشير إليها بعد فكّ المرجع قبل تحديد ما تغيّر.
1. افحص الوسم المحدد بدقة
استبدل v1.2.3 بالوسم المذكور في الخطأ، وorigin باسم المستودع البعيد لديك. هذه الأوامر لا تغيّر المراجع.
git show-ref --verify refs/tags/v1.2.3
git rev-parse 'refs/tags/v1.2.3^{}'
git ls-remote --tags origin 'refs/tags/v1.2.3' 'refs/tags/v1.2.3^{}'يعرض الأمر الأول معرّف كائن الوسم المحلي. يفكّ الأمر الثاني مرجع الوسم المشروح للوصول إلى الكائن الذي يشير إليه. يعرض ناتج المستودع البعيد مرجع الوسم، وللوسم المشروح سطراً ينتهي بـ ^{} يوضح الكائن الهدف بعد فكّ المرجع.
استخدم أسماء المراجع الكاملة الموضحة هنا. قد يشمل البحث بالبادئة v1.2.3 الوسم v1.2.30 أيضاً. إذا لم يكن هناك وسم مطابق في المستودع البعيد، فتوقف؛ هذه الخطوات ليست سبباً لحذف الوسم المحلي.
2. احفظ المرجع المحلي الأصلي
أنشئ وسماً محلياً للاستعادة قبل استبدال أي شيء. تشترط الوسيطة الفارغة في النهاية ألا يكون اسم النسخة الاحتياطية مستخدماً من قبل.
git update-ref refs/tags/backup/v1.2.3 refs/tags/v1.2.3 ""
git rev-parse refs/tags/v1.2.3 refs/tags/backup/v1.2.3يجب أن يتطابق معرّفا الكائنين. بذلك تحتفظ بكائن الوسم الأصلي، بما في ذلك رسالة الوسم المشروح وتوقيعه. إذا فشل الإنشاء لأن النسخة الاحتياطية موجودة بالفعل، فاختر اسماً جديداً وتحقق منه قبل المتابعة.
احتفظ بالنسخة الاحتياطية حتى تُحلّ مسألة الاختلاف. تظلّ محلية ما لم تدفعها إلى المستودع البعيد؛ لا تستخدم git push --tags لهذا الإصلاح.
3. حدّث الوسم الذي تحققت منه فقط
نفّذ هذا فقط بعد التأكد من أن الوسم البعيد هو النسخة الصحيحة وأن النسخة الاحتياطية موجودة. تسمح علامة + في البداية باستبدال هذا المرجع المحلي المحدد.
git fetch --no-tags --no-prune --no-prune-tags origin '+refs/tags/v1.2.3:refs/tags/v1.2.3'
git show-ref --verify refs/tags/v1.2.3
git rev-parse 'refs/tags/v1.2.3^{}'يعطّل --no-tags التتبّع التلقائي للوسوم الأخرى. ويعطّل --no-prune و--no-prune-tags تنظيف المراجع المُعدّ مسبقاً لهذه العملية، حتى لا يتسع نطاق الإصلاح. لا يجري دفع أي فرع أو وسم بعيد أو استبداله في المستودع البعيد.
قارن كائن الوسم المجلوب والكائن الهدف بعد فكّ مرجعه بالمعرّفات البعيدة التي فحصتها. إذا تغيّر المستودع البعيد أثناء الإصلاح، فتوقف وافحص السبب قبل استخدام الوسم في إصدار. تظلّ النسخة الاحتياطية تشير إلى الكائن الأصلي.
لماذا يرفض Git التحديث
منذ Git 2.20، تتطلب عملية fetch السماح الصريح بالتحديث القسري لاستبدال مرجع موجود ضمن refs/tags/*. تسري هذه القاعدة حتى لو كانت هناك علاقة سلف بين الالتزامين الهدفين؛ لا تُحدّث الوسوم وفق قواعد fast-forward الخاصة بالفروع.
إذا كان الوسم المحلي يشير إلى الإصدار الصحيح، فاحتفظ به وتواصل مع المسؤول عن الصيانة. يؤدي استبدال وسم بعيد منشور إلى تغيير ما يحصل عليه المستخدمون الآخرون تحت اسم الإصدار نفسه.
مراجع Git الرسمية
افحص أولاً، ثم غيّر المرجع الضروري فقط.
يجمع FluxGit الوسوم وفحص حالة المستودع والعمليات التي تتطلب مراجعة ضمن عميل Git مكتبي لأنظمة macOS وWindows وLinux. استخدم الأوامر أعلاه لتشخيص هذا الخطأ في Git قبل تغيير أي مرجع.