لینک کوتاه مطلب : https://hsgar.com/?p=5824

چیزهایی که کاش همه درباره Git بدانند (قسمت دوم)

چیزهایی که کاش همه درباره Git بدانند (قسمت دوم)

این یک نوشته است
سخنرانی ای که در ماه دسامبر انجام دادم برای کارفرمای قبلی من طولانی است بنابراین من آن را در چندین بخش منتشر می کنم:

  • قسمت اول:
  • قسمت دوم (شما اینجا هستید):
  • اطلاعات بیشتر بعداً:
    • شعبه ها ساختگی هستند
    • انجام تغییرات جزئی
    • فشار دادن و واکشی؛ شاخه های ردیابی
    • نام مستعار و دستورات سفارشی

مهمترین مطالب در قسمت اول آمده است.

از دست دادن چیزها واقعا سخت است

مخزن Git یک فایل سیستم فقط ضمیمه است. می‌توانید عکس‌های فوری از فایل‌ها و فهرست‌ها اضافه کنید، اما نمی‌توانید تغییر یا حذف کنید هر چیزی. دستورات Git گاهی اوقات مدعی تغییر داده ها هستند. مثلا git commit --amend پیشنهاد می کند که یک commit را اصلاح کند. اینطور نیست. چیزی به نام اصلاح یک تعهد وجود ندارد. تعهدات تغییر ناپذیر هستند

بلکه یک کامیت کاملاً جدید می نویسد و سپس کمی به کامیت قبلی پشت می کند. اما ارتکاب قدیمی هنوز وجود دارد، بکر، برای همیشه.

در یک مخزن Git می توانید از دست دادن چیزها، به معنای فراموش کردن جایی که هستند. اما تقریباً همیشه می توان آنها را دوباره پیدا کرد، به هر طریقی، و زمانی که آنها را پیدا کردید دقیقاً مانند قبل خواهند بود. اگر شما git commit --amend و بعداً نظر خود را تغییر دهید، اگر به دلایلی آن را می خواهید، بازگرداندن تعهد قبلی ⸢ اصلاح نشده⸣ سخت نیست.

  • اگر SHA برای یک فایل دارید، همیشه همان نسخه فایل با همان محتویات خواهد بود.

  • اگر SHA برای دایرکتوری دارید (یک «درخت» در اصطلاح Git) همیشه حاوی همان نسخه‌های فایل‌های مشابه با نام‌های مشابه است.

  • اگر SHA برای یک commit دارید، همیشه حاوی اطلاعات فرااطلاعات مشابه (توضیحات، زمانی که ساخته شده است، توسط چه کسی، و غیره) و دقیقاً همان عکس فوری از کل درخت فایل خواهد بود.

اشیاء می توانند نام ها و توضیحات دیگری داشته باشند که می آیند و می روند، اما SHA برای همیشه باقی است.

(یک ویژگی کوچک در این مورد وجود دارد: اگر SHA باشد فقط روشی برای ارجاع به یک شی خاص، اگر نام دیگری نداشته باشد، و اگر چند ماه از آن استفاده نکرده باشید، ممکن است Git آن را به طور کامل از مخزن حذف کند.)

اما اگر چیزی را از دست بدهید چه؟

پاسخ های خوبی برای این سوال وجود دارد، اما فکر می کنم اولین چیزی که باید بدانیم این است git-reflog، زیرا اکثر موارد را پوشش می دهد.

را git-reflog دستور یعنی:

“SHAهای commit هایی را که اخیراً بازدید کرده ام لیست کنید”

وقتی می دوم git reflog بالای خروجی می‌گوید چه commit‌هایی را اخیراً بررسی کرده‌ام، با خط بالایی commitی است که در حال حاضر بررسی کرده‌ام:

    523e9fa1 HEAD@{0}: checkout: moving from dev to pasha
    5c31648d HEAD@{1}: pull: Fast-forward
    07053923 HEAD@{2}: checkout: moving from pr2323 to dev
    ...

آخرین کاری که انجام دادم این بود که شعبه ای که نامش را گذاشته بود را بررسی کردم pasha; نوک commit آن در 523e9f1a است.

قبل از آن، من انجام دادم git pull و Git محلی من را به روز کرد dev شاخه از راه دور، به روز رسانی آن به 5c31648d.

قبل از آن، من تغییر کرده بودم dev از شاخه ای متفاوت
pr2323. در آن زمان، قبل از کشش، dev ارجاع به ارتکاب
07053923.

پایین تر در خروجی برخی از commit هایی هستند که در اوت گذشته بازدید کردم:

    ...
    58ec94f6 HEAD@{928}: pull --rebase origin dev: checkout 58ec94f6d6cb375e09e29a7a6f904e3b3c552772
    e0cfbaee HEAD@{929}: commit: WIP: model classes for condensedPlate and condensedRNAPlate
    f8d17671 HEAD@{930}: commit: Unskip tests that depend on standard seed data
    31137c90 HEAD@{931}: commit (amend): migrate pedigree tests into test/pedigree
    a4a2431a HEAD@{932}: commit: migrate pedigree tests into test/pedigree
    1fe585cb HEAD@{933}: checkout: moving from LAB-808-dao-transaction-test-mode to LAB-815-pedigree-extensions
    ...

فرض کنید در یک کابوس وحشتناک Git گرفتار شده ام. شاید من کل مجموعه آزمایشی را حذف کرده ام یا به طور تصادفی خود را قرار داده ام نگرانی جزیی در یک پیام commit قرار دهید یا الگوهای گزارش را با 150 گیگابایت پورن بزی بازنویسی کنید. می توانم به حالت قبل برگردم. درست قبل از اینکه اشتباه بزرگ خود را مرتکب شوم، در reflog به دنبال SHA commit می‌گردم و سپس:

    git reset --hard 881f53fa

وای، این فقط یک خواب بد بود.

(البته اگر همکاران من واقعاً اره پورن بز، نمی تواند آن را برطرف کند.)

من می خواهم نامزد کنم وایل ای. کایوت طلسم گیت بودن زیرا Wile E. همیشه خود را در موقعیت هایی مانند این قرار می دهد:

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

اما پس از آن، در صحنه بعدی، او به طور جادویی آسیبی ندیده است. این Git است.

پیدا کردن چیزهای قدیمی با git-reflog

  • git reflog به خودی خود مکان هایی را فهرست می کند که HEAD بوده است
  • git reflog some-branch مکان هایی را فهرست می کند که some-branch بوده است
  • که HEAD@{1} چیزی در reflog اگر نمی خواهید از SHA استفاده کنید، خروجی راه دیگری برای نامگذاری commit است.
  • می توانید آن را به اختصار just @{1}.
  • لوکیشن های زیر را می توان با استفاده کرد هر دستور git که از شما می خواهد یک commit را شناسایی کنید:

    • @{17} (HEAD همانطور که 17 اقدام پیش بود)
    • @{18:43} (HEAD همانطور که در ساعت 18:43 امروز بود)
    • @{yesterday} (HEAD همانطور که 24 ساعت پیش بود)
    • dev@{'3 days ago'} (dev مثل 3 روز پیش)
    • some-branch@{'Aug 22'} (some-branch همانطور که در 22 اوت گذشته بود)

    (استفاده با git-checkout، git-reset، git-show، git-diff، و غیره.)

  • همچنین مفید است:

    git show dev@{'Aug 22'}:path/to/some/file.txt
    

    «آن فایل را همانطور که بود چاپ کنید dev، مانند dev در 22 اوت بود”

همه چیز هنوز آنجاست

اگر نتوانید آن را پیدا کنید چه؟

وحشت نکنید! احتمالاً شخصی با تجربه بیشتر می تواند آن را برای شما پیدا کند. اگر یک متخصص محلی Git دارید، از آنها کمک بخواهید.

و اگر آنها سرشان شلوغ باشد و نتوانند فوراً به شما کمک کنند، چیزی که به دنبال آن هستید تا زمانی که منتظر آنها هستید ناپدید نمی شود. مخزن فقط ضمیمه است. هر نسخه از همه چیز ذخیره می شود. اگر امروز می توانستند آن را پیدا کنند، فردا باز هم می توانند آن را پیدا کنند.

(Git خواهد شد در نهایت عکس های فوری گم شده و استفاده نشده را دور بیندازید، اما معمولاً چیزی را که در 90 روز گذشته استفاده کرده اید نیست.)

اگر از کاری که انجام داده اید پشیمان شوید چه؟

وحشت نکنید! احتمالاً می تواند آن را به همان شکلی که بود برگرداند.

گیت ردی از خود بر جای می گذارد

هنگامی که یک commit می کنید، Git چیزی شبیه به این را چاپ می کند:

    your-topic-branch 4e86fa23 Rework foozle subsystem

اگر باید دوباره آن commit را پیدا کنید، SHA 4e86fa23 در ترمینال شما اسکرول بک است.

هنگامی که یک شاخه از راه دور واکشی می کنید، Git چاپ می کند:

       6e8fab43..bea7535b  dev        -> origin/dev

چه تعهدی بود origin/dev قبل از واکشی؟ در 6e8fab43. حالا این چه تعهدی است؟ bea7535b.

اگه بخوای ببینی قبلا چطور بود چی؟ مشکلی نیست، 6e8fab43
هنوز آنجاست اسمش نیست origin/dev دیگر، اما SHA برای همیشه است. هنوز هم می توانید آن را بررسی کنید و به آن نگاه کنید:

    git checkout -b how-it-was-before 6e8fab43

اگر بخواهید شرایط را با وضعیت فعلی مقایسه کنید، چه می شود؟

    git log 6e8fab43..bea7535b
    git show 6e8fab43..bea7535b
    git diff 6e8fab43..bea7535b

Git سعی می کند دنباله ای از پودر سوخاری در ترمینال شما باقی بگذارد. دائماً در حال چاپ SHAهایی است که ممکن است دوباره بخواهید.

چند چیز می توان برای همیشه گم شو!

پس از آن همه صحبت در مورد اینکه چگونه Git چیزها را از دست نمی دهد، باید به استثناها اشاره کنم. استثنای بزرگ این است که اگر فایل‌هایی ایجاد کرده‌اید یا تغییراتی در درخت کاری ایجاد کرده‌اید، Git تا زمانی که آن‌ها را با آن اضافه نکنید، از آن‌ها بی‌اطلاع است. git-add. تا آن زمان، این تغییرات در درخت کار وجود دارد، اما در مخزن نیست، و اگر آنها را دور بیندازید، Git نمی‌تواند به شما در بازگرداندن آنها کمک کند.

توصیه خوب است زود و اغلب متعهد شوید. اگر متعهد نیستید، حداقل تغییرات را با آن اضافه کنید git-add. فایل‌هایی که اضافه شده‌اند اما تعهد نشده‌اند در مخزن ذخیره می‌شوند، اگرچه یافتن آنها سخت است زیرا در یک commit با یک شناسه SHA بسته‌بندی نشده‌اند.

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

را دستورات خطرناک هستند git-reset و git-checkout

که درخت کار را اصلاح می کند و بنابراین ممکن است تغییراتی را که در مخزن وجود ندارد پاک کند. Git سعی می کند قبل از انجام کاری مخرب برای تغییرات درخت کاری شما به شما هشدار دهد.

git-rev-parse

چندی پیش دیدیم که زبان گیت برای صحبت در مورد commit ها و فایل ها بسیار پیچیده است:

            my-topic-branch@{'Aug 22'}:path/to/some/file.txt

این زبان کجا مستند شده است؟ شاید جایی نباشد که انتظارش را دارید: در دفترچه راهنما آمده است git-rev-parse.

را git rev-parse فرمان کمتر از آنچه که باید شناخته شده است. این یک توصیف از یک شی را می گیرد و آن را به یک SHA تبدیل می کند. چرا مفید است؟ شاید نه، اما

را git-rev-parser صفحه مرد نحو توصیفاتی را که Git درک می کند توضیح می دهد.

یک عادت خوب این است که هر چند ماه یکبار از روی دفترچه استفاده کنید. شما هر بار چیز جدید و مفیدی را انتخاب خواهید کرد.

مورد علاقه من این است که اگر از نحو استفاده کنید :/foozle شما آخرین commit را در شاخه فعلی که پیام آن ذکر شده است دریافت می کنید
foozle. مثلا:

    git show :/foozle

یا

    git log :/introduce..:/remove

در هفته آینده (احتمالا)، چند موضوع متفرقه در مورد استفاده موثرتر از Git.

[Other articles in category /prog/git]

پیوند دائمی

لینک منبع

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.