| GIT-CHECKOUT(1) | دستورات عمومی کاربر | GIT-CHECKOUT(1) |
نام (NAME)
git-checkout - جابهجایی میان شاخهها یا بازیابی فایلهای درخت کاری
خلاصه دستور (SYNOPSIS)
git checkout [-q] [-f] [-m] [<branch>] git checkout [-q] [-f] [-m] --detach [<branch>] git checkout [-q] [-f] [-m] [--detach] <commit> git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new-branch>] [<start-point>] git checkout <tree-ish> [--] <pathspec>... git checkout <tree-ish> --pathspec-from-file=<file> [--pathspec-file-nul] git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>... git checkout [-f|--ours|--theirs|-m|--conflict=<style>] --pathspec-from-file=<file> [--pathspec-file-nul] git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]
توضیحات (DESCRIPTION)
دستور git checkout دارای دو حالت اصلی است:
برای چگونگی تصمیمگیری گیت در انتخاب هریک از این دو حالت، بخش «ابهامزدایی از آرگومانها (ARGUMENT DISAMBIGUATION)» در ادامه را ببینید.
git checkout [<branch>]
اگر <branch> یافت نشود، اما دقیقاً در یک ریموت شاخه ردیابی با نام منطبق وجود داشته باشد (آن را <remote> مینامیم) و گزینه --no-guess مشخص نشده باشد، معادل دستور زیر در نظر گرفته میشود:
$ git checkout -b <branch> --track <remote>/<branch>
اجرای git checkout بدون تعیین یک شاخه، هیچ اثری ندارد مگر آنکه اطلاعات ردیابی شاخه فعلی را چاپ کند.
git checkout -b <new-branch> [<start-point>]
اگر در دریافت <new-branch> خطایی رخ دهد، برای نمونه اگر دریافت کامیت <start-point> باعث رونویسی تغییرات کامیتنشده شما شود، این عملیات با شکست مواجه خواهد شد.
git checkout -B <branch> [<start-point>]
git checkout --detach [<branch>], git checkout [--detach] <commit>
حذف کردن <branch> باعث جدا شدن HEAD در نوک (tip) شاخه فعلی میشود.
git checkout <tree-ish> [--] <pathspec>..., git checkout <tree-ish> --pathspec-from-file=<file> [--pathspec-file-nul]
برای نمونه، دستور git checkout main file.txt فایل file.txt را با نسخه موجود در شاخه main جایگزین خواهد کرد.
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [--] <pathspec>..., git checkout [-f|--ours|--theirs|-m|--conflict=<style>] --pathspec-from-file=<file> [--pathspec-file-nul]
برای نمونه، اگر کامیتی را چکاوت کنید، فایل file.txt را ویرایش نمایید، و سپس متوجه شوید که آن تغییرات اشتباه بودهاند، دستور git checkout file.txt تمامی تغییرات مرحلهبندینشده (unstaged) در file.txt را دور میاندازد.
اگر فایل دارای تعارض در ادغام (merge conflict) باشد و شما هنوز دستور git add file.txt (یا معادل آن) را برای علامتگذاری به عنوان رفع تعارض اجرا نکرده باشید، این دستور با شکست مواجه میشود. میتوانید از گزینه -f استفاده کنید تا به جای شکست، ورودیهای ادغامنشده نادیده گرفته شوند؛ از --ours یا --theirs برای جایگزینی آنها با نسخه یک سمت خاص از ادغام استفاده نمایید؛ یا از گزینه -m برای جایگزینی آنها با نتیجه اولیه ادغام دارای تعارض بهره ببرید.
git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]
گزینهها (OPTIONS)
-q, --quiet
--progress, --no-progress
-f, --force
هنگام دریافت مسیرها از ایندکس، در صورت وجود ورودیهای ادغامنشده با شکست مواجه نمیشود؛ در عوض، ورودیهای ادغامنشده نادیده گرفته میشوند.
--ours, --theirs
توجه داشته باشید که هنگام اجرای git rebase و git pull --rebase، ممکن است ours و theirs جابهجا به نظر برسند؛ --ours نسخه موجود در شاخهای را ارائه میدهد که تغییرات بر روی آن بازپایهریزی (rebase) میشوند، در حالی که --theirs نسخه موجود در شاخهای را ارائه میدهد که کارهای در حال بازپایهریزی شما را در بر دارد.
دلیل این امر این است که rebase در گردش کاری به کار میرود که تاریخچه موجود در ریموت را به عنوان تاریخچه مرجع و مشترک تلقی میکند، و کارهای انجامشده روی شاخهای را که بازپایهریزی میکنید به عنوان کارهای شخص ثالث در نظر میگیرد که باید یکپارچه شوند، و شما در طول بازپایهریزی موقتاً نقش نگهدارنده تاریخچه مرجع را به عهده میگیرید. به عنوان نگهدارنده تاریخچه مرجع، شما باید تاریخچه ریموت را به عنوان ours (یعنی "تاریخچه مرجع مشترک ما")، و کارهایی را که روی شاخه جانبی خود انجام دادهاید به عنوان theirs (یعنی "کار یکی از مشارکتکنندگان روی آن") در نظر بگیرید.
-b <new-branch>
-B <new-branch>
-t, --track[=(direct|inherit)]
اگر گزینه -b داده نشود، نام شاخه جدید از شاخه ردیابی ریموت برگرفته میشود؛ این کار با نگاه به بخش محلی refspec پیکربندیشده برای ریموت مربوطه و سپس حذف بخش ابتدایی تا علامت "*" صورت میگیرد. این امر به ما میگوید که هنگام انشعاب از origin/hack (یا remotes/origin/hack، یا حتی refs/remotes/origin/hack)، از نام hack به عنوان شاخه محلی استفاده کنیم. اگر نام دادهشده فاقد اسلش باشد، یا حدس زدن بالا به نامی خالی منجر شود، فرآیند حدس زدن متوقف میشود. در چنین حالتی میتوانید با -b صریحاً یک نام مشخص کنید.
--no-track
--guess, --no-guess
$ git checkout -b <branch> --track <remote>/<branch>
اگر شاخه در چندین ریموت وجود داشته باشد و نام یکی از آنها در متغیر پیکربندی checkout.defaultRemote مشخص شده باشد، برای ابهامزدایی از آن استفاده خواهیم کرد، حتی اگر <branch> میان تمامی ریموتها یکتا نباشد. برای نمونه، آن را روی checkout.defaultRemote=origin تنظیم کنید تا در صورتی که <branch> مبهم باشد اما در ریموت origin وجود داشته باشد، همیشه شاخههای ریموت از آنجا دریافت شوند. همچنین گزینه checkout.defaultRemote در git-config(1) را ببینید.
رفتار پیشفرض، --guess است. برای غیرفعال کردن آن از --no-guess استفاده کنید.
رفتار پیشفرض میتواند از طریق متغیر پیکربندی checkout.guess تنظیم شود.
-l
-d, --detach
--orphan <new-branch>
ایندکس و درخت کاری طوری تنظیم میشوند که گویی پیشتر دستور git checkout <start-point> را اجرا کردهاید. این به شما امکان میدهد با اجرای ساده git commit -a برای ساختن کامیت ریشه، تاریخچه جدیدی را آغاز کنید که مجموعهای از مسیرهای مشابه با <start-point> را ثبت مینماید.
این گزینه زمانی مفید است که بخواهید درخت یک کامیت را بدون افشای تاریخچه کامل آن منتشر کنید. ممکن است بخواهید این کار را برای انتشار شاخه متنباز از پروژهای انجام دهید که درخت فعلی آن "پاک" است، اما تاریخچه کامل آن شامل کدهای اختصاصی یا دارای محدودیتهای دیگر است.
اگر میخواهید یک تاریخچه منفصل را شروع کنید که مجموعهای از مسیرها را کاملاً متفاوت با مسیرهای <start-point> ثبت میکند، باید بلافاصله پس از ایجاد شاخه یتیم (orphan)، با اجرای دستور git rm -rf . از بالاترین سطح درخت کاری، ایندکس و درخت کاری را پاک کنید. پس از آن آماده خواهید بود تا با کپی کردن فایلها از جای دیگر، استخراج یک فایل تاربال و غیره، فایلهای جدید خود را آماده کرده و درخت کاری را دوباره پر نمایید.
--ignore-skip-worktree-bits
-m, --merge
هنگام دریافت مسیرها از ایندکس، این گزینه به شما امکان میدهد ادغام دارای تعارض را در مسیرهای مشخصشده بازسازی کنید. این گزینه را نمیتوان هنگام دریافت مسیرها از یک tree-ish استفاده کرد.
--conflict=<style>
-p, --patch
این بدان معناست که میتوانید از دستور git checkout -p برای دور ریختن انتخابی ویرایشها از درخت کاری فعلی خود استفاده کنید. برای یادگیری نحوه کار با حالت --patch، به بخش "Interactive Mode" در git-add(1) مراجعه نمایید.
توجه داشته باشید که این گزینه بهطور پیشفرض از حالت بدون همپوشانی (no overlay) استفاده میکند (همچنین گزینه --overlay را ببینید)، و در حال حاضر از حالت همپوشانی (overlay) پشتیبانی نمیکند.
-U<n>, --unified=<n>
--inter-hunk-context=<n>
--ignore-other-worktrees
--overwrite-ignore, --no-overwrite-ignore
--recurse-submodules, --no-recurse-submodules
--overlay, --no-overlay
--pathspec-from-file=<file>
--pathspec-file-nul
<branch>
میتوانید از ساختار @{-N} برای ارجاع به N-امین شاخه/کامیتِ قبلیِ دریافتشده با دستور "git checkout" استفاده نمایید. همچنین میتوانید - را مشخص کنید که مترادف با @{-1} است.
به عنوان یک حالت خاص، میتوانید از <rev-a>...<rev-b> به عنوان میانبری برای پایه ادغام (merge base) میان <rev-a> و <rev-b> در صورتی که دقیقاً یک پایه ادغام وجود داشته باشد استفاده کنید. شما میتوانید حداکثر یکی از <rev-a> و <rev-b> را حذف کنید که در این صورت پیشفرض آن HEAD خواهد بود.
<new-branch>
<start-point>
به عنوان یک حالت خاص، میتوانید از <rev-a>...<rev-b> به عنوان میانبری برای پایه ادغام (merge base) میان <rev-a> و <rev-b> در صورتی که دقیقاً یک پایه ادغام وجود داشته باشد استفاده کنید. شما میتوانید حداکثر یکی از <rev-a> و <rev-b> را حذف کنید که در این صورت پیشفرض آن HEAD خواهد بود.
<tree-ish>
به عنوان یک حالت خاص، میتوانید از <rev-a>...<rev-b> به عنوان میانبری برای پایه ادغام میان <rev-a> و <rev-b> در صورتی که دقیقاً یک پایه ادغام وجود داشته باشد استفاده کنید. شما میتوانید حداکثر یکی از <rev-a> و <rev-b> را حذف کنید که در این صورت پیشفرض آن HEAD خواهد بود.
--
<pathspec>...
برای جزئیات بیشتر، به مدخل pathspec در gitglossary(7) مراجعه کنید.
سر جداشده (DETACHED HEAD)
بهطور معمول، HEAD به یک شاخه نامگذاریشده ارجاع دارد (مانند master). در همین حال، هر شاخه به یک کامیت مشخص اشاره میکند. بیایید مخزنی با سه کامیت را در نظر بگیریم که روی یکی از آنها برچسب خورده و شاخه master دریافت شده است:
HEAD (refers to branch 'master')
|
v
a---b---c branch 'master' (refers to commit 'c')
^
|
tag 'v2.0' (refers to commit 'b')
هنگامی که کامیتی در این وضعیت ایجاد میشود، شاخه بهروزرسانی میشود تا به کامیت جدید اشاره کند. به طور دقیقتر، git commit یک کامیت جدید به نام d ایجاد میکند که والد آن کامیت c است، و سپس شاخه master را بهروزرسانی میکند تا به کامیت جدید d اشاره کند. در این حالت، HEAD همچنان به شاخه master اشاره دارد و بنابراین اکنون بهطور غیرمستقیم به کامیت d ارجاع میدهد:
$ edit; git add; git commit
HEAD (refers to branch 'master')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
گاهی اوقات مفید است که بتوانید کامیتی را دریافت کنید که در نوک (tip) هیچ شاخه نامگذاریشدهای قرار ندارد، یا حتی کامیت جدیدی بسازید که توسط هیچ شاخه نامگذاریشدهای ارجاع داده نشده باشد. بیایید ببینیم چه اتفاقی میافتد اگر کامیت b را دریافت کنیم (در اینجا دو روش انجام این کار نشان داده شده است):
$ git checkout v2.0 # or
$ git checkout master^^
HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
توجه داشته باشید که صرفنظر از اینکه از کدام دستور چکاوت استفاده کنیم، HEAD اکنون مستقیماً به کامیت b اشاره دارد. این وضعیت به عنوان قرار داشتن در حالت سر جداشده (HEAD جداشده) شناخته میشود. این حالت به سادگی به این معناست که HEAD به یک کامیت مشخص اشاره دارد، در مقابل اینکه به یک شاخه نامگذاریشده ارجاع دهد. بیایید ببینیم هنگام ایجاد یک کامیت چه رخ میدهد:
$ edit; git add; git commit
HEAD (refers to commit 'e')
|
v
e
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
اکنون کامیت جدیدی به نام e وجود دارد، اما تنها توسط HEAD ارجاع داده میشود. البته میتوانیم در این وضعیت یک کامیت دیگر نیز اضافه کنیم:
$ edit; git add; git commit
HEAD (refers to commit 'f')
|
v
e---f
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
در واقع، ما میتوانیم تمام عملیاتهای معمول گیت را انجام دهیم. اما بیایید ببینیم وقتی شاخه master را چکاوت میکنیم چه رخ میدهد:
$ git checkout master
HEAD (refers to branch 'master')
e---f |
/ v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
بسیار مهم است که درک کنیم در این نقطه هیچ چیزی به کامیت f ارجاع ندارد. در نهایت کامیت f (و در نتیجه کامیت e) توسط فرآیند روتین جمعآوری زباله (garbage collection) در گیت حذف خواهد شد، مگر اینکه پیش از رخ دادن آن، ارجاعی به آن ایجاد نماییم. اگر هنوز از کامیت f جابهجا نشدهایم، هر یک از دستورات زیر یک ارجاع به آن ایجاد میکند:
$ git checkout -b foo # or "git switch -c foo" (1) $ git branch foo (2) $ git tag foo (3)
| 1. | یک شاخه جدید به نام foo ایجاد میکند که به کامیت f اشاره دارد، و سپس HEAD را بهروزرسانی میکند تا به شاخه foo ارجاع دهد. به عبارت دیگر، پس از این دستور دیگر در وضعیت سر جداشده (detached HEAD) نخواهیم بود. |
| 2. | به طور مشابه یک شاخه جدید به نام foo ایجاد میکند که به کامیت f اشاره دارد، اما HEAD را در وضعیت جداشده باقی میگذارد. |
| 3. | یک برچسب (tag) جدید به نام foo ایجاد میکند که به کامیت f اشاره دارد، و HEAD را در وضعیت جداشده باقی میگذارد. |
اگر از کامیت f دور شده باشیم، ابتدا باید نام شیء (object name) آن را بازیابی کنیم (معمولاً با استفاده از git reflog)، و سپس میتوانیم ارجاعی به آن ایجاد نماییم. برای مثال، برای مشاهده دو کامیت آخری که HEAD به آنها اشاره داشته است، میتوانیم از یکی از این دستورات استفاده کنیم:
$ git reflog -2 HEAD # or $ git log -g -2 HEAD
ابهامزدایی از آرگومانها (ARGUMENT DISAMBIGUATION)
هنگامی که دستور git checkout <something> را اجرا میکنید، گیت تلاش میکند تا حدس بزند که آیا <something> به عنوان یک شاخه، یک کامیت یا مجموعهای از فایل(ها) در نظر گرفته شده است، و سپس به آن شاخه یا کامیت جابهجا میشود، یا فایلهای مشخصشده را بازیابی میکند.
در صورت وجود هرگونه ابهام، گیت با <something> به عنوان یک شاخه یا کامیت رفتار میکند، اما میتوانید از دو خط تیره -- استفاده کنید تا گیت را مجبور سازد که پارامتر را به عنوان فهرستی از فایلها و/یا دایرکتوریها در نظر بگیرد، مانند زیر:
git checkout -- file.txt
مثالها (EXAMPLES)
۱. مسیرها (1. Paths)
دنباله دستورات زیر شاخه master را دریافت میکند، فایل Makefile را به دو بازبینی قبل برمیگرداند، فایل hello.c را به اشتباه حذف میکند، و آن را دوباره از ایندکس بازیابی مینماید.
$ git checkout master (1) $ git checkout master~2 Makefile (2) $ rm -f hello.c $ git checkout hello.c (3)
| 1. | تغییر شاخه |
| 2. | برداشتن یک فایل از کامیتی دیگر |
| 3. | بازیابی hello.c از ایندکس |
اگر میخواهید تمام فایلهای منبع C را از ایندکس خارج کرده و دریافت کنید، میتوانید بنویسید:
$ git checkout -- '*.c'
به نقلقولهای اطراف *.c دقت کنید. فایل hello.c نیز دریافت خواهد شد، حتی اگر دیگر در درخت کاری وجود نداشته باشد، زیرا الگوی انطباق فایل (globbing) برای مطابقت با ورودیهای موجود در ایندکس استفاده میشود (نه در درخت کاری توسط شل).
اگر شاخهای با نام نامناسب hello.c داشته باشید، این مرحله با دستور تعویض به آن شاخه اشتباه گرفته میشود. در عوض باید بنویسید:
$ git checkout -- hello.c
۲. ادغام (2. Merge)
پس از کار در شاخه اشتباه، تعویض به شاخه درست با دستور زیر انجام میشود:
$ git checkout mytopic
با این حال، شاخه "اشتباه" شما و شاخه درست mytopic ممکن است در فایلهایی که به صورت محلی ویرایش کردهاید تفاوت داشته باشند، که در این صورت دریافت بالا با خطایی مانند این مواجه خواهد شد:
$ git checkout mytopic error: You have local changes to 'frotz'; not switching branches.
میتوانید فلگ -m را به دستور بدهید که تغییرات محلی شما را به شاخه جدید منتقل میکند:
$ git checkout -m mytopic Applied autostash. Switched to branch 'mytopic' The following paths have local changes: M frotz
پس از تعویض شاخه، اصلاحات محلی مجدداً اعمال شده و در فایل ایندکس شما ثبت نمیشوند، بنابراین دستور git diff به شما نشان میدهد که از زمان نوک شاخه جدید چه تغییراتی اعمال کردهاید.
۳. تعارض در ادغام (3. Merge conflict)
هنگامی که گزینه --merge (-m) داده میشود و تغییرات محلی با تغییرات شاخهای که قصد تعویض به آن را داریم همپوشانی داشته باشند، تغییرات در استش ذخیره شده و پس از تعویض شاخه دوباره اعمال میشوند. اگر این فرآیند به تعارض منجر شود، ورودی استش ذخیره شده و پیامی چاپ میشود:
$ git checkout -m mytopic Your local changes are stashed, however applying them resulted in conflicts. You can either resolve the conflicts and then discard the stash with "git stash drop", or, if you do not want to resolve them now, run "git reset --hard" and apply the local changes later by running "git stash pop".
پیکربندی (CONFIGURATION)
تمام موارد زیر این خط در این بخش بهطور انتخابی از مستندات git-config(1) گنجانده شدهاند. محتوا با آنچه در آنجا آمده یکسان است:
checkout.defaultRemote
در حال حاضر این مورد توسط git-switch(1) و git-checkout(1) زمانی استفاده میشود که git checkout <something> یا git switch <something> شاخه <something> را روی ریموت دیگری دریافت کند، و توسط git-worktree(1) زمانی که دستور git worktree add به یک شاخه ریموت ارجاع میدهد. این تنظیم ممکن است در آینده برای سایر دستورات یا عملکردهای شبیه به چکاوت نیز استفاده شود.
checkout.guess
checkout.workers
نکته
دریافت موازی معمولاً کارایی بهتری برای مخازن قرارگرفته روی SSDها یا بر بستر NFS به همراه دارد. برای مخازن واقع در دیسکهای چرخان (HDD) و/یا سیستمهایی با تعداد اندک هستههای پردازشی، معمولاً دریافت متوالی پیشفرض کارایی بهتری از خود نشان میدهد. اندازه و سطح فشردهسازی یک مخزن نیز ممکن است بر میزان بهینه بودن کارکرد نسخه موازی تأثیر بگذارد.
checkout.thresholdForParallelism
همچنین ببینید (SEE ALSO)
گیت (GIT)
بخشی از مجموعه git(1)
| 2026-06-29 | Git 2.55.0 |