| GIT-RESET(1) | Git Manual | GIT-RESET(1) |
نام (NAME)
git-reset - بازنشانی HEAD یا ایندکس به یک وضعیت مشخص
خلاصه دستور (SYNOPSIS)
git reset [--ft | --xed [-N] | -- git reset [-q] [<tree-ish>] [--] <pathspec>... git reset [-q] [--athspec-from-file=<file> [--athspec-file-nul]] [<tree-ish>] git reset (--atch | -p) [<tree-ish>] [--] [<pathspec>...]
توضیحات (DESCRIPTION)
دستور git reset یکی از کارهای زیر را انجام میدهد:
git reset [<mode>] [<commit>]
حالت <mode> باید یکی از موارد زیر باشد (پیشفرض --xed):
--xed
اگر -N مشخص شود، مسیرهای حذفشده به عنوان قصد افزودن (intent-to-add) علامتگذاری میشوند (به git-add?R(1) مراجعه کنید).
--ft
--
--rge
--ep
--ecurse-submodules, --0-recurse-submodules
git reset [-q] [<tree-ish>]
[--] <pathspec>..., git reset [-q]
[--athspec-from-file=<file>
[--athspec-file-nul]]
[<tree-ish>]
این بدان معناست که git reset <pathspec> برعکس git add <pathspec> است: تمام تغییرات در فایل(ها) یا دایرکتوریهای مشخصشده را از حالت استیج خارج میکند (unstage). این معادل است با git restore --aged <pathspec>....
در این حالت، git reset تنها ایندکس را بهروزرسانی میکند (بدون بهروزرسانی HEAD یا فایلهای درخت کاری). اگر میخواهید علاوه بر ورودیهای ایندکس، فایلها را نیز بهروزرسانی کنید، از git-restore(1) استفاده کنید.
git reset (--atch
| -p) [<tree-ish>] [--]
[<pathspec>...]
این بدان معناست که git reset -p برعکس git add -p است، یعنی میتوانید از آن برای خارج کردن گزینشی تغییرات از حالت استیج استفاده کنید. برای یادگیری نحوه استفاده از گزینه --atch به بخش "Interactive Mode" در git-add(1) مراجعه کنید.
برای آشنایی با تفاوتهای میان این سه دستور، بخش "Reset, restore and revert" را در git(1) ببینید.
گزینهها (OPTIONS)
-q, --quiet
--efresh, --0-refresh
--athspec-from-file=<file>
--athspec-file-nul
-U<n>, --nified=<n>
--inter-hunk-context=<n>
--
<pathspec>...
برای جزئیات بیشتر، مدخل pathspec را در gitglossary(7) ببینید.
مثالها (EXAMPLES)
لغو دستور add
$ edit (1) $ git add frotz.c filfre.c $ mailx (2) $ git reset (3) $ git pull git://info.example.com/ nitfol (4)
| 1. | شما با خوشحالی در حال کار بر روی چیزی هستید و میبینید که تغییرات در این فایلها در وضعیت خوبی هستند. نمیخواهید هنگام اجرای git diff آنها را ببینید، زیرا قصد دارید روی فایلهای دیگر کار کنید و تغییرات این فایلها تمرکزتان را به هم میزند. |
| 2. | کسی از شما میخواهد pull کنید و تغییرات ارزش ادغام کردن را دارند. |
| 3. | با این حال، شما قبلاً ایندکس را دستکاری کردهاید (یعنی ایندکس شما با کامیت HEAD مطابقت ندارد). اما میدانید pull شما بر روی frotz.c یا filfre.c تأثیری ندارد، بنابراین تغییرات ایندکس را برای این دو فایل بازمیگردانید. تغییرات شما در درخت کاری همچنان در آنجا باقی میماند. |
| 4. | سپس میتوانید pull و merge کنید، در حالی که تغییرات frotz.c و filfre.c همچنان در درخت کاری باقی ماندهاند. |
لغو یک کامیت و انجام مجدد آن
$ git commit ... $ git reset --ft HEAD^ (1) $ edit (2) $ git commit -a -c ORIG_HEAD (3)
| 1. | این کار بیشتر زمانی انجام میشود که به یاد میآورید آنچه به تازگی کامیت کردهاید ناقص است، یا پیام کامیت را اشتباه نوشتهاید، یا هر دو. درخت کاری را همانطور که قبل از "reset" بود باقی میگذارد. |
| 2. | اصلاحات را روی فایلهای درخت کاری اعمال کنید. |
| 3. | دستور "reset" سرشاخه قدیمی را در .git/ORIG_HEAD کپی میکند؛ کامیت را با شروع از پیام لاگ آن دوباره انجام دهید. اگر نیازی به ویرایش بیشتر پیام ندارید، میتوانید گزینه -C را به جای آن ارسال کنید. همچنین گزینه --mend در git-commit(1) را ببینید. |
لغو یک کامیت و تبدیل آن به یک شاخه موضوعی
$ git branch topic/wip (1) $ git reset -- $ git switch topic/wip (3)
| 1. | شما چند کامیت ایجاد کردهاید، اما متوجه میشوید که برای حضور در شاخه master زود بودند. میخواهید کار روی آنها را در یک شاخه موضوعی صیقل دهید، بنابراین شاخه topic/wip را از HEAD فعلی ایجاد میکنید. |
| 2. | شاخه master را به عقب بازگردانید تا از شر آن سه کامیت خلاص شوید. |
| 3. | به شاخه topic/wip جابهجا شوید و به کار ادامه دهید. |
حذف دائمی کامیتها
$ git commit ... $ git reset --
| 1. | سه کامیت آخر (HEAD، HEAD^ و HEAD~2) نامناسب بودند و هرگز نمیخواهید دوباره آنها را ببینید. اگر قبلاً این کامیتها را به شخص دیگری دادهاید، این کار را انجام ندهید. (برای پیامدهای این کار بخش "RECOVERING FROM UPSTREAM REBASE" را در git-rebase(1) ببینید). |
لغو یک ادغام (merge) یا دریافت (pull)
$ git pull (1) Auto-merging nitfol CONFLICT (content): Merge conflict in nitfol Automatic merge failed; fix conflicts and then commit the result. $ git reset -- $ git pull . topic/branch (3) Updating from 41223... to 13134... Fast-forward $ git reset --
| 1. | تلاش برای بهروزرسانی از upstream منجر به تعارضهای زیادی شد؛ شما در حال حاضر آماده نبودید وقت زیادی را صرف ادغام کنید، بنابراین تصمیم میگیرید آن را به بعد موکول کنید. |
| 2. | دستور "pull" کامیت ادغام را نساخته است، بنابراین git reset -- |
| 3. | یک شاخه موضوعی را در شاخه جاری ادغام میکنید، که منجر به یک fast-forward میشود. |
| 4. | اما شما تصمیم گرفتید که شاخه موضوعی هنوز برای استفاده عمومی آماده نیست. دستور "pull" یا "merge" همیشه سرشاخه اصلی شاخه جاری را در ORIG_HEAD باقی میگذارد، بنابراین ریست سخت به آن، فایل ایندکس و درخت کاری شما را به آن وضعیت برمیگرداند و سرشاخه شاخه را به آن کامیت بازنشانی میکند. |
لغو ادغام یا pull در یک درخت کاری دارای تغییرات
$ git pull (1) Auto-merging nitfol Merge made by recursive. nitfol | 20 +++++---- ... $ git reset --rge ORIG_HEAD (2)
| 1. | حتی اگر تغییرات محلی در درخت کاری خود داشته باشید، وقتی میدانید که تغییر در شاخه دیگر با آنها تداخلی ندارد، میتوانید با خیال راحت git pull کنید. |
| 2. | پس از بررسی نتیجه ادغام، ممکن است متوجه شوید تغییر موجود در شاخه دیگر رضایتبخش نیست. اجرای git reset -- |
جریان کاری دچار وقفه
$ git switch feature ;# you were working in "feature" branch and $ work work work ;# got interrupted $ git commit -a -m "snapshot WIP" (1) $ git switch master $ fix fix fix $ git commit ;# commit with real log $ git switch feature $ git reset --ft HEAD^ ;# go back to WIP state (2) $ git reset (3)
| 1. | این کامیت بعداً دور انداخته خواهد شد، بنابراین یک پیام لاگ موقتی اشکالی ندارد. |
| 2. | این کار کامیت WIP را از تاریخچه کامیت حذف میکند و درخت کاری شما را به وضعیت دقیقاً قبل از ثبت آن تصویر لحظهای بازمیگرداند. |
| 3. | در این مرحله فایل ایندکس همچنان تمام تغییرات WIP را دارد که شما به عنوان snapshot WIP کامیت کرده بودید. این کار ایندکس را بهروزرسانی میکند تا فایلهای WIP شما را به عنوان کامیتنشده نشان دهد. همچنین git-stash(1) را ببینید. |
بازنشانی یک فایل خاص در ایندکس
$ git reset -- frotz.c (1) $ git commit -m "Commit files in index" (2) $ git add frotz.c (3)
| 1. | این کار فایل را از ایندکس حذف میکند در حالی که آن را در دایرکتوری کاری نگه میدارد. |
| 2. | این کار تمام تغییرات دیگر موجود در ایندکس را کامیت میکند. |
| 3. | فایل را دوباره به ایندکس اضافه میکند. |
حفظ تغییرات در درخت کاری همزمان با حذف برخی کامیتهای قبلی
$ git tag start $ git switch -c branch1 $ edit $ git commit ... (1) $ edit $ git switch -c branch2 (2) $ git reset --ep start (3)
| 1. | این اولین ویرایشهای شما را در branch1 کامیت میکند. |
| 2. | در یک دنیای ایدهآل، میتوانستید هنگامی که branch2 را ساختید و به آن جابهجا شدید متوجه شوید که کامیت قبلی به موضوع جدید تعلق ندارد (یعنی git switch -c branch2 start)، اما هیچکس بینقص نیست. |
| 3. | اما میتوانید پس از جابهجایی به branch2، از reset --ep برای حذف کامیت ناخواسته استفاده کنید. |
تقسیم یک کامیت به توالی چند کامیت مجزا
$ git reset -N HEAD^ (1)
$ git add -p (2)
$ git diff --ached (3)
$ git commit -c HEAD@{1} (4)
... (5)
$ git add ... (6)
$ git diff --ached (7)
$ git commit ... (8)
| 1. | ابتدا، تاریخچه را یک کامیت به عقب بازنشانی کنید تا کامیت اصلی حذف شود، اما درخت کاری با تمام تغییرات باقی بماند. گزینه -N اطمینان میدهد هر فایل جدیدی که با HEAD اضافه شده است همچنان نشانهگذاری شده باشد تا git add -p آنها را پیدا کند. |
| 2. | در مرحله بعد، با استفاده از قابلیت git add -p تکههای diff را به صورت تعاملی برای افزودن انتخاب میکنیم. این دستور درباره هر تکه diff به ترتیب از شما سؤال میکند و میتوانید از دستورات سادهای مانند "yes, include this"، "No don’t include this" یا حتی قابلیت بسیار قدرتمند "edit" استفاده کنید. |
| 3. | پس از رضایت از تکههایی که میخواهید شامل شوند، باید با استفاده از git diff --ached آنچه را که برای اولین کامیت آماده شده بررسی کنید. این دستور تمام تغییراتی را نشان میدهد که به ایندکس منتقل شدهاند و در آستانه کامیت شدن هستند. |
| 4. | سپس، تغییرات ذخیرهشده در ایندکس را کامیت کنید. گزینه -c مشخص میکند که پیام کامیت از پیام اصلی که در کامیت اول با آن شروع کرده بودید پیشپر شود. این کار برای جلوگیری از تایپ مجدد آن مفید است. عبارت HEAD@{1} نماد خاصی برای کامیتی است که HEAD پیش از کامیت بازنشانی اصلی در آن قرار داشت (۱ تغییر قبل). برای جزئیات بیشتر به git-reflog(1) مراجعه کنید. همچنین میتوانید از هر مرجع کامیت معتبر دیگری استفاده کنید. |
| 5. | میتوانید مراحل ۲ تا ۴ را چندین بار تکرار کنید تا کد اصلی را به هر تعداد کامیت تقسیم نمایید. |
| 6. | اکنون شما بسیاری از تغییرات را به کامیتهای اختصاصی خود تفکیک کردهاید، و برای انتخاب تمام تغییرات کامیتنشده باقیمانده ممکن است دیگر نیازی به استفاده از حالت وصله در git add نداشته باشید. |
| 7. | یک بار دیگر بررسی کنید تا مطمئن شوید آنچه میخواهید را گنجاندهاید. همچنین ممکن است بخواهید اطمینان حاصل کنید که git diff هیچ تغییر باقیماندهای را برای کامیت بعدی نشان نمیدهد. |
| 8. | و سرانجام آخرین کامیت را بسازید. |
بحث و بررسی (DISCUSSION)
جدولهای زیر نشان میدهند هنگام اجرای دستور زیر چه اتفاقی میافتد:
git reset --
برای بازنشانی HEAD به یک کامیت دیگر (target) با گزینههای مختلف بازنشانی بسته به وضعیت فایلها.
در این جدولها، A، B، C و D وضعیتهای متفاوتی از یک فایل هستند. برای مثال، سطر اول جدول نخست به این معنی است که اگر یک فایل در درخت کاری در وضعیت A، در ایندکس در وضعیت B، در HEAD در وضعیت C و در target در وضعیت D باشد، آنگاه git reset --ft target فایل را در درخت کاری در وضعیت A و در ایندکس در وضعیت B باقی میگذارد. این دستور HEAD (یعنی سرشاخه شاخه فعلی، در صورت حضور در یکی از شاخهها) را به target (که فایل را در وضعیت D دارد) بازنشانی میکند (یعنی انتقال میدهد).
working index HEAD target working index HEAD
--------------------------------------------------- A B C D --ft A B D
--xed A D D
--
--rge (disallowed)
--ep (disallowed)
working index HEAD target working index HEAD
--------------------------------------------------- A B C C --ft A B C
--xed A C C
--
--rge (disallowed)
--ep A C C
working index HEAD target working index HEAD
--------------------------------------------------- B B C D --ft B B D
--xed B D D
--
--rge D D D
--ep (disallowed)
working index HEAD target working index HEAD
--------------------------------------------------- B B C C --ft B B C
--xed B C C
--
--rge C C C
--ep B C C
working index HEAD target working index HEAD
--------------------------------------------------- B C C D --ft B C D
--xed B D D
--
--rge (disallowed)
--ep (disallowed)
working index HEAD target working index HEAD
--------------------------------------------------- B C C C --ft B C C
--xed B C C
--
--rge B C C
--ep B C C
دستور git reset --rge برای استفاده هنگام بازنشانی از یک ادغام دارای تعارض در نظر گرفته شده است. هر عملیات ادغام تضمین میکند فایل درخت کاری که در ادغام دخیل است، پیش از شروع عملیات نسبت به ایندکس تغییر محلی نداشته باشد، و نتیجه را در درخت کاری مینویسد. بنابراین اگر تفاوتی بین ایندکس و target و همچنین بین ایندکس و درخت کاری مشاهده کنیم، به این معنی است که ما از وضعیتی که یک عملیات ادغام پس از شکست با تعارض باقی گذاشته بازنشانی نمیکنیم. به همین دلیل در این حالت گزینه --rge را مجاز نمیدانیم.
دستور git reset --ep برای استفاده هنگام حذف برخی از آخرین کامیتها در شاخه فعلی در عین حفظ تغییرات در درخت کاری در نظر گرفته شده است. اگر تعارض احتمالی بین تغییرات موجود در کامیتی که میخواهیم حذف کنیم و تغییرات موجود در درخت کاری که میخواهیم نگه داریم وجود داشته باشد، بازنشانی غیرمجاز است. به همین دلیل اگر هم بین درخت کاری و HEAD و هم بین HEAD و target تغییراتی وجود داشته باشد، غیرمجاز است. برای ایمنی بیشتر، در صورت وجود ورودیهای ادغامنشده نیز غیرمجاز است.
جدولهای زیر نشان میدهند هنگامی که ورودیهای ادغامنشده وجود دارند چه اتفاقی میافتد:
working index HEAD target working index HEAD
--------------------------------------------------- X U A B --ft (disallowed)
--xed X B B
--
--rge B B B
--ep (disallowed)
working index HEAD target working index HEAD
--------------------------------------------------- X U A A --ft (disallowed)
--xed X A A
--
--rge A A A
--ep (disallowed)
X به معنای هر وضعیتی و U به معنای ایندکس ادغامنشده است.
گیت (GIT)
بخشی از مجموعه git(1)
| 2026-06-29 | Git 2.55.0 |