GITFORMAT-INDEX(5) راهنمای Git GITFORMAT-INDEX(5)

gitformat-index - ساختار و قالب نمایه گیت

$GIT_DIR/index

ساختار و قالب نمایه گیت (Git index format)

تمام اعداد دودویی در ترتیب بایت شبکه (network byte order / big-endian) هستند.
در مخزنی که از الگوریتم سنتی SHA-1 استفاده می‌کند، چکسام‌ها و شناسه‌های شیء
(نام اشیاء) که در ادامه آمده‌اند همگی با استفاده از SHA-1 محاسبه می‌شوند. به همین ترتیب،
در مخازن مبتنی بر SHA-256، این مقادیر با استفاده از SHA-256 محاسبه می‌گردند.
در اینجا نسخه ۲ توصیف شده است مگر آنکه خلاف آن ذکر شود.
•یک سرآیند ۱۲ بایتی شامل:
امضای ۴ بایتی:
  امضا برابر است با { 'D', 'I', 'R', 'C' } (مخفف "dircache")
شماره نسخه ۴ بایتی:
  نسخه‌های پشتیبانی‌شده فعلی ۲، ۳ و ۴ هستند.
تعداد مدخل‌های نمایه به صورت عدد ۳۲ بیتی.
•تعدادی مدخل نمایه مرتب‌شده (به بخش‌های بعد مراجعه کنید).
•افزونه‌ها (Extensions)
افزونه‌ها با امضا شناسایی می‌شوند. اگر گیت افزونه‌های اختیاری را درک نکند،
می‌تواند از آنها صرف‌نظر کند.
امضای افزونه ۴ بایتی. اگر بایت اول بین 'A'..'Z' باشد،
افزونه اختیاری است و می‌توان آن را نادیده گرفت.
اندازه افزونه به صورت ۳۲ بیتی
داده‌های افزونه
•چک‌سام هش روی تمام محتوای فایل نمایه تا قبل از این چک‌سام.

مدخل‌های نمایه بر اساس فیلد نام به صورت صعودی مرتب شده‌اند،
که به عنوان رشته‌ای از بایت‌های بدون علامت تفسیر می‌شود (یعنی ترتیب ()memcmp،
بدون محلی‌سازی، بدون رفتار ویژه با جداکننده شاخه '/'). مدخل‌های با
نام یکسان بر اساس فیلد مرحله (stage) خود مرتب می‌شوند.
یک مدخل نمایه معمولاً نشان‌دهنده یک فایل است. با این حال، اگر sparse-checkout
در حالت مخروطی فعال باشد (`core.sparseCheckoutCone` فعال باشد) و افزونه
`extensions.sparseIndex` فعال شده باشد، نمایه ممکن است حاوی مدخل‌هایی
برای شاخه‌های خارج از تعریف sparse-checkout باشد. این مدخل‌ها دارای
حالت `040000` بوده، شامل بیت `SKIP_WORKTREE` هستند، و مسیر آنها با یک جداکننده
شاخه ختم می‌شود.
۳۲ بیت ثانیه‌های ctime، آخرین زمانی که متادیتای فایل تغییر کرده است
  این داده از (2)stat به دست می‌آید
۳۲ بیت کسر نانوثانیه‌ای ctime
  این داده از (2)stat به دست می‌آید
۳۲ بیت ثانیه‌های mtime، آخرین زمانی که داده‌های فایل تغییر کرده است
  این داده از (2)stat به دست می‌آید
۳۲ بیت کسر نانوثانیه‌ای mtime
  این داده از (2)stat به دست می‌آید
۳۲ بیت dev
  این داده از (2)stat به دست می‌آید
۳۲ بیت ino
  این داده از (2)stat به دست می‌آید
۳۲ بیت mode، تقسیم‌شده به (بیت‌های پرارزش به کم‌ارزش)
۱۶ بیت استفاده‌نشده، باید صفر باشد
۴ بیت نوع شیء (object type)
  مقادیر معتبر در مبنای دو عبارتند از 1000 (فایل معمولی)، 1010 (پیوند نمادین)
  و 1110 (gitlink)
۳ بیت استفاده‌نشده، باید صفر باشد
۹ بیت مجوزهای یونیکس. برای فایل‌های معمولی تنها 0755 و 0644 معتبر هستند.
پیوندهای نمادین و gitlinkها در این فیلد مقدار 0 دارند.
۳۲ بیت uid
  این داده از (2)stat به دست می‌آید
۳۲ بیت gid
  این داده از (2)stat به دست می‌آید
اندازه فایل ۳۲ بیتی
  این اندازه فایل روی دیسک از (2)stat است که به ۳۲ بیت کوتاه شده است.
شناسه شیء (Object name) برای شیء نشان‌داده‌شده
فیلد ۱۶ بیتی 'flags' تقسیم‌شده به (بیت‌های پرارزش به کم‌ارزش)
۱ بیت پرچم assume-valid
۱ بیت پرچم extended (در نسخه ۲ باید صفر باشد)
۲ بیت مرحله یا stage (هنگام ادغام)
۱۲ بیت طول نام مسیر در صورتی که طول کمتر از 0xFFF باشد؛ در غیر این صورت مقدار
0xFFF در این فیلد ذخیره می‌شود.
(نسخه ۳ یا بالاتر) یک فیلد ۱۶ بیتی، تنها در صورتی معتبر است که
"extended flag" در بالا مقدار ۱ داشته باشد، تقسیم‌شده به (بیت‌های پرارزش به کم‌ارزش).
۱ بیت رزرو شده برای آینده
۱ بیت پرچم skip-worktree (مورد استفاده در sparse checkout)
۱ بیت پرچم intent-to-add (مورد استفاده توسط "git add -N")
۱۳ بیت استفاده‌نشده، باید صفر باشد
نام مسیر مدخل (با طول متغیر) نسبت به شاخه اصلی و ریشه مخزن
  (بدون اسلش آغازین). نویسه '/' به عنوان جداکننده مسیر استفاده می‌شود. اجزای
  مسیر خاص "."، ".." و ".git" (بدون نقل‌قول) غیرمجاز هستند.
  اسلش پایانی نیز غیرمجاز است.
کدگذاری دقیق مشخص نشده است، اما نویسه‌های '.' و '/' با
کدگذاری ۷ بیتی ASCII ذخیره می‌شوند و کدگذاری نمی‌تواند حاوی بایت
NUL باشد (به عبارت دیگر، این یک مسیر استاندارد UNIX است).
(نسخه ۴) در نسخه ۴، نام مسیر مدخل نسبت به نام مسیر مدخل قبلی
  فشرده‌سازی پیشوندی (prefix-compressed) می‌شود (اولین مدخل به گونه‌ای
  کدگذاری می‌شود که گویی نام مسیر مدخل قبلی یک رشته خالی است). در ابتدای
  هر مدخل، یک عدد صحیح N با کدگذاری با عرض متغیر (همان کدگذاری مورد استفاده برای
  آفست در مدخل‌های بسته OFS_DELTA؛ نگاه کنید به linkgit:gitformat-pack[5]) ذخیره
  می‌شود و به دنبال آن یک رشته S خاتمه‌یافته با NUL می‌آید. با حذف N بایت از
  انتهای نام مسیر مدخل قبلی و الحاق رشته S به آن، نام مسیر این مدخل حاصل
  می‌شود.
۱ تا ۸ بایت nul در صورت نیاز جهت تراز کردن (pad) مدخل به مضربی از هشت بایت،
در حالی که نام همچنان با NUL خاتمه می‌یابد.
(نسخه ۴) در نسخه ۴، بایت‌های ترازکننده (padding) پس از نام مسیر وجود
ندارد.
تفسیر مدخل‌های نمایه در حالت نمایه تفکیک‌شده (split index) کاملاً
متفاوت است. برای جزئیات به بخش مربوطه در ادامه مراجعه کنید.

از آنجا که نمایه مدخل‌هایی را برای شاخه‌ها ذخیره نمی‌کند، مدخل‌های حافظه نهان
نمی‌توانند اشیاء درختی را که از قبل در پایگاه‌داده اشیاء برای بخش‌هایی از نمایه که
نسبت به یک کامیت موجود بدون تغییر مانده‌اند وجود دارند، توصیف کنند. افزونه درخت حافظه نهان
یک ساختار درختی بازگشتی را ذخیره می‌کند که درخت‌های از پیش موجود و کاملاً منطبق بر
بخش‌هایی از مدخل‌های حافظه نهان را شرح می‌دهد. این امر با محاسبه صرفاً درخت‌هایی که برای
کامیت جدید "تازه" هستند، تولید شیء درخت از روی نمایه را سرعت می‌بخشد. همچنین هنگام
مقایسه نمایه با درختی دیگر، مانند `HEAD^{tree}`، فرآیند را تسریع می‌کند، زیرا در صورت اثبات
برابری ساختار درختی، می‌توان بخش‌هایی از نمایه را نادیده گرفت.
ساختار درختی بازگشتی از گره‌هایی استفاده می‌کند که تعداد مشخصی مدخل حافظه نهان،
فهرستی از زیرگره‌ها، و یک شناسه شیء (OID) را ذخیره می‌کنند. OID در صورت وجود، به درخت
موجود متناظر با آن گره اشاره می‌کند. زیرگره‌ها متناظر با زیرشاخه‌هایی هستند که خود دارای
گره‌های درخت حافظه نهان می‌باشند. تعداد مدخل‌های حافظه نهان برابر با تعداد مدخل‌های حافظه نهان در
نمایه است که مسیرهای درون دایرکتوری آن درخت را شرح می‌دهند.
این افزونه ساختار کامل دایرکتوری را در افزونه درخت حافظه نهان ردیابی می‌کند، اما این ساختار
معمولاً بسیار کوچک‌تر از فهرست کامل مدخل‌های حافظه نهان است.
هنگامی که مسیری در نمایه به‌روزرسانی می‌شود، گیت تمام گره‌های درخت حافظه نهان
بازگشتی متناظر با شاخه‌های والد آن مسیر را باطل می‌کند. ما این گره‌های درخت را با قرار دادن
مقدار "-1" به عنوان تعداد مدخل‌های حافظه نهان، به صورت "نامعتبر" ذخیره می‌کنیم. گره‌های
نامعتبر همچنان بازه‌ای از مدخل‌های نمایه را در بر دارند که به گیت اجازه می‌دهد هنگام بازسازی کامل
درخت حافظه نهان، توان پردازشی خود را متمرکز سازد.
امضای این افزونه برابر است با { 'T', 'R', 'E', 'E' }.
مجموعه‌ای از مدخل‌ها کل افزونه را تشکیل می‌دهند؛ که هر یک از آنها
شامل موارد زیر است:
•جزء مسیر خاتمه‌یافته با NUL (نسبت به شاخه والد آن)؛
•عدد ده‌دهی ASCII نشان‌دهنده تعداد مدخل‌های درون نمایه که توسط درخت این مدخل پوشش داده می‌شوند (entry_count)؛
•یک نویسه فاصله (ASCII 32)؛
•عدد ده‌دهی ASCII که نشان‌دهنده تعداد زیردرخت‌های این درخت است؛
•یک نویسه خط جدید (ASCII 10)؛ و
•شناسه شیء (Object name) حاصل از نوشتن این بازه از نمایه به صورت یک شیء درخت.
یک مدخل می‌تواند در وضعیت باطل‌شده (invalidated) باشد که با مقدار منفی
در فیلد entry_count مشخص می‌شود. در این حالت، هیچ نام شیئی وجود ندارد و
مدخل بعدی بلافاصله پس از نویسه خط جدید آغاز می‌شود. هنگام نوشتن یک مدخل نامعتبر،
همواره باید مقدار -1 برای entry_count درج شود.
مدخل‌ها به ترتیب بالا به پایین و ابتدا-عمق (depth-first) نوشته می‌شوند. اولین
مدخل نمایانگر سطح ریشه مخزن است، و به دنبال آن اولین زیردرخت ریشه--به عنوان مثال A--
می‌آید (با نام آن نسبت به ریشه)، سپس اولین زیردرخت A (با نام آن نسبت به A)، و به همین
ترتیب. تعداد مشخص‌شده زیردرخت‌ها نشان می‌دهد چه زمانی سطح جاری از پشته بازگشتی
کامل شده است.

یک تداخل (conflict) در نمایه به صورت مجموعه‌ای از مدخل‌ها با شماره مرحله (stage) بالاتر نمایش داده می‌شود.
هنگامی که یک تداخل حل می‌شود (مانند اجرای "git add path")، این مدخل‌های مراحل بالاتر حذف شده و
یک مدخل مرحله صفر (stage-0) با نتیجه حل تداخل اضافه می‌گردد.
هنگامی که این مدخل‌های مراحل بالاتر حذف می‌شوند، در افزونه resolve undo ذخیره
می‌گردند تا در صورتی که کاربر بخواهد فرآیند حل تداخل را از ابتدا تکرار کند، تداخل‌ها
قابل بازیابی باشند (مثلاً با دستور "git checkout -m").
امضای این افزونه برابر است با { 'R', 'E', 'U', 'C' }.
مجموعه‌ای از مدخل‌ها کل افزونه را تشکیل می‌دهند؛ که هر یک از آنها
شامل موارد زیر است:
•نام مسیر خاتمه‌یافته با NUL که مدخل آن را شرح می‌دهد (نسبت به ریشه مخزن، یعنی مسیر کامل)؛
•سه عدد هشت‌هشتی (octal) اسکی خاتمه‌یافته با NUL، برای حالت مدخل‌ها در مراحل ۱ تا ۳ (مرحله ناموجود با "0" در این فیلد مشخص می‌شود)؛ و
•حداکثر سه نام شیء برای مدخل در مراحل ۱ تا ۳ (برای مرحله ناموجود مقداری نوشته نمی‌شود).

در حالت نمایه تفکیک‌شده، بخش عمده مدخل‌های نمایه را می‌توان در یک فایل
جداگانه ذخیره کرد. این افزونه تغییراتی را ثبت می‌کند که باید بر روی آن فایل اعمال
شوند تا نمایه نهایی تولید گردد.
امضای این افزونه برابر است با { 'l', 'i', 'n', 'k' }.
این افزونه شامل موارد زیر است:
•هش فایل نمایه به اشتراک‌گذاشته‌شده (shared index). مسیر فایل نمایه اشتراکی $GIT_DIR/sharedindex.<hash> است. اگر همه بیت‌ها صفر باشند، نمایه به فایل نمایه اشتراکی نیازی ندارد.
•یک بیت‌مپ حذفی با کدگذاری ewah؛ که در آن هر بیت نشان‌دهنده یک مدخل در نمایه اشتراکی است. اگر بیتی تنظیم شده باشد، مدخل متناظر با آن در نمایه اشتراکی از نمایه نهایی حذف خواهد شد. توجه داشته باشید، از آنجا که عملیات حذف موقعیت مدخل‌های نمایه را تغییر می‌دهد ولی در فاز جایگزینی به موقعیت‌های اصلی نیاز است، بهتر است ابتدا مدخل‌ها را صرفاً برای حذف علامت‌گذاری کرده و پس از انجام جایگزینی، حذف گروهی صورت پذیرد.
•یک بیت‌مپ جایگزینی با کدگذاری ewah؛ که هر بیت نمایانگر یک مدخل در نمایه اشتراکی است. اگر بیتی تنظیم شده باشد، مدخل متناظر با آن در نمایه اشتراکی با یک مدخل موجود در این فایل نمایه جایگزین خواهد شد. تمام مدخل‌های جایگزین‌شده به صورت مرتب در این نمایه ذخیره می‌شوند. اولین بیت "1" در بیت‌مپ جایگزینی متناظر با اولین مدخل نمایه، دومین بیت "1" متناظر با دومین مدخل و به همین ترتیب خواهد بود. مدخل‌های جایگزین‌شده ممکن است جهت صرفه‌جویی در فضا نام مسیر خالی داشته باشند.
مدخل‌های باقیمانده نمایه پس از موارد جایگزین‌شده، به نمایه نهایی اضافه
خواهند شد. این مدخل‌های افزوده نیز ابتدا بر اساس نام مدخل و سپس شماره
مرحله مرتب می‌شوند.

حافظه نهان فایل‌های ردیابی‌نشده، فهرست فایل‌های ردیابی‌نشده و داده‌های
لازم جهت اعتبارسنجی حافظه نهان را ذخیره می‌کند. امضای این افزونه برابر است
با { 'U', 'N', 'T', 'R' }.
افزونه با ساختار زیر آغاز می‌شود:
•توالی‌ای از رشته‌های خاتمه‌یافته با NUL، که اندازه توالی با کدگذاری عرض متغیر در ابتدای آن آمده است. هر رشته محیطی را توصیف می‌کند که حافظه نهان در آن قابل استفاده است.
•داده‌های stat مربوط به $GIT_COMMON_DIR/info/exclude. بخش "مدخل نمایه" از فیلد ctime تا "اندازه فایل" را بررسی کنید.
•داده‌های stat مربوط به core.excludesFile
•مقدار ۳۲ بیتی dir_flags (به ساختار struct dir_struct مراجعه کنید)
•هش فایل $GIT_COMMON_DIR/info/exclude. هش خالی (null hash) نشان‌دهنده عدم وجود فایل است.
•هش core.excludesFile. هش خالی نشان می‌دهد که فایل وجود ندارد.
•رشته خاتمه‌یافته با NUL شامل نام فایل نادیده‌گیری به ازای هر دایرکتوری (per-dir exclude file). این نام معمولاً ".gitignore" است.
•تعداد بلوک‌های دایرکتوری پس از آن، با کدگذاری عرض متغیر. اگر این عدد صفر باشد، افزونه در همین نقطه با یک NUL پس از آن خاتمه می‌یابد.
•تعدادی بلوک دایرکتوری به ترتیب جستجوی اول‌عمق (depth-first-search)، که هر یک شامل موارد زیر است:
•تعداد مدخل‌های ردیابی‌نشده، با کدگذاری عرض متغیر.
•تعداد بلوک‌های زیرشاخه، با کدگذاری عرض متغیر.
•نام شاخه خاتمه‌یافته با NUL.
•تعدادی نام فایل/شاخه ردیابی‌نشده خاتمه‌یافته با NUL.

داده‌های باقیمانده برای هر بلوک شاخه بر اساس نوع دسته‌بندی می‌شوند:

•یک بیت‌مپ ewah، بیت n-ام مشخص می‌کند که آیا دایرکتوری n-ام حاوی مدخل‌های معتبر در حافظه نهان ردیابی‌نشده هست یا خیر.
•یک بیت‌مپ ewah، بیت n-ام مقدار بیت "check-only" تابع ()read_directory_recursive را برای دایرکتوری n-ام ذخیره می‌کند.
•یک بیت‌مپ ewah، بیت n-ام نشان می‌دهد که آیا داده‌های hash و stat برای دایرکتوری n-ام معتبر بوده و در داده‌های بعدی وجود دارند یا خیر.
•آرایه‌ای از داده‌های stat. داده n-ام متناظر با n-امین بیت "یک" در بیت‌مپ ewah قبلی است.
•آرایه‌ای از مقادیر هش. هش n-ام متناظر با n-امین بیت "یک" در بیت‌مپ ewah قبلی است.
•یک بایت NUL.

حافظه نهان پایشگر فایل‌سیستم، فایل‌هایی را که قلاب core.fsmonitor
تغییرات آنها را گزارش کرده است ردیابی می‌کند. امضای این افزونه برابر
است با { 'F', 'S', 'M', 'N' }.
افزونه با ساختار زیر آغاز می‌شود:
•شماره نسخه ۳۲ بیتی: نسخه‌های پشتیبانی‌شده فعلی ۱ و ۲ هستند.
•(نسخه ۱) برچسب زمانی ۶۴ بیتی: داده‌های افزونه تمام تغییرات را تا زمان داده‌شده منعکس می‌کنند که به صورت نانوثانیه‌های سپری‌شده از نیمه‌شب ۱ ژانویه ۱۹۷۰ ذخیره می‌شود.
•(نسخه ۲) رشته خاتمه‌یافته با null: یک نشانه مبهم (opaque token) که توسط برنامه پایشگر سیستم فایل تعریف شده است. داده‌های افزونه کلیه تغییرات را نسبت به آن نشانه بازتاب می‌دهند.
•اندازه بیت‌مپ ۳۲ بیتی: اندازه بیت‌مپ CE_FSMONITOR_VALID.
•یک بیت‌مپ ewah، بیت n-ام نشان می‌دهد که آیا مدخل n-ام نمایه فاقد وضعیت CE_FSMONITOR_VALID است یا خیر.

نشانگر پایان مدخل نمایه (EOIE) برای یافتن انتهای مدخل‌های نمایه با طول متغیر
و آغاز افزونه‌ها به کار می‌رود. نرم‌افزار می‌تواند از این شناسه برای دسترسی سریع
به افزونه‌های نمایه بدون نیاز به پیمایش تک‌تک مدخل‌های نمایه استفاده کند.
از آنجا که باید امکان بارگذاری این بخش پیش از مدخل‌های با طول متغیر و
سایر افزونه‌های نمایه وجود داشته باشد، این افزونه باید در انتها نوشته شود.
امضای این افزونه برابر است با { 'E', 'O', 'I', 'E' }.
این افزونه شامل موارد زیر است:
•آفست ۳۲ بیتی تا انتهای مدخل‌های نمایه
•هش محاسبه‌شده روی انواع افزونه‌ها و اندازه آنها (و نه محتوای آنها). برای مثال، اگر افزونه "TREE" به طول N بایت و افزونه "REUC" به طول M بایت داشته باشیم و پس از آنها "EOIE" قرار گیرد، مقدار هش برابر خواهد بود با:
Hash("TREE" + <binary-representation-of-N> +
        "REUC" + <binary-representation-of-M>)

جدول آفست مدخل‌های نمایه (IEOT) جهت کاهش بار پردازشی (CPU) هنگام بارگذاری
نمایه استفاده می‌شود؛ این کار با ایجاد امکان پردازش چندنخی (multi-threading) در فرآیند
تبدیل مدخل‌های حافظه نهان از قالب روی دیسک به ساختار درون حافظه صورت می‌پذیرد.
امضای این افزونه برابر است با { 'I', 'E', 'O', 'T' }.
این افزونه شامل موارد زیر است:
•نسخه ۳۲ بیتی (در حال حاضر ۱)
•تعدادی مدخل آفست نمایه که هر یک شامل موارد زیر است:
•آفست ۳۲ بیتی از ابتدای فایل تا اولین مدخل حافظه نهان در این بلوک از مدخل‌ها.
•تعداد ۳۲ بیتی مدخل‌های حافظه نهان موجود در این بلوک

هنگام استفاده از sparse-checkout در حالت مخروطی (cone mode)، برخی شاخه‌های کامل
درون نمایه را می‌توان با اشاره به یک شیء درخت به جای ثبت تمام مسیرهای گسترش‌یافته درون
آن خلاصه کرد. نمایه‌ای که شامل چنین مدخل‌هایی باشد یک "نمایه تُنُک" (sparse index) نامیده
می‌شود. قالب‌های نمایه نسخه ۴ و قدیمی‌تر با فرض وجود چنین مدخل‌هایی طراحی نشده بودند.
بنابراین، در این نسخه‌ها، نمایه‌ای که حاوی مدخل‌های شاخه تنک باشد شامل این افزونه با
امضای { 's', 'd', 'i', 'r' } خواهد بود. مانند افزونه split-index،
ابزارها نباید با یک نمایه تنک تعامل داشته باشند مگر اینکه این افزونه را پشتیبانی کنند.

بخشی از مجموعه git(1)

2026-06-29 Git 2.55.0