Dangit, Git!?!

گیت سخته: امکان اشتباه زیاده، و فهمیدن اینکه چطوری میشه درستش کرد غیرممکنه. راهنمای گیت مشکل معروف مرغ و تخم مرغ رو داره وقتی که نمیدونی چی جستجو کنی که خودتو از منجلاب نجات بدی، مگه این که اسم اون چیزی که دنبالش هستی رو بدونی.

بنابراین من اینجا چند مورد از موقعیت های بدی که دچارش شده بودم رو براتون گذاشتم، و روش اینکه چطوری در نهایت از پس اونا بر اومدم به زبان فارسی ساده.

ای واای، من یه اشتباه وحشتناک کردم، لطفا بهم بگو که گیت ماشین زمان داره!؟!

git reflog
# تو لیست هر کاری که تو گیت انجام بدی رو
# خواهی دید، در همه برنچ ها!
# هر کدوم یه اندیس HEAD@{index} داره
# یکی رو پیدا کن قبل از اینکه همه چی رو خراب کنی
git reset HEAD@{index}
# ماشین جادویی زمان

وقتی چیزی رو تصادفی پاک میکنی میتونی از این استفاده کنی، یا برای پاک کردن چیزی که باعث ترکیدن ریپو شده، یا حتی برای برگشت بعد از یه ادغام بد، یا برای برگشت به زمانی که همه چیز درست بود. من از reflog زیاد استفاده میکنم. یک نکته فوق العاده کاربردی برای اونایی که بارها بارها و بارها اضافه کردن اونو پیشنهاد داده بودن.

ای واای، من کامیت کردم و بلافاصله متوجه شدم که به یک تغییر کوچیک نیاز دارم!

# تغییرتو انجام بده
git add . # یا فایل هاتو تک تک اضافه کن
git commit --amend --no-edit
# حالا کامیت آخر شما اون تغییر رو داره !
# اخطار: هیچ وقت کامیت های عمومی رو amend نکنید

این واسه من زمانی پیش میاد که من کامیت کنم، بعد تست ها/ لینت ها ... رو اجرا کنم و خرابکاری ...، من یه فاصله جا انداخته بودم. تو همچنین میتونی تغییراتت رو انجام بدی و بعد اینو بزنی : rebase -i و شاهد له شدن تغییرات باشی، اما این حدود یک میلیون بار سریعتره.

اخطار: نباید هیچوقت کامیت هایی که داخل یک شاخه عمومی/به اشتراک گذاشته شده پوش کردی رو amend کنی! فقط کامیت هایی که فقط در لوکال خودت هستن رو amend کن وگرنه بد میبینی

ای واای، من باید پیام آخرین کامیتم رو تغییر بدم!

git commit --amend
# درخواست ها رو دنبال کن تا پیام کامیتت رو تغییر بدی

الزامات قالب بندی پیام کامیت احمقانه.

ای واای، من تصادفی یه چیزی رو تو مَستر کامیت کردم که باید توی یک شاخه کاملا جدید کامیت میکردم!

# یک برنچ جدید از وضعیت فعلی مَستر بسازید
git branch some-new-branch-name
# کامیت آخر رو از برنچ مَستر پاک کنید
git reset HEAD~ --hard
git checkout some-new-branch-name
# کامیت شما حالا در این برنچ زیست میکنه :)

نکته: اگر شما کامیت رو در یک شاخه عمومی/ اشتراک گذاشته شده پوش کرده باشید این مورد کار نمی کند، و اگر چیزهای دیگه رو اول امتحان کنی، احتمالا به git reset HEAD@{number-of-commits-back} به جای HEAD~ نیاز پیدا میکنی . غم بینهایت. همچنین، خیلی خیلی خیلی از افراد یه روش کوتاه تر بهم پیشنهاد دادن که نمیدونستم. از همتون ممنونم!

ای واای، من تصادفی تو یک شاخه اشتباه کامیت کردم!

# کامیت آخر رو برگردون، اما تغییرات رو داشته باش
git reset HEAD~ --soft
git stash
# به شاخه صحیح انتقال بده
git checkout name-of-the-correct-branch
git stash pop
git add . 
# یا پرونده های منفرد اضافه کنید
git commit -m "your message here"
# حالا تغییراتت روی شاخه صحیح هستن

خیلیا استفاده از cherry-pick رو برای این شرایط پیشنهاد داده بودن، بنابراین هر روشی که احساس بهتری بهش داری رو انتخاب کن!

git checkout name-of-the-correct-branch
# کامیت آخر رو به مَستر بیار
git cherry-pick master
# از مَستر پاکش کن
git checkout master
git reset HEAD~ --hard

ای واای، من یه diff اجرا کردم اما هیچ اتفاقی نیافتاد!

اگه میدونی که یه سری تغییرات در فایل ها ایجاد کردی، اما diff خالیه، احتمالا فایل هاتو add کردی به stage و نیاز داری از یه فلگ خاص استفاده کنی.

git diff --staged
فایل هاتو بریز تو پوشه ¯/_(ツ)_\¯ (بله، میدونم این یه فیچره، باگ نیست، اما این گیج کننده است و واضح نیست برای دفعه اول که باهاش مواجه میشی !)

ای واای، من باید یک کامیت رو برگردونم مشابه 5 کامیت قبل!

# کامیتی که میخای برگردونی رو پیدا کن
git log
# با استفاده از دکمه های بالا و پایین در history جستجو کن  
# وقتی که کامیتت و پیدا کردی، هش رو ذخیره کن
git revert [saved hash]
# گیت یک کامیت ایجاد میکنه که اون کامیت رو لغو میکنه
# درخواست ها رو دنبال کن تا پیام کامیت رو ویرایش کنی 
# یا فقط ذخیره و کامیت کن

معلومه که نباید بگردی و محتوای فایل قدیمی رو در فایل موجود برای بازگشت تغییرات کپی-پیست کنی! اگر یک باگ کامیت کردی، میتونی کامیت رو یک جا برگردونی با دستور revert.

همچنین میتونی به جای همه کامیت فقط یک فایل رو برگردونی! البته، در سبک اصلی گیت، این یک مجموعه کاملا متفاوت از دستورهاست ...

ای واای، میخام تغییراتم به یک فایل رو برگردونم!

# یک هش از یک کامیت قبل از تغییر فایل پیدا کن
git log
# با استفاده از دکمه های بالا و پایین در history جستجو کن
# وقتی که کامیتت و پیدا کردی، هش رو ذخیره کن
git checkout [saved hash] -- path/to/file
# نسخه قبلی فایل در ایندکس شما خواهد بود
git commit -m "Wow, you don't have to copy-paste to undo"

وقتی من بالاخره همچین چیزی رو فهمیدم خیلی خفن بود. خفن. خ-ف-ن. حالا جدی, کجای دنیا دیدید checkout -- بهترین روش برای برگردوندن یک فایل باشه؟ :دستان لینوس تروالدز می لرزد:

این نویز رو بیخیال شید، من بیخیال میشم.

cd ..
sudo rm -r stupid-git-repo-dir
git clone https://some.github.url/stupid-git-repo-dir.git
cd stupid-git-repo-dir

با تشکر از Eric V. برای این موارد. همه شکایت ها در مورد استفاده از sudo در این طنز به او بر می گردد.

هرچند در واقع، اگر شاخه شما خیییلی خراب شده بود که نیاز پیدا کردید که وضعیت ریپو تون رو به وضعیت ریپوی ریموت با یک روش "مورد-قبول-گیت" برگردونید، اینو امتحان کنید، اما آگاه باشید این دستورات مخرب و غیر قابل بازگشت هستند!

# آخرین وضعیت origin رو بگیر
git fetch origin
git checkout master
git reset --hard origin/master
# فایل ها و دایرکتوری های دنبال نشده را پاک کن
git clean -d --force
# checkout/reset/clean رو برای هر شاخه خراب شده تکرار کن

سلب مسئولیت: این سایت به عنوان یک مرجع جامع درنظر گرفته نشده است.و بله، برای انجام کارهای مشابه این روش های تئوری دیگری با خلوص بیشتری هم هست، اما من با آزمون و خطاهای بسیاری به این روش ها رسیدم و من این ایده باحال رو داشتم که اونا رو با دوز بالایی از شوخ طبعی به اشتراک بگذارم. استفاده کنید یا بی بهره بمونید هر طور تمایل دارید!

تشکر فراوان از هر کسی که داوطلبانه این سایت رو به زبان های مختلف ترجمه کرد، تو شاهکاری! Michael Botha (af) · Khaja Md Sher E Alam (bn) · Eduard Tomek (cs) · Moritz Stückler (de) · Franco Fantini (es) · Hamid Moheb (fa) · Senja Jarva (fi) · Michel (fr) · Alex Tzimas (gr) · Elad Leev (he) · Aryan Sarkar (hi) · Ricky Gultom (id) · fedemcmac (it) · Meiko Hori (ja) · Zhunisali Shanabek (kk) · Gyeongjae Choi (ko) · Rahul Dahal (ne) · Martijn ten Heuvel (nl) · Łukasz Wójcik (pl) · Davi Alexandre (pt_BR) · Catalina Focsa (ro) · Daniil Golubev (ru) · Nemanja Vasić (sr) · Björn Söderqvist (sv) · Kitt Tientanopajai (th) · Taha Paksu (tr) · Andriy Sultanov (ua) · Tao Jiayuan (zh) . و همچنین همکاری Allie Jones · Artem Vorotnikov · David Fyffe · Frank Taillandier · Iain Murray · Lucas Larson · Myrzabek Azil

اگه دوس داری کمک کنی یک ترجمه به زبان تو اضافه بشه، یک PR ثبت کن در GitHub