Git 2026

فصل ۱۰ · Source Control از صفر

Source Control از صفر — Ctrl+Shift+G

خانهٔ روزانهٔ Git در VS Code پنل Source Control است. میانبر ثابت این کتاب Ctrl+Shift+G است. اینجا هر کلیک را به ترتیب می‌نویسیم و برای هر تفاوت («چرا مال من این‌طور است؟») دلیل دقیق می‌آید.

🎯 اهداف یادگیری

  • پنل را با کلیک مشخص باز کنی و بدانی بعد از آن باید چه ببینی
  • اگر دکمه یا لیست تو با عکس کتاب یکی نبود، در همان لحظه علت را بدانی
  • یک فایل را از Save تا Commit، کلیک‌به‌کلیک، تمام کنی
  • Stage، Unstage، Discard و Stage Selected Ranges را بدون حدس بزنی

🧭 قبل از اولین کلیک — عکس کتاب مال یک حالت است

عکس‌های این فصل از یک VS Code واقعی‌اند: ویندوز، زبان انگلیسی، تم تیره، مخزنی که Working Tree تمیز است و origin پانزده کامیت جلوتر. صفحهٔ تو باید دکمه‌های همان‌جا را داشته باشد، نه لزوماً همان عدد ۱۵ یا همان نام فایل.

چیزی که در عکس می‌بینی مال تو ممکن است چرا؟
برچسب انگلیسی Source Control، Commit، Sync Changes فارسی: «کنترل منبع»، «ثبت»، «همگام‌سازی تغییرات» زبان نمایش VS Code. موقعیت دکمه یکی است؛ فقط نوشته عوض می‌شود.
تم تیرهٔ سرمه‌ای تم روشن یا تم دیگر رنگ عوض می‌شود؛ نام فرمان‌ها عوض نمی‌شود.
Sync Changes 15↓ Commit یا Publish Branch یا هیچ دکمهٔ آبی بستگی دارد تغییرات محلی داری یا نه، و آیا origin هست یا نه — پایین، سه حالت.
حرف M کنار src/auth.ts فایل و حرف دیگر، یا لیست خالی مثال کتاب است. تو فایل خودت را می‌بینی.
Graph پایین پنل Graph نیست نسخهٔ قدیمی VS Code، یا بخش جمع شده؛ فلش > را باز کن.
میانبر Ctrl+Shift+G در مک گاهی باید Cmd نباشد؛ همین Ctrl است در VS Code روی مک هم پیش‌فرض Ctrl+Shift+G است نه Cmd.
زبان عکس‌ها انگلیسی است عمداً

در شکل‌ها متن فارسی نمی‌گذاریم (برعکس می‌شود). اگر VS Code تو فارسی است، همان دکمه را از روی جایگاه پیدا کن نه از روی املای کتاب.

⌨️ باز کردن پنل — سه کلیک معادل، یکی کافی است

یکی از این سه را بزن؛ هر سه باید همان ستون چپ را باز کنند:

  1. صفحه کلید: Ctrl+Shift+G (ویندوز، لینوکس، مک)
  2. ماوس: در نوار باریک چپ (Activity Bar) روی آیکون شاخه/Git کلیک کن — در عکس کتاب شمارهٔ ۱
  3. اگر هیچ‌کدام کار نکرد: Ctrl+Shift+P → تایپ کن View: Show Source Control → Enter

بعد از باز شدن باید ببینی: ستون سمت چپ با عنوان Source Control. ادیتور سمت راست سر جایش می‌ماند.

اگر مال تو این‌طور نیست:

چه دیدی علت چه کار کن
هیچ پنلی باز نشد فوکوس روی ترمینال است و میانبر قورت داده شد یک‌بار روی ادیتور کلیک کن، دوباره Ctrl+Shift+G
پنل Explorer باز شد نه Git آیکون اشتباه (دو سند بالا) آیکون سوم/چهارم Activity Bar؛ یا همان Palette
ستون آمد ولی نوشته Git not found / Git not installed VS Code فایل git.exe را پیدا نکرده Palette → Git: Show Git Output. Settings → git.path را به مسیر نصب Git بده. از نو VS Code را باز کن
ستون آمد، کاملاً خالی، بدون Message پوشه باز نیست File → Open Folder روی پوشهٔ پروژه

🧭 آناتومی — بعد از باز شدن، این چهار نقطه را لمس کن

آناتومی نزدیک پنل Source Control

شکل ۹ — برش نزدیک. شماره‌ها را با فهرست زیر تطبیق بده. دکمهٔ آبی اینجا Sync است نه Commit؛ برای تو ممکن است برعکس باشد.

  1. کلیک روی آیکون Git در Activity Bar. اگر روی آیکون عدد بود یعنی فایل تغییرکرده داری. اگر عدد نبود، یا Working Tree تمیز است یا نشان روی آیکون دیگری است (در عکس کامل کتاب، نشان آبی روی Extensions است نه Git — این باگ نیست).
  2. عنوان Source Control و سه‌نقطهٔ ··· بالا-راست. یک کلیک روی ··· منوی Fetch / Pull / Push / Stash را باز می‌کند (فصل ۱۱).
  3. یک کلیک داخل جعبهٔ Message — مکان‌نما باید چشمک بزند. این‌جا متن کامیت را می‌نویسی. Ctrl+Enter فقط وقتی کار می‌کند که فوکوس همین جعبه باشد.
  4. دکمهٔ بزرگ زیر جعبه — برچسبش ثابت نیست. VS Code بر اساس وضعیت مخزن یکی از این‌ها را می‌نویسد: Initialize Repository، Publish Branch، Commit، Sync Changes، یا Commit (merge).

پایین همان ستون، بدون عوض کردن پنل:

  • Graph — یک کلیک روی > یا روی کلمهٔ Graph. اگر نبود، VS Code را به‌روز کن یا Palette → Git: View History.
  • نوار وضعیت پایین-چپ پنجره (نه داخل ستون): نام شاخه. یک کلیک روی نام شاخه = فهرست عوض کردن شاخه.
نوار وضعیت Git در VS Code

شکل ۹ب — یک کلیک روی main. عدد ↓ و ↑ مال این مخزن است؛ مال تو ۰ و ۰ هم طبیعی است.

اگر نوار وضعیت شاخه نشان نمی‌دهد: یا پوشه Git ندارد، یا Git پیدا نشده. اول همان جدول «اگر مال تو این‌طور نیست» را بالا ببین.

😶 دکمهٔ بزرگ زیر Message — از روی برچسب بفهم کجایی

VS Code یک دکمهٔ اصلی دارد. برچسب را بخوان؛ حدس نزن.

حالت ۱ — نوشته Initialize Repository / Publish to GitHub

یعنی پوشه‌ای که Open Folder کرده‌ای فایل .git ندارد.

Initialize Repository در Source Control

شکل ۹پ — فقط وقتی `.git` نیست این دو دکمه را می‌بینی.

کلیک‌ها:

  1. File → Open Folder — پوشهٔ خود پروژه را انتخاب کن، نه درایو و نه پوشهٔ والد.
  2. Ctrl+Shift+G.
  3. یک کلیک روی Initialize Repository. معادل git init. بعد از کلیک باید جعبهٔ Message ظاهر شود و اگر فایلی باشد، لیست Changes پر شود.
  4. همان لحظه فایل .gitignore بساز (Ctrl+N، ذخیره با همین نام) تا node_modules در Changes نیاید.
  5. Publish to GitHub را فقط اگر می‌خواهی ریپو روی GitHub ساخته شود بزن. اگر بزنی و وارد حساب نباشی، پنجرهٔ ورود مرورگر باز می‌شود — این خطا نیست.

اگر بعد از Initialize هنوز همان دو دکمه را می‌بینی: پوشهٔ اشتباه باز است. در Explorer باید .git را (گاهی مخفی) ببینی. File → Open Folder را تکرار کن.

اگر Publish خاکستری است یا خطا می‌دهد: Accounts پایین Activity Bar → Sign in to GitHub. بدون ورود، Publish کار نمی‌کند؛ Initialize کار می‌کند.

حالت ۲ — نوشته Sync Changes (شاید با عدد ↓ یا ↑)

یعنی مخزن هست، فایل ذخیره‌شدهٔ تغییرکرده برای کامیت نداری، ولی با origin هم‌تراز نیستی.

  • ۱۵↓ = روی سرور ۱۵ کامیت هست که تو نداری → Sync تقریباً pull است.
  • ↑۳ = تو ۳ کامیت داری که سرور ندارد → Sync تقریباً push است.
  • هر دو = واگرایی؛ Sync ممکن است merge بسازد.

لیست Changes خالی در این حالت موفقیت است (nothing to commit, working tree clean)، نه اینکه Git خراب باشد.

اگر Sync را زدی و از تو تأیید خواست: تنظیم git.confirmSync روشن است — Yes بگو یا در Settings خاموشش کن.

اگر Sync خطا داد (rejected / diverged): فصل ۱۱ — اول Fetch، بعد Pull یا Pull (Rebase). Force نزن.

حالت ۳ — نوشته Commit (یا Commit با فلش ▾)

یعنی حداقل یک فایل در Changes یا Staged هست.

اگر تو Commit می‌بینی و کتاب Sync: تو فایل ذخیره‌نشده یا تغییرکرده داری؛ کتاب در آن عکس Working Tree تمیز نشان می‌دهد. هر دو درست‌اند.

✍️ مسیر کامل کامیت — کلیک به کلیک

هدف: یک فایل را عوض کنی و در تاریخچه ثبت شود.

کامیت و diff در Source Control

شکل ۱۰ — بعد از مرحلهٔ ۴ باید چیزی شبیه این ببینی: پیام، فایل‌ها با M/U، diff سبز/قرمز.

  1. فایل را در ادیتور عوض کن و Ctrl+S بزن.
    باید ببینی: روی آیکون Git عدد می‌آید؛ فایل در Changes ظاهر می‌شود.
    اگر نیامد: Save نشده، یا فایل داخل .gitignore است، یا پوشهٔ دیگری Open است.

  2. Ctrl+Shift+G.
    باید ببینی: نام فایل + حرف M یا U.

  3. یک کلیک روی نام فایل در Changes.
    باید ببینی: سمت راست، diff. خط قرمز = حذف، سبز = اضافه.
    اگر سمت راست همان Welcome VS Code ماند: روی نام فایل کلیک نشده؛ روی فضای خالی ستون کلیک کرده‌ای.

  4. یک کلیک روی + سمت راست همان فایل (وقتی نشانگر روی ردیف است ظاهر می‌شود). معادل git add.
    باید ببینی: فایل از Changes به Staged Changes می‌پرد.
    اگر + نبود: نشانگر را روی ردیف فایل ببر. در بعضی تم‌ها + فقط hover است. یا Palette → Git: Stage Changes.

  5. یک کلیک داخل جعبهٔ Message و بنویس مثلاً feat(auth): add JWT refresh flow.
    اگر جعبه غیرفعال است: هنوز Staged نداری و Smart Commit خاموش است — مرحلهٔ ۴ را بزن. یا فوکوس روی ادیتور است.

  6. Ctrl+Enter (مک: Cmd+Enter) یا یک کلیک روی دکمهٔ Commit.
    باید ببینی: لیست خالی می‌شود، دکمه ممکن است به Sync/Publish عوض شود، نوار وضعیت ↑1 بگیرد اگر remote داری.

اگر کلیک Commit همهٔ فایل‌ها را برد نه فقط یکی: git.enableSmartCommit روشن است. Settings → این گزینه را Off کن. از این به بعد بدون Stage، دکمه Commit کار نمی‌کند یا هشدار می‌دهد.

اگر خطا Signing failed / secret key: فصل ۲ — امضا روشن است ولی کلید SSH signing روی این ماشین نیست. موقتاً git.enableCommitSigning را Off کن یا کلید را بساز.

اگر خطا Please tell me who you are: user.name و user.email ست نشده — فصل ۲.

📦 Staged در برابر Changes — دو کلیک معکوس

Staged Changes و Changes جدا

شکل ۱۰ب — بالا می‌رود داخل کامیت؛ پایین هنوز نمی‌رود. اگر فقط یک لیست می‌بینی، یا چیزی Stage نکرده‌ای یا Untracked جداست.

می‌خواهی کلیک دقیق باید ببینی
فایل برود برای کامیت + روی ردیف در Changes ردیف می‌پرد به عنوان Staged Changes
پشیمان از Stage - روی ردیف در Staged برمی‌گردد به Changes؛ فایل روی دیسک همان است
همه را Stage + روی نوار عنوان Changes (نه روی فایل) همه می‌روند بالا
تغییرات فایل روی دیسک دور ریخته شود راست‌کلیک روی ردیف Changes → Discard Changes → تأیید فایل از لیست می‌رود؛ محتوای ادیتور به نسخهٔ قبلی برمی‌گردد

اگر Staged Changes را به‌عنوان عنوان جدا نمی‌بینی: هنوز + نزدی. با Smart Commit روشن، ممکن است بدون این عنوان هم Commit همه را بگیرد — برای همین خاموشش کردیم.

اگر Discard را زدی و فایل برگشت: Untracked (U) را Discard کردن یعنی حذف فایل از دیسک. VS Code معمولاً «Are you sure?» می‌پرسد. اگر پرسید و Yes گفتی، از Timeline برگردان (پایین فصل).

اگر Untrackedها ته یک لیست قاطی‌اند نه گروه جدا: Settings → git.untrackedChanges را بگذار separate.

🔬 hunk — سه کلیک آبی روی خود diff

hunk = چند خط سبز/قرمز پشت‌سرهم. معادل git add -p.

Stage Selected Ranges روی diff

شکل ۱۰پ — این سه لینک آبی فقط وقتی فایل را از Changes باز کرده باشی بالای hunk ظاهر می‌شوند.

  1. در Changes یک کلیک روی فایل.
  2. در diff، خطوطی که می‌خواهی را با ماوس رنگ کن (یا هیچی انتخاب نکن اگر کل hunk را می‌خواهی).
  3. یک کلیک روی یکی از سه لینک آبی بالای hunk:
    • Stage Change = کل این hunk
    • Stage Selected Ranges = فقط خطوط انتخاب‌شده
    • Discard Change = همین hunk از روی دیسک برگردد

باید ببینی: اگر فقط بخشی Stage شد، فایل هم در Staged می‌ماند هم در Changes (حرف گاهی M دو جا). این درست است.

اگر لینک آبی نبود:

  • diff را از Timeline باز کرده‌ای نه از Changes — ببند، از Source Control روی فایل کلیک کن.
  • روی نمای پیش‌نمایش Markdown هستی نه متن — روی تب فایل خام کلیک کن.
  • تنظیم diffEditor.renderSideBySide فرق ندارد؛ لینک‌ها باید باشند. VS Code را به‌روز کن.

▾ فلش کنار Commit — یک کلیک، پنج فرمان

یک کلیک روی فلش ▾ سمت راست دکمهٔ Commit (نه خود Commit).

منوی Commit در Source Control

شکل ۱۰ت — اگر فلش را نمی‌بینی، دکمه هنوز Commit نیست (Sync/Publish است) یا عرض ستون خیلی کم است؛ ستون را بکش عریض‌تر کن.

کلیک روی چه می‌شود اگر مال تو خاکستری / نیست
Commit فقط ثبت محلی باید Staged یا Smart Commit داشته باشی
Commit & Push ثبت + ارسال به origin origin نباشد → اول Publish Branch
Commit & Sync ثبت + pull/push tracking نداشته باشی، Push جدا بزن
Undo Last Commit آخرین کامیت باز می‌شود، فایل‌ها Staged می‌مانند کامیت نداری
Amend آخرین کامیت را با Stage فعلی و پیام جدید عوض می‌کند بعد از push نزن
Amend بعد از push

هش عوض می‌شود. اگر همکار آن کامیت را گرفته، تاریخچه دوپاره می‌شود.

⌨️ میانبر وقتی فوکوس کجاست؟

Ctrl+Enter فقط داخل جعبهٔ Message کامیت می‌زند. اگر فوکوس روی ادیتور باشد، ممکن است کار دیگری بکند یا هیچ.

یک کلیک داخل Message، بعد Ctrl+Enter. اگر عادت شد: بعد از Stage، کلیک Message، میانبر.

کار کلیک / کلید شرط
باز کردن پنل Ctrl+Shift+G —
کامیت Ctrl+Enter فوکوس روی Message
Palette Ctrl+Shift+P سپس Git: —
Diff Enter روی ردیف فایل فوکوس لیست Changes
Stage همه Git: Stage All Changes —

🧵 Timeline — این یکی داخل Source Control نیست

کلیک‌ها: آیکون Explorer بالا-چپ Activity Bar (دو سند) → فایل را در درخت انتخاب کن → پایین همان ستون تب Timeline را باز کن (اگر جمع است، عنوان Timeline را کلیک کن).

Timeline فایل در VS Code

شکل ۱۰ث — اگر Timeline خالی است، فایل را انتخاب نکرده‌ای یا Git در این پوشه نیست.

یک کلیک روی یک ردیف Timeline آن نسخه را مقایسه می‌کند. Local History برای Discard فایل Untracked است.

🧪 تمرین — هر کدام را تا «باید ببینی» پیش برو

تمرین ۱. پوشهٔ خالی Open Folder → باید Initialize ببینی → کلیک Initialize → README.md بساز و Save → باید U در Changes → + → Message docs: add readme → Ctrl+Enter → باید لیست خالی شود.

تمرین ۲. سه فایل را Save کن → فقط روی یکی + → Commit → باید دو فایل در Changes مانده باشد. اگر هر سه رفتند، Smart Commit را Off کن و تمرین را تکرار کن.

تمرین ۳. یک فایل را چند خط عوض کن → از Changes باز کن → فقط بعضی خط‌ها را Stage Selected Ranges بزن → باید فایل هم بالا هم پایین باشد.

تمرین ۴. Discard یک M → از Timeline برگردان.

سؤالات مصاحبه (با پاسخ)

Junior — چرا Save کافی نیست؟ Save فقط فایل روی دیسک را عوض می‌کند. تاریخچه با کلیک Commit ساخته می‌شود.

Mid — چرا مال من دکمه Commit است و در عکس Sync؟ چون تو تغییر ذخیره‌شده داری و عکس کتاب Working Tree تمیز + origin جلوتر را نشان می‌دهد. دکمه بر اساس وضعیت عوض می‌شود.

Senior — Publish to GitHub دقیقاً بعد از چند کلیک چه می‌سازد؟ ریپو، origin، و push -u. بدون Sign in، همان کلیک پنجرهٔ ورود باز می‌کند نه خطا.

✅ چک‌لیست فهم

  • سه راه باز کردن پنل را بلدی و اگر باز نشد جدول بالا را بلدی
  • از روی برچسب دکمهٔ بزرگ می‌گویی در کدام حالتی
  • مسیر Save → کلیک فایل → + → Message → Ctrl+Enter را بدون حدس می‌روی
  • اگر صفحه با عکس یکی نبود، ستون «چرا؟» را می‌دانی نه اینکه کتاب غلط است

فصل بعد: همان پنل، سطح فوق‌پیشرفته — با همین قرارداد «کلیک / باید ببینی / اگر فرق داشت».

فصل ۱۰ از ۳۶ · مرجع جامع و حرفه‌ای Git و GitHub · ویرایش 1.0.0