دليل للتراجع عن الأخطاء باستخدام Git (الجزء الثاني)
نشرت: 2022-03-10في هذا الجزء الثاني من سلسلتنا حول "Undoing Mistakes with Git" ، سننظر إلى الخطر بشجاعة مرة أخرى: لقد أعددت أربعة سيناريوهات جديدة ليوم القيامة - بما في ذلك ، بالطبع ، بعض الطرق الذكية لإنقاذ أعناقنا! ولكن قبل أن نتعمق في الأمر: ألق نظرة على المقالات السابقة على Git للاطلاع على المزيد من أساليب الإنقاذ الذاتي التي تساعدك على التراجع عن أخطائك مع Git!
دعنا نذهب!
استعادة فرع محذوف باستخدام Reflog
هل سبق لك أن حذفت فرعًا ، وبعد فترة وجيزة ، أدركت أنه لا يجب عليك فعل ذلك؟ في حالة عدم معرفتك بهذا الشعور ، وهو أمر بعيد الاحتمال ، يمكنني أن أخبرك أنه ليس جيدًا. يتسلل إليك مزيج من الحزن والغضب ، بينما تفكر في كل العمل الشاق الذي تم بذله في التزامات هذا الفرع ، وكل الشفرة القيمة التي فقدتها الآن.
لحسن الحظ ، هناك طريقة لإعادة هذا الفرع من الموت - بمساعدة أداة Git المسماة "Reflog". لقد استخدمنا هذه الأداة في الجزء الأول من سلسلتنا ، ولكن إليك القليل من التنشيط: إن Reflog يشبه دفتر اليومية حيث يلاحظ Git كل حركة لمؤشر HEAD في مستودعك المحلي. بعبارات أخرى أقل غرابة: في أي وقت تقوم فيه بتسجيل الخروج ، أو الالتزام ، أو الدمج ، أو تغيير العنوان الأساسي ، أو اختيار الكرز ، وما إلى ذلك ، يتم إنشاء إدخال دفتر يومية. هذا يجعل Reflog شبكة أمان مثالية عندما تسوء الأمور!
دعنا نلقي نظرة على مثال ملموس:
$ git branch * feature/login master
يمكننا أن نرى أن لدينا حاليًا feature/login
الخاصة بنا التي تم التحقق منها. لنفترض أن هذا هو الفرع الذي سنحذفه (بدون قصد). قبل أن نتمكن من القيام بذلك ، ومع ذلك ، نحتاج إلى التبديل إلى فرع مختلف لأننا لا نستطيع حذف فرع HEAD الحالي الخاص بنا!
$ git checkout master $ git branch -d feature/login
لقد انتهى الآن فرع الميزات القيمة الخاص بنا - وسأمنحك دقيقة (أ) لفهم خطورة خطأنا و (ب) للحزن قليلاً. بعد أن تمسح الدموع ، نحتاج إلى إيجاد طريقة لإعادة هذا الفرع! لنفتح Reflog (ببساطة عن طريق كتابة git reflog
) ونرى ما يخبئه لنا:
فيما يلي بعض التعليقات لمساعدتك في فهم النتيجة:
- بادئ ذي بدء ، عليك أن تعرف أن Reflog يفرز إدخالاته ترتيبًا زمنيًا: العناصر الأحدث موجودة في أعلى القائمة.
- العنصر العلوي (وبالتالي الأحدث) هو أمر
git checkout
الذي قمنا به قبل حذف الفرع. تم تسجيله هنا في Reflog لأنه أحد "حركات مؤشر HEAD" التي يسجلها Reflog بشكل كامل. - للتراجع عن خطأنا الجسيم ، يمكننا ببساطة العودة إلى الحالة السابقة - والتي تم تسجيلها أيضًا بشكل نظيف وواضح في Reflog!
لذلك دعونا نجرب هذا ، من خلال إنشاء فرع جديد (باسم الفرع "المفقود") يبدأ عند هذه الحالة "قبل" SHA-1:
$ git branch feature/login 776f8ca
وفويلا! ستسعد برؤية أننا استعدنا الآن فرعنا الذي يبدو أنه مفقود!
إذا كنت تستخدم واجهة مستخدم رسومية لسطح المكتب من Git مثل "Tower" ، فيمكنك أن تأخذ اختصارًا لطيفًا: ما عليك سوى الضغط على CMD + Z على لوحة المفاتيح للتراجع عن الأمر الأخير - حتى لو قمت بحذف فرع عنيف!
نقل الالتزام إلى فرع مختلف
في العديد من الفرق ، هناك اتفاق على عدم الالتزام بفروع طويلة الأمد مثل الفروع main
أو develop
: يجب أن تتلقى الفروع مثل هذه التزامات جديدة فقط من خلال عمليات الدمج (مثل عمليات الدمج أو إعادة التأسيس). ومع ذلك ، فإن الأخطاء لا مفر منها بالطبع: فنحن ننسى أحيانًا هذه الفروع ونرتكبها! إذن كيف يمكننا تنظيف الفوضى التي أحدثناها؟
لحسن الحظ ، يمكن تصحيح هذه الأنواع من المشاكل بسهولة. دعونا نشمر عن سواعدنا ونبدأ العمل.
الخطوة الأولى هي التبديل إلى فرع الوجهة الصحيح ثم نقل الالتزام بإفراط باستخدام أمر cherry-pick
:
$ git checkout feature/login $ git cherry-pick 776f8caf
سيكون لديك الآن الالتزام على الفرع المطلوب ، حيث كان يجب أن يكون في المقام الأول. مدهش!
ولكن لا يزال هناك شيء واحد يجب القيام به: نحن بحاجة إلى تنظيف الفرع الذي هبط فيه عن طريق الخطأ في البداية! أنشأ أمر cherry-pick
، إذا جاز التعبير ، نسخة من الالتزام - لكن الأصل لا يزال موجودًا في فرعنا طويل الأمد:
هذا يعني أنه يتعين علينا العودة إلى الفرع طويل الأمد واستخدام git reset
لإزالته:
$ git checkout main $ git reset --hard HEAD~1
كما ترى ، نحن نستخدم الأمر git reset
هنا لمحو الالتزام الخاطئ. تخبر المعلمة HEAD~1
Git بـ "الرجوع إلى مراجعة واحدة خلف HEAD" ، مما يمحو بفعالية الالتزام الأعلى (وفي حالتنا: غير المرغوب فيه) من تاريخ هذا الفرع.
وفويلا: أصبح الالتزام الآن حيث كان يجب أن يكون في المقام الأول وفرعنا الذي يمتد لفترة طويلة نظيف - كما لو أن خطأنا لم يحدث أبدًا!
تحرير رسالة التزام قديم
من السهل جدًا تهريب خطأ مطبعي في رسالة الالتزام - واكتشافه فقط في وقت لاحق. في مثل هذه الحالة ، لا يمكن استخدام خيار --amend
git commit
القديم الجيد لإصلاح هذه المشكلة ، لأنه يعمل فقط مع آخر التزام. لتصحيح أي التزام أقدم من ذلك ، يتعين علينا اللجوء إلى أداة Git تسمى “Interactive Rebase”.
أولاً ، علينا إخبار Interactive Rebase أي جزء من سجل الالتزام نريد تعديله. يتم ذلك عن طريق إدخال تجزئة التزام: يلتزم الوالد بالشيء الذي نريد التلاعب به.
$ git rebase -i 6bcf266b
سيتم فتح نافذة محرر بعد ذلك. يحتوي على قائمة بجميع الالتزامات بعد ذلك الذي قدمناه كأساس لـ Interactive Rebase في الأمر:
هنا ، من المهم ألا تتبع دافعك الأول: في هذه الخطوة ، لا نقوم بتحرير رسالة الالتزام حتى الآن. بدلاً من ذلك ، نخبر Git فقط بنوع التلاعب الذي نريد القيام به مع الالتزام (الالتزامات). ملائم تمامًا ، هناك قائمة بالكلمات الرئيسية للإجراءات المذكورة في التعليقات أسفل هذه النافذة. بالنسبة لحالتنا ، نقوم بترميز السطر رقم 1 بإعادة reword
(وبالتالي استبدال pick
القياسي).
كل ما تبقى للقيام به في هذه الخطوة هو حفظ وإغلاق نافذة المحرر. في المقابل ، ستفتح نافذة محرر جديدة تحتوي على الرسالة الحالية للالتزام الذي قمنا بترميزه. والآن حان الوقت أخيرًا لإجراء تعديلاتنا!
إليك العملية برمتها في لمحة سريعة بالنسبة لك:
تصحيح الالتزام المنكسر (بطريقة أنيقة للغاية)
أخيرًا ، سنلقي نظرة على fixup
، سكين الجيش السويسري لأدوات التراجع. ببساطة ، يسمح لك بإصلاح الالتزام المكسور / غير الكامل / غير الصحيح بعد حدوثه. إنها حقًا أداة رائعة لسببين:
- لا يهم ما هي المشكلة.
ربما نسيت إضافة ملف ، أو كان يجب حذف شيء ما ، أو إجراء تغيير غير صحيح ، أو مجرد خطأ إملائي.fixup
يعمل في كل هذه المواقف! - إنه أنيق للغاية.
رد فعلنا الطبيعي الغريزي على خطأ في الالتزام هو إنتاج التزام جديد يعمل على حل المشكلة. طريقة العمل هذه ، مهما بدت بديهية ، تجعل سجل الالتزام الخاص بك يبدو فوضويًا للغاية ، قريبًا جدًا. لديك التزامات "أصلية" ومن ثم هذه الالتزامات الصغيرة "الإسعافات الأولية" التي تعمل على إصلاح الأخطاء التي حدثت في الالتزامات الأصلية. تاريخك مليء بالتعهدات الصغيرة التي لا معنى لها والتي تجعل من الصعب فهم ما حدث في قاعدة التعليمات البرمجية الخاصة بك.
هذا هو المكان الذي يأتي فيه fixup
. فهو يسمح لك بالاستمرار في تنفيذ تصحيح الضمادة المساعدة. ولكن هنا يأتي السحر: ثم يطبقه على الالتزام الأصلي المكسور (إصلاحه بهذه الطريقة) ثم يتجاهل الالتزام الإسعافي القبيح تمامًا!
يمكننا أن نذهب من خلال مثال عملي معًا! لنفترض أن الالتزام المحدد هنا معطل.
لنفترض أيضًا أنني أعددت تغييرات في ملف باسم error.html
من شأنها حل المشكلة. إليك الخطوة الأولى التي يتعين علينا القيام بها:
$ git add error.html $ git commit --fixup 2b504bee
نحن ننشئ التزامًا جديدًا ، لكننا نخبر Git أن هذا التزام خاص: إنه إصلاح لالتزام قديم باستخدام تجزئة SHA-1 المحددة ( 2b504bee
في هذه الحالة).
الخطوة الثانية ، الآن ، هي بدء جلسة Rebase التفاعلية - لأن fixup
ينتمي إلى مجموعة الأدوات الكبيرة لـ Interactive Rebase.
$ git rebase -i --autosquash 0023cddd
هناك شيئان يستحقان الشرح حول هذا الأمر. أولاً ، لماذا قدمت 0023cddd
المراجعة هنا؟ لأننا بحاجة إلى بدء جلسة Rebase التفاعلية الخاصة بنا عند التزام الوالدين بزميلنا المكسور.
ثانيًا ، ما هو خيار --autosquash
؟ يستغرق الكثير من العمل عن أكتافنا! في نافذة المحرر التي تفتح الآن ، كل شيء جاهز بالفعل لنا:
بفضل خيار --autosquash
، قامت Git بالفعل بالرفع الثقيل لنا:
- لقد وضع علامة على الالتزام الصغير الخاص بنا باستخدام الكلمة الأساسية
fixup
. بهذه الطريقة ، سيقوم Git بدمجه مع الالتزام أعلاه مباشرةً ثم يتجاهله. - كما أعاد ترتيب الأسطر وفقًا لذلك ، ونقل التزام المساعدة الشريطية الخاص بنا مباشرةً أسفل الالتزام الذي نريد إصلاحه (مرة أخرى: يعمل
fixup
من خلال الجمع بين الالتزام المرمز مع الالتزام أعلاه !).
باختصار: ليس لدينا ما نفعله سوى إغلاق النافذة!
دعنا نلقي نظرة أخيرة على النتيجة النهائية.
- تم إصلاح الالتزام الذي تم كسره سابقًا: فهو يحتوي الآن على التغييرات التي أعددناها في التزام المساعدة الأساسية.
- تم التخلي عن الالتزام القبيح للإسعافات الأولية: سجل الالتزام نظيف وسهل القراءة - كما لو لم يكن هناك خطأ على الإطلاق.
إن معرفة كيفية التراجع عن الأخطاء قوة عظمى
تهانينا! أنت الآن قادر على إنقاذ رقبتك في العديد من المواقف الصعبة! لا يمكننا حقاً تجنب هذه المواقف: بغض النظر عن خبرتنا كمطورين ، فإن الأخطاء هي ببساطة جزء من الوظيفة. ولكن الآن بعد أن عرفت كيفية التعامل معها ، يمكنك مواجهتها بمعدل ضربات قلب مسترخي.
إذا كنت تريد معرفة المزيد حول التراجع عن الأخطاء مع Git ، يمكنني أن أوصي بـ "First Aid Kit for Git" ، وهي سلسلة من مقاطع الفيديو القصيرة حول هذا الموضوع بالضبط.
استمتع بارتكاب الأخطاء - وبالطبع التراجع عنها بسهولة!