Future ForgeFuture ForgeFuture ForgeFuture Forge
خدماتنمونه‌کارهاپکیج‌هاابزارهای رایگانیادداشت‌هادرباره ماتماس
شروع پروژه
  1. خانه
  2. /یادداشت‌ها
Future ForgeFuture Forge

استودیوی مهندسی محصول — طراحی، ساخت و استقرار نرم‌افزار.

پروژه‌تان را مطرح کنید

ارتباط

hello@futureforge.ir09128464105
Future ForgeFuture Forge

استودیوی مهندسی محصول — طراحی، ساخت و استقرار نرم‌افزار.

خدمات

طراحی و ساخت محصولتوسعه فول‌استکممیزی مهندسیمشاوره معماریزیرساخت و استقرارهوش مصنوعی در محصول

کاوش

نمونه‌کارهایادداشت‌هاپرسش‌هاپکیج‌ها

ابزارهای رایگان

ممیزی مهندسیمشاور معماریتخمین پروژهابزار پرامپت

شرکت

درباره ماتماسحریم خصوصیشرایط استفاده

پروژه‌تان را مطرح کنید

مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ می‌کنیم.

پروژه‌تان را مطرح کنید

ارتباط

hello@futureforge.ir09128464105
GitHubLinkedIn

© 2026 FutureForge. همه حقوق محفوظ است.

خانهخدماتابزارهای رایگانشروع پروژه
واژه‌نامه

Working Tree، Staging و Repository: سه لایهٔ روزمرهٔ Git

تفاوت Working tree، Index/Staging و تاریخچهٔ Repository؛ چرا git add وجود دارد و status چه می‌گوید — با Pro Git Reset Demystified و git-scm.

سا
سهیل ابراهیم‌پور

بنیان‌گذار و مهندس محصول

·۲۹ شهریور ۱۴۰۵·9 دقیقه مطالعه
Working tree Staging Repositorygit addindexstaging areagit statusthree treesHEAD
سه ستون استیکی کنار خروجی git status

بیشتر سردرگمی‌های تازه‌واردها از یک جمله می‌آید: «تغییر دادم ولی Commit نشده.» در Git سه لایهٔ جدا وجود دارد. Pro Git در فصل Reset Demystified آن‌ها را گاهی Three Trees می‌نامد: Working Directory (یا Working Tree)، Index (Staging Area)، و HEAD (آخرین Commit روی Branch جاری به‌عنوان نمایندهٔ تاریخچهٔ ثبت‌شده). تا این سه تا را جدا نکنید، git status مثل پیام خطای تصادفی به‌نظر می‌رسد.

زاویهٔ این مقاله مشکل‌محور است: چرا Git عمداً Staging دارد؟ چه زمانی تغییراتتان فقط روی دیسک‌اند، چه زمانی برای Commit بعدی آماده‌اند، و چه زمانی بخشی از تاریخچه‌اند. مقالهٔ ۰۷۰ این لایه‌ها را نام برد؛ اینجا عمق عملی و اشتباه‌های پرهزینه است.

Working Tree تا Staging Area تا Repository با git add و commit

پاسخ کوتاه

Working tree جایی است که فایل‌ها را ویرایش می‌کنید. Staging (Index) پیشنهاد شما برای محتویات Commit بعدی است — با git add پر می‌شود. Repository در معنای روزمرهٔ این بحث، تاریخچهٔ Commitهای ثبت‌شده است که با git commit از روی Index ساخته می‌شود و HEAD به نوک آن اشاره می‌کند. می‌توانید فقط بخشی از تغییرات را Stage کنید؛ بقیه modified می‌مانند.

Staging کنترل است نه بوروکراسی: اجازه می‌دهد یک Commit تمیز بسازید وقتی روی دیسک هنوز کار ناتمام دارید.

لایه ۱: Working Tree

Sandbox قابل ویرایش. Clone یا checkout فایل‌ها را اینجا باز می‌کند. وضعیت فایل‌ها از دید Git:

  • Tracked: Git از قبل آن‌ها را می‌شناسد (در Commit قبلی یا Stage).
  • Untracked: فایل جدید که هنوز add نشده.
  • Modified: tracked که نسبت به Index یا HEAD فرق دارد.
  • Ignored: مطابق .gitignore؛ معمولاً در status دیده نمی‌شود.

تغییر در Working tree به‌تنهایی تاریخچه را عوض نمی‌کند. خاموش کردن لپ‌تاپ تغییرات ذخیره‌نشدهٔ ادیتور را از بین می‌برد؛ تغییرات ذخیره‌شده روی دیسک می‌مانند ولی هنوز Commit نیستند.

لایه ۲: Staging Area (Index)

Index یک فایل ساختاریافته در .git است که Pro Git آن را «پیشنهاد Commit بعدی» می‌نامد. git add محتوا را از Working tree به Index کپی مفهومی می‌کند. git commit از Index snapshot می‌سازد، نه لزوماً از تمام Working tree.

bash

git status git add src/auth.py git restore --staged src/auth.py # unstage git diff # working vs index git diff --cached # index vs HEAD

این جداسازی اجازه می‌دهد دو موضوع قاطی‌شده روی دیسک را در دو Commit جدا ثبت کنید (با add -p یا Stage انتخابی). میان‌بر git commit -a فقط فایل‌های tracked را Stage می‌کند؛ untracked را نمی‌گیرد.

لایه ۳: تاریخچهٔ Repository (HEAD / Commits)

وقتی commit می‌زنید، Git از Index یک tree می‌سازد، شیء Commit با پیام و والد ایجاد می‌کند، و Branch جاری را جلو می‌برد. از این لحظه تغییر بخشی از تاریخچه است (تا وقتی بازنویسی تاریخچه نکنید). HEAD معمولاً به Branch جاری اشاره می‌کند؛ detached HEAD حالت پیشرفته‌تری است برای بازرسی.

Restore/checkout و reset هر کدام روی لایه‌های متفاوت اثر می‌گذارند؛ جزئیات مخرب را در ۲۱۳ همین سری می‌خوانید. اینجا فقط بدانید: «برگرداندن» مبهم است مگر بگویید کدام لایه.

جدول: هر فرمان کدام لایه را لمس می‌کند؟

فرمان رایجWorking treeIndexتاریخچه/HEAD
ویرایش در ادیتوربلهخیرخیر
git addخواندنبه‌روزخیر
git commitخیر*مبنای snapshotCommit جدید
git diffدر برابر Index——
git diff --cached—در برابر HEAD—
git restore --stagedخیربرمی‌گرداندخیر

* مگر hook یا گزینهٔ خاص؛ مدل پایه بدون دست زدن به Working tree Commit می‌سازد.

چرا Staging وجود دارد؟ مسئله‌ای که حل می‌کند

بدون Staging، هر Commit مجبور بود «همهٔ تغییرات کثیف روی دیسک» را بگیرد یا ابزار بیرونی فایل‌ها را جدا کند. با Index می‌توانید:

  • Fix فوری را Commit کنید و WIP را موقتاً کنار بگذارید (یا بعداً stash — ۲۱۲).
  • Review شخصی قبل از ثبت: diff --cached همان چیزی است که وارد تاریخچه می‌شود.
  • از Commit تصادفی Secret در فایل مجاور جلوگیری نسبی کنید (باز هم مسئولیت با شماست).

تیم‌هایی که همیشه commit -a می‌زنند، عملاً Staging را دور می‌زنند؛ برای پروژه‌های کوچک ممکن است قابل قبول باشد، ولی کنترل ریز را از دست می‌دهید.

خواندن git status مثل نقشه

خروجی status معمولاً سه ناحیه دارد: changes to be committed (در Index)، changes not staged for commit (Working tree کثیف نسبت به Index)، و untracked files. اگر چیزی «هم Stage شده هم دوباره modify شده»، یعنی بعد از add دوباره ویرایش کرده‌اید — برای Commit نهایی باید دوباره add کنید.

bash

git status -sb git add -p # stage تکه‌تکه

اشتباه‌های رایج

  1. فرض اینکه ذخیره در ادیتور = Commit.
  2. add کردن کل پروژه با git add . بدون نگاه به untracked (خطر Secret و node_modules).
  3. ترس از Staging و استفادهٔ دائم از commit -a روی تغییرهای درهم.
  4. گیج شدن بین git diff و git diff --cached.
  5. پاک کردن فایل از Working tree و فکر کردن که از Index/تاریخچه هم رفته.

مسیر تمرین ۱۵ دقیقه‌ای

  1. یک مخزن آزمایشی init کنید و یک فایل Commit کنید.
  2. دو فایل را عوض کنید؛ فقط یکی را add کنید؛ status را بخوانید.
  3. diff و diff --cached را مقایسه کنید.
  4. Commit بزنید؛ ببینید فایل دوم هنوز modified است.
  5. فایل دوم را Stage و Commit کنید.

سناریوی واقعی: دو موضوع روی یک دیسک

در حال Fix کردن باگ ورود هستید که ناگهان باید یک typo در README را هم برای Release امروز Commit کنید. بدون Staging مجبورید یا همه را با هم Commit کنید یا تغییر باگ را دور بریزید/Stash کنید. با Index: فقط README را add و Commit می‌کنید؛ Fix ورود modified می‌ماند برای Commit بعدی. این همان مسئلهٔ روزمره‌ای است که Staging حل می‌کند.

bash

git add README.md git commit -m "Fix typo in install section of README" git status # auth fix still modified

سه diff که باید حفظ باشید

  • git diff: Working tree در برابر Index — چه چیزی هنوز Stage نشده.
  • git diff --cached / --staged: Index در برابر HEAD — چه چیزی وارد Commit بعدی می‌شود.
  • git diff HEAD: Working tree در برابر آخرین Commit — تصویر کلی کثیفی نسبت به تاریخچه.

بسیاری از باگ‌های «فکر کردم Commit شد» از نخواندن همین سه نما می‌آید. قبل از Push، --cached را یک‌بار بخوانید انگار Reviewer هستید.

پیوند با Reset و Restore بدون ورود به خطر

وقتی می‌گویید «برش گردان»، باید بگویید کدام لایه: فقط Unstage؟ فقط فایل روی دیسک؟ یا حرکت Branch در تاریخچه؟ Pro Git Reset Demystified دقیقاً برای همین سه لایه نوشته شده است. در این سری، جزئیات پرریسک در ۲۱۳ است؛ اینجا فقط قرارداد زبانی را ثابت کنید تا فرمان اشتباه نزنید.

Partial stage با add -p

وقتی یک فایل دو موضوع قاطی دارد، git add -p تکه‌ها را جدا Stage می‌کند. این مهارت مستقیماً به Commit اتمی ۲۰۴ وصل است. اگر hunkها بد شکسته شدند، ادیتور را تمیزتر کنید یا تغییر را دو نوبت جدا انجام دهید.

bash

git add -p src/service.py git diff --cached git commit -m "One concern only"

فایل Untracked و دام add .

git add . همهٔ untracked غیرignore را Stage می‌کند: .env، dump دیتابیس، کلید. عادت امن‌تر: add مسیرهای مشخص، یا اول status، یا templateهای gitignore زبان/فریم‌ورک. Staging قدرت است؛ قدرت بدون نگاه به status خطر است.

وضعیت‌های ترکیبی که تازه‌واردها را می‌ترساند

فایلی که هم staged است هم بعداً دوباره modify شده، در status دو بار ظاهر می‌شود: نسخهٔ Stage برای Commit بعدی و نسخهٔ کثیف روی دیسک. اگر الآن commit بزنید، فقط نسخهٔ Stage می‌رود؛ تغییرات بعدی روی دیسک می‌مانند. این رفتار درست است، نه باگ. دوباره add کنید اگر می‌خواهید آخرین ویرایش هم داخل همان Commit باشد.

حالت دیگر: rename که Git گاهی به‌صورت delete+add تشخیص می‌دهد. برای تاریخچه مهم است ولی برای مدل سه لایه همان قواعد Stage اعمال می‌شود.

تمرین تشخیص لایه با سؤال

  1. اگر لپ‌تاپ خاموش شود و فایل ذخیره شده باشد، کدام لایه مانده؟ Working tree.
  2. اگر add کرده باشید ولی commit نه؟ Index هم همان snapshot را دارد.
  3. اگر commit کرده ولی push نه؟ تاریخچهٔ محلی؛ Remote نه.
  4. اگر push کرده باشید؟ Remote هم همان Commit را دارد (با فرض موفق بودن).

هر بار که کسی می‌گوید «کدم پرید»، با این چهار سؤال لایه را پیدا کنید؛ بعد فرمان مناسب معنی پیدا می‌کند.

سوالات متداول

آیا می‌توان Staging را نادیده گرفت؟

از نظر فنی با -a یا ابزارهای GUI بله؛ از نظر مهارتی بهتر است مدل را بفهمید بعد تصمیم بگیرید کجا میان‌بر بزنید.

Index همان stash است؟

خیر. Stash انبار موقت جداگانه است؛ Index صف Commit بعدی.

چرا بعد از merge conflict هم پای Index وسط است؟

Conflict یعنی Git نتوانسته Index را کامل از ادغام پر کند؛ بعد از حل، add فایل‌ها Index را کامل می‌کند و commit ادغام را می‌بندد (۲۰۷).

خلاصه

Working tree محل ویرایش، Staging محل انتخاب محتوای Commit بعدی، و تاریخچهٔ Repository محل ثبت ماندگار است. git add و دو نوع diff ابزار خواندن این لایه‌ها هستند. وقتی status را لایه لایه بخوانید، Git قابل پیش‌بینی می‌شود.

قدم بعد: Commit را به‌عنوان شیء تاریخچه بشناسید (۲۰۴)، بعد Branch به‌عنوان اشاره‌گر متحرک (۲۰۵).

منابع و مراجع

  • Pro Git — Git Tools Reset Demystified — https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified
  • Pro Git — Recording Changes to the Repository — https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository
  • git-status documentation — https://git-scm.com/docs/git-status
  • git-add documentation — https://git-scm.com/docs/git-add
  • git-commit documentation — https://git-scm.com/docs/git-commit

نویسنده

سا

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

یادداشت‌های مرتبط

یادداشت‌های مرتبط

دسته‌بندی‌ها

خدمات مرتبط

از یادداشت تا پروژه

اگر موضوع این مقاله به سیستم یا محصول شما نزدیک است، می‌توانیم درباره دامنه واقعی صحبت کنیم.

اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، می‌توانید درباره پروژه صحبت کنیم.

مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ می‌کنیم.

سهیل ابراهیم‌پور
یادداشت‌ها
Monolith در برابر Microservices: کدام را انتخاب کنیم؟
Logging چیست؟ ثبت رویداد برای تشخیص و پاسخ به حادثه
Empty State، Error State و Loading State چیست؟
UX مهم‌تر است یا UI؟
چرا متن بد می‌تواند حتی یک UI زیبا را خراب کند؟

معماری نرم‌افزار

Monolith در برابر Microservices: کدام را انتخاب کنیم؟

۲۹ شهریور ۱۴۰۵

عملیات و استقرار

Logging چیست؟ ثبت رویداد برای تشخیص و پاسخ به حادثه

۲۹ شهریور ۱۴۰۵

مهندسی محصول

Empty State، Error State و Loading State چیست؟

۲۹ شهریور ۱۴۰۵

مهندسی محصول

UX مهم‌تر است یا UI؟

۲۹ شهریور ۱۴۰۵

مهندسی محصول

چرا متن بد می‌تواند حتی یک UI زیبا را خراب کند؟

۲۹ شهریور ۱۴۰۵
همه یادداشت‌ها219
معماری نرم‌افزار13
واژه‌نامه37
عملیات و استقرار87
مهندسی محصول74
راهنمای وب8
طراحی و ساخت محصول
توسعه فول‌استک
ممیزی مهندسی
مشاوره معماری
زیرساخت و استقرار
پروژه‌تان را مطرح کنید
ابزارهای رایگان
پروژه‌تان را مطرح کنید