جلسه 2: مدیریت فایل‌ها، انتخاب مرحله‌ای و کامیت‌های حرفه‌ای

سطح: مقدماتی زمان مطالعه: به‌روزرسانی: 2025-10-30
1 2 3 4 5 6 7 8 9 10

هدف این جلسه: ساختن تاریخچهٔ قابل اعتماد و قابل خواندن. با انتخاب آگاهانهٔ تغییرات، پیام‌های استاندارد و فرایندهای امن، پروژه‌ات برای خودت و تیم شفاف می‌ماند.

اهداف

  • تسلط روی وضعیت‌های فایل (untracked, modified, staged, committed)
  • دیدن تفاوت‌ها قبل/بعد از Stage
  • انتخاب تکه‌ای تغییرات با git add -p
  • ساخت پیام‌های کوتاه و گویا + اصلاح امن آخرین کامیت
  • راه‌اندازی .gitignore در سطح پروژه و سراسری

وضعیت فایل‌ها در Git

هر فایل در یکی از این حالت‌هاست: Untracked (جدید و ناشناخته)، Modified (ویرایش شده)، Staged (در صفِ کامیت بعدی) یا Committed (ثبت شده در تاریخچه).

همیشه با git status شروع کن تا بفهمی الان کجا هستی.

بررسی تغییرات: status/diff

پایش سریع

git status
git diff            # تفاوت فایل‌های unstaged
git add file.js
git diff --staged   # تفاوت‌هایی که قرار است commit شوند

اول diff بدون Stage، بعد از افزودن به Stage، diff نهایی را ببین تا اشتباه وارد کامیت نشود.

لغو تغییرات ناخواسته

git restore file.js            # برگرداندن تغییرات unstaged
git restore --staged file.js   # خارج کردن از Stage

برای فایل‌های جدید (Untracked) از حذف دستی یا git clean با احتیاط استفاده کن.

انتخاب مرحله‌ای: git add -p

وقتی چند تغییر نامرتبط در یک فایل داری، با حالت تعاملی آن‌ها را تکه‌تکه وارد کامیت‌های جدا کن.

git add -p app.js
# کلیدهای مفید در حالت تعاملی:
# y = افزودن این hunk، n = افزودن نکردن
# s = خرد کردن hunk به تکه‌های کوچک‌تر
# e = ویرایش دستی hunk
# q = خروج، ? = راهنما
قانون طلایی: «هر کامیت یک قصهٔ کوچک و مستقل.» add -p ابزار عملی همین قانون است.

حذف/انتقال/تغییرنام: rm و mv

حذف از گیت یا از دیسک؟

git rm file.txt           # از گیت + از دیسک حذف و Stage حذف
git rm --cached .env      # فقط از گیت حذف، روی دیسک بماند
git commit -m "chore: drop tracked secret file"

برای فایل‌هایی که «نباید» ردیابی شوند (مثل .env)، بعد از --cached حتماً الگو را به .gitignore اضافه کن.

تغییر نام/انتقال

git mv old.js src/new.js
git commit -m "refactor: move module to src/"

Git تغییرنام را از روی شباهت تشخیص می‌دهد، ولی git mv مرحله‌بندی را تمیز انجام می‌دهد.

.gitignore محلی و سراسری

فایل‌های تولیدی، موقتی و خصوصی را وارد تاریخچه نکن. الگوها را در سطح مخزن یا به‌صورت سراسری تعریف کن.

در ریشهٔ پروژه

# .gitignore (نمونهٔ متداول)
node_modules/
dist/
.env
.DS_Store
.vscode/
.idea/

سراسری (global)

# Windows
git config --global core.excludesfile "%USERPROFILE%\\.gitignore_global"
notepad %USERPROFILE%\\.gitignore_global

# macOS/Linux
git config --global core.excludesfile "~/.gitignore_global"
nano ~/.gitignore_global

# پیشنهاد داخل .gitignore_global
.DS_Store
Thumbs.db
.vscode/
.idea/
اگر فایلی قبلاً track شده، فقط اضافه‌کردنش به .gitignore کافی نیست؛ با git rm --cached از گیت حذفش کن.

کامیت‌های حرفه‌ای: پیام استاندارد + اصلاح امن

یک پیام خوب کوتاه، روشن و هدف‌دار است. فرمت پیشنهادی:

# قالب پیشنهادی
type(scope): subject
# نمونه‌ها
feat(auth): add JWT login
fix(parser): prevent null crash
chore(ci): add Node 20 to matrix

اگر آخرین کامیت اشتباه شد و هنوز Push نکرده‌ای:

# اصلاح پیام
git commit --amend

# افزودن تغییرات جاافتاده بدون تغییر پیام
git add missed-file.js
git commit --amend --no-edit
بعد از Push عمومی، بهتر است تاریخچه را بازنویسی نکنی. به‌جایش از git revert استفاده کن (جلسهٔ ۶).

سناریوهای واقعی (گام‌به‌گام)

۱) «تغییرات زیادِ قاطی‌شده» را مرتب کن

  1. git status → ببین چه چیزهایی تغییر کرده.
  2. git add -p روی فایل‌های بزرگ → فقط تکه‌های مربوط به «رفع باگ» را اضافه کن.
  3. git diff --staged → بررسی نهایی.
  4. git commit -m "fix(...): ..."
  5. حالا نوبت تکه‌های مربوط به «بهبود ظاهر» است: تکرار مراحل با پیام جدید feat/ui یا style.

۲) «فایل حساس» اشتباهی وارد ریپو شده

  1. به‌صورت اضطراری: git rm --cached .env
  2. در .gitignore الگو را اضافه کن.
  3. git commit -m "chore: untrack .env and ignore it"
  4. اگر قبلاً Push شده و حساس است، کلید/توکن را در سرویس مقصد باطل و بازتولید کن.

۳) «تغییر نام و جابجایی ماژول» با تاریخچهٔ خوانا

  1. git mv utils.js src/utils/index.js
  2. git diff --staged → تأیید.
  3. git commit -m "refactor: move utils to src/utils/"
  4. تغییر کدهای وابسته را در کامیت جداگانه انجام بده تا دلیل هر کامیت شفاف باشد.

تمرین

  1. یک ریپوی تست با سه فایل بساز؛ در یک فایل چند تغییر نامرتبط بده و با add -p دو کامیت مرتب ایجاد کن.
  2. یک .gitignore محلی و یک سراسری بساز (با core.excludesfile).
  3. یک بار عمداً پیام اشتباه بده و با --amend اصلاحش کن.
  4. یک فایل را با git mv جابجا کن و دلیل جابجایی را در پیام توضیح بده.

خطاهای رایج و نکات ایمنی

  • «فایل ignore می‌شود ولی هنوز در status می‌آید»: قبلاً track شده؛ git rm --cached بزن.
  • «add -p گیج‌کننده است»: در حالت تعاملی کلید ? راهنما نشان می‌دهد. از s برای خردکردن تکه‌ها استفاده کن.
  • «می‌خواهم آخرین کامیت را تغییر بدهم ولی Push کرده‌ام»: امن‌ترین راه git revert در جلسهٔ ۶ است.
  • «فایل مهم را حذف کردم»: اگر commit شده بوده، با git checkout <commit> -- path یا ابزارهای جلسهٔ ۶ (reflog) برگردان.

منابع تکمیلی