
تفاوت Git Reset، Revert و Restore چیست؟ راهنمای کاربردی با مثال
هنگام کار با Git ممکن است یک فایل را اشتباه تغییر دهید، یک Commit نامناسب بسازید یا تغییراتی را Push کنید که بعداً متوجه شوید باید برگردانده شوند. در چنین شرایطی، سه دستور git reset، git revert و git restore میتوانند به شما کمک کنند؛ اما هرکدام برای هدف متفاوتی طراحی شدهاند.
اگر میخواهید کار با Git را از پایه یاد بگیرید، آموزش گیت، گیت هاب و گیت لب از صفر میتواند مسیر یادگیری منسجمی برای آشنایی با Repository، Branch، Commit و دستورات پرکاربرد Git در اختیار شما قرار دهد. در این مقاله، تفاوت Reset، Revert و Restore را بررسی میکنیم تا بدانید در هر موقعیت از کدام دستور استفاده کنید.
تفاوت Git Reset، Revert و Restore در یک نگاه
هر سه دستور برای نوعی «برگرداندن» استفاده میشوند، اما روی بخشهای متفاوتی از پروژه تأثیر میگذارند.
| دستور | کاربرد اصلی | تأثیر بر Commit | تأثیر بر تاریخچه |
|---|---|---|---|
git reset | جابهجایی HEAD و تغییر وضعیت شاخه یا Index | ممکن است وضعیت شاخه را به Commit قبلی منتقل کند | در صورت جابهجایی شاخه، تاریخچه قابل مشاهده آن تغییر میکند |
git restore | برگرداندن محتوای فایل یا خارج کردن فایل از Stage | Commit جدیدی ایجاد نمیکند | تاریخچه Commitها را تغییر نمیدهد |
git revert | خنثی کردن اثر یک Commit | یک Commit جدید میسازد | تاریخچه قبلی حفظ میشود |
به زبان ساده:
- Restore: برای برگرداندن تغییرات فایلها یا خارج کردن آنها از Stage.
- Revert: برای خنثی کردن اثر یک Commit با ایجاد Commit جدید.
Reset: برای جابهجا کردن
HEADو تغییر وضعیت شاخه، Index یا Working Tree، بسته به گزینه استفادهشده.
Git Reset چیست؟
دستور git reset برای تغییر موقعیت HEAD، جابهجایی وضعیت شاخه نسبت به یک Commit مشخص و در برخی حالتها تغییر وضعیت فایلها و Stage استفاده میشود.
برای مثال، فرض کنید تاریخچه پروژه شما به شکل زیر است:
A → B → C → D
اگر دستور زیر را اجرا کنید:
git reset HEAD~1
در حالت پیشفرض، یعنی --mixed، شاخه از D به C منتقل میشود. تغییرات مربوط به Commit D در Working Tree باقی میمانند، اما از Stage خارج میشوند.
دستور Reset سه حالت مهم دارد.
۱. git reset --soft
در حالت --soft، فقط HEAD و موقعیت شاخه به Commit مشخصشده منتقل میشوند. تغییرات فایلها و وضعیت Stage حفظ میشوند.
git reset --soft HEAD~1
فرض کنید آخرین Commit را ساختهاید، اما پیام Commit اشتباه است یا میخواهید چند تغییر را با هم در یک Commit قرار دهید. با این دستور میتوانید به Commit قبلی برگردید، در حالی که تغییرات همچنان Stage شدهاند.
پس از اصلاح، میتوانید دوباره Commit بسازید:
git commit -m "Updated commit message"
۲. git reset --mixed
حالت --mixed، حالت پیشفرض Reset است. در این حالت، HEAD و Index به وضعیت Commit موردنظر برمیگردند، اما تغییرات فایلها در Working Tree باقی میمانند.
git reset --mixed HEAD~1
این حالت زمانی کاربرد دارد که میخواهید آخرین Commit را از تاریخچه فعلی شاخه خارج کنید، اما تغییرات فایلها را از دست ندهید و دوباره انتخاب کنید که کدام فایلها باید Stage شوند.
برای بررسی وضعیت فایلها میتوانید از دستور زیر استفاده کنید:
git status
۳. git reset --hard
در حالت --hard، HEAD، Index و Working Tree به وضعیت Commit موردنظر برمیگردند.
git reset --hard HEAD~1
در نتیجه، تغییرات محلی Trackشدهای که با وضعیت Commit هدف تفاوت دارند، ممکن است از بین بروند. به همین دلیل، این دستور باید با دقت استفاده شود.
نکته مهم: git reset --hard جایگزین مناسبی برای بررسی تغییرات مهم نیست. قبل از اجرای آن، مطمئن شوید که تغییرات محلی موردنیاز خود را ذخیره کردهاید. همچنین این دستور بهطور معمول فایلهای Untracked را حذف نمیکند؛ برای حذف آنها باید از دستورات مربوط به پاکسازی فایلهای بدون Track استفاده شود.
تفاوت سه حالت Reset
| حالت | HEAD | Index یا Stage | Working Tree |
|---|---|---|---|
--soft | تغییر میکند | حفظ میشود | حفظ میشود |
--mixed | تغییر میکند | به Commit هدف برمیگردد | حفظ میشود |
--hard | تغییر میکند | به Commit هدف برمیگردد | به Commit هدف برمیگردد |
Git Restore چیست؟
دستور git restore برای مدیریت محتوای فایلها در Working Tree و Index طراحی شده است. این دستور بهطور مستقیم برای جابهجایی شاخه یا حذف Commitها استفاده نمیشود.
با Restore میتوانید تغییرات یک فایل را کنار بگذارید، محتوای آن را از یک Commit مشخص بازیابی کنید یا فایلی را از Stage خارج کنید.
۱. برگرداندن تغییرات یک فایل
فرض کنید فایل file.txt را تغییر دادهاید، اما هنوز Commit نکردهاید و تصمیم گرفتهاید تغییرات آن را حذف کنید.
git restore file.txt
این دستور محتوای فایل را از وضعیت مرجع پیشفرض، معمولاً HEAD، بازیابی میکند. در نتیجه، تغییرات ثبتنشده آن فایل در Working Tree از بین میرود.
هشدار: اگر تغییرات مهمی در فایل دارید، پیش از اجرای این دستور از آنها نسخه پشتیبان بگیرید؛ چون ممکن است نتوانید تغییرات حذفشده را بهسادگی بازیابی کنید.
۲. بازیابی فایل از یک Commit مشخص
گاهی میخواهید محتوای یک فایل را از Commit قبلی دریافت کنید، بدون اینکه شاخه را به آن Commit منتقل کنید.
git restore --source=HEAD~1 file.txt
در این مثال، محتوای file.txt از Commit قبلی بازیابی میشود و در Working Tree قرار میگیرد. این کار بهخودیخود Commit جدیدی ایجاد نمیکند.
اگر بخواهید نسخه بازیابیشده را در Commit بعدی قرار دهید، باید آن را Stage و سپس Commit کنید:
git add file.txt
git commit -m "Restore file.txt"
۳. خارج کردن فایل از Stage
فرض کنید دستور زیر را اجرا کردهاید:
git add file.txt
اما بعداً تصمیم گرفتهاید این فایل فعلاً در Commit بعدی قرار نگیرد. برای خارج کردن آن از Stage میتوانید از این دستور استفاده کنید:
git restore --staged file.txt
در این حالت، فایل از Index خارج میشود، اما تغییرات آن در Working Tree باقی میمانند.
این کاربرد با git restore file.txt تفاوت مهمی دارد:
| دستور | نتیجه |
|---|---|
git restore file.txt | تغییرات فایل در Working Tree را برمیگرداند |
git restore --staged file.txt | فایل را از Stage خارج میکند و تغییرات آن را حفظ میکند |
اگر هنوز با مفاهیم پایه برنامهنویسی و ساختار پروژههای نرمافزاری آشنا نیستید، آموزش مبانی برنامهنویسی از صفر میتواند برای شروع یادگیری مفاهیم پایه مفید باشد.
Git Revert چیست؟
دستور git revert برای خنثی کردن اثر یک Commit استفاده میشود. برخلاف Reset، این دستور Commit قبلی را از تاریخچه حذف نمیکند؛ بلکه یک Commit جدید میسازد که تغییرات Commit موردنظر را معکوس میکند.
فرض کنید تاریخچه پروژه به شکل زیر است:
A → B → C → D
اگر بخواهید اثر Commit D را خنثی کنید، میتوانید از دستور زیر استفاده کنید:
git revert HEAD
Git تغییرات Commit آخر را معکوس میکند و یک Commit جدید به تاریخچه اضافه میشود:
A → B → C → D → E
در اینجا Commit E اثر تغییرات D را خنثی میکند؛ اما خود Commit D همچنان در تاریخچه باقی میماند.
چرا Revert برای Commitهای Pushشده کاربرد دارد؟
وقتی یک Commit را به Repository مشترک Push کردهاید، ممکن است اعضای دیگر تیم نیز آن را دریافت کرده باشند. استفاده از Reset و Push اجباری برای حذف آن Commit میتواند تاریخچه مشترک را تغییر دهد و باعث ایجاد مشکل برای دیگران شود.
در چنین شرایطی، Revert معمولاً راهکار مناسبتری برای خنثی کردن تغییرات است؛ زیرا با ایجاد یک Commit جدید، تاریخچه قبلی را حفظ میکند.
البته Revert همیشه بدون نیاز به بررسی انجام نمیشود. اگر تغییرات Commit با تغییرات بعدی تداخل داشته باشند، ممکن است Git از شما بخواهد Conflictها را برطرف کنید.
خنثی کردن یک Commit مشخص
برای برگرداندن اثر یک Commit خاص، میتوانید شناسه آن را مشخص کنید:
git revert a1b2c3d
بهجای a1b2c3d باید شناسه واقعی Commit موردنظر را قرار دهید.
برای مشاهده تاریخچه Commitها نیز میتوانید از دستور زیر استفاده کنید:
git log --oneline
Git Reset یا Revert کدام را استفاده کنیم؟
انتخاب دستور مناسب به این بستگی دارد که میخواهید چه چیزی را تغییر دهید و آیا Commit موردنظر قبلاً با دیگران به اشتراک گذاشته شده است یا نه.
وقتی Commit فقط روی سیستم شماست
اگر Commit هنوز Push نشده و میخواهید تاریخچه شاخه محلی خود را اصلاح کنید، Reset میتواند کاربرد داشته باشد.
برای مثال:
git reset --soft HEAD~1
این دستور آخرین Commit را از موقعیت فعلی شاخه عقب میبرد، اما تغییرات آن را Stageشده نگه میدارد.
اگر قصد دارید تغییرات را حفظ کنید اما آنها را دوباره بررسی و Stage کنید، حالت --mixed نیز میتواند مناسب باشد.
وقتی Commit قبلاً Push شده است
اگر Commit به Repository مشترک Push شده و افراد دیگری بر اساس آن کار میکنند، Revert معمولاً گزینهای برای خنثی کردن اثر آن Commit بدون بازنویسی تاریخچه مشترک است.
git revert HEAD
در این حالت، یک Commit جدید ساخته میشود و اعضای تیم میتوانند تاریخچه را بهصورت منسجم دنبال کنند.
وقتی فقط یک فایل را میخواهید برگردانید
اگر مشکل شما فقط تغییرات یک فایل است و هنوز نیازی به تغییر تاریخچه Commitها ندارید، Restore انتخاب مستقیمتری است.
git restore file.txt
یک قانون ساده برای به خاطر سپردن
- فقط تغییرات فایل را میخواهید کنار بگذارید؟ →
git restore - میخواهید یک فایل را از Stage خارج کنید؟ →
git restore --staged - میخواهید اثر یک Commit را خنثی کنید و تاریخچه را حفظ کنید؟ →
git revert - میخواهید موقعیت
HEADیا وضعیت شاخه را به Commit قبلی منتقل کنید؟ →git reset
یک مثال واقعی؛ از اشتباه در فایل تا اصلاح Commit
فرض کنید در یک پروژه وب، فایل index.html را تغییر دادهاید و سپس تغییرات را Commit کردهاید:
A → B → C → D
حالا سه موقعیت مختلف را بررسی کنیم.
موقعیت اول: تغییر فایل هنوز Commit نشده است
شما بخشی از index.html را اشتباه تغییر دادهاید و میخواهید آن را به آخرین نسخه Commitشده برگردانید:
git restore index.html
در این حالت فقط محتوای فایل برگردانده میشود و تاریخچه Commitها تغییری نمیکند.
موقعیت دوم: آخرین Commit اشتباه ساخته شده است
فرض کنید Commit D را ساختهاید، اما میخواهید تغییرات آن را نگه دارید و پس از اصلاح، Commit جدیدی بسازید:
git reset --soft HEAD~1
اکنون Commit آخر از موقعیت فعلی شاخه عقب برده شده است، اما تغییرات آن همچنان Stage هستند.
موقعیت سوم: Commit اشتباه قبلاً Push شده است
اگر Commit D را Push کردهاید و میخواهید اثر آن را خنثی کنید:
git revert HEAD
Git یک Commit جدید ایجاد میکند که تغییرات D را معکوس میکند:
A → B → C → D → E
در اینجا D حذف نشده است؛ بلکه E برای خنثی کردن اثر آن ساخته شده است.
Git در مسیر یادگیری برنامهنویسی و توسعه وب
Git به یک زبان برنامهنویسی خاص محدود نیست و در پروژههای مختلف نرمافزاری، از توسعه وب تا پروژههای Python، استفاده میشود. یادگیری آن به شما کمک میکند تغییرات پروژه را مدیریت کنید، نسخههای قبلی را بررسی کنید و در پروژههای تیمی هماهنگی بیشتری داشته باشید.
اگر در مسیر توسعه وب فعالیت میکنید، آموزش فرانتاند میتواند در کنار یادگیری Git به شناخت بهتر روند توسعه پروژههای وب کمک کند.
همچنین اگر با Python کار میکنید، آموزش پایتون از صفر میتواند نقطه شروعی برای یادگیری این زبان و مدیریت نسخه پروژههای آن با Git باشد.
اشتباهات رایج هنگام استفاده از Git Reset، Revert و Restore
کاربران تازهکار Git معمولاً در موقعیتهای زیر دچار اشتباه میشوند:
- اجرای عجولانه
git reset --hardبدون بررسی تغییرات محلی. - استفاده از Reset برای تغییر تاریخچهای که قبلاً با اعضای تیم به اشتراک گذاشته شده است.
- تصور اینکه Reset و Restore دقیقاً یک کار انجام میدهند.
- تصور اینکه Revert، Commit قبلی را از تاریخچه حذف میکند.
- فراموش کردن بررسی وضعیت پروژه قبل از اجرای دستورات برگشت.
- تصور اینکه هر نوع تغییر را میتوان بدون بررسی Conflictها با Revert خنثی کرد.
پیش از اجرای دستورات حساس، ابتدا وضعیت پروژه را بررسی کنید:
git status
برای مشاهده تاریخچه کوتاه و خوانای Commitها نیز میتوانید از این دستور استفاده کنید:
git log --oneline
اگر میخواهید قبل از تغییر تاریخچه شاخه، وضعیت فعلی آن را بهتر بررسی کنید، مشاهده نام Branch و Commit فعلی نیز میتواند مفید باشد:
git branch --show-current
git log -1
سؤالات متداول
آیا Git Reset تاریخچه را تغییر میدهد؟
اگر Reset موقعیت شاخه یا HEAD را به Commit قبلی منتقل کند، تاریخچه قابل مشاهده آن شاخه تغییر میکند. Commitهای حذفشده از نوک شاخه ممکن است همچنان از طریق برخی امکانات بازیابی Git قابل دسترسی باشند، اما دیگر در مسیر معمول تاریخچه شاخه قرار ندارند.
تفاوت Git Revert با Reset چیست؟
git revert با ایجاد یک Commit جدید، اثر Commit قبلی را خنثی میکند و تاریخچه قبلی را حفظ میکند. در مقابل، git reset میتواند موقعیت HEAD و شاخه را به Commit قبلی منتقل کند و در برخی حالتها وضعیت Index و Working Tree را نیز تغییر دهد.
Git Restore برای چیست؟
git restore برای برگرداندن محتوای فایلها در Working Tree یا خارج کردن فایلها از Stage استفاده میشود. این دستور بهطور معمول برای حذف Commit یا جابهجایی شاخه کاربرد ندارد.
برای برگرداندن آخرین Commit چه دستوری بزنیم؟
پاسخ به هدف شما بستگی دارد:
- اگر میخواهید یک Commit محلی را عقب ببرید و تغییرات را نگه دارید،
reset --softیاreset --mixedمیتواند مطرح باشد. - اگر میخواهید اثر یک Commit را بدون حذف آن از تاریخچه خنثی کنید،
revertگزینه مرتبط است. - اگر فقط میخواهید تغییرات یک فایل را کنار بگذارید،
restoreکاربرد دارد.
آیا git reset --hard خطرناک است؟
این دستور میتواند تغییرات محلی Trackشده را که با Commit هدف تفاوت دارند، از بین ببرد. بنابراین پیش از استفاده از آن باید مطمئن شوید تغییرات مهم خود را ذخیره کردهاید.
آیا git revert همیشه Commit جدید میسازد؟
در حالت معمول، بله. Revert برای خنثی کردن تغییرات یک Commit، Commit جدیدی ایجاد میکند. اگر هنگام Revert با Conflict روبهرو شوید، ابتدا باید Conflictها را برطرف کنید و سپس فرایند Revert را تکمیل کنید.
جمعبندی
تفاوت Git Reset، Revert و Restore در چیزی است که هر دستور برمیگرداند و نحوه تأثیر آن بر پروژه:
git restoreبرای برگرداندن محتوای فایلها و خارج کردن فایلها از Stage کاربرد دارد.git revertبرای خنثی کردن اثر یک Commit با ایجاد Commit جدید استفاده میشود و تاریخچه قبلی را حفظ میکند.git resetبرای جابهجاییHEADو تغییر وضعیت شاخه، Index یا Working Tree در حالتهای مختلف به کار میرود.
پیش از اجرای هر دستور، ابتدا وضعیت پروژه را بررسی کنید. بهخصوص هنگام استفاده از git reset --hard مطمئن شوید که تغییرات مهم محلی را از دست نمیدهید.
اگر میخواهید کار با Git، GitHub و GitLab را از پایه تا کار با Repository، Branch و Commit یاد بگیرید، دوره آموزش گیت، گیت هاب و گیت لب از صفر میتواند مسیر یادگیری شما را منظمتر کند.




