مقدمه

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

ابزار اصلی ما برای این سفر در زمان، دستور git checkout است. در این درس یاد می‌گیریم چگونه با استفاده از این دستور بین نسخه‌های مختلف پروژه جابجا شویم و با مفهوم کلیدی HEAD آشنا خواهیم شد.

مفهوم HEAD و حالت Detached HEAD

قبل از استفاده از checkout، باید با یکی از مفاهیم بنیادی گیت آشنا شویم: HEAD. در گیت، HEAD یک اشاره‌گر (pointer) است که همیشه به موقعیت فعلی شما در تاریخچه پروژه اشاره می‌کند. به عبارت دیگر، HEAD پاسخ سوال «ما الان کجای تاریخچه هستیم؟» را می‌دهد.

در حالت عادی، HEAD به یک برنچ (مانند main) اشاره می‌کند. این یعنی شما در نوک آن برنچ قرار دارید و هر کامیت جدیدی که ایجاد کنید، به انتهای همان برنچ اضافه شده و HEAD نیز همراه آن به جلو حرکت می‌کند.

اما زمانی که شما به جای یک برنچ، یک هش کامیت خاص را checkout می‌کنید، HEAD دیگر به یک برنچ اشاره نمی‌کند، بلکه مستقیماً به آن کامیت خاص اشاره خواهد کرد. به این وضعیت، حالت Detached HEAD (هِد جدا شده) می‌گویند. این حالت یک وضعیت موقتی و اکتشافی است. شما می‌توانید کد را در آن نقطه از تاریخ بررسی کنید، اما اگر در این حالت کامیتی ایجاد کنید، آن کامیت به هیچ برنچی تعلق نخواهد داشت و پس از بازگشت به یک برنچ اصلی، ممکن است آن را از دست بدهید.

جابجایی بین نسخه‌ها با دستور git checkout

فرض کنید می‌خواهیم به یک نسخه قدیمی‌تر از پروژه برگردیم. فرآیند کار به این صورت است:

  1. ابتدا با دستور git log --oneline تاریخچه کامیت‌ها را مشاهده می‌کنیم تا هش کامیت مورد نظر را پیدا کنیم.
  2. سپس هش کامیت (یا ۷ کاراکتر اول آن) را کپی کرده و دستور checkout را اجرا می‌کنیم.
git checkout a1b2c3d

با اجرای این دستور، گیت فایل‌های موجود در پوشه کاری (Working Directory) شما را به گونه‌ای تغییر می‌دهد که دقیقاً با وضعیت پروژه در زمان ثبت آن کامیت مطابقت داشته باشند. همچنین گیت یک پیام هشدار طولانی در مورد قرار گرفتن در حالت Detached HEAD به شما نمایش می‌دهد. نگران نباشید، این حالت خطرناک نیست و فقط یک حالت آزمایشی است.

ایجاد یک برنچ جدید از یک کامیت قدیمی

حالا فرض کنید در حین بررسی یک کامیت قدیمی در حالت Detached HEAD، یک باگ را پیدا کرده‌اید و می‌خواهید آن را برطرف کنید. یا شاید می‌خواهید یک قابلیت جدید را بر پایه آن نسخه قدیمی توسعه دهید. همانطور که گفتیم، کامیت مستقیم در این حالت ایده خوبی نیست.

راه حل صحیح، ایجاد یک برنچ جدید از همین نقطه است. این کار به کامیت‌های جدید شما یک «لنگر» یا «شاخه» مشخص در تاریخچه می‌دهد. برای این کار، از آپشن -b در دستور checkout استفاده می‌کنیم:

git checkout -b fix-old-bug

این دستور یک برنچ جدید به نام fix-old-bug از همین کامیت فعلی ایجاد کرده و بلافاصله شما را به آن منتقل می‌کند. اکنون HEAD دیگر جدا شده نیست و به برنچ جدید شما اشاره دارد. شما می‌توانید با خیال راحت کامیت‌های جدید خود را در این برنچ ثبت کنید.

بازگشت به زمان حال

پس از اتمام گشت‌وگذار در گذشته، بازگشت به آخرین نسخه پروژه بسیار ساده است. کافیست نام برنچ اصلی خود را دوباره checkout کنید:

git checkout main

این دستور اشاره‌گر HEAD را به نوک برنچ main بازمی‌گرداند و فایل‌های پوشه کاری شما را به آخرین نسخه به‌روزرسانی می‌کند.