Future ForgeFuture ForgeFuture ForgeFuture Forge
ServicesWorkPackagesFree toolsNotesAboutContact
Start
  1. Home
  2. /Notes
Future ForgeFuture Forge

Product engineering studio — design, build, and deploy software.

Discuss your project

Contact

hello@futureforge.ir09128464105
Future ForgeFuture Forge

Product engineering studio — design, build, and deploy software.

Services

Product engineeringFull-stack engineeringEngineering auditArchitecture consultingInfrastructure and deploymentAI in the product

Explore

WorkNotesFAQPackages

Free tools

Engineering auditArchitecture advisorProject estimatorPrompt tool

Company

AboutContactPrivacyTerms of use

Discuss your project

Describe the problem and the constraints. If there is a fit, we will schedule a conversation.

Discuss your project

Contact

hello@futureforge.ir09128464105
GitHubLinkedIn

© 2026 FutureForge. All rights reserved.

HomeServicesFree toolsStart
Glossary

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

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

SE
Soheil Ebrahimpour

Founder & product engineer

·Sep 20, 2026·9 min read
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

Author

SE

Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.

Related notes

Related notes

Categories

Related services

From note to project

If this topic is close to your product or system, we can talk about the real scope.

If you are unsure about architecture or the build path, we can talk about the project.

Describe the problem and the constraints. If there is a fit, we will schedule a conversation.

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

Software architecture

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

Sep 20, 2026

Operations

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

Sep 20, 2026

Product engineering

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

Sep 20, 2026

Product engineering

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

Sep 20, 2026

Product engineering

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

Sep 20, 2026
All notes219
Software architecture13
Glossary37
Operations87
Product engineering74
Web guide8
Product engineering
Full-stack engineering
Engineering audit
Architecture consulting
Infrastructure and deployment
Discuss your project
Free tools
Discuss your project