آنچه در این مقاله میخوانید
- Git فقط برای ثبت نسخهها نیست
- git status: قبل از هر کاری وضعیت را ببینید
- git diff: تغییرات را قبل از Commit بررسی کنید
- git add -p: همه تغییرات را یکجا Stage نکنید
- git bisect: پیدا کردن Commit خراب بدون بررسی تک تک Commitها
- git stash: تغییرات نیمه کاره را موقتا کنار بگذارید
- git log: تاریخچه پروژه را قابل خواندن کنید
- برای هر کار یک Branch جدا بسازید
- git restore: فایل را به آخرین نسخه برگردانید
- git worktree: هم زمان روی دو Branch کار کنید
- git reflog: کامیت های از دست رفته را پیدا کنید
- git rebase -i: تاریخچه Commitها را مرتب کنید
- git blame: ببینید هر خط چه زمانی تغییر کرده است
- Aliasها: دستورات طولانی را کوتاه کنید
- تفاوت اصلی سنیورها در حفظ کردن دستورها نیست
- خلاصه دستورات پرکاربرد Git
- جمع بندی
سنیورها از کدام دستورات git استفاده می کنند؟
۲ مرداد ۱۴۰۵
خیلی از برنامهنویسها کار با Git را با سه دستور شروع میکنند و مدتها هم با همان سه دستور ادامه میدهند:
git add .
git commit -m "update"
git push
تا وقتی همهچیز درست پیش برود، چند دستور پایه Git کافی است. تفاوت از جایی مشخص میشود که Commit اشتباهی ثبت شود، تاریخچه Branch بههم بریزد یا لازم باشد کد ازدسترفته را برگردانید. سنیورها پیش از Commit تغییرات را بررسی میکنند و در زمان خطا سراغ ابزارهایی مثل git diff، git reflog و git restore میروند؛ کاری که در پروژههای اجراشده روی هاست ابری یا سرور مجازی حساستر است.
در ادامه میخوانید:
- چرا Git فقط ابزاری برای ثبت نسخهها نیست؟
- بررسی وضعیت Repository با
git status - دیدن تغییرات قبل از Commit با
git diff - انتخاب بخشی از تغییرات با
git add -p - پیدا کردن Commit خراب با
git bisect - کنار گذاشتن موقت تغییرات با
git stash - خواندن تاریخچه پروژه با
git log - ساخت Branch جدا برای هر کار
- بازگرداندن فایلها با
git restore - کار همزمان روی چند Branch با
git worktree - بازیابی Commitهای پاکشده با
git reflog - مرتبکردن تاریخچه با Interactive Rebase
- پیدا کردن سابقه هر خط با
git blame - کوتاهکردن دستورات با Alias

Git فقط برای ثبت نسخهها نیست
گیت در هر کامیت یک تصویر از وضعیت پروژه نگه میدارد. برنچها مسیرهای جداگانه همین تاریخچهاند و دستورهایی مثل Merge و Rebase مشخص میکنند این مسیرها چطور به هم متصل شوند. به همین دلیل، حذف یک Commit همیشه بهمعنای پاکشدن کامل آن نیست و Git در بسیاری از مواقع شناسه و جای آن را در reflog نگه میدارد.
سنیورها پیش از اجرای هر دستور، ابتدا بررسی میکنند در کدام Branch هستند، چه فایلهایی تغییر کردهاند و HEAD به کدام Commit اشاره میکند. سپس تصمیم میگیرند تغییرات را Commit کنند، کنار بگذارند، برگردانند یا به Branch دیگری انتقال دهند. این بررسی هنگام کار روی Repository یک هاست ابری یا سرور مجازی جلوی بسیاری از خطاهای پیش از Deploy را میگیرد.
وقتی Git را مثل یک خط زمانی ببینید، دستوراتش هم منطقیتر میشوند. git status وضعیت فعلی را نشان میدهد، git diff تغییرات را مشخص میکند، git log مسیر Commitها را نمایش میدهد و git reflog جابهجاییهای اخیر HEAD را ثبت میکند. با این دید، هنگام بروز اشتباه میدانید باید کدام بخش از تاریخچه Git را بررسی کنید.
با سرور مجازی لیارا، قدرت، سرعت و امنیت را یکجا داشته باشید!
✅ منابع اختصاصی✅ استقرار سریع بدون پیچیدگی ✅ قیمت مقرونبهصرفه
خرید سرور مجازی لیارا
git status: قبل از هر کاری وضعیت را ببینید
بیشتر خطاهای Git از خود دستورها شروع نمیشوند؛ از این شروع میشوند که برنامهنویس نمیداند الان دقیقاً کجاست. ممکن است روی Branch اشتباهی باشید، فایل حساسی مثل .env را تغییر داده باشید یا چند فایل آزمایشی کنار کد اصلی باقی مانده باشند. اجرای git status پیش از Commit یا جابهجایی بین Branchها، این موارد را همان ابتدا نشان میدهد.
git status
خروجی این دستور به شما میگوید:
- اکنون روی کدام Branch هستید
- چه فایلهایی تغییر کردهاند
- کدام فایلها وارد Stage شدهاند
- چه فایلهایی هنوز Untracked هستند
- آیا Branch محلی از Remote جلوتر یا عقبتر است
برای نمونه، چنین خروجیای را در نظر بگیرید:
On branch feature/login
Changes not staged for commit:
modified: src/auth.js
Untracked files:
debug.log
.env.local
اگر پروژه روی سرور مجازی یا هاست ابری قرار دارد، بهتر است پیش از Pull، Merge و Deploy نیز git status را اجرا کنید. این بررسی کوتاه مشخص میکند فایل آزمایشی، تنظیمات محلی یا تغییر ثبتنشدهای روی محیط باقی مانده است یا نه.
در این وضعیت، اگر مستقیم git add . را اجرا کنید، ممکن است فایلهای debug.log و .env.local هم وارد Commit شوند. همین چند خط خروجی به شما هشدار میدهد که پیش از Stage کردن فایلها، باید آنها را بررسی کنید.
برنامهنویسهای باتجربه معمولاً git status را در چند نقطه اجرا میکنند: پیش از Commit، قبل از git switch، پیش از Rebase و پس از رفع Conflict. این عادت ساده کمک میکند دستور بعدی را با حدس اجرا نکنید.
نسخه کوتاهتر خروجی هم در دسترس است:
git status --short
خروجی این دستور فشردهتر است:
M src/auth.js
?? debug.log
?? .env.local
در این نمایش، M یعنی فایل تغییر کرده و ?? یعنی Git هنوز فایل را دنبال نمیکند.
اگر با Repositoryهای شلوغ کار میکنید، نسخه کوتاه خواناتر است؛ اما زمانی که در رفتار Git شک دارید، همان git status کامل اطلاعات روشنتری در اختیارتان میگذارد.
چه زمانی git status را اجرا کنیم؟
لازم نیست بعد از هر خط کد سراغ این دستور بروید. چهار زمان بیش از بقیه کاربرد دارد:
- پیش از Stage کردن فایلها
- پیش از ساخت Commit
- پیش از تغییر Branch
- بعد از Merge یا Rebase ناموفق
این بررسی روی سیستم شخصی و محیط اصلی یکسان نیست. هنگام کار مستقیم روی هاست ابری یا سرور مجازی، وجود یک فایل تغییرکرده ممکن است Pull یا Deploy بعدی را خراب کند. پیش از هر تغییر روی محیط اصلی، ابتدا git status را بخوانید و بعد سراغ دستور بعدی بروید.
git diff: تغییرات را قبل از Commit بررسی کنید
git status به شما میگوید کدام فایلها تغییر کردهاند، اما نشان نمیدهد داخل آن فایلها چه اتفاقی افتاده است. برای دیدن جزئیات تغییرات باید از git diff کمک بگیرید. این دستور یکی از سادهترین راهها برای جلوگیری از Commitهای ناقص یا اشتباه است.
git diff
خروجی این دستور تفاوت میان فایلهای فعلی و آخرین وضعیت ثبتشده را نشان میدهد. یعنی میتوانید ببینید چه خطهایی حذف شدهاند، چه خطهایی اضافه شدهاند و کدام قسمتها تغییر کردهاند.
برای نمونه، ممکن است پیش از Commit متوجه شوید یک console.log آزمایشی هنوز داخل کد مانده است:
function login(user) {
+ console.log(user);
return authenticate(user);
}
یا شاید هنگام تست، مقدار یک تنظیم را موقتاً عوض کرده باشید و فراموش کرده باشید آن را برگردانید:
-const API_URL = "https://api.example.com";
+const API_URL = "http://localhost:3000";
اگر فقط نام فایلها را در git status ببینید، این جزئیات از چشم شما پنهان میمانند. git diff همان بازبینی کوتاهی است که پیش از Commit باید انجام شود.
تفاوت git diff و git diff –staged
دستور معمولی git diff فقط تغییراتی را نشان میدهد که هنوز وارد Stage نشدهاند:
git diff
اما اگر فایلها را با git add وارد Stage کرده باشید، برای دیدن نسخهای که قرار است Commit شود باید این دستور را اجرا کنید:
git diff --staged
برای نمونه، این ترتیب را در نظر بگیرید:
git add src/auth.js
git diff --staged
در این حالت، خروجی دقیقاً همان تغییراتی را نشان میدهد که با Commit بعدی ثبت خواهند شد.
این تفاوت مهم است؛ چون ممکن است بخشی از تغییرات را Stage کرده باشید و بخشی دیگر هنوز بیرون مانده باشد. دستور اول تغییرات بیرون Stage را نشان میدهد و دستور دوم تغییرات داخل Stage را.
مقایسه همه تغییرات با آخرین Commit
اگر میخواهید همه تغییرات فعلی، چه Staged و چه Unstaged، را در مقایسه با آخرین Commit ببینید، از این دستور استفاده کنید:
git diff HEAD
HEAD به Commit فعلی اشاره دارد. این دستور نشان میدهد اگر اکنون همه تغییرات را Commit کنید، نسخه جدید چه تفاوتی با Commit قبلی خواهد داشت.
بررسی تغییرات یک فایل مشخص
در Repositoryهای بزرگ، خروجی git diff ممکن است طولانی باشد. برای دیدن تغییرات یک فایل خاص، مسیر آن را جلوی دستور بنویسید:
git diff src/auth.js
برای فایل Stageشده نیز میتوانید همین کار را انجام دهید:
git diff --staged src/auth.js
این روش زمانی کاربرد دارد که فقط میخواهید بخش مشخصی از کد را بررسی کنید.
مقایسه دو Branch
git diff فقط برای تغییرات ثبتنشده نیست. با آن میتوانید تفاوت دو Branch را هم ببینید:
git diff main..feature/login
این دستور نشان میدهد Branch مربوط به Login چه تفاوتی با main دارد. پیش از ساخت Pull Request، این مقایسه کمک میکند مطمئن شوید تغییر نامرتبطی وارد Branch نشده است.
برای مشاهده نام فایلهای تغییرکرده، بدون نمایش همه خطوط کد، از گزینه --stat استفاده کنید:
git diff --stat main..feature/login
خروجی آن شبیه این است:
src/auth.js | 18 +++++++++-----
tests/auth.test.js | 24 ++++++++++++++++++++
2 files changed, 37 insertions(+), 5 deletions(-)
عادت مناسب پیش از هر Commit
یک ترتیب ساده برای بازبینی تغییرات این است:
git status
git diff
git add src/auth.js
git diff --staged
git commit
ابتدا فایلهای تغییرکرده را میبینید، سپس تغییرات داخل آنها را بررسی میکنید. بعد فقط فایل موردنظر را وارد Stage میکنید و در آخر، محتوای Commit را یک بار دیگر میخوانید.
git diff فقط یک ابزار نمایش تغییرات نیست. این دستور آخرین فرصت شما برای پیدا کردن کد آزمایشی، فایل حساس، تغییر ناخواسته یا بخشی است که هنوز آماده ثبت نیست.
در پروژهای که روی هاست ابری منتشر میشود، git diff --staged آخرین فرصت برای دیدن تغییراتی است که قرار است وارد نسخه بعدی شوند. همین بررسی روی سرور مجازی نیز جلوی Deploy شدن آدرسهای Local، فایلهای Debug و تنظیمات اشتباه را میگیرد.

git add -p: همه تغییرات را یکجا Stage نکنید
دستور git add . سریع است، اما همیشه انتخاب خوبی نیست. این دستور تمام فایلها و تغییرات پوشه فعلی را وارد Stage میکند؛ حتی تغییراتی که هنوز آماده Commit نیستند یا اصلاً ربطی به Commit فعلی ندارند.
git add .
فرض کنید هنگام رفع یک باگ در سیستم ورود، چند متن رابط کاربری را هم عوض کردهاید و یک console.log آزمایشی نیز به همان فایل اضافه شده است. اگر git add . را اجرا کنید، همه این تغییرات در یک Commit قرار میگیرند. چنین Commitی بعداً بررسی، Revert یا Cherry-pick کردن را سختتر میکند.
برای انتخاب دقیق تغییرات، از دستور زیر استفاده کنید:
git add -p
حرف p کوتاهشده patch است. Git تغییرات را بخشبهبخش نشان میدهد و از شما میپرسد که هر بخش وارد Stage شود یا نه. به هر بخش از تغییرات یک hunk گفته میشود.
خروجی دستور ممکن است شبیه این باشد:
@@ -10,6 +10,7 @@ function login(user) {
validateUser(user);
+ console.log(user);
return authenticate(user);
}
Stage this hunk [y,n,q,a,d,s,e,?]?
در این مرحله، خودتان مشخص میکنید این بخش وارد Commit بعدی شود یا بیرون بماند.
گزینههای پرکاربرد عبارتاند از:
y: این بخش را وارد Stage کنn: این بخش را رد کنs: این بخش را به قسمتهای کوچکتر تقسیم کنe: محتوای بخش را پیش از Stage کردن ویرایش کنq: از حالت انتخاب خارج شو
در بیشتر مواقع، فقط کلیدهای y، n و s کافی هستند.
این روش برای پروژههایی که نسخه اصلی آنها روی هاست ابری یا سرور مجازی اجرا میشود، کاربرد بیشتری دارد؛ چون فقط تغییر مرتبط با باگ وارد Commit میشود و کدهای آزمایشی همراه آن Deploy نمیشوند.
جداکردن چند تغییر داخل یک فایل
یکی از کاربردهای اصلی git add -p زمانی است که داخل یک فایل چند کار جدا انجام دادهاید.
برای نمونه، در فایل auth.js این تغییرات را دارید:
-const TOKEN_EXPIRE_TIME = 300;
+const TOKEN_EXPIRE_TIME = 900;
function login(user) {
+ console.log("login started");
return authenticate(user);
}
-function getErrorMessage() {
- return "Error";
+function getErrorMessage() {
+ return "Login failed";
}
در این مثال سه تغییر جدا دیده میشود:
- تغییر زمان انقضای Token
- اضافهشدن یک Log آزمایشی
- اصلاح متن خطا
ممکن است فقط تغییر زمان انقضای Token مربوط به باگ فعلی باشد. با git add -p میتوانید همان بخش را Stage کنید و دو تغییر دیگر را برای Commitهای بعدی نگه دارید.
git add -p src/auth.js
بعد از انتخاب تغییرات، با دستور زیر بررسی کنید چه چیزی وارد Stage شده است:
git diff --staged
سپس Commit را بسازید:
git commit -m "Fix token expiration time"
تغییرات باقیمانده همچنان در فایل هستند، اما داخل این Commit قرار نمیگیرند.
اگر یک hunk چند تغییر را با هم نشان داد
گاهی Git چند تغییر نزدیک به هم را در یک hunk نمایش میدهد. در این حالت، کلید s را بزنید تا Git آن بخش را به قسمتهای کوچکتر تقسیم کند:
Stage this hunk [y,n,q,a,d,s,e,?]? s
اگر تغییرات آنقدر به هم نزدیک باشند که Git نتواند آنها را جدا کند، گزینه e اجازه میدهد Patch را دستی ویرایش کنید. این گزینه کمی حساستر است و باید خطهای Patch را با دقت تغییر دهید.
خارج کردن بخشی از تغییرات از Stage
اگر قبلاً با git add . همهچیز را وارد Stage کردهاید، لازم نیست Stage را کامل پاک کنید. با دستور زیر میتوانید تغییرات را بخشبهبخش از Stage بیرون بیاورید:
git reset -p
در نسخههای جدید Git، دستور زیر هم برای همین کار قابل استفاده است:
git restore --staged -p
این دستورات مانند git add -p عمل میکنند، با این تفاوت که مسیر برعکس است؛ یعنی هر بخش انتخابشده از Stage خارج میشود.
یک ترتیب مطمئن برای ساخت Commit
برای اینکه فقط تغییرات مرتبط داخل Commit قرار بگیرند، این ترتیب کاربردی است:
git status
git diff
git add -p
git diff --staged
git commit -m "Fix login validation"
در این روش ابتدا وضعیت فایلها را میبینید، سپس تغییرات را میخوانید، بخشهای موردنظر را انتخاب میکنید و پیش از Commit یک بار دیگر محتوای Stage را بررسی میکنید.
برنامهنویسهای باتجربه معمولاً Commit را بر اساس موضوع تغییر میسازند، نه بر اساس فایل. ممکن است یک فایل شامل چند تغییر جدا باشد و هرکدام در Commit دیگری قرار بگیرند. git add -p همین جداسازی را ممکن میکند و تاریخچه Git را خواناتر نگه میدارد.
git bisect: پیدا کردن Commit خراب بدون بررسی تک تک Commitها
گاهی میدانید یک باگ در نسخه فعلی وجود دارد، اما چند هفته قبل همان بخش بدون مشکل کار میکرده است. میان این دو نسخه هم دهها Commit ثبت شده و معلوم نیست کدامیک باگ را وارد پروژه کرده است.
بررسی دستی تمام Commitها وقتگیر است. git bisect این جستوجو را با روش دودویی انجام میدهد؛ یعنی هر بار Commitهای باقیمانده را تقریباً نصف میکند تا به Commit خراب برسد.
برای شروع، این دستور را اجرا کنید:
git bisect start
بعد باید به Git بگویید وضعیت فعلی خراب است:
git bisect bad
سپس آخرین Commit یا Tag سالم را مشخص کنید:
git bisect good v2.3.1
Git حالا یک Commit میان نسخه سالم و نسخه خراب را Checkout میکند. شما پروژه را اجرا یا تست میکنید و نتیجه را به Git میگویید.
اگر آن Commit سالم بود:
git bisect good
اگر باگ در آن وجود داشت:
git bisect bad
Git دوباره سراغ Commit میانی بخش باقیمانده میرود. این کار ادامه پیدا میکند تا Commitی که باگ را وارد کرده پیدا شود.
یک مثال واقعی
فرض کنید نسخه v2.3.1 سالم بوده، اما Branch فعلی با خطای Login روبهرو است:
git bisect start
git bisect bad
git bisect good v2.3.1
بعد از اجرای این دستورات، Git پیامی شبیه این نشان میدهد:
Bisecting: 39 revisions left to test after this
حالا تست Login را اجرا میکنید. اگر خطا وجود نداشت:
git bisect good
اگر خطا دیده شد:
git bisect bad
پس از چند بار تکرار، Git Commit مشکوک را نمایش میدهد:
a1b2c3d is the first bad commit
در این مرحله میتوانید جزئیات Commit را ببینید:
git show a1b2c3d
بعد از پایان کار، Repository را به وضعیت قبلی برگردانید:
git bisect reset
چرا git bisect سریع است؟
اگر میان نسخه سالم و خراب ۸۰ Commit وجود داشته باشد، لازم نیست هر ۸۰ Commit را تست کنید. چون Git در هر مرحله محدوده را نصف میکند، معمولاً با حدود هفت تست به جواب میرسید.
برای ۱۰۰۰ Commit هم حدود ده مرحله کافی است. به همین دلیل، git bisect برای باگهایی که زمان ورودشان مشخص نیست، بسیار سریعتر از بررسی دستی تاریخچه است.
اجرای خودکار تست در Git Bisect
اگر پروژه تست خودکار دارد، لازم نیست هر Commit را دستی بررسی کنید. میتوانید یک دستور تست را به Git بدهید:
git bisect run npm test
Git هر Commit را Checkout میکند و تست را اجرا میکند. اگر دستور با کد خروجی 0 تمام شود، Commit سالم در نظر گرفته میشود. اگر کد خروجی غیرصفر باشد، Commit خراب علامت میخورد.
برای یک تست مشخص:
git bisect run npm test -- auth.test.js
یا در پروژههای Python:
git bisect run pytest tests/test_login.py
این روش زمانی خوب جواب میدهد که باگ با یک تست ثابت قابل تشخیص باشد.
انتخاب Commit سالم درست
یکی از خطاهای رایج در استفاده از git bisect، انتخاب نسخهای است که از سالمبودن آن مطمئن نیستید. Commit مشخصشده با git bisect good باید واقعاً بدون آن باگ باشد؛ وگرنه Git ممکن است Commit اشتباهی را معرفی کند.
پیش از شروع، نسخه سالم را Checkout و تست کنید:
git checkout v2.3.1
سپس دوباره به Branch فعلی برگردید:
git switch -
حالا میتوانید Bisect را با اطمینان بیشتری آغاز کنید.
چه زمانی از git bisect استفاده کنیم؟
این دستور برای چنین موقعیتهایی مناسب است:
- باگ در گذشته وجود نداشته، اما زمان ورودش معلوم نیست
- تعداد Commitهای مشکوک زیاد است
- برای تشخیص سالم یا خراب بودن هر Commit، تست مشخصی دارید
- جستوجوی متن با
git log -Sسرنخ کافی نمیدهد
اگر دقیقا میدانید چه خط یا عبارتی تغییر کرده، شاید git log -S سریعتر باشد. اما وقتی فقط رفتار خراب را میشناسید، git bisect گزینه دقیقتری است.
برای نمونه، اگر نسخهای که روی هاست ابری اجرا شده سالم است اما نسخه تازه روی سرور مجازی خطا میدهد، میتوانید Commit مربوط به نسخه سالم را با git bisect good و Commit فعلی را با git bisect bad مشخص کنید. Git سپس محدوده میان این دو نسخه را بررسی میکند تا Commit خراب پیدا شود.
چگونه یک پیام کامیت مناسب را در گیت بنویسیم (راهنمای کامل)
کامیت مناسب در گیت
git stash: تغییرات نیمه کاره را موقتا کنار بگذارید
فرض کنید وسط نوشتن یک Feature هستید و هنوز کارتان تمام نشده است. در همین لحظه، یک باگ فوری گزارش میشود و باید سریع به Branch دیگری بروید. نه میخواهید تغییرات ناقص را Commit کنید و نه میتوانید آنها را حذف کنید.
برای نمونه، ممکن است در حال آمادهکردن نسخه جدید یک پروژه روی هاست ابری باشید، اما همزمان لازم شود یک باگ فوری را روی سرور مجازی بررسی کنید. در این حالت، git stash تغییرات نیمهکاره را موقتاً کنار میگذارد.
git stash برای همین موقعیت ساخته شده است. این دستور تغییرات فعلی را موقتاً کنار میگذارد و Working Directory را به آخرین Commit برمیگرداند. بعد از تمامشدن کار فوری، میتوانید تغییرات قبلی را دوباره برگردانید.
git stash
پس از اجرای دستور، میتوانید Branch را عوض کنید:
git switch hotfix/login-timeout
باگ را برطرف کنید، Commit بسازید و دوباره به Branch قبلی برگردید:
git switch feature/new-dashboard
حالا تغییرات ذخیرهشده را برگردانید:
git stash pop
git stash pop آخرین Stash را اعمال میکند و در صورت موفقبودن، آن را از فهرست Stashها حذف میکند.
برای Stash نام مشخص بنویسید
اگر چند بار از git stash استفاده کنید، بعداً تشخیصدادن هر مورد سخت میشود. بهتر است همان ابتدا برای آن توضیح بنویسید:
git stash push -m "WIP: dashboard filters"
عبارت WIP مخفف Work in Progress است و نشان میدهد تغییرات هنوز کامل نشدهاند.
برای دیدن Stashهای ذخیرهشده، از این دستور استفاده کنید:
git stash list
خروجی ممکن است شبیه این باشد:
stash@{0}: On feature/dashboard: WIP: dashboard filters
stash@{1}: On fix/login: temporary validation changes
هر Stash یک شناسه مانند stash@{0} دارد. شماره صفر همیشه به تازهترین مورد اشاره میکند.
تفاوت git stash pop و git stash apply
این دو دستور شبیه هم هستند، اما رفتار یکسانی ندارند.
git stash pop
تغییرات را برمیگرداند و سپس Stash را از فهرست حذف میکند.
git stash apply
تغییرات را برمیگرداند، اما نسخه ذخیرهشده را نگه میدارد.
اگر مطمئن نیستید تغییرات بدون Conflict برمیگردند، apply انتخاب مطمئنتری است. بعد از بررسی نتیجه، میتوانید Stash را دستی حذف کنید:
git stash drop stash@{0}
برگرداندن یک Stash مشخص
اگر چند Stash دارید، لازم نیست همیشه تازهترین مورد را برگردانید. شناسه موردنظر را جلوی دستور بنویسید:
git stash apply stash@{1}
پیش از اعمال آن هم میتوانید خلاصه تغییراتش را ببینید:
git stash show stash@{1}
برای دیدن Diff کامل:
git stash show -p stash@{1}
این بررسی کمک میکند اشتباهی Stash مربوط به Branch دیگری را روی کد فعلی اعمال نکنید.
فایلهای Untracked بهصورت پیشفرض ذخیره نمیشوند
دستور معمولی git stash فقط فایلهایی را کنار میگذارد که Git از قبل آنها را دنبال میکند. فایلهای Untracked در پوشه باقی میمانند.
برای ذخیرهکردن فایلهای Untracked هم از گزینه -u استفاده کنید:
git stash -u
یا:
git stash push --include-untracked
برای ذخیره فایلهای Ignored نیز گزینه -a وجود دارد:
git stash -a
این گزینه را با دقت اجرا کنید؛ چون ممکن است فایلهای حجیم، Buildها یا پوشههای موقتی را هم وارد Stash کند.
فقط بخشی از تغییرات را Stash کنید
گاهی فقط بخشی از تغییرات باید کنار گذاشته شود و بقیه باید در Working Directory بمانند. گزینه -p تغییرات را بخشبهبخش نشان میدهد:
git stash -p
Git برای هر Hunk از شما میپرسد که ذخیره شود یا نه. رفتار آن شبیه git add -p است.
برای نمونه، ممکن است در یک فایل هم تغییر مربوط به باگ فوری داشته باشید و هم کد Feature نیمهکاره. با git stash -p فقط کد Feature را کنار میگذارید و تغییر مربوط به باگ را نگه میدارید.
ساخت Branch از روی Stash
اگر پس از مدتی متوجه شدید تغییرات Stashشده باید در Branch جداگانه ادامه پیدا کنند، از این دستور استفاده کنید:
git stash branch feature/dashboard-filters stash@{0}
Git یک Branch تازه میسازد، به Commitی که Stash از روی آن ساخته شده برمیگردد و تغییرات را روی همان Branch اعمال میکند.
این روش زمانی مفید است که Branch فعلی از زمان ساخت Stash تغییر زیادی کرده و اعمال مستقیم آن Conflict ایجاد میکند.
اگر هنگام Pop کردن Conflict رخ داد
git stash تغییرات را بدون توجه به وضعیت جدید Branch برنمیگرداند. اگر همان خطها از زمان ساخت Stash تغییر کرده باشند، ممکن است Conflict رخ دهد.
پس از رفع Conflictها، فایلها را Stage کنید:
git add path/to/file
اگر از git stash pop استفاده کرده باشید و Conflict رخ دهد، Git معمولاً Stash را حذف نمیکند. بعد از اطمینان از بازگشت کامل تغییرات، خودتان آن را پاک کنید:
git stash drop stash@{0}
Stash جای Commit را نمی گیرد
Stash برای توقف کوتاهمدت کار مناسب است، نه نگهداری تغییرات برای چند هفته. Stashها نام Branch ندارند، در Remote ذخیره نمیشوند و بهسادگی فراموش میشوند.
اگر یک بخش از کار کامل شده یا لازم است همتیمیها به آن دسترسی داشته باشند، بهتر است Commit بسازید یا Branch جداگانه ایجاد کنید. از Stash زمانی استفاده کنید که میخواهید برای مدت کوتاهی کار فعلی را متوقف کنید و کمی بعد به همان نقطه برگردید.
یک مسیر معمول برای رسیدگی به باگ فوری چنین است:
git status
git stash push -u -m "WIP: unfinished dashboard"
git switch hotfix/login-timeout
# رفع باگ و ساخت Commit
git switch -
git stash pop
در اینجا git switch - شما را به Branch قبلی برمیگرداند. سپس git stash pop تغییرات نیمهکاره را دوباره روی همان Branch قرار میدهد.

git log: تاریخچه پروژه را قابل خواندن کنید
خروجی ساده git log معمولاً طولانی و شلوغ است. هر Commit با شناسه کامل، نام نویسنده، تاریخ و پیام نمایش داده میشود و پیدا کردن مسیر Branchها میان این اطلاعات آسان نیست.
برای دیدن نسخه کوتاهتر تاریخچه، از این دستور استفاده کنید:
git log --oneline
در این حالت، هر Commit فقط در یک خط دیده میشود:
a81d9f2 Fix login validation
5e7c1aa Add token refresh test
2b4f083 Update authentication middleware
ابتدای هر خط، نسخه کوتاه Commit ID قرار دارد و بعد از آن Commit message نوشته شده است. همین شناسه کوتاه برای بیشتر دستورهایی مثل git show، git cherry-pick و git revert کافی است.
نمایش Branchها و Mergeها در تاریخچه
برای دیدن مسیر Branchها، گزینه --graph را اضافه کنید:
git log --oneline --graph
خروجی ممکن است شبیه این باشد:
* 8b70ad1 Merge branch 'feature/login'
|\
| * 72fe9a4 Add login rate limit
| * b4f2d17 Validate refresh token
|/
* 9d83c01 Update user model
خطها و علامتهای سمت چپ نشان میدهند Commitها روی کدام مسیر ساخته شدهاند و Branchها در چه نقطهای از هم جدا یا دوباره Merge شدهاند.
برای نمایش نام Branchها، Tagها و referenceها نیز گزینه --decorate را اضافه کنید:
git log --oneline --graph --decorate
خروجی کاملتر به این شکل دیده میشود:
* 4ea612b (HEAD -> feature/login) Fix token expiration
* 91f38ae Add login tests
* 2f622a1 (origin/main, main) Update dependencies
در این مثال، HEAD روی Branch با نام feature/login قرار دارد و main و origin/main هر دو به Commit دیگری اشاره میکنند.
ترکیب این سه گزینه یکی از خواناترین شکلهای نمایش تاریخچه Git است:
git log --oneline --graph --decorate
نمایش تاریخچه همه Branchها
git log در حالت عادی فقط Commitهایی را نشان میدهد که از Branch فعلی قابلدسترسی هستند. برای دیدن تمام Branchهای محلی و Remote، گزینه --all را اضافه کنید:
git log --oneline --graph --decorate --all
این دستور زمانی کاربرد دارد که میخواهید بفهمید یک Commit روی کدام Branch قرار گرفته یا مسیر چند Branch را کنار هم ببینید.
مشاهده جزئیات یک Commit با git show
پس از پیدا کردن Commit موردنظر در Log، با این دستور جزئیاتش را ببینید:
git show a81d9f2
git show اطلاعات Commit، پیام آن و Diff مربوط به تغییرات را نمایش میدهد.
اگر فقط خلاصه فایلهای تغییرکرده را میخواهید:
git show --stat a81d9f2
خروجی شبیه این است:
src/auth.js | 12 ++++++++----
tests/auth.test.js | 18 ++++++++++++++++++
2 files changed, 26 insertions(+), 4 deletions(-)
دیدن تاریخچه یک فایل مشخص
برای بررسی Commitهایی که یک فایل را تغییر دادهاند، مسیر فایل را بعد از -- بنویسید:
git log -- src/auth.js
برای نمایش کوتاهتر:
git log --oneline -- src/auth.js
اگر فایل در گذشته Rename شده باشد، گزینه --follow به Git میگوید تاریخچه پیش از تغییر نام را هم دنبال کند:
git log --oneline --follow -- src/auth.js
این دستور زمانی مفید است که فایل فعلی نام تازهای دارد، اما میخواهید Commitهای مربوط به نسخه قدیمی آن را نیز ببینید.
مشاهده Diff هر Commit در تاریخچه فایل
اگر فقط فهرست Commitها کافی نیست و میخواهید تغییرات هر Commit را هم ببینید، گزینه -p یا --patch را اضافه کنید:
git log -p --follow -- src/auth.js
در این حالت، Git تاریخچه فایل را همراه با خطهای اضافه و حذفشده نمایش میدهد.
برای محدودکردن تعداد Commitها:
git log -p -5 -- src/auth.js
این دستور فقط پنج Commit آخر مربوط به فایل را نشان میدهد.
جست و جو در Commit messageها
برای پیدا کردن Commitهایی که عبارت مشخصی در پیامشان دارند، از --grep استفاده کنید:
git log --grep="login"
جستوجوی بدون حساسیت به حروف بزرگ و کوچک:
git log --grep="login" -i
این روش زمانی کاربرد دارد که پیام Commit را کامل به خاطر ندارید، اما یک واژه از آن یادتان مانده است.
پیدا کردن Commitی که یک عبارت را اضافه یا حذف کرده است
اگر میخواهید بفهمید یک تابع، متغیر یا متن در کدام Commit وارد کد شده یا از آن حذف شده است، از گزینه -S استفاده کنید:
git log -S "refreshToken"
برای دیدن Diff همان Commitها:
git log -p -S "refreshToken"
این جستوجو بهدنبال تغییر تعداد دفعات حضور عبارت میگردد. اگر یک Commit عبارت را اضافه یا حذف کرده باشد، در خروجی دیده میشود.
برای جستوجوی تغییرات بر پایه الگوی Regex میتوانید از -G کمک بگیرید:
git log -G "refresh.*token"
تفاوت این دو گزینه در این است که -S تغییر تعداد یک عبارت ثابت را دنبال میکند، اما -G خطهای Diff را با Regex مقایسه میکند.
محدود کردن تاریخچه بر اساس نویسنده و تاریخ
برای دیدن Commitهای یک نویسنده مشخص:
git log --author="Sara"
برای محدودکردن بر اساس بازه زمانی:
git log --since="2 weeks ago"
یا:
git log --after="2026-05-01" --before="2026-06-01"
این گزینهها در Repositoryهای بزرگ که هزاران Commit دارند، جستوجو را سریعتر میکنند.
دیدن تاریخچه اصلی بدون Merge commitها
اگر Branch اصلی Mergeهای زیادی دارد و فقط میخواهید مسیر اصلی Commitها را ببینید، از این دستور استفاده کنید:
git log --oneline --first-parent
برای حذف Merge commitها از خروجی:
git log --oneline --no-merges
ترکیب این دو گزینه، نمایی سادهتر از تغییرات مستقیم Branch اصلی میدهد:
git log --oneline --no-merges --first-parent
ساخت Alias برای Git Log
تایپکردن گزینههای --oneline --graph --decorate --all در هر بار استفاده وقتگیر است. میتوانید برای آن یک Git alias بسازید:
git config --global alias.lg "log --oneline --graph --decorate --all"
پس از آن، فقط این دستور را اجرا کنید:
git lg
اگر Bash یا Zsh استفاده میکنید، Alias ترمینال هم قابلاستفاده است:
alias gl='git log --oneline --graph --decorate --all'
بعد از آن، gl همان تاریخچه گرافیکی را نمایش میدهد.
git log زمانی ارزش واقعی خود را نشان میدهد که فقط برای دیدن چند Commit آخر از آن استفاده نکنید. با فیلترهای درست، این دستور به شما میگوید یک تغییر چه زمانی وارد پروژه شده، چه کسی آن را نوشته، روی کدام Branch قرار دارد و فایل موردنظر در ماههای گذشته چه مسیری را طی کرده است.
برای هر کار یک Branch جدا بسازید
کار مستقیم روی main ریسک بالایی دارد. اگر آزمایش شما خراب شود یا بخشی از کد هنوز آماده نباشد، Branch اصلی هم درگیر میشود. به همین دلیل، سنیورها برای هر Feature، باگ یا آزمایش یک Branch جدا میسازند.
git switch -c fix-login-bug
این دستور یک Branch تازه با نام fix-login-bug میسازد و همان لحظه شما را به آن منتقل میکند.
از اینجا به بعد میتوانید بدون دستزدن به main کد را تغییر دهید، Commit بسازید یا بخشی از کار را کنار بگذارید.اگر ایده جواب نداد، Branch را حذف میکنید و Branch اصلی همان وضعیت قبلی را دارد.
برای دیدن Branch فعلی و Branchهای موجود:
git branch
برای برگشتن به main:
git switch main
برای رفتن به Branch قبلی نیز کافی است این دستور را اجرا کنید:
git switch -
نام Branch بهتر است مشخص کند قرار است چه کاری در آن انجام شود:
git switch -c feature/user-profile
git switch -c fix/payment-timeout
git switch -c refactor/auth-service
این نامها در زمان بررسی Pull Request یا خواندن تاریخچه، خیلی روشنتر از نامهایی مثل test، new یا branch-2 هستند.
Branch در Git سبک و سریع است. پس لازم نیست چند تغییر نامرتبط را روی یک Branch نگه دارید. هر کار جدا، Branch جدا؛ همین عادت Commitها و Pull Requestها را خواناتر میکند.
اگر پروژه روی هاست ابری یا سرور مجازی اجرا میشود، بهتر است Branch مربوط به Feature، Hotfix و نسخه اصلی از هم جدا باشند. این جداسازی احتمال Deploy شدن کد ناقص روی محیط اصلی را کمتر میکند.
git restore: فایل را به آخرین نسخه برگردانید
گاهی فایلی را اشتباه تغییر میدهید و میخواهید همه تغییرات آن را کنار بگذارید. برای این کار از دستور زیر استفاده کنید:
git restore app.js
این دستور فایل را به آخرین نسخه ثبتشده در Commit فعلی برمیگرداند. تغییرات ثبتنشده فایل حذف میشوند؛ پس پیش از اجرا مطمئن شوید چیزی لازم ندارید.
اگر فایل را وارد Stage کردهاید اما هنوز نمیخواهید Commit شود، از این دستور کمک بگیرید:
git restore --staged app.js
این دستور فایل را از Stage خارج میکند، اما تغییرات داخل آن باقی میمانند.
تفاوت این دو دستور ساده است:
git restore app.js
تغییرات فایل را پاک میکند.
git restore --staged app.js
فقط فایل را از Stage بیرون میآورد.
برای بازگرداندن چند فایل، مسیر همه آنها را جلوی دستور بنویسید:
git restore app.js config.js
برای کنار گذاشتن تمام تغییرات ثبتنشده پوشه فعلی نیز این دستور وجود دارد:
git restore .
دستور دوم همه فایلهای دنبالشده را به آخرین Commit برمیگرداند؛ پس پیش از اجرا حتماً git diff را ببینید.
git restore زمانی مناسب است که دقیقاً میدانید کدام فایل باید برگردد. برای حذف تغییرات چند فایل یا کل پروژه، بهتر است ابتدا git status و git diff را بررسی کنید تا چیزی را ناخواسته از دست ندهید.
git worktree: هم زمان روی دو Branch کار کنید
گاهی وسط یک Feature هستید و باید بدون کنارگذاشتن کار فعلی، یک باگ فوری را روی Branch دیگری اصلاح کنید. این موقعیت در پروژههایی که روی هاست ابری یا سرور مجازی اجرا میشوند زیاد پیش میآید. git worktree یک پوشه جدا برای Branch دوم میسازد تا هر دو Branch را همزمان باز نگه دارید.
git worktree add ../hotfix-login hotfix/login-timeout
اگر Branch با نام hotfix/login-timeout از قبل وجود داشته باشد، همین دستور آن را در پوشه تازه باز میکند. برای ساخت یک Branch تازه همراه با Worktree از گزینه -b استفاده کنید:
git worktree add -b hotfix/login-timeout ../hotfix-login main
در این مثال، Git یک Branch تازه از روی main میسازد و فایلهای آن را داخل پوشه hotfix-login قرار میدهد.
این دستور زمانی هم کاربرد دارد که نسخه اصلی پروژه روی سرور مجازی اجرا میشود و باید همزمان یک Hotfix را بررسی کنید. بهجای جابهجایی پیاپی میان Branchها، برای Branch مربوط به رفع باگ یک پوشه جدا میسازید و نسخه فعلی کارتان را دستنخورده نگه میدارید.
حالا میتوانید وارد پوشه دوم شوید:
cd ../hotfix-login
پس از پایان کار، Worktree را حذف کنید:
git worktree remove ../hotfix-login
git worktree برای کارهای فوری یا طولانی، از Stash کردن و جابهجایی پیدرپی بین Branchها تمیزتر است؛ چون هر Branch پوشه مستقل خودش را دارد.
برای نمونه، میتوانید Branch اصلی پروژه را در پوشه فعلی نگه دارید و Hotfix مربوط به سرور مجازی را در Worktree دیگری باز کنید. پس از تست نیز نسخه اصلاحشده را روی هاست ابری Deploy کنید.
git reflog: کامیت های از دست رفته را پیدا کنید
گاهی بعد از Rebase، Reset یا حذف یک Branch فکر میکنید Commitها برای همیشه پاک شدهاند. در بسیاری از مواقع، Git هنوز رد آنها را در reflog نگه میدارد.
git reflog
این دستور جابهجاییهای اخیر HEAD را نشان میدهد:
a81d9f2 HEAD@{0}: rebase: checkout main
7c42a11 HEAD@{1}: commit: Fix login bug
اگر Commit موردنظر را پیدا کردید، میتوانید آن را بررسی کنید:
git show 7c42a11
یا یک Branch تازه از روی آن بسازید:
git switch -c recovered-branch 7c42a11
اگر پیش از Deploy روی هاست ابری یا سرور مجازی، Commit اشتباهی حذف شده باشد، git reflog یکی از اولین جاهایی است که باید بررسی کنید.
بعد از ساخت Branch، فایلها و تاریخچه آن را بررسی کنید:
git switch recovered-branch
git log --oneline
اگر همان Commit گمشده را لازم داشتید، میتوانید آن را نگه دارید، Cherry-pick کنید یا Branch بازیابیشده را Push کنید. بهتر است مستقیم روی Commit پیداشده Reset نکنید؛ ساخت Branch تازه مسیر امنتری برای بررسی آن است.
git rebase -i: تاریخچه Commitها را مرتب کنید
گاهی پیش از ساخت Pull Request، چند Commit پراکنده دارید:
fix
another fix
small update
final fix
با Interactive Rebase میتوانید این Commitها را ترکیب، جابهجا یا نامگذاری دوباره کنید:
git rebase -i HEAD~4
بعد از اجرای دستور، Git فهرست Commitها را باز میکند. گزینههای پرکاربرد عبارتاند از:
pick: نگهداشتن Commitreword: تغییر پیام Commitsquash: ترکیب Commit با Commit قبلیfixup: ترکیب بدون نگهداشتن پیام Commit
برای نمونه، چند Commit کوچک را میتوانید به یک Commit خواناتر تبدیل کنید:
Improve authentication error handling
Interactive Rebase را بهتر است روی Commitهایی اجرا کنید که هنوز Push نشدهاند یا کسی کارش را بر پایه آنها ادامه نداده است. پس از Rebase نیز تاریخچه را با این دستور بررسی کنید:
git log --oneline
این دستور کمک میکند Branch را پیش از ارسال برای Review مرتبتر کنید.
git blame: ببینید هر خط چه زمانی تغییر کرده است
نام git blame کمی خشن به نظر میرسد، اما این دستور برای سرزنشکردن کسی نیست. با آن میتوانید ببینید هر خط فایل را چه کسی، در چه Commitی و چه زمانی تغییر داده است.
git blame app.js
خروجی هر خط، Commit ID، نام نویسنده و تاریخ تغییر را نشان میدهد. اگر بخشی از کد عجیب است یا میخواهید دلیل وجود یک شرط قدیمی را بفهمید، ابتدا Commit مربوط به همان خط را پیدا کنید و بعد جزئیاتش را ببینید:
git show COMMIT_ID
برای بررسی چند خط مشخص نیز میتوانید بازه بدهید:
git blame -L 20,40 app.js
این دستور فقط خطهای ۲۰ تا ۴۰ را بررسی میکند.
git blame زمانی خوب است که بخواهید ریشه یک تغییر را پیدا کنید، نه اینکه فقط بدانید چه کسی آن را نوشته است.
Aliasها: دستورات طولانی را کوتاه کنید
اگر یک دستور را بارها در روز اجرا میکنید، لازم نیست هر بار کامل آن را بنویسید. با Alias میتوانید نسخه کوتاهتری برای آن بسازید.
برای نمونه:
alias gs='git status'
alias ga='git add'
alias gp='git push'
alias gl='git log --oneline --graph --decorate'
بعد از تعریف این Aliasها، بهجای دستور کامل فقط مینویسید:
gs
gl
برای اینکه Aliasها بعد از بستن Terminal هم باقی بمانند، آنها را داخل فایل .bashrc یا .zshrc قرار دهید.
Git نیز سیستم Alias داخلی دارد:
git config --global alias.st status
git config --global alias.lg "log --oneline --graph --decorate"
حالا میتوانید این دستورها را اجرا کنید:
git st
git lg
Aliasها فقط چند ثانیه از هر دستور کم میکنند، اما همین کوتاهشدن باعث میشود دستورهایی مثل git status و git log را بیشتر و منظمتر اجرا کنید.
تفاوت اصلی سنیورها در حفظ کردن دستورها نیست
سنیورها لزوماً دستورهای بیشتری حفظ نکردهاند. تفاوت اصلی این است که هنگام خرابشدن اوضاع، دستپاچه نمیشوند. اول وضعیت Repository را میبینند، بعد سراغ راه برگشت میروند.
سه عادت ساده بیشتر از هر چیز به این آرامش کمک میکنند:
git diff
git stash
git reflog
git diff قبل از Commit خطاها را نشان میدهد، git stash کار نیمهتمام را موقتاً کنار میگذارد و git reflog رد Commitهایی را نگه میدارد که ظاهراً از دست رفتهاند.
کسی که این سه دستور را درست بلد باشد، خیلی کمتر از اشتباههای Git میترسد. چون میداند قبل از هر تغییر باید وضعیت را بررسی کند و اگر چیزی خراب شد، هنوز راه برگشت دارد.
خلاصه دستورات پرکاربرد Git
| دستور | کاربرد |
|---|---|
git status | دیدن وضعیت فعلی Repository |
git diff | بررسی تغییرات ثبتنشده |
git diff --staged | بررسی تغییراتی که Commit خواهند شد |
git add -p | Stage کردن بخشهای انتخابی |
git bisect | پیدا کردن Commit خراب |
git stash | کنار گذاشتن موقت تغییرات |
git log | خواندن تاریخچه Commitها |
git restore | بازگرداندن فایل تغییرکرده |
git worktree | بازکردن همزمان چند Branch |
git reflog | پیدا کردن Commitهای ازدسترفته |
git rebase -i | مرتبکردن Commitها |
git blame | پیدا کردن سابقه تغییر هر خط |
جمع بندی
سنیورها با Git سریعتر کار نمیکنند چون دهها دستور را از حفظ هستند. آنها پیش از Commit، فایلها را بررسی میکنند، تغییرات نامرتبط را جدا نگه میدارند و زمانی که چیزی خراب میشود، مسیر برگشت را میشناسند.
git status و git diff پیش از ثبت کد به کار میآیند. git add -p Commitها را دقیقتر میکند، git stash و git worktree برای جابهجایی میان کارها هستند و git reflog زمانی به دادتان میرسد که Commitی را گم کرده باشید.
این نکات در پروژههایی که روی هاست ابری یا سرور مجازی اجرا میشوند جدیتر هستند. پیش از Pull یا Deploy باید بدانید چه فایلهایی تغییر کردهاند، کدام Commit قرار است منتشر شود و در صورت بروز خطا چطور به نسخه قبلی برگردید.
برای شروع، همین پنج دستور را وارد کار روزانه خود کنید:
git status
git diff
git add -p
git stash
git reflog
هرچه شناخت شما از تاریخچه و وضعیت Git بیشتر شود، نیازتان به اجرای دستورهای تصادفی و جستوجوی عجولانه کمتر خواهد شد.

