رفع مشکلات و خطاها در Git – به زبان ساده


در این نوشته به بررسی روشهای استفاده از دستورهای git reflog و git reset برای ذخیره کد نرمافزاری میپردازیم. تصور کنید یک توسعهدهنده هستید که مشغول افزودن یک ویژگی جدید به اپلیکیشن خود هستید و این کار چند روز طول کشیده است. تیم توسعه روند حرکتی هر چند کندی داشته است و از این رو تصمیم میگیرید که با همه این فشارها، شاخه توسعه نرمافزار را در master ادغام کنید. علیرغم استرس، این کار الزامی است و این درست همان جایی است که همه مشکلات Git منتظر هستند رخ بدهند.
احتمالاً شما تلاش میکنید کد خودتان را ادغام کنید و ناگهان 10 مورد «تعارض» (conflict) از جای نامعلومی سبز میشوند. ممکن است تلاش کنید چند کامیت را در یکی ادغام کنید و یا حس ماجراجویی بیشتری داشته باشید و تلاش کنید عملیات رعبآور rebase را اجرا نمایید. در این زمان ناگهان متوجه میشوید که همه تغییرها و کامیتهای شما از دست رفتهاند و نیمی از شاخه master پاک شده است و در واقع همه کار همتیمیها به هدر رفته است.
در هر حال این موقعیتی است که ممکن است برای همه پیش بیاید؛ اما باید بدانید که برای آن راه چارهای وجود دارد.
چگونه میتوان مشکلات Git را مدیریت کرد؟
مدیریت چنین وضعیتی که در بخش قبلی بیان کردیم به میزان بد بودن این وضعیت وابسته است. در ادامه قصد داریم به توصیف انواع مقدماتی undo بپردازیم که یک کامیت منفرد را بازگردانی (revert) یا ترمیم (amend) میکند. اگر با این مفاهیم آشنا هستید، میتوانید از این قسمت رد شده و به بخشی که در ادامه در مورد اصطلاح rebase یا merge نادرست صحبت کردهایم مراجعه کنید. همچنین میتوانید به بخشی که در مورد بازگرداندن همه تغییرات انجام یافته در یک شاخه به حالت قبل توضیح داده شده است بروید.
Undo کردن یک تغییر، بازگردانی و ترمیم کامیتها
دو روش رایج برای undo کردن آخرین کامیت وجود دارد. روش نخست معمولاً زمانی مورد استفاده قرار میگیرد که یک غلط املایی رخ داده یا فراموش کرده باشیم یک فایل را به کامیت اخیر اضافه کنیم و میخواهیم آن را بدون این که کسی خبردار بشود اصطلاح کنیم. در این حالت، میتوانید از دستور زیر استفاده کرده و همه فایلهایی که فراموش شدهاند را اضافه کنید:
Git از شما سؤال میکند که آیا میخواهد یک پیام کامیت جدید بنویسید یا نه. شما میتوانید با افزودن فلگ no-edit-- از این سؤال نیز رد شوید. اگر کامیتهای خود را بررسی کنید متوجه میشوید که کامیت مشکلدار ناپدید شده است و کسی هم از این موضوع خبردار نشده است. همه کار به همین سادگی است.
اما به خاطر داشته باشید که وقتی تغییرات خود را به سرور ریموت push کنید، مسئول آن کامیت خواهید بود. در این حالت، اگر میخواهید کاری مانند آن چه در بخش قبل توضیح دادیم، انجام دهید، باید به اطلاع دیگران برسانید که مشکلی پیش آمده و قصد دارید آن را اصلاح کنید. در این وضعیت میتوانید از دستور زیر استفاده کنید:
این دستور ابتدا تغییراتی که اخیراً ایجاد شده را با افزودن کامیت جدید Undo میکند و بدین ترتیب آنها را revert خواهد کرد. آن را میتوان به صورت یک متضاد کامیت تصور کرد. بدین معنی که مجموع کامیتهای بد و این کامیتهای revert شده در واقع معادل هیچ خواهند بود، گویی هیچ تغییری رخ نداده است. در این حالت یک کامیت دوم اضافه میشود که این بار شامل تغییرات کامیت شده جدید است. بنابراین زمانی که کامیت revert را push کنید، هیچ کس کامیتهای ناسازگار و ترمیم شده را نخواهد داشت و Git آنها در مورد این تغییرات اطلاعی نخواهند داشت.
شاید کنجکاو باشید که معنی کلمه HEAD که با حروف بزرگ نوشته شده چیست؟ HEAD یک اشارهگر یا ارجاع به کامیت آخر در شاخه بررسی شده فعلی است. در حال حاضر لازم نیست توجه چندانی به آن بکنید؛ اما در صورتی که در چیزی بزرگتر از پیام کامیت آخر خرابکاری کرده باشید، توجه به آن حائز اهمیت خواهد بود.
Undo کردن چند تغییر با git reflog
reflog مانند یک برادر بزرگتر است که همه گامهای شما را تحت نظر دارد.
باز کردن reflog برای نخستین بار تا حدودی شبیه به زمانی است که متوجه میشوید که گوگل تا چه میزان از اطلاعات شخصی شما مطلع است. این وضعیت تا حدودی آزاردهنده است؛ اما در اغلب موارد موجب هوشیاری ما شده و در مواردی موجب نجات ما نیز میشود. احتمالاً از این موضوع اطلاع دارید که Git سابقه کامیت شما را میداند، چون در عمل به همین منظور ساخته شده است؛ اما اگر دستور زیر را اجرا کنید:
احتمالاً تعجب خواهید کرد. دستکم در مواردی که در حال کار روی پروژهای با تعدادی از همتیمیها هستید کلی دستورهای pull ،merge ،rebase ،clone و سوئیچ بین شاخههای مختلف وجود دارد. هر کاری که با استفاده از تغییرات کامیت انجام میدهید در reflog قابل مشاهده است. اگر پس از این که خرابکاری بزرگی صورت گرفته است اقدام به مشاهده reflog بکنید، میتوانید این اشتباه را در بین چند خط آخر ملاحظه کنید.
در بخش قبلی در مورد HEAD صحبت کردیم. در reflog میتوانید HEAD کنونی را مشاهده کنید که دارای یک افست برای اقدام خاص Git است. بنابراین برای مثال {HEAD@{0 دقیقاً همان معادل HEAD است؛ اما احتمالاً میتوانید ببینید که آخرین تغییر که همه چیز درست بوده است احتمالاً افست بزرگتری نسبت به آن دارد. این همه آن چیزی است که برای رفع مشکل بزرگ خود به آن نیاز دارید.
اینک باید یک نقطه را که قصد دارید به آنجا بازگردید، در سابقه reflog انتخاب کنید. سپس با استفاده از وارد کردن q از reflog خارج شوید و دستور زیر را اجرا کنید:
به همین سادگی شما میتوانید به نقطهای که انتخاب کردهاید، بازگردید. روش کار بسیار ساده است. اما یک کاربرد دیگر واقعاً مفید برای انجام یک ریست سخت نیز وجود دارد که همه تغییرات را پیش از ادغام در شاخه به صورت یک کامیت ساده درمیآورد.
Undo کردن همه تغییرات با یک دستور پیشرفته Git
اگر قصد دارید همه کامیتها را بدون نیاز به باز کردن Vim در یک کامیت منفرد ادغام کنید و نمیخواهید تا انتهای reflog اسکرول کرده و جایی که شاخه عملاً آغاز شده را بیابید، میتوانید از یک دستور دیگر Git بهره بگیرید. این دستور به صورت زیر است:
با این که دستور فوق طولانی است؛ اما مطمئناً فایده زیادی دارد. در واقع این دستور از سه دستور متفاوت تشکیل یافته است که به هم متصل شدهاند، به طوری که خروجی یکی، ورودی دیگری است. این دستورها را یک به یک شرح میدهیم:
- git rev-parse --abbrev-rev HEAD نام شاخهای که هم اینک در آن قرار دارید بازگشت میدهد.
- (git merge-base master $(name of your branch بهترین جد مشترک را بین master و شاخه شما مییابد که احتمالاً آن لحظهای است که این شاخه را ساختهاید و hash این عمل را باز میگرداند.
- (git reset $(hash of the branch creation همان طور که از نام آن مشخص است، همه کامیتها، ادغامها، rebase-ها و غیره را undo میکند و در عین حال تغییراتی که در کد ایجاد شده را حفظ میکند.
بنابراین اینک شما همه تغییرات را از حالت ردگیری خارج کردهاید و میتوانید همه آنها را به صورت جمعی در یک کامیت منفرد وارد کنید. به این منظور کافی است صرفاً یک نام تعیین کنید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزش های برنامه نویسی
- آموزش گیت (Git) برای مدیریت نسخه توزیع شده
- مجموعه آموزش های مهندسی نرم افزار
- راهنمای پیشرفته Git برای مبتدیان — به زبان ساده
- آموزش تاریخچه گیت (Git) و مقدمات آن
- نصب گیت (Git) روی اوبونتو — به زبان ساده
- چگونه از گیت (Git) به طرز موثرتری استفاده کنیم؟ — به زبان ساده
==