Git 2026

فصل ۱۲ · diff و log

دیدن تغییر — diff، log، blame و bisect

برای فهمیدن «چه عوض شد» فایل کامل را نخوان — تفاوت دو نسخه را بخوان. این فصل سه نوع diff، فیلتر log، و پیدا کردن کامیت خراب با bisect را جدا می‌کند.

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

  • diff سه سطحی (unstaged / staged / بین کامیت‌ها) را جدا کنی
  • log را فیلتر کنی تا در ده هزار کامیت گم نشوی
  • با bisect باگ را در log₂(n) قدم پیدا کنی

📐 سه diff

سه نگاه
git diff                  # Working vs Index
git diff --staged         # Index vs HEAD
git diff main...HEAD      # سه نقطه: از جد مشترک
git diff main..HEAD       # دو نقطه: تفاوت نوک‌ها
سه‌نقطه در برابر دونقطه

A...B یعنی «تغییرات B از وقتی از A جدا شد» — دقیقاً همان چیزی که PR نشان می‌دهد. A..B نوک A را با نوک B مقایسه می‌کند و ممکن است تغییرات نامرتبط A را هم بیاورد.

در VS Code کلیک روی فایل Changes = git diff. کلیک روی Staged = git diff --staged. Open Changes با Alt گاهی side-by-side را عوض می‌کند.

diff بهتر
{
  "diffEditor.renderSideBySide": true,
  "diffEditor.ignoreTrimWhitespace": false,
  "diffEditor.hideUnchangedRegions.enabled": true
}

hideUnchangedRegions در فایل‌های بزرگ ۲۰۲۶ نجات‌دهنده است.

📜 log حرفه‌ای

جست‌وجوی تاریخچه
git log --grep="refresh" -i
git log -S "rotateToken" -p          # pickaxe: کی این رشته آمد/رفت؟
git log -G "function rotate" -p      # regex روی diff
git log --since="2026-01-01" --until="2026-03-01" -- src/auth.ts
git log --no-merges --first-parent   # خط اصلی محصول

--first-parent روی main پر از merge، داستان محصول را می‌خواند نه داستان شاخه‌ها را.

🎯 bisect — کارآگاه باینری

پیدا کردن کامیت خراب
git bisect start
git bisect bad                # HEAD خراب است
git bisect good v1.2.0        # این تگ سالم بود
# Git وسط را checkout می‌کند — تست کن
git bisect good               # یا bad
git bisect reset

اسکریپت‌پذیر:

bisect خودکار
git bisect start HEAD v1.2.0
git bisect run npm test

در VS Code می‌توانی هر گام را از Graph با Checkout انجام دهی؛ اما bisect run در ترمینال سریع‌تر است.

-w و ignore-revs

برای blame تمیز: فایل .git-blame-ignore-revs با هش کامیت‌های format-only، بعد:

git config blame.ignoreRevsFile .git-blame-ignore-revs

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

Junior — git diff بدون آرگومان چه می‌کند؟ Working در برابر Index.

Mid — pickaxe چیست؟ -S کامیت‌هایی را می‌آورد که تعداد رخداد یک رشته را عوض کرده‌اند.

Senior — چرا first-parent برای main مهم است؟ چون هر merge یک دنیای موازی است؛ برای رگرسیون محصول معمولاً فقط خط اصلی اهمیت دارد.

✅ چک‌لیست فهم

  • A...B را از A..B جدا می‌کنی
  • -S را برای یافتن تولد یک تابع بلدی
  • یک bisect موفق انجام داده‌ای

فصل بعد: stash، worktree و sparse-checkout — چند کار موازی بدون هرج‌ومرج.

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