| GIT-FAST-IMPORT(1) | Git Manual | GIT-FAST-IMPORT(1) |
نام (NAME)
git-fast-import - واردکننده سریع دادههای گیت از سایر سامانههای کنترل نسخه
خلاصه دستور (SYNOPSIS)
frontend | git fast-import [<گزینهها>]
توضیحات (DESCRIPTION)
این برنامه معمولاً چیزی نیست که کاربر نهایی بخواهد مستقیماً آن را اجرا کند. بیشتر کاربران نهایی مایلند از یکی از برنامههای پیشانی (frontend) موجود استفاده کنند که نوع خاصی از منبع خارجی را تجزیه کرده و محتویات ذخیرهشده در آن را به git fast-import تحویل میدهد.
دستور fast-import یک جریان ترکیبی از دستور/داده را از ورودی استاندارد میخواند و یک یا چند فایل بسته (packfile) را مستقیماً در مخزن جاری مینویسد. هنگامی که EOF در ورودی استاندارد دریافت میشود، fast import ارجاعهای بهروزشده شاخه و برچسب را مینویسد و مخزن جاری را با دادههای تازه واردشده کاملاً بهروز میکند.
بخش پشتیبان (backend) ابزار fast-import میتواند دادهها را به درون یک مخزن خالی (مخزنی که پیشتر توسط git init مقداردهی اولیه شده است) وارد کند یا یک مخزن پرشده موجود را بهصورت افزایشی بهروزرسانی نماید. اینکه آیا واردسازی افزایشی از یک منبع خارجی خاص پشتیبانی میشود یا خیر، به برنامه پیشانی مورد استفاده بستگی دارد.
گزینهها (OPTIONS)
--force
--quiet
--stats
--allow-unsafe-features
این گزینه را تنها در صورتی فعال کنید که به برنامه تولیدکننده جریان fast-import اعتماد دارید! این گزینه بهطور خودکار برای برنامههای کمکی دوردست (remote-helpers) که از قابلیت import استفاده میکنند فعال میشود، چرا که آنها از قبل برای اجرای کد خود مورد اعتماد هستند.
--signed-tags=<mode>
--signed-commits=<mode>
گزینههای برنامههای پیشانی (Options for Frontends)
--cat-blob-fd=<fd>
--date-format=<fmt>
--done
مکانهای فایلهای نشان (Locations of Marks Files)
--export-marks=<file>
--import-marks=<file>
--import-marks-if-exists=<file>
--relative-marks, --no-relative-marks
نشانهای نسبی و غیرنسبی را میتوان با درهمآمیختن گزینههای --(no-)-relative-marks با گزینههای --(import|export)-marks= ترکیب کرد.
بازنویسی زیرماژول (Submodule Rewriting)
--rewrite-submodules-from=<name>:<file>, --rewrite-submodules-to=<name>:<file>
پارامتر <name> میتواند هر رشته دلخواهی باشد که فاقد نویسه دونقطه است، اما هنگام مشخص کردن نشانهای متناظر باید از مقدار یکسانی در هر دو گزینه استفاده شود. میتوان زیرماژولهای متعددی را با مقادیر متفاوتی برای <name> مشخص کرد. استفاده نکردن از این گزینهها در جفتهای متناظر یک خطا به شمار میآید.
این گزینهها در وهله اول هنگام تبدیل یک مخزن از یک الگوریتم درهمسازی به الگوریتمی دیگر مفید هستند؛ بدون آنها، اگر fast-import با یک زیرماژول روبهرو شود با شکست مواجه خواهد شد، چرا که راهی برای نوشتن شناسه شیء در الگوریتم درهمسازی جدید ندارد.
تنظیم کارایی و فشردهسازی (Performance and Compression Tuning)
--active-branches=<n>
--big-file-threshold=<n>
--depth=<n>
--export-pack-edges=<file>
--max-pack-size=<n>
fastimport.unpackLimit
کارایی (PERFORMANCE)
طراحی fast-import به آن امکان میدهد پروژههای بزرگ را با کمترین میزان مصرف حافظه و زمان پردازش وارد کند. با فرض اینکه فرانتاند بتواند پابهپای fast-import پیش رود و جریانی مداوم از دادهها را به آن تغذیه کند، زمان واردسازی برای پروژههایی با بیش از ۱۰ سال تاریخچه و حاوی بیش از ۱۰۰٬۰۰۰ کامیت مجزا، معمولاً تنها در ۱ تا ۲ ساعت روی سختافزاری کاملاً متوسط (حدود ۲٬۰۰۰ دلار در سال ۲۰۰۷) به پایان میرسد.
بیشتر گلوگاهها در دسترسی به دادههای مبدأ خارجی (مبدأ صرفاً نمیتواند بازبینیها را به اندازه کافی سریع استخراج کند) یا ورودی/خروجی دیسک (fast-import با همان سرعتی که دیسک دادهها را میپذیرد مینویسد) رخ میدهند. در صورتی که دادههای مبدأ روی درایوی متفاوت از مخزن مقصد گیت ذخیره شده باشند (به دلیل تداخل کمتر در ورودی/خروجی)، فرایند واردسازی سریعتر اجرا خواهد شد.
هزینه توسعه (DEVELOPMENT COST)
یک فرانتاند معمولی برای fast-import معمولاً در حدود ۲۰۰ خط کد Perl/Python/Ruby است. بیشتر توسعهدهندگان توانستهاند تنها در عرض چند ساعت واردکنندههایی کارآمد ایجاد کنند، حتی با وجود اینکه این نخستین مواجهه آنها با fast-import و گاهی حتی با گیت بوده است. با توجه به اینکه بیشتر ابزارهای تبدیل یکبارمصرف هستند (یک بار استفاده میشوند و دیگر به سراغ آنها بازنمیگردند)، این یک وضعیت ایدهآل است.
عملیات موازی (PARALLEL OPERATION)
همانند git push یا git fetch، واردسازیهای مدیریتشده توسط fast-import را میتوان با خیال راحت در کنار فراخوانیهای موازی git repack -a -d یا git gc، یا هر عملیات دیگر گیت (از جمله git prune، زیرا اشیاء شل هرگز توسط fast-import استفاده نمیشوند) اجرا کرد.
ابزار fast-import ارجاعات شاخه یا برچسبی را که فعالانه در حال وارد کردن آنهاست قفل نمیکند. پس از واردسازی، در طول مرحله بهروزرسانی ارجاع، fast-import هر یک از ارجاعات موجود شاخه را بررسی میکند تا مطمئن شود بهروزرسانی از نوع رو به جلو (fast-forward) خواهد بود (کامیت ذخیرهشده در ارجاع در تاریخچه جدید کامیتی که قرار است نوشته شود گنجانده شده باشد). اگر بهروزرسانی از نوع رو به جلو نباشد، fast-import از بهروزرسانی آن ارجاع صرفنظر میکند و در عوض یک پیام هشدار چاپ مینماید. ابزار fast-import همیشه تلاش خواهد کرد تا تمام ارجاعات شاخه را بهروزرسانی کند و با اولین شکست متوقف نمیشود.
بهروزرسانیهای شاخه را میتوان با --force اجبار کرد، اما توصیه میشود که این کار تنها در مخزنی انجام شود که در غیر این صورت آرام و بدون فعالیت دیگر است. استفاده از --force برای واردسازی اولیه در یک مخزن خالی ضروری نیست.
بحث فنی (TECHNICAL DISCUSSION)
ابزار fast-import مجموعهای از شاخهها را در حافظه دنبال میکند. هر شاخهای را میتوان در هر نقطهای از فرایند واردسازی با ارسال دستور commit در جریان ورودی ایجاد یا اصلاح کرد. این طراحی به یک برنامه فرانتاند اجازه میدهد تعداد نامحدودی از شاخهها را به طور همزمان پردازش کند و کامیتها را به ترتیبی که از دادههای مبدأ در دسترس قرار میگیرند تولید نماید. این کار همچنین برنامههای فرانتاند را به میزان قابل توجهی ساده میسازد.
ابزار fast-import از دایرکتوری کاری فعلی یا هر فایلی درون آن استفاده نکرده و آن را تغییر نمیدهد. (با این حال، مخزن فعلی گیت را، همانطور که توسط GIT_DIR ارجاع داده شده، بهروزرسانی میکند.) بنابراین یک فرانتاند واردسازی میتواند از دایرکتوری کاری برای اهداف خود، مانند استخراج بازبینیهای فایل از منبع خارجی استفاده کند. این نادیده گرفتن دایرکتوری کاری همچنین به fast-import امکان میدهد بسیار سریع اجرا شود، زیرا هنگام جابهجایی میان شاخهها نیازی به انجام هیچ عملیات پرهزینه بهروزرسانی فایل ندارد.
قالب ورودی (INPUT FORMAT)
به استثنای دادههای خام فایل (که گیت آنها را تفسیر نمیکند)، قالب ورودی fast-import مبتنی بر متن (ASCII) است. این قالب متنی، توسعه و اشکالزدایی برنامههای فرانتاند را، بهویژه هنگامی که از زبانی سطح بالاتر مانند Perl، Python یا Ruby استفاده میشود، ساده میکند.
ابزار fast-import درباره ورودی خود بسیار سختگیر است. هر جا در زیر SP میگوییم، منظور دقیقاً یک فاصله است. به همین ترتیب LF به معنای یک (و فقط یک) خطشکن (linefeed) و HT به معنای یک (و فقط یک) تب افقی (horizontal tab) است. ارائه نویسههای فضای خالی اضافی باعث نتایج غیرمنتظره خواهد شد، مانند نامهای شاخه یا نامهای فایل با فاصلههای ابتدایی یا انتهایی در نامشان، یا توقف زودهنگام fast-import هنگامی که با ورودی غیرمنتظره روبهرو میشود.
توضیحات جریان (Stream Comments)
به منظور کمک به اشکالزدایی فرانتاندها، fast-import هر خطی را که با # (پوند/هش در ASCII) آغاز شود تا انتهای خط شامل LF نادیده میگیرد. یک خط توضیح میتواند شامل هر دنبالهای از بایتها باشد که شامل LF نباشد و بنابراین میتواند برای گنجاندن هرگونه اطلاعات دقیق اشکالزدایی که ممکن است مختص فرانتاند بوده و هنگام بررسی جریان داده fast-import مفید باشد، استفاده شود.
قالبهای تاریخ (Date Formats)
قالبهای تاریخ زیر پشتیبانی میشوند. یک فرانتاند باید قالبی را که برای این واردسازی به کار خواهد برد، با ارسال نام قالب در گزینه خط فرمان --date-format=<fmt> انتخاب کند.
raw
زمان رویداد توسط <time> به عنوان تعداد ثانیههای سپریشده از مبدأ یونیکس (نیمهشب ۱ ژانویه ۱۹۷۰، ساعت هماهنگ جهانی UTC) مشخص میشود و به صورت یک عدد صحیح دهدهی ASCII نوشته میشود.
اختلاف محلی توسط <offutc> به عنوان اختلاف مثبت یا منفی از UTC مشخص میشود. برای مثال EST (که ۵ ساعت از UTC عقبتر است) در <tz> با “-0500” بیان میشود در حالی که UTC به صورت “+0000” است. اختلاف محلی تأثیری بر <time> نمیگذارد؛ این مقدار صرفاً به عنوان توصیهای برای کمک به روالهای قالببندی جهت نمایش برچسب زمان استفاده میشود.
اگر اختلاف محلی در دادههای مبدأ در دسترس نباشد، از “+0000” یا متداولترین اختلاف محلی استفاده کنید. برای مثال، بسیاری از سازمانها یک مخزن CVS دارند که تاکنون تنها توسط کاربرانی که در همان مکان و منطقه زمانی مستقر بودهاند مورد دسترسی قرار گرفته است. در این حالت میتوان اختلاف معقولی را از UTC فرض کرد.
برخلاف قالب rfc2822، این قالب بسیار سختگیر است. هرگونه تغییر در قالببندی باعث میشود fast-import مقدار را رد کند، و ممکن است برخی بررسیهای صحتسنجی بر روی مقادیر عددی نیز انجام شود.
raw-permissive
rfc2822
یک مقدار نمونه “Tue Feb 6 11:22:18 2007 -0500” است. تجزیهکننده گیت دقیق است، اما کمی سهلگیرانه عمل میکند. این همان تجزیهکنندهای است که توسط git am هنگام اِعمال وصلههای دریافتشده از طریق ایمیل استفاده میشود.
برخی از رشتههای بدشکل ممکن است به عنوان تاریخهای معتبر پذیرفته شوند. در برخی از این موارد گیت همچنان قادر خواهد بود تاریخ صحیح را از رشته بدشکل به دست آورد. همچنین انواعی از رشتههای بدشکل وجود دارند که گیت آنها را اشتباه تجزیه میکند، اما همچنان معتبر تلقی مینماید. رشتههای به شدت بدشکل رد خواهند شد.
برخلاف قالب raw در بالا، اطلاعات منطقه زمانی/اختلاف UTC موجود در رشته تاریخ RFC 2822 برای تنظیم مقدار تاریخ به UTC پیش از ذخیرهسازی استفاده میشود. بنابراین مهم است که این اطلاعات تا حد ممکن دقیق باشند.
اگر دادههای مبدأ از تاریخهایی به سبک RFC 2822 استفاده میکنند، فرانتاند باید اجازه دهد fast-import تجزیه و تبدیل را مدیریت کند (به جای اینکه خودش تلاش کند آن را انجام دهد)، زیرا تجزیهکننده گیت در عمل به خوبی آزموده شده است.
فرانتاندها در صورتی که دادههای مبدأ از قبل از قالب مبدأزمانی یونیکس (UNIX-epoch) استفاده میکنند، یا بتوان آنها را به ارائه تاریخ در آن قالب ترغیب کرد، یا قالب آنها به آسانی به آن قابل تبدیل باشد، باید قالب raw را ترجیح دهند، زیرا هیچ ابهامی در تجزیه وجود ندارد.
now
این یک قالب نمایشی است. زمان و منطقه زمانی فعلی این سیستم همواره در زمان ایجاد توسط fast-import در رشته هویت کپی میشود. هیچ راهی برای مشخص کردن زمان یا منطقه زمانی متفاوت وجود ندارد.
این قالب ویژه از آنجا ارائه شده است که پیادهسازی آن کوتاه است و ممکن است برای فرایندی مفید باشد که میخواهد همین حالا یک کامیت جدید ایجاد کند، بدون نیاز به استفاده از دایرکتوری کاری یا git update-index.
اگر از دستورهای جداگانه author و committer در یک commit استفاده شود، ممکن است برچسبهای زمانی مطابقت نداشته باشند، زیرا ساعت سیستم دو بار (یک بار برای هر دستور) استعلام خواهد شد. تنها راه برای اطمینان از اینکه اطلاعات هویتی هر دو مؤلف و ثبتکننده دارای برچسب زمانی یکسانی باشند، حذف author (و در نتیجه کپی شدن از committer) یا استفاده از یک قالب تاریخ به غیر از now است.
دستورها (COMMANDS)
ابزار fast-import چندین دستور را برای بهروزرسانی مخزن فعلی و کنترل فرایند واردسازی جاری میپذیرد. بحث دقیقتر (همراه با مثالها) درباره هر دستور در ادامه میآید.
commit
tag
reset
blob
alias
checkpoint
progress
done
get-mark
cat-blob
ls
feature
option
commit
یک شاخه را با یک کامیت جدید ایجاد یا بهروزرسانی میکند و یک تغییر منطقی را در پروژه به ثبت میرساند.
'commit' SP <ref> LF
mark?
original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
('gpgsig' SP <algo> SP <format> LF data)?
('encoding' SP <encoding> LF)?
data
('from' SP <commit-ish> LF)?
('merge' SP <commit-ish> LF)*
(filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)*
LF?
که در آن <ref> نام شاخهای است که کامیت روی آن ثبت میشود. معمولاً در گیت نامهای شاخهها دارای پیشوند refs/heads/ هستند، بنابراین برای وارد کردن نشان شاخه CVS یعنی RELENG-1_0، از refs/heads/RELENG-1_0 برای مقدار <ref> استفاده میشود. مقدار <ref> باید یک نام مرجع (refname) معتبر در گیت باشد. از آنجا که LF در نام مرجع گیت مجاز نیست، هیچ نحوی برای نقلقول یا گریز (escape) در اینجا پشتیبانی نمیشود.
دستور mark میتواند به صورت اختیاری درج شود و از fast-import درخواست کند تا یک مرجع به کامیت تازه ایجادشده را برای استفادههای بعدی توسط فرانتاند ذخیره نماید (برای ساختار قالب به بخش زیر مراجعه کنید). بسیار متداول است که فرانتاندها برای هر کامیتی که ایجاد میکنند نشانهای ثبت نمایند، تا امکان ایجاد شاخهها در آینده از هر کامیت واردشده فراهم باشد.
دستور data که پس از committer میآید باید پیام کامیت را ارائه دهد (برای نحوه نگارش دستور data به بخش زیر مراجعه کنید). برای وارد کردن یک پیام کامیت خالی، از دادهای با طول ۰ استفاده کنید. پیامهای کامیت دارای قالبی آزاد هستند و توسط گیت تفسیر نمیشوند. در حال حاضر آنها باید به صورت UTF-8 کدگذاری شوند، چرا که fast-import اجازه تعیین کدگذاریهای دیگر را نمیدهد.
صفر یا چند دستور از دستورات filemodify، filedelete، filecopy، filerename، filedeleteall و notemodify میتوانند برای بهروزرسانی محتویات شاخه پیش از ایجاد کامیت گنجانده شوند. این دستورات را میتوان به هر ترتیبی ارائه داد. با این حال توصیه میشود که در همان کامیت، دستور filedeleteall پیش از تمام دستورات filemodify، filecopy، filerename و notemodify قرار گیرد، زیرا filedeleteall شاخه را کاملاً پاکسازی میکند (بخش زیر را ببینید).
نویسه LF بعد از دستور اختیاری است (پیشتر اجباری بود). توجه داشته باشید که به دلایل سازگاری با نسخههای پیشین، اگر کامیت به یک دستور data ختم شود (یعنی هیچ دستور from، merge، filemodify، filedelete، filecopy، filerename، filedeleteall یا notemodify نداشته باشد)، آنگاه ممکن است به جای یکی، دو دستور LF در انتهای دستور ظاهر شوند.
author
دستور author در صورتی که اطلاعات نویسنده با اطلاعات کامیتکننده متفاوت باشد، میتواند به صورت اختیاری درج شود. اگر author حذف شود، fast-import به طور خودکار از اطلاعات ثبتکننده (committer) برای بخش نویسنده کامیت استفاده خواهد کرد. برای شرح فیلدهای موجود در author به بخش زیر مراجعه کنید، زیرا این فیلدها با committer یکسان هستند.
committer
دستور committer مشخص میکند چه کسی این کامیت را ایجاد کرده و چه زمانی آن را ثبت نموده است.
در اینجا <name> نام نمایشی شخص (به عنوان مثال “Com M Itter”) و <email> نشانی ایمیل شخص (“cm@example.com”) است. LT و GT نمادهای عینی کوچکتری (\x3c) و بزرگتری (\x3e) هستند. وجود این نمادها برای تفکیک نشانی ایمیل از سایر فیلدهای درون خط الزامی است. توجه داشته باشید که <name> و <email> آزادقالب بوده و میتوانند حاوی هر دنبالهای از بایتها به جز LT، GT و LF باشند. <name> معمولاً دارای کدگذاری UTF-8 است.
زمان اعمال تغییر توسط <when> و با استفاده از قالب تاریخی که از طریق گزینه خط فرمان --date-format=<fmt> انتخاب شده است، مشخص میشود. برای مجموعه قالبهای پشتیبانیشده و نحوه نگارش آنها، بخش “Date Formats” (قالبهای تاریخ) در بالا را ببینید.
gpgsig
دستور اختیاری gpgsig برای گنجاندن یک امضای PGP/GPG یا سایر امضاهای رمزنگاریشده که دادههای کامیت را امضا میکنند استفاده میشود.
'gpgsig' SP <git-hash-algo> SP <signature-format> LF data
دستور gpgsig دو آرگومان میگیرد:
یک کامیت میتواند حداکثر یک امضا برای قالب شیء SHA-1 (ذخیرهشده در سرایند "gpgsig") و یک امضا برای قالب شیء SHA-256 (ذخیرهشده در سرایند "gpgsig-sha256") داشته باشد.
برای شرح مفصل دستور data که حاوی دادههای خام امضا است، بخش زیر را ببینید.
با این حال، در پیادهسازی فعلی امضاها هنوز بررسی نمیشوند. (تنظیم اولیه گزینه پیکربندی extensions.compatObjectFormat ممکن است در زمان پیادهسازی این ویژگی، به اعتبارسنجی امضاهای هر دو قالب شیء SHA-1 و SHA-256 کمک نماید.)
یادداشت
این قابلیت بسیار آزمایشی است و قالب دستور gpgsig ممکن است در آینده بدون هیچ تضمینی برای سازگاری تغییر کند.
encoding
دستور اختیاری encoding کدگذاری پیام کامیت را مشخص میکند. بیشتر کامیتها UTF-8 هستند و کدگذاری ذکر نمیشود، اما این دستور اجازه میدهد پیامهای کامیت بدون نیاز به کدگذاری مجدد اولیه وارد گیت شوند.
from
دستور from برای تعیین کامیتی استفاده میشود که این شاخه باید از آن مقداردهی اولیه شود. این بازنگری، اولین نیا (اجداد) کامیت جدید خواهد بود. وضعیت درخت ساختهشده در این کامیت با وضعیت موجود در کامیت from آغاز میشود و با اصلاحات محتوایی موجود در این کامیت تغییر مییابد.
حذف دستور from در اولین کامیت یک شاخه جدید باعث میشود که fast-import آن کامیت را بدون هیچ نیایی ایجاد کند. این حالت معمولاً فقط برای کامیت اولیه یک پروژه مطلوب است. اگر فرانتاند هنگام ایجاد یک شاخه جدید همه فایلها را از ابتدا ایجاد کند، میتوان به جای from از دستور merge استفاده نمود تا کامیت با یک درخت خالی آغاز شود. در شاخههای موجود، معمولاً صرفنظر کردن از دستور from مطلوب است، زیرا کامیت فعلی روی آن شاخه به طور خودکار به عنوان اولین نیا کامیت جدید فرض میشود.
از آنجا که LF در نام مرجع یا عبارت SHA-1 گیت مجاز نیست، هیچ نحوی برای نقلقول یا گریز در درون <commit-ish> پشتیبانی نمیشود.
در اینجا <commit-ish> هر یک از موارد زیر است:
دلیل اینکه fast-import از : برای مشخص کردن ارجاع نشان استفاده میکند این است که این نویسه در نام شاخههای گیت مجاز نیست. نویسه پیشین : تفکیک میان نشان ۴۲ (:42) و شاخه ۴۲ (42 یا refs/heads/42)، یا یک SHA-1 خلاصهشده که تصادفاً تنها از ارقام مبنای ۱۰ تشکیل شده را آسان میسازد.
نشانها باید قبل از اینکه مورد استفاده قرار گیرند، (از طریق mark) اعلان شوند.
حالت خاص شروع مجدد یک واردسازی افزایشی از مقدار شاخه فعلی باید به این صورت نوشته شود:
from refs/heads/branch^0
پسوند ^0 ضروری است زیرا fast-import اجازه نمیدهد که یک شاخه از خودش شروع شود، و شاخه حتی قبل از اینکه دستور from از ورودی خوانده شود در حافظه ایجاد میگردد. افزودن ^0 باعث میشود fast-import کامیت را از طریق کتابخانه تجزیه بازنگری گیت حل کند، نه جدول شاخههای داخلی خود، و بدین ترتیب مقدار موجود شاخه بارگذاری شود.
merge
یک کامیت نیا (اجداد) اضافی را در بر میگیرد. پیوند نیاکانی اضافی، نحوه ساخت وضعیت درخت در این کامیت را تغییر نمیدهد. اگر هنگام ایجاد یک شاخه جدید دستور from حذف شود، اولین کامیت merge به عنوان نخستین نیا کامیت فعلی در نظر گرفته خواهد شد و شاخه بدون هیچ فایلی کار خود را آغاز میکند. تعداد نامحدودی از دستورات merge به ازای هر کامیت توسط fast-import مجاز است و بدین ترتیب یک ادغام چندطرفه (n-way merge) ایجاد میشود.
در اینجا <commit-ish> هر یک از عبارتهای تعیین کامیت است که توسط from نیز پذیرفته میشوند (بخش بالا را ببینید).
filemodify
در یک دستور commit برای افزودن فایلی جدید یا تغییر محتوای فایلی موجود گنجانده میشود. این دستور دو روش مختلف برای مشخص کردن محتوای فایل دارد.
قالب داده خارجی (External data format)
'M' SP <mode> SP <dataref> SP <path> LF
در اینجا معمولاً <dataref> باید یا یک ارجاع نشان (:<idnum>) باشد که توسط یک دستور قبلی blob تنظیم شده است، یا SHA-1 کامل ۴۰ بایتی از یک شیء blob موجود در گیت. اگر <mode> برابر با 040000 باشد، آنگاه <dataref> باید SHA-1 کامل ۴۰ بایتی از یک شیء درختی (tree) موجود در گیت یا یک ارجاع نشان تنظیمشده با --import-marks باشد.
قالب داده درونخطی (Inline data format)
'M' SP <mode> SP 'inline' SP <path> LF data
برای شرح تفصیلی دستور data به ادامه متن در زیر مراجعه کنید.
در هر دو قالب، <mode> نوع مدخل فایل است که در مبنای هشت (اکتال) مشخص میشود. گیت تنها از حالتهای زیر پشتیبانی میکند:
در هر دو قالب، <path> مسیر کامل فایلی است که باید اضافه شود (اگر از قبل وجود ندارد) یا تغییر یابد (اگر از قبل وجود دارد).
یک <path> میتواند به صورت بایتهای بدون نقلقول یا یک رشته نقلقولشده به سبک C نوشته شود.
هنگامی که یک <path> با یک علامت نقلقول دوتایی (") آغاز نمیشود، یک رشته بدون نقلقول است و به صورت بایتهای لفظی بدون هیچ دنباله گریزی تجزیه میشود. با این حال، اگر نام فایل شامل LF باشد یا با علامت نقلقول دوتایی آغاز شود، نمیتوان آن را به عنوان یک رشته بدون نقلقول نمایش داد و باید در نقلقول قرار گیرد. علاوه بر این، مسیر مبدأ <path> در filecopy یا filerename در صورتی که شامل SP باشد باید در نقلقول قرار گیرد.
هنگامی که یک <path> با یک علامت نقلقول دوتایی (") آغاز میشود، یک رشته نقلقولشده به سبک C است، که در آن نام کامل فایل در یک جفت علامت نقلقول دوتایی محصور شده و از دنبالههای گریز استفاده میشود. برخی نویسهها باید با قرار دادن یک بکاسلش پیش از آنها گریز داده شوند: LF به صورت \n، بکاسلش به صورت \\، و علامت نقلقول دوتایی به صورت \" نوشته میشود. برخی نویسهها را میتوان به صورت اختیاری با دنبالههای گریز نوشت: \a برای زنگ (bell)، \b برای پسبر (backspace)، \f برای برگهخور (form feed)، \n برای سطر جدید (line feed)، \r برای بازگشت به ابتدای سطر (carriage return)، \t برای تب افقی، و \v برای تب عمودی. هر بایتی را میتوان با کدهای اکتال ۳ رقمی نوشت (مانند \033). تمام نامهای فایل را میتوان به صورت رشتههای نقلقولشده نمایش داد.
یک <path> باید از جداکنندههای دایرکتوری به سبک یونیکس (اسلش رو به جلو /) استفاده کند و مقدار آن باید به شکل متعارف (canonical) باشد. به این معنی که نباید:
ریشه درخت را میتوان با یک رشته خالی به عنوان <path> نمایش داد.
یک <path> نمیتواند شامل NUL باشد، چه به صورت لفظی و چه به صورت گریزیافته مانند \000. توصیه میشود که <path> همواره با استفاده از UTF-8 کدگذاری شود.
filedelete
در یک دستور commit برای حذف یک فایل یا حذف بازگشتی یک دایرکتوری کامل از شاخه گنجانده میشود. چنانچه حذف فایل یا دایرکتوری موجب خالی شدن دایرکتوری والد آن شود، دایرکتوری والد نیز بهطور خودکار حذف خواهد شد. این فرایند بهصورت آبشاری در ساختار درختی به سمت بالا ادامه مییابد تا به نخستین دایرکتوری غیرخالی یا به ریشه برسد.
'D' SP <path> LF
در اینجا <path> مسیر کامل فایل یا زیردایرکتوری است که باید از شاخه حذف شود. برای شرح تفصیلی <path>، به filemodify در بالا مراجعه کنید.
filecopy
یک فایل یا زیردایرکتوری موجود را بهصورت بازگشتی به مکانی دیگر درون شاخه رونوشت (کپی) میکند. فایل یا دایرکتوری مبدأ باید از قبل وجود داشته باشد. اگر مقصد وجود داشته باشد، محتوای رونوشتشده از مبدأ بهطور کامل جایگزین آن خواهد شد.
'C' SP <path> SP <path> LF
در اینجا نخستین <path> مکان مبدأ و دومین <path> مقصد است. برای شرح تفصیلی آنچه که <path> میتواند باشد، به filemodify در بالا مراجعه کنید. برای استفاده از مسیر مبدأیی که حاوی فاصله (SP) است، مسیر باید در علامت نقلقول قرار گیرد.
دستور filecopy بلافاصله اعمال میشود. پس از رونوشت مکان مبدأ به مقصد، هر دستور دیگری که در ادامه روی مکان مبدأ اعمال شود، هیچ تأثیری بر مقصد رونوشت نخواهد داشت.
filerename
نام یک فایل یا زیردایرکتوری موجود را تغییر داده و به مکانی دیگر درون شاخه منتقل میکند. فایل یا دایرکتوری مبدأ باید از قبل وجود داشته باشد. اگر مقصد وجود داشته باشد، با دایرکتوری مبدأ جایگزین خواهد شد.
'R' SP <path> SP <path> LF
در اینجا نخستین <path> مکان مبدأ و دومین <path> مقصد است. برای شرح تفصیلی آنچه که <path> میتواند باشد، به filemodify در بالا مراجعه کنید. برای استفاده از مسیر مبدأیی که حاوی فاصله (SP) است، مسیر باید در علامت نقلقول قرار گیرد.
دستور filerename بلافاصله اعمال میشود. پس از تغییر نام مکان مبدأ به مقصد، هر دستور دیگری که در ادامه روی مکان مبدأ اعمال شود فایلهای جدیدی در آنجا ایجاد خواهد کرد و تأثیری بر مقصد تغییر نام نخواهد داشت.
توجه داشته باشید که filerename همانند یک filecopy و به دنبال آن یک filedelete روی مکان مبدأ است. استفاده از filerename مزیت عملکردی اندکی دارد، اما این مزیت به قدری ناچیز است که هرگز ارزش تلاش برای تبدیل یک جفت حذف/افزودن در محتوای مبدأ به تغییر نام را برای fast-import ندارد. این دستور filerename صرفاً برای سهولت فرانتآندهایی ارائه شده است که در حال حاضر اطلاعات تغییر نام را در اختیار دارند و نمیخواهند خود را با تجزیه آن به یک filecopy و به دنبال آن یک filedelete به زحمت بیندازند.
filedeleteall
در یک دستور commit برای حذف تمام فایلها (و همچنین تمام دایرکتوریها) از شاخه گنجانده میشود. این دستور ساختار داخلی شاخه را بازنشانی میکند تا هیچ فایلی درون آن نباشد، و به فرانتاند امکان میدهد که متعاقباً تمام فایلهای مد نظر را از ابتدا اضافه کند.
'deleteall' LF
این دستور در صورتی بسیار مفید است که فرانتاند نداند (یا اهمیتی ندهد که بداند) در حال حاضر چه فایلهایی روی شاخه وجود دارند، و بنابراین نتواند دستورات مناسب filedelete را برای بهروزرسانی محتوا تولید کند.
صادر کردن یک دستور filedeleteall و به دنبال آن دستورات لازم filemodify برای تنظیم محتوای صحیح، همان نتایجی را ایجاد میکند که ارسال صرفاً دستورات مورد نیاز filemodify و filedelete به همراه دارد. با این حال، رویکرد filedeleteall ممکن است fast-import را وادار کند به ازای هر شاخه فعال حافظه کمی بیشتر (کمتر از ۱ مبیبایت حتی برای اکثر پروژههای بزرگ) مصرف کند؛ بنابراین به فرانتآندهایی که میتوانند بهراحتی فقط مسیرهای تحت تأثیر یک کامیت را به دست آورند، توصیه میشود که از آن روش استفاده کنند.
notemodify
در یک دستور commit <notes-ref> برای افزودن یک یادداشت جدید جهت حاشیهنویسی یک <commit-ish> یا تغییر محتوای این حاشیهنویسی گنجانده میشود. از نظر داخلی، این دستور مشابه filemodify 100644 روی مسیر <commit-ish> است (که ممکن است به زیردایرکتوریهایی تقسیم شود). توصیه نمیشود از هیچ دستور دیگری برای نوشتن روی درخت <notes-ref> استفاده کنید مگر filedeleteall برای حذف تمام یادداشتهای موجود در این درخت. این دستور دو شیوه متفاوت برای مشخص کردن محتوای یادداشت دارد.
قالب داده خارجی
'N' SP <dataref> SP <commit-ish> LF
در اینجا <dataref> میتواند یک ارجاع نشانگر (:<idnum>) باشد که توسط یک دستور پیشین blob تنظیم شده است، یا یک هش کامل ۴۰ بایتی SHA-1 از یک شیء بلاب موجود در گیت.
قالب داده درونخطی
'N' SP 'inline' SP <commit-ish> LF data
برای شرح تفصیلی دستور data به پایین مراجعه کنید.
در هر دو قالب، <commit-ish> هر یک از عبارات مشخصکننده کامیت است که توسط from نیز پذیرفته میشود (به بالا مراجعه کنید).
mark
ترتیبی میدهد تا fast-import ارجاعی به شیء فعلی را ذخیره کند، و به فرانتاند اجازه میدهد در آینده بدون دانستن SHA-1 این شیء، آن را فراخوانی کند. در اینجا شیء فعلی همان دستور ایجاد شیئی است که دستور mark درون آن ظاهر شده است. این شیء میتواند commit، tag، و blob باشد، اما commit رایجترین مورد استفاده است.
'mark' SP ':' <idnum> LF
که در آن <idnum> عددی است که توسط فرانتاند به این نشان (mark) اختصاص داده شده است. مقدار <idnum> به صورت یک عدد صحیح دهدهی ASCII بیان میشود. مقدار 0 رزرو شده است و نمیتواند به عنوان یک نشان استفاده شود. تنها مقادیر بزرگتر یا مساوی با 1 میتوانند به عنوان نشان استفاده شوند.
نشانهای جدید به طور خودکار ایجاد میشوند. نشانهای موجود را میتوان به سادگی با استفاده مجدد از همان <idnum> در یک دستور mark دیگر، به شیء دیگری منتقل کرد.
original-oid
نام شیء در سامانه کنترل نسخهٔ اصلی را ارائه میدهد. ابزار fast-import به سادگی این دستورالعمل را نادیده میگیرد، اما فرایندهای پالایشی (فیلتر) که پیش از ارسال به fast-import روی جریان داده کار کرده و آن را اصلاح میکنند، ممکن است از این اطلاعات بهره ببرند.
'original-oid' SP <object-identifier> LF
که در آن <object-identifier> هر رشتهای است که شامل LF نباشد.
tag
یک برچسب یادداشتدار با ارجاع به یک کامیت مشخص ایجاد میکند. برای ایجاد برچسبهای سبک (غیر یادداشتدار)، دستور reset در زیر را ببینید.
'tag' SP <name> LF mark? 'from' SP <commit-ish> LF original-oid? 'tagger' (SP <name>)? SP LT <email> GT SP <when> LF data
که در آن <name> نام برچسبی است که باید ایجاد شود.
نامهای برچسب هنگام ذخیره در گیت به طور خودکار با پیشوند refs/tags/ ذخیره میشوند، بنابراین وارد کردن نماد شاخه CVS به نام RELENG-1_0-FINAL فقط از RELENG-1_0-FINAL برای <name> استفاده میکند، و fast-import ارجاع متناظر را به صورت refs/tags/RELENG-1_0-FINAL مینویسد.
مقدار <name> باید یک refname معتبر در گیت باشد و بنابراین ممکن است شامل اسلش روبهجلو (forward slash) باشد. از آنجا که LF در یک refname گیت معتبر نیست، هیچ نحو نقلقول یا گریزی در اینجا پشتیبانی نمیشود.
دستور from همانند دستور commit است؛ برای جزئیات به بخش بالا مراجعه کنید.
دستور tagger از قالبی مشابه با committer در درون commit استفاده میکند؛ مجدداً برای جزئیات به بخش بالا مراجعه کنید.
دستور data پس از tagger باید پیام برچسب یادداشتدار را فراهم کند (برای نحو دستور data به بخش زیر مراجعه کنید). برای وارد کردن پیام برچسب خالی از دادهای با طول 0 استفاده کنید. پیامهای برچسب قالب آزاد دارند و توسط گیت تفسیر نمیشوند. در حال حاضر آنها باید با کدگذاری UTF-8 کدبندی شوند، زیرا fast-import اجازه تعیین سایر کدگذاریها را نمیدهد.
امضای برچسبهای یادداشتدار در حین واردسازی از درون fast-import پشتیبانی نمیشود. تلاش برای گنجاندن امضای PGP/GPG خودتان توصیه نمیشود، زیرا فرانتاند (به سادگی) به مجموعه کامل بایتهایی که معمولاً در چنین امضایی قرار میگیرند دسترسی ندارد. اگر امضا کردن لازم است، برچسبهای سبک را از درون fast-import با استفاده از reset ایجاد کنید، سپس نسخههای یادداشتدار آن برچسبها را به صورت برونخط (آفلاین) با فرایند استاندارد git tag ایجاد کنید.
reset
شاخهٔ نامگذاریشده را ایجاد (یا بازسازی) میکند، که به صورت اختیاری از یک بازنگری (revision) خاص شروع میشود. دستور reset به فرانتاند امکان میدهد یک دستور from جدید را برای یک شاخهٔ موجود صادر کند، یا یک شاخه جدید از یک کامیت موجود بدون ایجاد یک کامیت جدید بسازد.
'reset' SP <ref> LF
('from' SP <commit-ish> LF)?
LF?
برای توضیحات تفصیلی درباره <ref> و <commit-ish>، بخش بالا تحت عنوان commit و from را ببینید.
نویسه LF پس از دستور اختیاری است (قبلاً الزامی بود).
دستور reset همچنین میتواند برای ایجاد برچسبهای سبک (غیر یادداشتدار) استفاده شود. برای نمونه:
reset refs/tags/938 from :938
برچسب سبک refs/tags/938 را ایجاد میکند که به هر کامیتی ارجاع دارد که نشان :938 به آن اشاره میکند.
blob
درخواست نوشتن یک بازنگری فایل در packfile را میدهد. این بازنگری به هیچ کامیتی متصل نیست؛ این اتصال باید در دستور بعدی commit با ارجاع به blob از طریق یک نشان اختصاصیافته برقرار شود.
'blob' LF mark? original-oid? data
دستور mark در اینجا اختیاری است چرا که برخی فرانتاندها تصمیم گرفتهاند SHA-1 گیت را برای blob خودشان تولید کنند و آن را مستقیماً به commit تحویل دهند. با این حال این کار معمولاً زحمتی بیشتر از ارزشش دارد، چرا که ذخیرهسازی نشانها کمهزینه و استفاده از آنها آسان است.
data
دادههای خام (برای استفاده به عنوان محتوای blob/فایل، پیامهای کامیت، یا پیامهای برچسب یادداشتدار) را در اختیار fast-import قرار میدهد. دادهها را میتوان با استفاده از تعداد دقیق بایت یا با تحدید توسط یک خط پایانی ارائه کرد. فرانتآندهای واقعی که برای تبدیلهای در سطح تولید (production) در نظر گرفته شدهاند باید همیشه از قالب تعداد دقیق بایت استفاده کنند، زیرا این روش پایدارتر است و عملکرد بهتری دارد. قالب تحدیدشده عمدتاً برای آزمایش fast-import در نظر گرفته شده است.
خطوط توضیحی که درون بخش <raw> از دستورات data ظاهر میشوند، همواره به عنوان بخشی از بدنه داده در نظر گرفته میشوند و بنابراین هرگز توسط fast-import نادیده گرفته نمیشوند. این ویژگی وارد کردن هرگونه محتوای فایل/پیامی را که خطوط آن ممکن است با # شروع شود، امن میسازد.
قالب تعداد دقیق بایت
'data' SP <count> LF <raw> LF?
که در آن <count> تعداد دقیق بایتهای ظاهرشده در درون <raw> است. مقدار <count> به صورت یک عدد صحیح دهدهی ASCII بیان میشود. نویسه LF در هر دو طرف <raw> در <count> محاسبه نمیشود و در دادههای واردشده گنجانده نخواهد شد.
نویسه LF پس از <raw> اختیاری است (قبلاً الزامی بود) اما توصیه میشود. گنجاندن همیشگی آن، اشکالزدایی جریان fast-import را آسانتر میکند زیرا دستور بعدی همیشه در ستون ۰ از خط بعدی آغاز میشود، حتی اگر <raw> با یک LF پایان نیافته باشد.
قالب تحدیدشده
'data' SP '<<' <delim> LF <raw> LF <delim> LF LF?
که در آن <delim> رشته جداکننده انتخابشده است. رشته <delim> نباید به تنهایی در یک خط درون <raw> ظاهر شود، زیرا در غیر این صورت fast-import تصور میکند که دادهها زودتر از آنچه در واقعیت است پایان یافتهاند. نویسه LF بلافاصله پس از <raw> بخشی از <raw> است. این یکی از محدودیتهای قالب تحدیدشده است؛ ارسال تکه دادهای که آخرین بایت آن LF نباشد، غیرممکن است.
نویسه LF پس از <delim> LF اختیاری است (قبلاً الزامی بود).
alias
ثبت میکند که یک نشان به یک شیء معین ارجاع میدهد، بدون اینکه ابتدا شیء جدیدی ایجاد شود.
'alias' LF mark 'to' SP <commit-ish> LF LF?
برای توضیحات تفصیلی درباره <commit-ish>، بخش بالا تحت عنوان from را ببینید.
checkpoint
دستور fast-import را مجبور میکند تا packfile فعلی را ببندد، یک packfile جدید آغاز کند، و تمام ارجاعهای شاخه، برچسبها و نشانهای فعلی را ذخیره نماید.
'checkpoint' LF LF?
توجه داشته باشید که وقتی packfile فعلی به --max-pack-size یا 4 GiB (هر کدام که محدودیت کمتری باشد) میرسد، fast-import به طور خودکار packfile را تعویض میکند. در طول یک تعویض خودکار packfile، دستور fast-import ارجاعهای شاخه، برچسبها یا نشانها را بهروزرسانی نمیکند.
از آنجا که یک checkpoint میتواند به مقدار قابل توجهی زمان پردازنده (CPU) و ورودی/خروجی دیسک (برای محاسبه جمع کنترلی کلی SHA-1 بسته، تولید فایل نمایه (index) متناظر، و بهروزرسانی ارجاعها) نیاز داشته باشد، تکمیل یک دستور checkpoint منفرد میتواند به راحتی چندین دقیقه به طول بینجامد.
فرانتاندها ممکن است ترجیح دهند در طول واردسازیهای بسیار بزرگ و طولانی، یا زمانی که نیاز دارند به یک فرایند گیت دیگر اجازه دسترسی به یک شاخه را بدهند، دستورهای checkpoint را صادر کنند. با این حال، با توجه به اینکه یک مخزن ۳۰ گیبیبایتی (30 GiB) از Subversion را میتوان از طریق fast-import در حدود ۳ ساعت در گیت بارگذاری کرد، ایجاد نقطه بازرسی (checkpointing) صریح ممکن است ضروری نباشد.
نویسه LF پس از دستور اختیاری است (قبلاً الزامی بود).
progress
باعث میشود که fast-import کل خط progress را بدون تغییر در کانال خروجی استاندارد خود (توصیفکننده پرونده ۱) هنگامی که دستور از جریان ورودی پردازش میشود، چاپ کند. این دستور در غیر این صورت هیچ تأثیری بر درونریزی فعلی یا هیچیک از وضعیتهای داخلی fast-import ندارد.
'progress' SP <any> LF LF?
بخش <any> از دستور میتواند شامل هر دنبالهای از بایتها باشد که حاوی LF نباشد. نویسه LF پس از دستور اختیاری است. فراخوانندگان ممکن است بخواهند خروجی را از طریق ابزاری مانند sed پردازش کنند تا بخش آغازین خط حذف شود، برای مثال:
frontend | git fast-import | sed 's/^progress //'
قرار دادن دستور progress بلافاصله پس از یک checkpoint به خواننده اطلاع میدهد که چه زمانی checkpoint تکمیل شده است و میتواند با اطمینان به مراجعی (refs) که fast-import بهروزرسانی کرده دسترسی پیدا کند.
get-mark
باعث میشود که fast-import مقدار SHA-1 متناظر با یک نشان را در stdout یا در توصیفکننده پروندهای که قبلاً با آرگومان --cat-blob-fd تنظیم شده است، چاپ کند. این دستور در غیر این صورت هیچ تأثیری بر درونریزی فعلی ندارد؛ هدف آن بازیابی SHA-1هایی است که کامیتهای بعدی ممکن است بخواهند در پیامهای کامیت خود به آنها ارجاع دهند.
'get-mark' SP ':' <idnum> LF
برای جزئیات درباره نحوه خواندن ایمن این خروجی، بخش “پاسخها به دستورات (Responses To Commands)” در ادامه را ببینید.
cat-blob
باعث میشود که fast-import یک بلاب (blob) را در توصیفکننده پروندهای که قبلاً با آرگومان --cat-blob-fd تعیین شده است، چاپ کند. این دستور در غیر این صورت هیچ تأثیری بر درونریزی فعلی ندارد؛ هدف اصلی آن بازیابی بلابهایی است که ممکن است در حافظه fast-import باشند اما از مخزن مقصد قابل دسترسی نباشند.
'cat-blob' SP <dataref> LF
مقدار <dataref> میتواند یک ارجاع نشان (:<idnum>) باشد که قبلاً تنظیم شده است، یا یک SHA-1 کامل ۴۰ بایتی از یک شیء بلاب گیت باشد، چه از قبل موجود بوده و چه آماده نوشته شدن باشد.
خروجی از همان قالب git cat-file --batch استفاده میکند:
<sha1> SP 'blob' SP <size> LF <contents> LF
این دستور میتواند در جایی که یک دستورالعمل filemodify ظاهر میشود استفاده شود، که اجازه میدهد در میانه یک کامیت به کار رود. برای یک filemodify با استفاده از یک دستورالعمل درونخطی، میتواند درست پیش از دستورالعمل data نیز ظاهر شود.
برای جزئیات درباره نحوه خواندن ایمن این خروجی، بخش “پاسخها به دستورات (Responses To Commands)” در ادامه را ببینید.
ls
اطلاعات مربوط به شیء موجود در یک مسیر را در توصیفکننده پروندهای که قبلاً با آرگومان --cat-blob-fd تعیین شده است، چاپ میکند. این امر چاپ یک بلاب از کامیت فعال (با cat-blob) یا نسخهبرداری از یک بلاب یا درخت از کامیت قبلی برای استفاده در کامیت فعلی (با filemodify) را امکانپذیر میسازد.
دستور ls همچنین میتواند در جایی که یک دستورالعمل filemodify ظاهر میشود استفاده شود، که اجازه میدهد در میانه یک کامیت به کار رود.
خواندن از کامیت فعال
'ls' SP <path> LF
خواندن از یک درخت نامگذاریشده
'ls' SP <dataref> SP <path> LF
برای شرح مفصل <path>، دستور filemodify در بالا را ببینید.
خروجی از همان قالب git ls-tree <tree> -- <path> استفاده میکند:
<mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
مقدار <dataref> نمایانگر شیء بلاب، درخت یا کامیت در <path> است و میتواند در دستورات بعدی get-mark، cat-blob، filemodify یا ls استفاده شود.
اگر هیچ فایل یا زیردرختی در آن مسیر وجود نداشته باشد، git fast-import در عوض گزارش میدهد:
missing SP <path> LF
برای جزئیات درباره نحوه خواندن ایمن این خروجی، بخش “پاسخها به دستورات (Responses To Commands)” در ادامه را ببینید.
feature
الزام میکند که fast-import از ویژگی مشخصشده پشتیبانی کند، وگرنه عملیات را لغو (abort) میکند.
'feature' SP <feature> ('=' <argument>)? LF
بخش <feature> از دستور میتواند هر یک از موارد زیر باشد:
date-format, export-marks, relative-marks, no-relative-marks, force
import-marks, import-marks-if-exists
get-mark, cat-blob, ls
notes
done
option
گزینه مشخصشده را طوری پردازش میکند که git fast-import مطابق با نیازهای فرانتاند رفتار کند. توجه داشته باشید گزینههایی که توسط فرانتاند مشخص میشوند، با هر گزینهای که کاربر ممکن است به خودِ git fast-import ارسال کند لغو و بازنویسی میشوند.
'option' SP <option> LF
بخش <option> از دستور میتواند شامل هر یک از گزینههای فهرستشده در بخش OPTIONS باشد که معناشناسی درونریزی را تغییر نمیدهند، بدون پیشوند --، و به همان شیوه با آن رفتار میشود.
دستورات option باید نخستین دستورات در ورودی باشند (بدون در نظر گرفتن دستورات feature)؛ فرستادن یک دستور option پس از هر دستور غیر از گزینه یک خطا است.
گزینههای خط فرمان زیر، معناشناسی درونریزی را تغییر میدهند و بنابراین نباید به عنوان option فرستاده شوند:
done
اگر ویژگی done در حال استفاده نباشد، طوری رفتار میشود که گویی EOF خوانده شده است. این میتواند برای آگاه ساختن fast-import به پایان زودهنگام استفاده شود.
اگر گزینه خط فرمان --done یا دستور feature done در حال استفاده باشد، دستور done الزامی است و نشاندهنده پایان جریان است.
پاسخها به دستورات (RESPONSES TO COMMANDS)
اشیاء جدید نوشتهشده توسط fast-import فوراً در دسترس نیستند. بیشتر دستورات fast-import تا نقطه بررسی (یا تکمیل) بعدی، هیچ تأثیر قابلمشاهدهای ندارند. فرانتاند میتواند بدون نگرانی از اینکه دستورات با چه سرعتی اعمال میشوند، آنها را برای پر کردن لوله ورودی fast-import ارسال کند که با سادهسازی زمانبندی، کارایی را بهبود میبخشد.
با این حال، برای برخی از فرانتاندها، خواندن مجدد دادهها از مخزن فعلی همزمان با بهروزرسانی آن مفید است (برای نمونه زمانی که محتوای منبع، اشیاء را بر اساس وصلههایی توصیف میکند که باید بر روی اشیاء واردشده پیشین اعمال شوند). این کار را میتوان با اتصال فرانتاند و fast-import از طریق لولههای دوطرفه انجام داد:
mkfifo fast-import-output frontend <fast-import-output | git fast-import >fast-import-output
فرانتاَندی که بدین صورت راهاندازی شده است، میتواند از دستورات progress، get-mark، ls و cat-blob برای خواندن اطلاعات از فرآیند واردسازیِ در حال انجام استفاده کند.
برای جلوگیری از بنبست (deadlock)، چنین فرانتاندهایی باید پیش از انجام عملیات نوشتن در fast-import که ممکن است مسدودکننده (blocking) باشند، تمام خروجیهای معلقِ progress، ls، get-mark و cat-blob را بهطور کامل مصرف کنند (بخوانند).
گزارشهای خرابی (CRASH REPORTS)
چنانچه ورودی نامعتبری به fast-import داده شود، با یک وضعیت خروج غیرصفر خاتمه مییابد و یک گزارش خرابی در بالاترین سطح مخزن گیت که در حال واردسازی به آن بود ایجاد میکند. گزارشهای خرابی شامل یک تصویر لحظهای (snapshot) از وضعیت داخلی fast-import و همچنین تازهترین دستوراتی هستند که منجر به خرابی شدهاند.
تمام دستورات اخیر (شامل توضیحات جریان، تغییرات فایل و دستورات پیشرفت) در تاریخچه دستورات درون گزارش خرابی نمایش داده میشوند، اما دادههای خام فایل و پیامهای کامیت از گزارش خرابی مستثنی هستند. این حذف و استثنا در فضای فایل گزارش صرفهجویی میکند و مقدار بافرینگی را که fast-import باید در حین اجرا انجام دهد کاهش میدهد.
پس از نوشتن یک گزارش خرابی، fast-import بستهِ بستهبندی (packfile) فعلی را میبندد و جدول نشانها (marks table) را صادر میکند. این امر به توسعهدهنده فرانتاند اجازه میدهد تا وضعیت مخزن را بررسی کرده و واردسازی را از نقطهای که دچار خرابی شده از سر بگیرد. شاخهها و برچسبهای تغییریافته در حین خرابی بهروزرسانی نمیشوند، زیرا واردسازی با موفقیت پایان نیافته است. اطلاعات شاخه و برچسب را میتوان در گزارش خرابی یافت و در صورت نیاز به بهروزرسانی، باید بهصورت دستی اعمال شوند.
یک نمونه خرابی:
$ cat >in <<END_OF_INPUT # my very first test commit commit refs/heads/master committer Shawn O. Pearce <spearce> 19283 -0400 # who is that guy anyway? data <<EOF this is my commit EOF M 644 inline .gitignore data <<EOF .gitignore EOF M 777 inline bob END_OF_INPUT
$ git fast-import <in fatal: Corrupt mode: M 777 inline bob fast-import: dumping crash report to .git/fast_import_crash_8434
$ cat .git/fast_import_crash_8434
fast-import crash report:
fast-import process: 8434
parent process : 1391
at Sat Sep 1 00:58:12 2007
fatal: Corrupt mode: M 777 inline bob
Most Recent Commands Before Crash --------------------------------- # my very first test commit commit refs/heads/master committer Shawn O. Pearce <spearce> 19283 -0400 # who is that guy anyway? data <<EOF M 644 inline .gitignore data <<EOF * M 777 inline bob
Active Branch LRU
-----------------
active_branches = 1 cur, 5 max
pos clock name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1) 0 refs/heads/master
Inactive Branches ----------------- refs/heads/master: status : active loaded dirty tip commit : 0000000000000000000000000000000000000000 old tree : 0000000000000000000000000000000000000000 cur tree : 0000000000000000000000000000000000000000 commit clock: 0 last pack :
------------------- END OF CRASH REPORT
نکات و ترفندها (TIPS AND TRICKS)
نکات و ترفندهای زیر از کاربران گوناگون fast-import گردآوری شدهاند و در اینجا به عنوان پیشنهاد ارائه میشوند.
استفاده از یک نشان در هر کامیت (Use One Mark Per Commit)
هنگام انجام تبدیل یک مخزن، به ازای هر کامیت از یک نشان یکتا (mark :<n>) استفاده کرده و گزینه --export-marks را در خط فرمان مشخص کنید. fast-import فایلی را تخلیه (dump) خواهد کرد که هر نشان و شناسه شیء SHA-1 گیت مربوط به آن را فهرست میکند. اگر فرانتاند بتواند نشانها را مجدداً به مخزن مبدأ پیوند دهد، با مقایسه هر کامیت گیت با بازبینی متناظر در مبدأ، بررسی صحت و کامل بودن واردسازی آسان خواهد بود.
هنگام انتقال از سامانهای مانند Perforce یا Subversion، این کار باید بسیار ساده باشد، چرا که نشان fast-import میتواند همان شماره مجموعهتغییرات (changeset) در Perforce یا شماره بازبینی در Subversion باشد.
جابهجایی آزادانه میان شاخهها (Freely Skip Around Branches)
لازم نیست تلاش کنید فرانتاند را به گونهای بهینهسازی کنید که در طول واردسازی در هر زمان فقط به یک شاخه محدود بماند. اگرچه ممکن است این کار برای fast-import اندکی سریعتر باشد، اما پیچیدگی کد فرانتاند را به میزان قابل توجهی افزایش میدهد.
سازوکار درونی LRU شاخهها در fast-import معمولاً بسیار خوب عمل میکند، و هزینه فعالسازی یک شاخه غیرفعال آنقدر پایین است که جابهجایی پیدرپی میان شاخهها عملاً هیچ تأثیری بر کارایی واردسازی ندارد.
مدیریت تغییر نامها (Handling Renames)
هنگام وارد کردن یک فایل یا دایرکتوری تغییرنامیافته، بهسادگی نام(های) قدیمی را حذف کرده و نام(های) جدید را در طول کامیت متناظر اصلاح کنید. گیت تشخیص تغییر نام را پس از واقعه (after-the-fact) انجام میدهد، نه به صورت صریح در حین یک کامیت.
استفاده از شاخههای اصلاح برچسب (Use Tag Fixup Branches)
برخی دیگر از سامانههای SCM به کاربر اجازه میدهند برچسبی از چندین فایل که متعلق به یک کامیت/مجموعهتغییرات یکسان نیستند ایجاد کند. یا برچسبهایی بسازد که زیرمجموعهای از فایلهای موجود در مخزن باشند.
وارد کردن این برچسبها به همان صورت در گیت، بدون ایجاد دستکم یک کامیت که فایلها را برای مطابقت با محتوای برچسب “اصلاح” (fixes up) کند، غیرممکن است. از دستور reset در fast-import برای بازنشانی یک شاخه ساختگی (dummy) خارج از فضای شاخههای عادی خود به کامیت پایه برای برچسب استفاده کنید، سپس یک یا چند کامیت اصلاح فایل را ثبت کرده و در نهایت شاخه ساختگی را برچسبگذاری نمایید.
برای نمونه، از آنجا که تمام شاخههای عادی تحت refs/heads/ ذخیره میشوند، نام شاخه اصلاح برچسب را TAG_FIXUP بگذارید. بدین ترتیب غیرممکن است که شاخه اصلاحِ مورد استفاده واردکننده، تداخل فضای نام با شاخههای واقعیِ واردشده از مبدأ پیدا کند (نام TAG_FIXUP متمایز از refs/heads/TAG_FIXUP است).
هنگام ثبت کامیتهای اصلاحی، استفاده از merge را برای پیوند دادن کامیت(هایی) که بازبینیهای فایل را برای شاخه اصلاح تأمین میکنند در نظر داشته باشید. انجام این کار به ابزارهایی مانند git blame امکان میدهد تا در تاریخچه واقعی کامیتها ردگیری کنند و فایلهای مبدأ را بهدرستی حاشیهنویسی نمایند.
پس از پایان کار fast-import، فرانتاند باید برای حذف شاخه ساختگی دستور rm .git/TAG_FIXUP را اجرا کند.
اکنون وارد کنید، بعداً مجدداً بستهبندی کنید (Import Now, Repack Later)
به محض اتمام کار fast-import، مخزن گیت کاملاً معتبر و آماده استفاده است. بهطور معمول این کار حتی برای پروژههای بسیار بزرگ (بیش از ۱۰۰٬۰۰۰ کامیت) تنها زمان بسیار کوتاهی میبرد.
با این حال، بستهبندی مجدد (repacking) مخزن برای بهبود محلیسازی دادهها (data locality) و کارایی دسترسی ضروری است. این فرآیند همچنین در پروژههای بسیار بزرگ میتواند ساعتها طول بکشد (بهویژه اگر از گزینه -f و یک پارامتر بزرگ --window استفاده شود). از آنجا که اجرای بستهبندی مجدد همزمان با خوانندگان و نویسندگان ایمن است، بستهبندی مجدد را در پسزمینه اجرا کنید و بگذارید هر زمان کارش به پایان رسید تمام شود. هیچ دلیلی وجود ندارد که برای کاوش در پروژه گیت جدید خود منتظر بمانید!
اگر ترجیح میدهید منتظر بستهبندی مجدد بمانید، تا زمان تکمیل بستهبندی مجدد اقدام به اجرای معیارسنجیها یا آزمونهای کارایی نکنید. خروجی fast-import فایلهای بستهای با بهینگی کمتر (suboptimal) است که اساساً هرگز در شرایط استفاده واقعی دیده نمیشوند.
بستهبندی مجدد دادههای تاریخی (Repacking Historical Data)
اگر دادههای واردشده بسیار قدیمی (برای مثال قدیمیتر از سال گذشته) را مجدداً بستهبندی میکنید، صرف زمان اضافه برای پردازنده و ارائه گزینه --window=50 (یا بیشتر) را هنگام اجرای git repack در نظر داشته باشید. این کار زمان بیشتری میبرد، اما فایل بسته کوچکتری نیز تولید خواهد کرد. شما تنها یک بار نیاز به صرف این تلاش دارید و هر کسی که از پروژه شما استفاده کند از مخزن کوچکتر بهرهمند خواهد شد.
گنجاندن برخی پیامهای پیشرفت (Include Some Progress Messages)
هر از گاهی، ترتیبی دهید که فرانتاند شما یک پیام progress به fast-import بفرستد. محتوای پیامها کاملاً آزاد و دلخواه است، بنابراین یک پیشنهاد میتواند این باشد که هر بار که تاریخ کامیت فعلی به ماه بعد میرود، ماه و سال جاری را خروجی دهد. کاربران شما با آگاهی از اینکه چه مقدار از جریان داده پردازش شده است، آسودهخاطرتر خواهند بود.
بهینهسازی فایل بسته (PACKFILE OPTIMIZATION)
هنگام بستهبندی یک blob، همیشه fast-import تلاش میکند تا نسبت به آخرین blob نوشتهشده دلتاسازی (deltify) کند. مگر اینکه تمهید خاصی توسط فرانتاند اندیشیده شده باشد، این مورد احتمالاً نسخه قبلی همان فایل نخواهد بود؛ بنابراین دلتای ایجادشده کوچکترین حالت ممکن نخواهد بود. فایل بسته حاصل فشرده خواهد شد، اما بهینه نخواهد بود.
فرانتاندهایی که دسترسی کارآمدی به تمام بازبینیهای یک فایل منفرد دارند (برای مثال خواندن یک فایل ,v در RCS/CVS) میتوانند انتخاب کنند که تمام بازبینیهای آن فایل را به عنوان دنبالهای از دستورات متوالی blob ارائه دهند. این امر به fast-import اجازه میدهد تا بازبینیهای مختلف فایل را نسبت به یکدیگر دلتاسازی کند، و در فایل بسته نهایی در فضا صرفهجویی شود. میتوان از نشانها برای شناسایی بازبینیهای منفرد فایل در طول دنبالهای از دستورات commit در مراحل بعدی استفاده کرد.
فایل(های) بسته ایجادشده توسط fast-import الگوهای دسترسی دیسک مناسبی را ترویج نمیکنند. این به دلیل آن است که fast-import دادهها را به همان ترتیبی که در ورودی استاندارد دریافت میکند مینویسد، در حالی که گیت معمولاً دادهها را در فایلهای بسته طوری سازماندهی میکند که جدیدترین دادهها (نوک کنونی) پیش از دادههای تاریخی قرار گیرند. گیت همچنین کامیتها را با یکدیگر دستهبندی میکند، که پیمایش بازبینیها را از طریق محلیسازی بهتر حافظه نهان سرعت میبخشد.
به همین دلیل اکیداً به کاربران توصیه میشود که پس از اتمام fast-import، مخزن را با دستور git repack -a -d مجدداً بستهبندی کنند، تا به گیت اجازه داده شود فایلهای بسته را برای دسترسی سریعتر به دادهها دوباره سازماندهی کند. اگر دلتاهای blob غیربهینه باشند (به بالا مراجعه کنید)، اضافه کردن گزینه -f برای وادار کردن به محاسبه مجدد همه دلتاها میتواند اندازه نهایی فایل بسته را به میزان قابل توجهی کاهش دهد (۳۰ تا ۵۰ درصد کوچکتر شدن کاملاً معمول است).
به جای اجرای git repack، میتوانید git gc --aggressive را نیز اجرا کنید که چیزهای دیگر را نیز پس از واردسازی بهینهسازی میکند (برای نمونه، بستهبندی ارجاعات سرگردان / pack loose refs). همانطور که در بخش «AGGRESSIVE» در git-gc(1) ذکر شده است، گزینه --aggressive دلتاهای جدیدی را با گزینه -f در git-repack(1) خواهد یافت. به دلایلی که در بالا شرح داده شد، استفاده از --aggressive پس از یک fast-import یکی از معدود مواردی است که سودمند بودن آن شناخته شده است.
مصرف حافظه (MEMORY UTILIZATION)
عوامل متعددی وجود دارند که بر میزان حافظه مورد نیاز fast-import برای انجام یک واردسازی تأثیر میگذارند. همانند بخشهای حیاتی هسته گیت، fast-import از تخصیصدهندههای حافظه اختصاصی خود برای سرشکن کردن هرگونه سربار مرتبط با malloc استفاده میکند. در عمل، fast-import به دلیل استفاده از تخصیص بلوکهای بزرگ، تمایل دارد هرگونه سربار malloc را به صفر تقلیل دهد.
به ازای هر شیء (per object)
برنامه fast-import یک ساختار درونحافظهای را برای هر شیء نوشتهشده در این اجرا نگهداری میکند. در یک سیستم ۳۲ بیتی این ساختار ۳۲ بایت و در یک سیستم ۶۴ بیتی (به دلیل اندازه بزرگتر اشارهگرها) این ساختار ۴۰ بایت است. اشیاء موجود در جدول تا زمان پایان یافتن fast-import آزاد نمیشوند. وارد کردن ۲ میلیون شیء در یک سیستم ۳۲ بیتی تقریباً به ۶۴ مبیبایت (MiB) حافظه نیاز دارد.
جدول اشیاء در واقع یک جدول درهمسازی (hashtable) با کلید نام شیء (همان SHA-1 یکتا) است. این پیکربندی ذخیرهسازی به fast-import اجازه میدهد تا از یک شیء موجود یا پیشتر نوشتهشده مجدداً استفاده کند و از نوشتن موارد تکراری در فایل بسته خروجی خودداری نماید. حبابهای تکراری در یک واردسازی بهطور شگفتآوری رایج هستند که معمولاً به دلیل ادغام شاخهها در مبدأ رخ میدهد.
به ازای هر نشان (per mark)
نشانها در یک آرایه تنک (sparse array) ذخیره میشوند و به ازای هر نشان از ۱ اشارهگر (۴ بایت یا ۸ بایت، بسته به اندازه اشارهگر) استفاده میکنند. اگرچه این آرایه تنک است، اما همچنان به فرانتاندها اکیداً توصیه میشود از نشانهای بین ۱ و n استفاده کنند، که در آن n تعداد کل نشانهای مورد نیاز برای این واردسازی است.
به ازای هر شاخه (per branch)
شاخهها به دو دسته فعال و غیرفعال طبقهبندی میشوند. مصرف حافظه این دو دسته بهطور چشمگیری متفاوت است.
شاخههای غیرفعال در ساختاری ذخیره میشوند که به ازای هر شاخه از ۹۶ یا ۱۲۰ بایت (به ترتیب در سیستمهای ۳۲ بیتی یا ۶۴ بیتی)، به علاوه طول نام شاخه (معمولاً زیر ۲۰۰ بایت) استفاده میکند. برنامه fast-import بهراحتی تا ۱۰٬۰۰۰ شاخه غیرفعال را در کمتر از ۲ مبیبایت حافظه مدیریت خواهد کرد.
شاخههای فعال همان سربار شاخههای غیرفعال را دارند، اما همچنین شامل رونوشتهایی از هر درختی هستند که اخیراً در آن شاخه اصلاح شده است. اگر زیردرخت include از زمان فعال شدن شاخه اصلاح نشده باشد، محتویات آن در حافظه بارگذاری نخواهد شد، اما اگر زیردرخت src با یک کامیت از زمان فعال شدن شاخه اصلاح شده باشد، آنگاه محتویات آن در حافظه بارگذاری خواهد شد.
از آنجا که شاخههای فعال فرادادههای مربوط به فایلهای موجود در آن شاخه را ذخیره میکنند، اندازه ذخیرهسازی آنها در حافظه میتواند تا میزان قابل توجهی رشد کند (به پایین مراجعه کنید).
برنامه fast-import بهطور خودکار شاخههای فعال را بر اساس یک الگوریتم ساده «کمترین استفاده اخیر» (LRU) به وضعیت غیرفعال منتقل میکند. زنجیره LRU در هر دستور commit بهروزرسانی میشود. حداکثر تعداد شاخههای فعال را میتوان در خط فرمان با --active-branches= افزایش یا کاهش داد.
به ازای هر درخت فعال (per active tree)
درختها (یا همان دایرکتوریها) علاوه بر حافظه مورد نیاز برای ورودیهایشان (بخش “به ازای هر فایل فعال” در زیر را ببینید)، تنها از ۱۲ بایت حافظه استفاده میکنند. هزینه یک درخت عملاً صفر است، چرا که سربار آن روی تکتک ورودیهای فایل سرشکن میشود.
به ازای هر ورودی فایل فعال (per active file entry)
فایلها (و اشارهگرها به زیردرختها) در درختهای فعال، به ازای هر ورودی به ۵۲ یا ۶۴ بایت (در پلتفرمهای ۳۲/۶۴ بیتی) نیاز دارند. برای صرفهجویی در فضا، نام فایلها و درختها در یک جدول مشترک رشتهها تجمیع (pool) میشوند، که باعث میشود نام فایل “Makefile” صرفنظر از اینکه چند بار در پروژه تکرار شود، تنها از ۱۶ بایت (پس از احتساب سربار سرآیند رشته) استفاده کند.
الگوریتم LRU شاخههای فعال، هنگامی که با مخزن مشترک رشتههای نام فایل و بارگذاری تنبل (lazy loading) زیردرختها همراه شود، به fast-import اجازه میدهد تا پروژههایی با بیش از ۲٬۰۰۰ شاخه و بیش از ۴۵٬۱۱۴ فایل را با ردپای حافظه بسیار محدود (کمتر از ۲.۷ مبیبایت به ازای هر شاخه فعال) بهطور کارآمد وارد کند.
سیگنالها (SIGNALS)
ارسال SIGUSR1 به فرایند git fast-import فایل بسته فعلی را زودهنگام به پایان میرساند و یک دستور checkpoint را شبیهسازی میکند. کاربر کمحوصله میتواند از این امکان برای بررسی اجمالی اشیاء و ارجاعات در یک واردسازیِ در حال انجام استفاده کند، که البته به بهای مقداری زمان اجرای بیشتر و فشردهسازی ضعیفتر تمام میشود.
پیکربندی (CONFIGURATION)
تمام موارد زیر این خط در این بخش، بهصورت گزینششده از مستندات git-config(1) گنجانده شدهاند. محتوا همان چیزی است که در آنجا یافت میشود:
fastimport.unpackLimit
همچنین ببینید (SEE ALSO)
گیت (GIT)
بخشی از مجموعه git(1)
| 2026-06-29 | Git 2.55.0 |