Git فایلها را همزمان در سه جا نگه میدارد: آنچه در ادیتور میبینی، پیشنویس کامیت بعدی، و آخرین عکس ثبتشده. اگر این سه را قاطی کنی، reset و Save و Commit برایت یکی به نظر میرسند.
🎯 اهداف یادگیری
- سه درخت را نام ببری و نقش هر کدام را بکشی
- وضعیت فایل را در VS Code بخوانی: U، M، A، D
- تفاوت unstaged و staged را با مثال نشان دهی
- بگویی
add،restoreوcommitدقیقاً چه چیزی را کپی میکنند
🧠 مدل ذهنی
Git فایلها را در سه لایه نگه میدارد:
- Working Tree — فایلهایی که در Explorer میبینی و با Save ذخیره میکنی. هنوز تاریخچه نیست.
- Index (Staging Area) — پیشنویس کامیت بعدی.
git addیا دکمهٔ Stage فایل را از دیسک به این پیشنویس کپی میکند. - Repository (HEAD) — آخرین عکس ثبتشده. فقط
commitاین لایه را جلو میبرد.
شکل ۲ — add از Working به Index میرود؛ commit از Index یک شیء commit میسازد.
status = diff(Working, Index) + diff(Index, HEAD)
دو ستون تغییرات در VS Code دقیقاً همین دو diff هستند.
🔍 خواندن git status
git status -sb # ## main # M src/auth.ts # فاصله + M یعنی تغییر در Working، هنوز stage نشده # M src/api.ts # M در ستون اول یعنی staged # MM README.md # هم staged هم بعدش دوباره ویرایش شده # ?? notes.txt # untracked — Git اصلاً نمیشناسدش
در VS Code همین اطلاعات چنین دیده میشود:
| نشانه | معنی | اقدام |
|---|---|---|
| U | Untracked | Stage یا به .gitignore بسپار |
| M | Modified | Stage / Discard |
| A | Added | فایل جدید staged |
| D | Deleted | حذف staged یا بازیابی |
| C | Conflict | Resolve در ادیتور |
🧪 آزمایش ۳۰ ثانیهای
echo "v1" > hello.txt git add hello.txt # Working = Index (هر دو v1) HEAD هنوز ندارد git commit -m "v1" # هر سه = v1 echo "v2" > hello.txt # Working=v2 Index=v1 HEAD=v1 git add hello.txt # Working=v2 Index=v2 HEAD=v1 git commit -m "v2" # هر سه = v2
حالا میفهمی چرا «کامیت نکردم ولی Save کردم» تاریخچه را عوض نمیکند — Save فقط Working Tree است.
🎛️ فرمانها روی کدام درخت؟
| فرمان | Working | Index | Repo |
|---|---|---|---|
| ویرایش در VS Code / Save | ✓ | ||
git add / Stage |
✓ | ||
git commit |
✓ | ||
git restore file |
✓ | ||
git restore --staged |
✓ | ||
git reset --soft |
✓ (HEAD حرکت) | ||
git reset --mixed |
✓ | ✓ | |
git reset --hard |
✓ | ✓ | ✓ |
--hard هر سه درخت را با کامیت هدف یکی میکند و تغییرات ذخیرهنشده را میکشد. در VS Code معادل Discard All Changes + حرکت HEAD است. تا فصل ۸ بدون تور ایمنی (reflog) نزدیکش نشو.
🖼️ در VS Code کجایند این درختها؟
- Explorer = Working Tree
- Source Control → Changes = diff(Working, Index)
- Source Control → Staged Changes = diff(Index, HEAD)
- Timeline / Git Graph = Repository
وقتی فایلی را Stage میکنی، از لیست Changes به Staged میپرد — یعنی کپی snapshot آن فایل به Index.
git add -p یا Stage انتخابی در VS Code (روی hunk). کامیت را مثل پاراگراف مینویسی نه مثل سطل زباله.
git add . کورکورانه. فایل env، آرتیفکت بیلد و رمز داخل کامیت میرود.
Junior — Staging یعنی چه؟ سبد خرید قبل از پرداخت. commit پرداخت است.
Mid — چرا Index وجود دارد؟ تا یک Working شلوغ را به چند کامیت معنادار بشکنی.
Senior — Index از نظر داده چیست؟ یک درخت مرتبشده از cache entryها (مسیر، mode، OID، stat) که commit آن را به یک tree object تبدیل میکند.
✅ چکلیست فهم
- سه درخت را بدون نگاه به کتاب نام میبری
Mدر ستون اول و دومstatus -sbرا بلدی- میدانی Save ≠ Commit
- Stage انتخابی را به
add .ترجیح میدهی
فصل بعد: اولین مخزن واقعی — init، add، commit، log.