Repository چیست؟ مخزن Git بهعنوان واحد حقیقت پروژه
تعریف دقیق Git repository: پوشهٔ .git، تفاوت مخزن محلی و Remote، bare در برابر non-bare، و اشتباههای رایج — با git-scm و Pro Git.
بنیانگذار و مهندس محصول

وقتی میگویید «مخزن را کلون کردم» یا «روی ریپو کار میکنم»، منظورتان معمولاً ترکیبی از فایلهای قابل ویرایش و تاریخچهٔ پنهان در پوشهٔ .git است. Repository (مخزن) در Git واحد منطقی پروژه است: همهٔ Commitها، Branchها، Tagها و تنظیمات محلی مربوط به همان تاریخچه. بدون این تصویر، Remote، Clone و «کدام پوشه را Push کنم؟» گیجکننده میماند.
مستندات gitrepository-layout و Pro Git توضیح میدهند که قلب مخزن دایرکتوری .git است: objects، refs، HEAD، config و index. آنچه در ریشه میبینید Working tree است؛ خودِ تاریخچه داخل .git زندگی میکند. GitHub Docs هم repository را محل ذخیرهٔ کد، تاریخچه و همکاری معرفی میکند — لایهٔ hosting روی همان مدل.
این صفحه زاویهٔ «واحد حقیقت» را میگیرد: مخزن چه هست، چه نیست، محلی در برابر Remote، و اشتباههایی که باعث از دست رفتن کار یا نشت Secret میشود. جزئیات سه لایهٔ Working/Staging/Repo در ۲۰۳ است.

پاسخ کوتاه
یک Git repository مجموعهای از اشیاء نسخهشده (blob، tree، commit) بههمراه ارجاعها (Branch/Tag) است که معمولاً در پوشهٔ .git نگه داشته میشود. مخزن محلی روی ماشین شماست؛ Remote نامی برای مخزن دیگر (اغلب روی GitHub) است که با Fetch/Push همگام میشود. Clone یک مخزن جدید محلی میسازد که تاریخچه را از Remote کپی کرده و معمولاً Working tree را checkout میکند.
فایلهای پروژه را میبینید؛ مخزن را وقتی میفهمید که .git را جدی بگیرید — آنجا تاریخچه است، نه در نام پوشه.
داخل یک مخزن چه چیزی هست؟
پوشهٔ .git
پس از git init یا clone، دایرکتوری .git ساخته میشود. طبق layout رسمی تقریباً اینها را دارد:
- objects/: ذخیرهٔ فشردهٔ محتوا و Commitها (content-addressable).
- refs/: اشارهگرهای Branch و Tag به hashها.
- HEAD: معمولاً اشاره به Branch جاری.
- config: تنظیمات همین مخزن (remoteها، user محلی اختیاری).
- index: Staging area برای Commit بعدی.
پاک کردن یا خراب کردن .git یعنی از دست دادن تاریخچهٔ محلی (مگر Remote یا بکاپ داشته باشید). هرگز .git را داخل ابزار بکاپ مبهم «همگامسازی جزئی» نگذارید بدون فهم پیامد.
Working tree
فایلهایی که ویرایش میکنید. بخشی از تجربهٔ روزمرهٔ مخزناند، اما خودِ دیتابیس نسخهها نیستند. میتوانید مخزن bare بدون Working tree داشته باشید (رایج روی سرور).
محلی، Remote، و Origin
مخزن محلی جایی است که Commit میزنید. Remote فقط یک URL و نام مستعار است (معمولاً origin). Push تاریخچه را به Remote میفرستد؛ Fetch آن را میآورد بدون ادغام اجباری در Branch جاری؛ Pull معمولاً Fetch + Merge/Rebase است.
bash
git init git remote add origin https://github.com/org/project.git git clone https://github.com/org/project.git
نکتهٔ مفهومی: هر Clone یک مخزن کامل است، نه «کش ضعیف از سرور». به همین دلیل کار آفلاین و Branch محلی ممکن است. سرور مرکزی در Git اختیاری است؛ قرارداد تیم آن را ضروری میکند.
جدول: واژههایی که با Repository قاطی میشوند
| واژه | معنی دقیقتر | اشتباه رایج |
|---|---|---|
| Repository | تاریخچه + ارجاعها (+ معمولاً working tree) | فقط پوشهٔ فایلهای فعلی |
| Project روی GitHub | مخزن Remote + Issues/PR/Actions | یکیگرفتن با خودِ Git |
| Working tree | فایلهای checkoutشده | کل مخزن |
| Bare repo | مخزن بدون working tree | «خالی از کد» به معنی بیتاریخچه |
| Fork | کپی مخزن روی حساب دیگر در هاست | Branch محلی |
ساخت مخزن: init در برابر clone
git init
برای پروژهٔ جدید روی دیسک محلی. .git ساخته میشود؛ هنوز Commitی نیست تا اولین snapshot را بزنید. مناسب شروع از صفر یا تبدیل پوشهٔ موجود.
git clone
کپی مخزن موجود از Remote (یا مسیر دیگر). تاریخچه، Branchهای Remote-tracking و معمولاً checkout یک Branch پیشفرض را میدهد. برای پیوستن به پروژهٔ موجود مسیر استاندارد است.
هر دو در نهایت یک مخزن محلی میسازند؛ تفاوت در مبدأ تاریخچه است.
یک پروژه چند مخزن؟
معمولاً یک محصول منطقی = یک مخزن (یا چند مخزن با مرز واضح سرویس). Monorepo چند بسته را در یک تاریخچه نگه میدارد؛ Polyrepo مرز را بین مخازن میگذارد. هیچکدام مطلق «بهتر» نیست: هزینهٔ CI، دسترسی، و اندازهٔ Review معیارند. Submodule و subtree برای وابستگی به مخزن دیگرند — پیچیدگی اضافه میکنند؛ فقط با قرارداد تیمی.
اشتباه پرهزینه: کپی کردن پوشهٔ پروژه بهجای Clone، بعد init دوباره — تاریخچهها از هم جدا میشوند و Merge واقعی سخت میشود.
امنیت و بهداشت مخزن
- Secret را Commit نکنید؛ .gitignore و اسکن تاریخچه برای نشت.
- مخزن عمومی یعنی تاریخچهٔ عمومی — حتی فایل پاکشده در Commit قدیمی ممکن است بماند.
- دسترسی Remote (تیم، deploy key) جدا از «داشتن Clone روی لپتاپ» است.
- حجم: binaryهای بزرگ بدون LFS مخزن را سنگین و Clone را کند میکنند.
اشتباههای رایج
- فکر کردن که حذف فایل از Working tree آن را از تاریخچه پاک میکند.
- Share کردن کل پوشه از طریق ZIP و از دست دادن .git.
- دو Remote با سیاست متناقض بدون قرارداد تیم.
- Commit روی ماشین مشترک با user.name اشتباه — هویت تاریخچه خراب میشود.
- فرض اینکه Private بودن روی GitHub یعنی نیازی به .gitignore برای Secret نیست.
مسیر داده: از فایل روی دیسک تا شیء در objects
وقتی فایلی را Commit میکنید، محتوا به blob تبدیل میشود، درخت پوشهها tree میسازد، و Commit به آن tree و والد اشاره میکند. همه با hash نامیده میشوند. این مدل توضیح میدهد چرا کپی خام فایلها «همان مخزن» نیست: بدون .git، فقط Working tree دارید نه تاریخچه.
دیدن مختصر اشیاء برای کنجکاوی:
bash
git cat-file -t HEAD git rev-parse HEAD ls .git/refs/heads/
نیازی نیست هر روز cat-file کنید؛ همین تصویر ذهنی جلوی ترس از «جادوی Remote» را میگیرد.
مخزن بهعنوان مرز امنیتی و حقوقی
انتخاب عمومی یا خصوصی، مجوز SPDX، و اینکه پیمانکار به کدام Remote دسترسی دارد، همه روی واحد Repository تعریف میشوند. قاطی کردن چند محصول نامرتبط در یک مخزن بدون قرارداد، هم Review را سخت میکند هم افشای تصادفی را. برعکس، خرد کردن بیدلیل به دهها مخزن میکرو بدون CI مشترک، هزینهٔ هماهنگی میسازد.
سوال تصمیمگیری: «آیا این تاریخچه باید با هم نسخه بخورد و با هم Review شود؟» اگر بله، احتمال یک مخزن (یا monorepo هدفمند) بیشتر است.
Clone عمیق، جزئی، و آرشیو
Clone پیشفرض معمولاً تاریخچهٔ کامل Branchهای Remote-tracking را میگیرد. برای مخازن خیلی بزرگ، shallow clone یا sparse checkout ابزارهای پیشرفتهاند — مفید برای CI، نه بهانه برای نفهمیدن مدل کامل. git bundle و export آرشیو برای انتقال آفلاین هم روی مفهوم همان مخزن سوارند.
- shallow: عمق تاریخچه محدود؛ برای Build سریع.
- mirror/bare: برای پشتیبان یا سرور مرکزی.
- worktree اضافه: چند Working tree روی یک .git — پیشرفته برای کارهای موازی محلی.
چند Remote؛ کی مفید است؟
علاوه بر origin، گاهی upstream برای Fork متنباز، یا remote پشتیبان داخلی تعریف میشود. زیاد کردن Remote بدون سند، Push به مقصد اشتباه میسازد. نامها را معنادار بگذارید و در README بنویسید origin کجاست.
bash
git remote -v git remote add upstream https://github.com/org/upstream.git git fetch upstream
علامتهای مخزن ناسالم
- تاریخچه پر از Commitهای «tmp» و فایلهای ویدیو چند صد مگابایتی.
- Branchهای متروک دههاتایی بدون صاحب.
- README خالی و نبود .gitignore پایه.
- دسترسی همه به force push روی main.
سلامت مخزن ترکیبی از فنی و فرآیندی است؛ ابزار alone کافی نیست.
Repository و پشتیبان؛ مرز مسئولیت
داشتن Remote روی GitHub پشتیبان مفیدی برای تاریخچهٔ کد است، ولی جایگزین سیاست پشتیبان سازمانی برای همهٔ داراییها نیست. همچنین حذف مخزن روی هاست یا از دست رفتن دسترسی حساب میتواند دردناک باشد؛ سازمانهای جدی دسترسی، مالکیت Organization، و گاهی mirror داخلی تعریف میکنند.
روی لپتاپ، پاک کردن پوشهٔ پروژه یعنی پاک کردن Working tree و .git محلی. اگر Push نشده باشد، کار از بین میرود. عادت: قبل از ترک میز، Push Branch فعال به Remote امن.
نامگذاری و کشف مخزن در سازمان
نام مبهم repo1 یا new-api-final پیدا کردن مالک و حوزه را سخت میکند. الگوی org/service-name یا team-prefix به جستوجو و CODEOWNERS کمک میکند. توضیح یکپاراگرافی در GitHub About و README، هزینهٔ onboarding را کم میکند — بخشی از خودِ مفهوم «مخزن بهعنوان واحد حقیقت» است نه تزئین.
- نام پایدار انتخاب کنید؛ Rename ممکن است URLها و CI را بشکند.
- موضوع مخزن را در description بنویسید.
- لینک به مستند معماری یا Runbook اگر وجود دارد.
سوالات متداول
آیا میتوانم .git را جابهجا کنم؟
مخزن به مسیر وابسته است؛ جابهجایی کل پوشهٔ پروژه معمولاً خوب است. جدا کردن .git از Working tree پیشرفته است (GIT_DIR) و برای روزمره لازم نیست.
مخزن خالی روی GitHub یعنی چه؟
Remote ساخته شده ولی هنوز Commitی Push نشده (یا فقط README اولیه). Clone همان را میگیرد؛ کار واقعی با Commit اول محلی یا از قالب شروع میشود.
فرق Organization repo با حساب شخصی؟
از دید Git همان Remote است؛ فرق در مجوز، Billing و سیاست سازمان روی هاست است.
خلاصه
Repository واحد حقیقت تاریخچهٔ پروژه در Git است: اشیاء و ارجاعها در .git، فایلهای قابل ویرایش در Working tree، و Remote بهعنوان نقطهٔ اشتراک. Clone مخزن کامل میسازد؛ init از صفر. بهداشت Secret و فهم اینکه حذف فایل ≠ پاک شدن از تاریخچه، از خودِ تعریف مهمترند.
بعدی: سه لایهٔ روزمره را در ۲۰۳ جدا کنید تا status و commit معنی دقیق پیدا کنند.
منابع و مراجع
- Pro Git — Getting a Git Repository — https://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository
- gitrepository-layout documentation — https://git-scm.com/docs/gitrepository-layout
- GitHub Docs — About repositories — https://docs.github.com/en/repositories/creating-and-managing-repositories/about-repositories
- GitHub Docs — Cloning a repository — https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository
- Pro Git — What is Git? — https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




