آموزش گیت – قسمت سوم

نویسنده : سید ایوب کوکبی ۱۸ اردیبهشت ۱۳۹۸
آموزش گیت - قسمت سوم

با دستور کامیت، نسخه‌های مختلفی از پروژه (اسنپ‌شات‌ها) را در مکان امنی (مخزن) ذخیره کرده‌اید. حالا اتفاقی افتاده و می‌خواهید به نسخه قبل بازگردید. موضوع این قسمت، بازگشت به نسخه‌های قبل یا ریست کردن تغییرات کامیت نشده است. در واقع بدون این قابلیت، گیت یا هر سیستم‌های کنترل نسخه دیگری سودی برای ما نداشت.

نمایش آی.دی کامیت‌ها

ابتدا در cmd یا git bash به فولدر my-git-repo بروید و یکبار log بگیرید:

git log --oneline

خروجی دستور چیزی شبیه این است البته checksumهای شما متفاوت است:

۱c310d2 Add navigation links
۵۴۶۵۰a3 Create blue and orange pages
b650e4b Create index page

به خاطر دارید با دستور git log جزئیات کامل هر کامیت را مشاهده می‌کردیم. در حال حاضر به خاطر استفاده از پرچم oneline– فقط ۷ کاراکتر اول هر چک‌سام نمایش داده می‌شود که البته همین رشته برای هر کامیت منحصر‌به‌فرد بوده و به عنوان ID برای هر یک محسوب می‌شود.

نمایش نسخه‌های قبلی

با دستور git checkout می‌توانید محتویات اسنپ‌شات‌های قبلی را ببینید. در دستور پایین به جای ۵۴۶۵۰a3، آی.دی مربوط به کامیت دوم را وارد کنید:

git checkout 54650a3

با اجرای این دستور اطلاعات زیادی دربارۀ detached HEAD نمایش داده می‌شود که کاری به آن نداریم. تنها چیزی که باید بدانید این است که اکنون اگر به فولدر پروژه نگاه کنید دقیقاً به نسخۀ ذخیره شده در آن اسنپ‌شات برگشته‌اید. فایل html را در مرورگر باز کنید تا مطمئن شوید اوضاع به حالت قبل برگشته است. با اجرای دستور git log خواهیم دید که کامیت سوم دیگر جزئی از پروژه نیست. بعد از چک‌اوت کردن کامیت دوم، تاریخچۀ مخزن به شکل زیر در می‌آید (دایرۀ قرمز کامیت جاری را نشان می‌دهد):

چک‌اوت کردن کامیت دوم

نمایش نسخه‌های قدیمی‌تر

بیایید کمی عقب‌تر برگردیم. چک‌سام را به کامیت اول تغییر دهید:

git checkout b650e4b

اکنون فایل‌های blue.html و orange.html حذف شده‌اند و در دستور log هم خبری از کامیت‌های قبلی نیست:

چک اوت کردن کامیت اول

در قسمت قبلی گفتیم که در گیت هیچگاه اسنپ‌شات‌ها را از دست نمی‌دهیم. اما الان همۀ کامیت‌ها را از دست دادیم. اگر دستور git status را بزنید همان پیامی را خواهید داد که اولین بار مخزن را ایجاد کردیم. یعنی هیچ کامیتی وجود ندارد. داستان چیست؟

# Not currently on any branch.
nothing to commit (working directory clean)

گرچه دستور log کامیت‌های قبلی را نشان نمی‌دهد ولی معنی‌اش این نیست که آن کامیت‌ها وجود ندارند، شما با وارد کردن چک‌سام کامیت‌های قبلی همچنان می‌توانید چک‌اوت کنید ولی راه آسان‌تری هم هست. عبارت On branch master به ما می‌گوید که روی شاخۀ master هستیم؛ جایی که کامیت‌های دوم و سوم در آن ذخیره شده‌اند. برای دریافت آخرین نسخۀ پروژه کافی است این شاخه را چک‌اوت کنیم. بعداً دربارۀ شاخه‌ها مفصل‌تر صحبت می‌کنیم.

بخوانید  آموزش گیت - قسمت اول

بازگشت به نسخۀ فعلی پروژه

همانطور که بالاتر گفتیم، چک‌اوت کردن شاخۀ مستر پروژه را به آخرین کامیت شاخۀ مستر می‌برد:

git checkout master

با اجرای این دستور، گیت working directory را به حالتی برمی‌گرداند که آخرین کامیت شاخۀ مستر را منعکس کند. یعنی فایل‌های blue.html, orange.html دوباره برمی‌گردند و محتویات فایل index.html هم به حالت قبل بازمی‌گردد. اکنون تاریخچه به شکل سابق خواهد بود:

وضعیت فعلی پروژه

تگ کردن releaseها در گیت

در گیت می‌توانیم هر زمانی که دوست داشتیم تگ گذاری کنیم. برای این کار در هر جایی از پروژه بودیم با دستور زیر عمل تگ گذاری را انجام می‌دهیم:

git tag -a v1.0 -m "Stable version of the website"

تگ (Tag)، ارجاعی به ریلیزهای رسمی پروژه است که هر زمان بخواهیم می‌توانیم به آن نسخه برگردیم. تگ‌ها اجازه می‌دهند تا برنامه‌نویسان هر زمان بخواهند به نسخه‌های مهم پروژه یا ددلاین‌های اصلی برگردند. برای مثال بعد از اجرای دستور بالا به جای استفاده از یک عدد رندم (checksum) می‌توانید با تگ v1.0 به کامیت سوم اشاره کنید. برای دیدن لیست تگ‌های موجود می‌توانید از دستور git tag استفاده کنید.

در دستور بالا، پرچم a- به گیت می‌گوید که تگی annotate شده ایجاد کند یعنی اجازه دهد نام، پیام (با پرچم m-) و تاریخی برای تگ مورد نظر انتخاب کنیم. از تگ‌ها به وفور برای تست قابلیت‌های جدید و بازگشت مجدد به نسخه‌های پایدار پروژه استفاده می‌شود.

تست تغییرات جدید

اکنون که نسخۀ پایداری از پروژه داریم به راحتی می‌توانیم هر تغییری را در پروژه اعمال کنیم. خواهید دید که چطور می‌توان با یک دستور به تگ قبلی بازگشت. فایل جدیدی به نام crazy.html با محتویات زیر به پروژه اضافه کنید:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>A Crazy Experiment</title>
  <meta charset="utf-8" />
</head>
<body>
  <h1>A Crazy Experiment</h1>
  <p>We're trying out a <span style="color: #F0F">crazy</span>
  <span style="color: #06C">experiment</span>!
    
  <p><a href="index.html">Return to home page</a></p>
</body>
</html>

استیج و کامیت کردن اسنپ‌شات

طبق روال فایل جدید را استیج و سپس کامیت می‌کنیم تا در تاریخچۀ پروژه قرار گیرد:

git add crazy.html
git status
git commit -m "Add a crazzzy experiment"
git log

استفاده از git status اجباری نیست ولی تمرین خوبی است که قبل از کامیت کردن status بگیرید تا دقیقاً بدانید از چه چیزی دارید کامیت می‌گیرید. این کار جلوی کامیت کردن ناخواستۀ فایل‌های نامربوط به اسنپ‌شات را می‌گیرد. طبق انتظار اگر دستور git log بزنید، کامیت جدید را در تاریخچه خواهید دید.

برگشتن به یک تگ مشخص

شاید لازم باشد به عقب برگردید و نسخۀ پایدار پروژه در ورژن ۱ را نگاهی بیندازید. به خاطر دارید که v1.0 اکنون ID کامیت سوم است:

git checkout v1.0

بعد از مشاهدۀ نسخۀ پایدارسایت تصمیم می‌گیریم که فایل جدیداً اضافه شده را از دور خارج کنیم. اما قبل از undo کردن تغییرات، ابتدا باید به شاخۀ مستر برگردید. در غیر این صورت تمام بروزرسانی‌های ما بر روی شاخه‌ای خواهد بود که وجود ندارد. در قسمت بعدی خواهیم گفت که چرا نباید در نسخه‌های قبلی اقدام به اعمال تغییرات کنیم.

git checkout master
git log --oneline

در حال حاضر باید تاریخچۀ کامل کامیت‌ها را ببینیم:

۵۱۴fbe7 Add a crazzzy experiment
۱c310d2 Add navigation links
۵۴۶۵۰a3 Create blue and orange pages
b650e4b Create index page

Undo کردن تغییرات کامیت شده

اکنون آماده‌ایم تا نسخۀ پایدار پروژه را بازیابی کنیم:

git revert 514fbe7

گیت هیچ وقت کامیتی را حذف نمی‌کند به همین دلیل بعد از اجرای دستور بالا، حذف شدن فایل crazy.html در غالب یک کامیت جدید با پیغام Revert Add a crazy file به تاریخچه اضافه می‌شود. شما می‌توانید پیغام پیش‌فرض را قبول کنید یا خودتان چیز دیگری بنویسید. دستور git log –oneline را بزنید. خواهید دید که کامیت جدیدی اضافه شده است.

۵۰۶bb9b Revert "Add a crazzzy experiment"
۵۱۴fbe7 Add a crazzzy experiment
۱c310d2 Add navigation links
۵۴۶۵۰a3 Create blue and orange pages
b650e4b Create index page

اکنون محتویات کامیت سوم و کامیت فعلی یعنی کامیت پنجم یکسان است. کامیت چهارم که فایل crazy.html در آن اضافه شده بود نیز در تاریخچه وجود دارد.

وضعیت فعلی تاریخچه

در هنگام استفاده از git revert کامیتی را وارد کنید که می‌خواهید undo شود نه کامیتی که می‌خواهید به آن برگردید. برای جلوگیری از اشتباه، دستور revert را undo بخوانید تا متوجه شوید بعد از آن باید کامیتی را وارد کنید که می‌خواهید undo شود.

بخوانید  روش‌های ساخت اپلیکیشن موبایل

اضافه کردن یک سری تغییرات جزئی

این بار تغییر کوچک دیگری اضافه می‌کنیم. یک فایل خالی به نام dummy.html به فولدر پروژه اضافه کنید. سپس در فایل index.html به فایل جدید لینک دهید؛ به صورت زیر:

<h2>Navigation</h2>
<ul>
  <li style="color: #F90">
    <a href="orange.html">The Orange Page</a>
  </li>
  <li style="color: #00F">
    <a href="blue.html">The Blue Page</a>
  </li>
  <li>
    <a href="dummy.html">The Dummy Page</a>
  </li>
</ul>

اکنون از تغییر جدید منصرف شده‌ایم ومی‌خواهیم به شرایط قبل بازگردیم. در واقع می‌خواهیم تغییرات کامیت نشده را کنسل کنیم. اینجا نمی‌توانیم از دستور git revert استفاده کنیم چون به آی.دی کامیت نیاز داریم که در حال حاضر نداریم.

undo کردن تغییرات کامیت نشده

قبل از این کار ابتدا یک status بگیرید تا وضعیت مخزن را مشاهده کنید:

git status

همانطور که می‌بینید فایل index.html با رنگ قرمز و برچسب modified ظاهر می‌شود که یعنی تغییرات اعمال شده را باید استیج کنیم. همچنین فایل dummy.txt به عنوان untracked برچسب خورده که باید استیج شود.

برای undo کردن تغییرات، فایل index که زیر نظر گیت قرار دارد باید تغییراتش به حالت قبل برگردد و فایل dummy هم کلاً حذف شود. ابتدا تکلیف index.html را روشن کنیم:

git reset --hard

دستور بالا تغییرات تمام فایل‌ها را به آخرین کامیت برمی‌گرداند. پرچم hard– تغییرات را به صورت فیزیکی برمی‌گرداند که در صورت استفاده نکردن از آن فقط فایل index را از ناحیۀ استیج برمی‌دارد ولی به تغییراتش کاری ندارد. در هر دو حالت دستور git reset فقط روی working directory و ناحیه staging کار می‌کند. بنابراین کامیت‌های ما در امان هستند و تغییری در تاریخچه به وجود نمی‌آید (git log).

بخوانید  آشنایی با گیت (git) - بخش دوم

حالا باید فایل‌های اضافی را حذف کنیم. فقط یک فایل dummy.html هست که باید حذف شود. می‌توانیم به صورت دستی این کار را انجام دهیم ولی در پروژه‌های بزرگ با تعداد زیادی فایل کار سختی است. راه بهتر استفاده از دستور پایین است:

git clean -f

این دستور تمام فایل‌های untracked را حذف می‌کند. بنابراین dummy.html حذف خواهد شد. بعد از دستور بالا اگر status بگیریم، گیت اعلام می‌کند که هیچ چیزی برای استیج وجود ندارد؛ یعنی همه چیز مطابق آخرین کامیت است.

در استفاده از git reset و git clean دقت کنید؛ چون این دستورات برخلاف revert روی اسنپ‌شات‌های کامیت شده کار نمی‌کنند بلکه تغییرات undo شده به صورت دائمی روی working directory اعمال می‌شود طوری که به هیچ وجه نمی‌توانید به شرایط قبل از undo برگردید.

جمع‌بندی

همانطور که در بخش‌های قبلی گفتیم، اغلب دستورات گیت روی سه کامپوننت تاثیر می‌گذارند: working directory، اسنپ‌شات‌های استیج شده یا اسنپ‌شات‌های کامیت شده. دستور git reset تغییرات working directory و اسنپ‌شات‌های استیج شده را undo می‌کند در حالی که git revert تغییرات اسنپ‌شات‌های کامیت شده را undo می‌کند.

فرق reset و revert در گیت
فرق ریست و ریورت در گیت

اشاره کردیم که دستور git revert به جای حذف کامیت، آن را در غالب یک کامیت جدید که بتوان به آن بازگشت ذخیره می‌کند. تنها یک دلیل برای این رفتار وجود دارد؛ اینکه در مخزن‌های ریموت، حذف یک کامیت می‌تواند عواقب بدی روی مشارکت سایر توسعه‌دهندگان داشته باشد. همچنین روش سوئیچ کردن بین کامیت‌ها و شاخه‌های مختلف را به کمک git checkout آموختیم. شاخه‌ها یا branching یکی از مهم‌ترین روش‌ها برای همکاری تیمی روی پروژه است که در قسمت بعدی به آن خواهیم پرداخت.

چکیدۀ دستورات

  • <git checkout <commit-id : نمایش کامیت قبلی؛
  • “<git tag -a <tag-name> -m “<description : ساخت تگ از آخرین کامیت؛
  • <git revert <commit-id : بازگرداندن تغییرات (undo) کامیت با ساخت یک کامیت جدید؛
  • git reset –hard : ریست کردن فایل‌های track شده به آخرین کامیت؛
  • git clean -f : حذف فایل‌های untracked؛
  • git reset –hard / git clan -f : حذف دائمی تغییرات کامیت نشده.

سید ایوب کوکبی

نویسنده و مترجم...

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *