| GITPROTOCOL-V2(5) | راهنمای Git | GITPROTOCOL-V2(5) |
نام (NAME)
gitprotocol-v2 - پروتکل ارتباطی گیت (Wire Protocol)، نسخه ۲
خلاصه دستور (SYNOPSIS)
<over-the-wire-protocol>
توضیحات (DESCRIPTION)
این سند مشخصات فنی نسخه ۲ پروتکل ارتباطی گیت (Wire Protocol) را ارائه میدهد. پروتکل نسخه ۲ نسبت به نسخه ۱ از راههای زیر بهبود یافته است:
در پروتکل نسخه ۲ ارتباطات دستور-محور هستند. در اولین تماس با یک سرور، فهرستی از قابلیتها اعلان خواهد شد. برخی از این قابلیتها دستوراتی هستند که کلاینت میتواند اجرای آنها را درخواست کند. پس از اتمام یک دستور، کلاینت میتواند از اتصال مجدداً استفاده کرده و اجرای دستورات دیگری را درخواست نماید.
چارچوببندی بسته-خط (PACKET-LINE FRAMING)
تمام ارتباطات با استفاده از قالببندی بسته-خط (packet-line framing) انجام میشود، دقیقاً مانند نسخه ۱. برای اطلاعات بیشتر به gitprotocol-pack(5) و gitprotocol-common(5) مراجعه کنید.
در پروتکل نسخه ۲ این بستههای ویژه دارای معانی زیر خواهند بود:
درخواست اولیه کلاینت (INITIAL CLIENT REQUEST)
به طور کلی یک کلاینت میتواند با ارسال version=2 از طریق کانال جانبی مربوط به انتقالِ در حال استفاده، که در نهایت متغیر GIT_PROTOCOL را تنظیم میکند، درخواست استفاده از پروتکل نسخه ۲ را بدهد. اطلاعات بیشتر را میتوان در gitprotocol-pack(5) و gitprotocol-http(5) و همچنین تعریف GIT_PROTOCOL در git(1) یافت. در تمام موارد پاسخ سرور اعلان قابلیتها است.
پروتکل انتقال Git (Git Transport)
هنگام استفاده از پروتکل انتقال git://، میتوانید با ارسال "version=2" به عنوان یک پارامتر اضافی درخواست استفاده از پروتکل نسخه ۲ را داشته باشید:
003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0
پروتکلهای انتقال SSH و File (SSH and File Transport)
هنگام استفاده از هر یک از پروتکلهای انتقال ssh:// یا file://، متغیر محیطی GIT_PROTOCOL باید صراحتاً شامل "version=2" تنظیم شود. ممکن است لازم باشد سرور به گونهای پیکربندی شود که اجازه عبور این متغیر محیطی را بدهد.
پروتکل انتقال HTTP (HTTP Transport)
هنگام استفاده از پروتکل انتقال http:// یا https:// کلاینت یک درخواست "هوشمند" info/refs همانطور که در gitprotocol-http(5) توضیح داده شده است ارسال میکند و با ارائه "version=2" در سرآیند Git-Protocol درخواست میکند که از نسخه ۲ استفاده شود.
C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0 C: Git-Protocol: version=2
یک سرور نسخه ۲ به این صورت پاسخ میدهد:
S: 200 OK S: <Some headers> S: ... S: S: 000eversion 2\n S: <capability-advertisement>
درخواستهای بعدی سپس مستقیماً به سرویس $GIT_URL/git-upload-pack ارسال میشوند. (این فرآیند برای git-receive-pack نیز یکسان است).
از گزینه --http-backend-info-refs برای git-upload-pack(1) استفاده میکند.
ممکن است لازم باشد سرور پیکربندی شود تا محتویات این سرآیند را از طریق متغیر GIT_PROTOCOL منتقل کند. به توضیحات موجود در git-http-backend(1) مراجعه کنید.
اعلان قابلیتها (CAPABILITY ADVERTISEMENT)
سروری که تصمیم میگیرد (بر اساس درخواست کلاینت) با استفاده از پروتکل نسخه ۲ ارتباط برقرار کند، با ارسال یک رشته نسخه در پاسخ اولیه خود و به دنبال آن اعلان قابلیتهای خود، به کلاینت اطلاع میدهد. هر قابلیت یک کلید (key) با یک مقدار (value) اختیاری است. کلاینتها باید تمام کلیدهای ناشناخته را نادیده بگیرند. معنای مقادیر ناشناخته به تعریف هر کلید واگذار میشود. برخی از قابلیتها دستوراتی را توصیف میکنند که کلاینت میتواند اجرای آنها را درخواست کند.
capability-advertisement = protocol-version
capability-list
flush-pkt
protocol-version = PKT-LINE("version 2" LF)
capability-list = *capability
capability = PKT-LINE(key[=value] LF)
key = 1*(ALPHA | DIGIT | "-_")
value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;")
درخواست دستور (COMMAND REQUEST)
پس از دریافت اعلان قابلیتها، کلاینت میتواند درخواستی برای انتخاب دستور مورد نظر خود همراه با هرگونه قابلیت یا آرگومان خاص ارسال کند. سپس یک بخش اختیاری وجود دارد که کلاینت میتواند هرگونه پارامتر یا پرسوجوی مخصوص دستور را ارائه دهد. در هر زمان تنها یک دستور واحد میتواند درخواست شود.
request = empty-request | command-request
empty-request = flush-pkt
command-request = command
capability-list
delim-pkt
command-args
flush-pkt
command = PKT-LINE("command=" key LF)
command-args = *command-specific-arg
command-specific-args are packet line framed arguments defined by each individual command.
سپس سرور بررسی خواهد کرد تا اطمینان حاصل کند که درخواست کلاینت شامل یک دستور معتبر و همچنین قابلیتهای معتبری است که اعلان شده بودند. اگر درخواست معتبر باشد، سرور دستور را اجرا خواهد کرد. سرور پیش از صدور پاسخ، حتماً باید (MUST) منتظر بماند تا کل درخواست کلاینت را دریافت کند. قالب پاسخ توسط دستوری که اجرا میشود تعیین میگردد، اما در همه موارد یک flush-pkt نشاندهنده پایان پاسخ است.
هنگامی که یک دستور به پایان رسید و کلاینت تمام پاسخ را از سرور دریافت کرد، کلاینت میتواند درخواست اجرای دستور دیگری را بدهد یا میتواند اتصال را قطع کند. کلاینت میتواند به صورت اختیاری یک درخواست خالی شامل فقط یک flush-pkt ارسال کند تا نشان دهد که درخواست دیگری ارسال نخواهد شد.
قابلیتها (CAPABILITIES)
دو نوع مختلف از قابلیتها وجود دارد: قابلیتهای عادی، که میتوانند برای انتقال اطلاعات یا تغییر رفتار یک درخواست استفاده شوند، و دستورات، که اقدامات اصلی هستند که یک کلاینت میخواهد انجام دهد (fetch، push، و غیره).
پروتکل نسخه ۲ به طور پیشفرض بدون وضعیت (stateless) است. این بدان معناست که تمام دستورات فقط باید یک دور (single round) دوام داشته باشند و از دید سمت سرور بدون وضعیت باشند، مگر اینکه کلاینت قابلیتی را درخواست کرده باشد که نشان دهد وضعیت باید توسط سرور حفظ شود. کلاینتها برای عملکرد صحیح نباید نیازمند مدیریت وضعیت در سمت سرور باشند (MUST NOT). این امر امکان توزیع بار چرخشی ساده (round-robin load-balancing) را در سمت سرور بدون نیاز به نگرانی در مورد مدیریت وضعیت فراهم میکند.
agent
سرور میتواند قابلیت agent را با مقدار X (به صورت agent=X) اعلان کند تا به کلاینت اطلاع دهد که سرور در حال اجرای نسخه X است. کلاینت میتواند به صورت اختیاری با گنجاندن قابلیت agent با مقدار Y (به صورت agent=Y) در درخواست خود به سرور، رشته agent خود را ارسال کند (اما اگر سرور قابلیت agent را اعلان نکرده باشد، کلاینت نباید این کار را انجام دهد - MUST NOT). رشتههای X و Y میتوانند شامل هر نویسه قابل چاپ ASCII به جز فاصله باشند (یعنی محدوده بایتی ۳۳ ⟨ x ⟨ ۱۲۶)، و معمولاً به صورت "package/version-os" هستند (مانند "git/1.8.3.1-Linux") که در آن os نام سیستمعامل است (مانند "Linux"). X و Y را میتوان با استفاده از متغیر محیطی GIT_USER_AGENT پیکربندی کرد و این متغیر اولویت دارد. مقدار os با استفاده از فیلد sysname از فراخوانی سیستمی uname(2) یا معادل آن بازیابی میشود. رشتههای agent صرفاً جنبه اطلاعاتی برای آمار و اهداف اشکالزدایی دارند و نباید (MUST NOT) برای فرض برنامهنویسیشده مبنی بر وجود یا عدم وجود ویژگیهای خاص مورد استفاده قرار گیرند.
ls-refs
ls-refs دستوری است که برای درخواست اعلان ارجاعات (reference advertisement) در نسخه ۲ استفاده میشود. برخلاف اعلان ارجاعات فعلی، ls-refs آرگومانهایی دریافت میکند که میتوان از آنها برای محدود کردن ارجاعات ارسالی از سرور استفاده کرد.
ویژگیهای اضافی که در دستور پایه پشتیبانی نمیشوند، به عنوان مقدار دستور در اعلان قابلیتها به صورت فهرستی از ویژگیها که با فاصله جدا شدهاند اعلان خواهند شد: "<command>=<feature-1> <feature-2>"
دستور ls-refs آرگومانهای زیر را دریافت میکند:
symrefs
علاوه بر شیئی که به آن اشاره شده، هنگام نمایش یک ارجاع نمادین (symbolic ref)،
ارجاع زیربنایی که به آن اشاره دارد را نیز نمایش میدهد.
peel
برچسبهای پوستهگیریشده (peeled tags) را نشان میدهد.
ref-prefix <prefix>
در صورت مشخص شدن، فقط ارجاعاتی نمایش داده میشوند که پیشوندی مطابق
با یکی از پیشوندهای ارائهشده داشته باشند. میتوان چندین مورد را مشخص کرد،
که در این صورت ارجاعات مطابق با هر یک از پیشوندها نشان داده خواهند شد.
توجه داشته باشید که این صرفاً برای بهینهسازی است؛ سرور در صورت تمایل
میتواند (MAY) ارجاعاتی را که با پیشوند مطابقت ندارند نیز نشان دهد،
و کلاینتها باید خودشان نتیجه را فیلتر کنند.
اگر ویژگی unborn اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند.
unborn
سرور اطلاعات مربوط به HEAD را حتی اگر یک symref اشارهکننده به یک شاخه
ایجادنشده (unborn branch) باشد به صورت "unborn HEAD symref-target:<target>"
ارسال خواهد کرد.
خروجی ls-refs به شرح زیر است:
output = *ref
flush-pkt
obj-id-or-unborn = (obj-id | "unborn")
ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)
ref-attribute = (symref | peeled)
symref = "symref-target:" symref-target
peeled = "peeled:" obj-id
fetch
fetch دستوری است که برای دریافت packfile در نسخه ۲ استفاده میشود. میتوان آن را به عنوان یک نسخه اصلاحشده از fetch نسخه ۱ در نظر گرفت که در آن ref-advertisement حذف شده است (زیرا دستور ls-refs این نقش را پر میکند) و قالب پیام برای حذف افزونگیها و امکان افزودن آسان الحاقات آینده اصلاح شده است.
ویژگیهای اضافی که در دستور پایه پشتیبانی نمیشوند، به عنوان مقدار دستور در اعلان قابلیتها به صورت فهرستی از ویژگیها که با فاصله جدا شدهاند اعلان خواهند شد: "<command>=<feature-1> <feature-2>"
یک درخواست fetch میتواند آرگومانهای زیر را بپذیرد:
want <oid>
شیئی را به سرور نشان میدهد که کلاینت میخواهد آن را بازیابی کند.
مقادیر want میتوانند هر چیزی باشند و محدود به اشیاء اعلانشده نیستند.
have <oid>
شیئی را به سرور نشان میدهد که کلاینت به صورت محلی دارد.
این به سرور اجازه میدهد تا یک packfile بسازد که فقط شامل اشیاء مورد
نیاز کلاینت باشد. میتوان چندین خط 'have' ارسال کرد.
done
به سرور نشان میدهد که مذاکره باید پایان یابد (یا در صورت انجام clone،
اصلاً آغاز نشود) و سرور باید از اطلاعات ارائهشده در درخواست برای
ساخت packfile استفاده کند.
thin-pack
درخواست میکند که یک thin pack ارسال شود، که یک بسته با دلتاهایی است که
به اشیاء پایهای اشاره میکنند که درون بسته قرار ندارند (اما مشخص است که
در سمت دریافتکننده وجود دارند). این میتواند ترافیک شبکه را به طور چشمگیری
کاهش دهد، اما دریافتکننده باید بداند چگونه با افزودن پایههای از دست رفته به بسته،
این بستهها را "ضخیم" (thicken) کند.
no-progress
درخواست میکند که اطلاعات پیشرفت که معمولاً در حین انتقال packfile روی کانال
جانبی ۲ (side-band channel 2) ارسال میشود، ارسال نشود. با این حال، کانال
جانبی ۳ همچنان برای پاسخهای خطا استفاده میشود.
include-tag
درخواست میکند که اگر اشیایی که برچسبهای حاشیهنویسیشده (annotated tags)
به آنها اشاره دارند در حال ارسال هستند، آن برچسبها نیز ارسال شوند.
ofs-delta
نشان میدهد که کلاینت PACKv2 را با دلتایی که به جای oid، بر اساس موقعیت
در بسته به پایه خود اشاره میکند، درک میکند. یعنی میتواند OBJ_OFS_DELTA
(معروف به نوع ۶) را در یک packfile بخواند.
اگر ویژگی shallow اعلان شده باشد، آرگومانهای زیر را میتوان در درخواست کلاینتها گنجاند و همچنین بخش shallow-info ممکن است به پاسخ سرور اضافه شود، همانطور که در زیر توضیح داده شده است.
shallow <oid>
کلاینت باید سرور را از تمام کامیتهایی که فقط کپیهای کمعمق (shallow) از آنها
دارد (به این معنی که والدین یک کامیت را ندارد) با ارسال یک خط 'shallow <oid>'
برای هر یک از این اشیاء مطلع کند تا سرور از محدودیتهای تاریخچه کلاینت آگاه باشد.
این کار به این دلیل است که سرور بداند کلاینت ممکن است تمام اشیاء قابل دسترس
از چنین کامیتهایی را نداشته باشد.
deepen <depth>
درخواست میکند که fetch/clone کمعمق بوده و دارای عمق کامیت <depth>
نسبت به سمت راه دور باشد.
deepen-relative
درخواست میکند که معنای دستور "deepen" تغییر کند تا نشان دهد که عمق درخواستی
به جای این که نسبت به کامیتهای درخواستی باشد، نسبت به مرز کمعمق فعلی کلاینت است.
deepen-since <timestamp>
درخواست میکند که clone/fetch کمعمق به جای عمق، در یک زمان مشخص بریده شود.
از نظر داخلی معادل اجرای "git rev-list --max-age=<timestamp>" است.
نمیتوان از آن همراه با "deepen" استفاده کرد.
deepen-not <rev>
درخواست میکند که clone/fetch کمعمق به جای عمق، در یک بازنگری مشخصشده
توسط '<rev>' بریده شود. از نظر داخلی معادل اجرای "git rev-list --not <rev>"
است. نمیتوان از آن همراه با "deepen" استفاده کرد، اما با "deepen-since"
قابل استفاده است.
اگر ویژگی filter اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند:
filter <filter-spec>
درخواست میکند که اشیاء مختلف از packfile با استفاده از یکی از چندین تکنیک
فیلترسازی حذف شوند. این موارد برای استفاده در عملیات کلون جزئی (partial clone)
و واکشی جزئی (partial fetch) در نظر گرفته شدهاند. برای مقادیر ممکن "filter-spec"
به `rev-list` مراجعه کنید. هنگام برقراری ارتباط با فرآیندهای دیگر، فرستندهها
باید (SHOULD) اعداد صحیح مقیاسبندیشده (مانند "1k") را به شکل کاملاً گسترشیافته
(مانند "1024") تبدیل کنند تا به قابلیت همکاری با دریافتکنندههای قدیمیتر که
ممکن است پسوندهای مقیاسبندی جدید را درک نکنند، کمک نمایند. با این حال،
دریافتکنندهها باید (SHOULD) پسوندهای زیر را بپذیرند: 'k'، 'm' و 'g' به ترتیب
برای ۱۰۲۴، ۱۰۴۸۵۷۶ و ۱۰۷۳۷۴۱۸۲۴.
اگر ویژگی ref-in-want اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند و همچنین بخش wanted-refs ممکن است به پاسخ سرور اضافه شود، همانطور که در زیر توضیح داده شده است.
want-ref <ref>
به سرور نشان میدهد که کلاینت میخواهد یک ارجاع خاص را بازیابی کند، که در آن
<ref> نام کامل یک ارجاع روی سرور است. ارسال want-ref برای یک ارجاع یکسان
بیش از یک بار، یک خطای پروتکل است.
اگر ویژگی sideband-all اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند:
sideband-all
به سرور دستور میدهد که کل پاسخ را مالتیپلکس (تسهیم) شده ارسال کند، نه فقط
بخش packfile را. تمام خطوط غیر flush و غیر delim در PKT-LINE در پاسخ
(نه فقط در بخش packfile) با یک بایت شروع میشوند که باند جانبی آن را مشخص میکند
(۱، ۲ یا ۳)، و سرور ممکن است "0005\2" (یک PKT-LINE از باند جانبی ۲ بدون بار داده)
را به عنوان یک بسته زنده نگهداشتن (keepalive) ارسال کند.
اگر ویژگی packfile-uris اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند و همچنین بخش packfile-uris ممکن است به پاسخ سرور اضافه شود، همانطور که در زیر توضیح داده شده است. توجه داشته باشید که حداکثر یک خط packfile-uris میتواند به سرور ارسال شود.
packfile-uris <comma-separated-list-of-protocols>
به سرور نشان میدهد که کلاینت مایل است به جای اشیاء موجود در packfile
ارسالی، URIهای مربوط به هر یک از پروتکلهای ارائهشده را دریافت کند. قبل از
انجام بررسی اتصالپذیری، کلاینت باید از تمام URIهای دادهشده دانلود کند.
در حال حاضر، پروتکلهای پشتیبانیشده "http" و "https" هستند.
اگر ویژگی wait-for-done اعلان شده باشد، آرگومان زیر را میتوان در درخواست کلاینت گنجاند.
wait-for-done
به سرور نشان میدهد که هرگز نباید "ready" را ارسال کند، بلکه باید قبل از ارسال
packfile منتظر بماند تا کلاینت "done" بگوید.
پاسخ fetch به تعدادی بخش تقسیم میشود که با بستههای جداکننده (0001) از هم جدا شدهاند و هر بخش با سرآیند بخش خود آغاز میشود. اکثر بخشها فقط زمانی ارسال میشوند که packfile ارسال شود.
output = acknowledgements flush-pkt |
[acknowledgments delim-pkt] [shallow-info delim-pkt]
[wanted-refs delim-pkt] [packfile-uris delim-pkt]
packfile flush-pkt
acknowledgments = PKT-LINE("acknowledgments" LF)
(nak | *ack)
(ready)
ready = PKT-LINE("ready" LF)
nak = PKT-LINE("NAK" LF)
ack = PKT-LINE("ACK" SP obj-id LF)
shallow-info = PKT-LINE("shallow-info" LF)
*PKT-LINE((shallow | unshallow) LF)
shallow = "shallow" SP obj-id
unshallow = "unshallow" SP obj-id
wanted-refs = PKT-LINE("wanted-refs" LF)
*PKT-LINE(wanted-ref LF)
wanted-ref = obj-id SP refname
packfile-uris = PKT-LINE("packfile-uris" LF) *packfile-uri
packfile-uri = PKT-LINE(40*(HEXDIGIT) SP *%x20-ff LF)
packfile = PKT-LINE("packfile" LF)
*PKT-LINE(%x01-03 *%x00-ff)
بخش acknowledgments
* اگر کلاینت با ارسال یک خط "done" مشخص کند که مذاکراتش به پایان رسیده است
(و در نتیجه از سرور میخواهد که یک packfile ارسال کند)، بخش acknowledgments
حتماً باید (MUST) از پاسخ سرور حذف شود.
بخش shallow-info
* اگر کلاینت یک fetch/clone کمعمق درخواست کرده باشد، یک کلاینت کمعمق
درخواست fetch کند، یا سرور کمعمق باشد، پاسخ سرور ممکن است شامل یک
بخش shallow-info باشد. بخش shallow-info در صورتی گنجانده خواهد شد که
(به دلیل یکی از شرایط فوق) سرور نیاز داشته باشد کلاینت را از هرگونه مرز کمعمق
یا تنظیمات مرزهای کمعمق فعلی کلاینت مطلع سازد.
بخش wanted-refs
* این بخش فقط در صورتی گنجانده میشود که کلاینت ارجاعی را با استفاده از یک خط
'want-ref' درخواست کرده باشد و بخش packfile نیز در پاسخ گنجانده شده باشد.
بخش packfile-uris
* این بخش فقط در صورتی گنجانده میشود که کلاینت 'packfile-uris' ارسال کرده
باشد و سرور حداقل یک URI از این دست برای ارسال داشته باشد.
بخش packfile
* این بخش فقط در صورتی گنجانده میشود که کلاینت خطوط 'want' را در درخواست
خود ارسال کرده باشد و یا با ارسال 'done' درخواست کرده باشد که مذاکره
بیشتری انجام نشود، یا اینکه سرور به این نتیجه رسیده باشد که نقطه برش کافی برای
تولید یک packfile را پیدا کرده است.
کد جریان میتواند یکی از موارد زیر باشد:
1 - دادههای بسته (pack data)
2 - پیامهای پیشرفت (progress messages)
3 - پیام خطای مهلک درست قبل از لغو جریان (fatal error message)
server-option
در صورت اعلان شدن، نشان میدهد که هر تعداد از گزینههای خاص سرور را میتوان در یک درخواست گنجاند. این کار با ارسال هر گزینه به عنوان یک خط قابلیت "server-option=<option>" در بخش capability-list یک درخواست انجام میشود.
گزینههای ارائهشده نباید شامل نویسههای NUL یا LF باشند.
object-format
سرور میتواند قابلیت object-format را با یک مقدار X (به صورت object-format=X) اعلان کند تا به کلاینت اطلاع دهد که سرور قادر به پردازش اشیاء با استفاده از الگوریتم هش X است. در صورت عدم تعیین، فرض میشود که سرور فقط SHA-1 را پشتیبانی میکند. اگر کلاینت مایل به استفاده از یک الگوریتم هش غیر از SHA-1 باشد، باید رشته object-format خود را مشخص کند.
session-id=<session-id>
سرور ممکن است یک شناسه نشست (session ID) را اعلان کند که میتواند برای شناسایی این فرآیند در چندین درخواست استفاده شود. کلاینت نیز میتواند شناسه نشست خود را به سرور اعلان کند.
شناسههای نشست باید برای یک فرآیند معین یکتا باشند. آنها باید در یک packet-line جا شوند و نباید شامل نویسههای غیرقابل چاپ یا فاصله باشند. پیادهسازی فعلی از شناسههای نشست trace2 استفاده میکند (برای جزئیات به api-trace2[1] مراجعه کنید)، اما ممکن است این موضوع تغییر کند و کاربرانِ شناسه نشست نباید به این واقعیت متکی باشند.
object-info
object-info دستوری برای بازیابی اطلاعات مربوط به یک یا چند شیء است. هدف اصلی آن این است که به کلاینت اجازه دهد بدون نیاز به واکشی کامل اشیاء، بر اساس این اطلاعات تصمیمگیری کند. اندازه شیء تنها اطلاعاتی است که در حال حاضر پشتیبانی میشود.
یک درخواست object-info آرگومانهای زیر را میپذیرد:
size درخواست میکند که اطلاعات اندازه برای هر شناسه شیء فهرستشده برگردانده شود.
oid <oid> شیئی را به سرور نشان میدهد که کلاینت میخواهد برای آن اطلاعات دریافت کند.
پاسخ object-info فهرستی از شناسههای شیء درخواستی و اطلاعات درخواستی مرتبط با آنها است که هر کدام با یک فاصله جدا شدهاند.
output = info flush-pkt
info = PKT-LINE(attrs) LF)
*PKT-LINE(obj-info LF)
attrs = attr | attrs SP attrs
attr = "size"
obj-info = obj-id SP obj-size
bundle-uri
اگر قابلیت bundle-uri اعلان شود، سرور از دستور ‘bundle-uri’ پشتیبانی میکند.
این قابلیت در حال حاضر بدون مقدار اعلان میشود (یعنی نه به صورت "bundle-uri=somevalue")، ممکن است در آینده مقداری برای پشتیبانی از الحاقات در سطح دستور اضافه شود. کلاینتها حتماً باید (MUST) هرگونه مقدار قابلیت ناشناخته را نادیده بگیرند و با گفتگوی 'bundle-uri` که پشتیبانی میکنند ادامه دهند.
دستور bundle-uri به این منظور در نظر گرفته شده است که قبل از fetch صادر شود تا URIهای فایلهای bundle (به git-bundle(1) مراجعه کنید) را برای "تغذیه اولیه" (seed) و آگاهسازی دستور fetch بعدی دریافت نماید.
کلاینت میتواند (CAN) دستور bundle-uri را قبل یا بعد از هر دستور معتبر دیگری صادر کند. برای مفید بودن برای کلاینتها، انتظار میرود که بعد از ls-refs و قبل از fetch صادر شود، اما میتواند (CAN) در هر زمانی در طول گفتگو صادر گردد.
بررسی bundle-uri
هدف از این ویژگی بهینهسازی مصرف منابع سرور در حالت متداول است، با تبدیل حالت متداولِ واکشی یک PACK بسیار بزرگ در حین اجرای git-clone(1) به یک واکشی افزایشی (incremental fetch) کوچکتر.
همچنین به سرورها امکان میدهد تا در ترکیب با یک uploadpack.packObjectsHook به حافظه نهان (کَش) بهتری دست یابند (به git-config(1) مراجعه کنید).
با تبدیل کلونها یا واکشیهای جدید به یک مذاکره قابل پیشبینیتر و متداولتر در برابر رأسهای (tips) فایل(های) bundle.* که اخیراً تولید شدهاند. سرورها حتی ممکن است با ورود pushهای جدید، نتایج چنین مذاکراتی را برای uploadpack.packObjectsHook از پیش تولید کنند.
یکی از راههایی که سرورها میتوانند از این بستهها بهره ببرند این است که سرور پیشبینی میکند که کلونهای تازه یک bundle شناختهشده را دانلود کرده و سپس با استفاده از نوک ارجاعات (ref tips) یافتشده در آن بسته (یا بستهها)، به وضعیت فعلی مخزن برسند.
پروتکل
برای bundle-uri
درخواست bundle-uri هیچ آرگومانی دریافت نمیکند، و همانطور که در بالا ذکر شد در حال حاضر مقدار قابلیتی را اعلان نمیکند. هر دوی اینها ممکن است در آینده اضافه شوند.
هنگامی که کلاینت یک درخواست command=bundle-uri صادر میکند، پاسخ فهرستی از جفتهای کلید-مقدار است که به صورت خطوط بسته با مقدار <key>=<value> ارائه میشوند. هر <key> باید به عنوان یک کلید پیکربندی از فضای نام bundle.* تفسیر شود تا فهرستی از بستهها را بسازد. این کلیدها توسط زیربخش bundle.<id>. گروهبندی میشوند، که در آن هر کلید مربوط به یک <id> مشخص، ویژگیهایی را به بسته تعریفشده توسط آن <id> اختصاص میدهد. برای جزئیات خاص این کلیدها و نحوه تفسیر مقادیر آنها توسط کلاینت گیت به git-config(1) مراجعه کنید.
کلاینتها حتماً باید (MUST) خط را مطابق با قالب بالا تجزیه کنند، خطوطی که با این قالب مطابقت ندارند باید (SHOULD) کنار گذاشته شوند. در چنین حالتی ممکن است (MAY) به کاربر هشدار داده شود.
انتظارات
کلاینت و
سرور در bundle-uri
محتوای URI
URI اعلانشده ممکن است حاوی یک فایل bundle باشد که دستور git bundle verify آن را میپذیرد. به این معنی که آنها حتماً باید (MUST) شامل یک یا چند نوک ارجاع برای استفاده کلاینت باشند، حتماً باید (MUST) پیشنیازها را (در صورت وجود) با پیشوندهای استاندارد "-" مشخص کنند، و در صورت لزوم باید (MUST) "object-format" خود را نشان دهند.
همچنین URI اعلانشده ممکن است حاوی یک فایل متنی ساده باشد که دستور git config list آن را میپذیرد (همراه با گزینه --file). جفتهای کلید-مقدار در این لیست در فضای نام bundle.* قرار دارند (به git-config(1) مراجعه کنید).
بازیابی خطای کلاینت در bundle-uri
مدیران سرور باید با اطمینان خاطر "bundle-uri" را فعال کنند و نگران نباشند که به عنوان مثال اگر CDN آنها از کار بیفتد، عملیات کلون یا واکشی با شکست قطعی روبرو شود. حتی اگر بسته(های) سرور ناقص باشند یا به نحوی اشکال داشته باشند، کلاینت همچنان باید به یک مخزن کارآمد دست یابد، دقیقاً همانطور که اگر تصمیم میگرفت از این الحاقیه پروتکل استفاده نکند.
تمام بحثهای بعدی درباره تعامل کلاینت و سرور حتماً باید (MUST) این موضوع را در نظر داشته باشند.
سرور به کلاینت در bundle-uri
یک سرور حتی ممکن است (MAY) بسته(هایی) را برگرداند که هیچ ارتباط مستقیمی با مخزن در حال کلون شدن ندارند (چه به طور تصادفی یا از روی پیکربندی عمدی و "هوشمندانه")، و انتظار داشته باشد که کلاینت دادههای مورد نظر خود را از بسته(ها) در صورت وجود استخراج کند.
کلاینت به سرور در bundle-uri
هنگامی که بسته(های) اعلانشده نیاز به مذاکره بیشتری ندارند
قطع زودهنگام اتصال کلاینت و بازیابی خطا
به این معنی که ممکن است کلاینت نیاز به اتصال مجدد و اجرای یک دستور fetch داشته باشد، و احتمالاً به استفاده نکردن از bundle-uri رجوع نماید.
این رفتار "میتواند (MAY)" بر اساس این فرض مشخص شده است (و نه یک "باید (SHOULD)") که سروری که URIهای بسته را اعلان میکند به احتمال زیاد در حال ارائه یک مخزن نسبتاً بزرگ است و به URIهایی اشاره میکند که شانس زیادی برای کارکرد صحیح دارند. کلاینت میتواند (MAY) مثلاً به اندازه بار داده بستهها به عنوان یک روش اکتشافی نگاه کند تا ببیند آیا قطع زودهنگام اتصال ارزش دارد یا خیر، در صورتی که بازگشت به یک گفتگوی کامل "fetch" لازم باشد.
هنگامی که بسته(های) اعلانشده به مذاکره بیشتری نیاز دارند
این امر امکان قطع سریع و زودهنگام اتصال از هر گفتگوی تعاملی سرور را فراهم میکند. کلاینت کورکورانه اعتماد میکند که نوکهای OID اعلانشده مرتبط هستند، و آنها را به عنوان خطوط have ارسال میکند، سپس هر نوکی را که میخواهد (معمولاً از اعلان "ls-refs") از طریق خطوط want درخواست مینماید. سپس سرور یک PACK (امیدوارم کوچک) را با تفاوت مورد انتظار بین نوکهای حاصل از بسته(ها) و دادههای درخواستی محاسبه خواهد کرد.
تنها اتصالی که کلاینت پس از آن نیاز به فعال نگهداشتن آن دارد، اتصال به بستههای ایستا است که همزمان دانلود میشوند؛ هنگامی که آنها و PACK افزایشی بازیابی شدند، باید باز شده و اعتبارسنجی شوند. هرگونه خطا در این مرحله باید به صورت برازنده بازیابی شود، به موارد بالا مراجعه کنید.
ویژگیهای
پروتکل bundle-uri
کلاینت یک لیست بسته را از جفتهای <key>=<value> ارائه شده توسط سرور میسازد. این جفتها بخشی از فضای نام bundle.* هستند همانطور که در git-config(1) مستند شده است. در این بخش، ما برخی از این کلیدها را بررسی میکنیم و اقداماتی را که کلاینت در پاسخ به این اطلاعات انجام میدهد شرح میدهیم.
به طور خاص، کلید bundle.version یک مقدار عددی صحیح را مشخص میکند. در حال حاضر تنها مقدار پذیرفتهشده 1 است، اما اگر کلاینت مقدار غیرمنتظرهای را در اینجا مشاهده کند، کلاینت حتماً باید (MUST) لیست بسته را نادیده بگیرد.
تا زمانی که bundle.version درک شود، سایر کلیدهای ناشناخته ممکن است (MAY) توسط کلاینت نادیده گرفته شوند. سرور سازگاری با کلاینتهای قدیمیتر را تضمین میکند، اگرچه کلاینتهای جدیدتر ممکن است بهتر بتوانند از کلیدهای اضافی برای به حداقل رساندن دانلودها استفاده کنند.
هرگونه افزودن ناسازگار با گذشته به جفتهای کلید-مقدار در سطح هر URI با مقدار یا مقادیر جدید bundle.version در خود اعلان قابلیت bundle-uri و/یا با آرگومانهای درخواست جدید bundle-uri در آینده محافظت خواهد شد.
برخی از نمونه جفتهای کلید-مقدار که در حال حاضر پیادهسازی نشدهاند اما میتوانند در آینده پیادهسازی شوند عبارتند از:
این امر امکان بهینهسازی حالت معمول سرورهایی را فراهم میکند که مایلند یک "بسته بزرگ" حاوی تنها شاخه "main" خود و/یا بهروزرسانیهای افزایشی آن را ارائه دهند.
کلاینتی که چنین پاسخی دریافت میکند میتواند (MAY) فرض کند که میتواند از بازیابی سرآیند از یک بسته در URI مشخصشده صرفنظر کند، و در نتیجه خود و سرور(ها) را از درخواست(های) مورد نیاز برای بررسی سرآیندهای آن بسته یا بستهها بینیاز کند.
promisor-remote=<pr-info>
سرور ممکن است برخی از ریموتهای promisor را که استفاده میکند یا از آنها آگاه است به کلاینتی که ممکن است بخواهد از آنها به عنوان ریموتهای promisor خود به جای این مخزن استفاده کند، اعلان نماید. در این حالت <pr-info> باید به این شکل باشد:
pr-info = pr-fields | pr-info ";" pr-fields
pr-fields = pr-field | pr-fields "," pr-field
pr-field = field-name "=" field-value
که در آن تمام field-name و field-value در یک pr-fields دادهشده، نامها و مقادیر فیلدهای مربوط به یک ریموت promisor منفرد هستند. یک field-name دادهشده نباید بیش از یک بار در یک pr-fields مشخص ظاهر شود (MUST NOT).
سرور حتماً باید (MUST) حداقل نامهای فیلد "name" و "url" را همراه با مقادیر فیلد مربوطه، که نام یک ریموت معتبر و URL آن هستند، در هر pr-fields اعلان کند. فیلدهای "name" و "url" حتماً باید (MUST) ابتدا در هر pr-fields و به همین ترتیب ظاهر شوند.
پس از این فیلدهای اجباری، سرور میتواند (MAY) فیلدهای اختیاری زیر را به هر ترتیبی اعلان کند:
partialCloneFilter
token
در حال حاضر هیچ فیلد دیگری توسط پروتکل تعریف نشده است. نام فیلدها به حروف کوچک و بزرگ حساس هستند و حتماً باید (MUST) دقیقاً همانطور که در بالا مشخص شده است منتقل شوند. کلاینتها حتماً باید (MUST) فیلدهایی را که تشخیص نمیدهند نادیده بگیرند تا امکان الحاقات آینده پروتکل فراهم شود.
کلاینت میتواند از اطلاعات منتقلشده از طریق این فیلدها استفاده کند تا تصمیم بگیرد که آیا ریموت promisor اعلانشده را میپذیرد یا خیر. همچنین، کلاینت را میتوان به گونهای پیکربندی کرد که مقادیر این فیلدها را ذخیره کند یا از آنها برای پیکربندی خودکار مخزن استفاده نماید (به "promisor.storeFields" در git-config(1) و --filter=auto در git-clone(1) مراجعه کنید).
مقادیر فیلد حتماً باید به صورت urlencoded باشند (MUST).
اگر کلاینت تصمیم بگیرد از یک یا چند ریموت promisor که سرور اعلان کرده است استفاده کند، میتواند با "promisor-remote=<pr-names>" پاسخ دهد که در آن <pr-names> باید به شکل زیر باشد:
pr-names = pr-name | pr-names ";" pr-name
که در آن pr-name نام urlencoded یک ریموت promisor است که سرور اعلان کرده و کلاینت آن را پذیرفته است.
ریموتهای promisor که کلاینت پذیرفته است، هنگام تلاش کلاینت برای واکشی اشیاء گمشده، قبل از سایر ریموتهای promisor پیکربندیشده امتحان خواهند شد.
توجه داشته باشید که در سراسر این سند، در صورتی که نویسههای ; و , در pr-name یا field-value ظاهر شوند، حتماً باید کدگذاری شوند (MUST).
اگر سرور هیچ ریموت promisor را که بتواند برای کلاینت مناسب باشد نداند، یا ترجیح دهد کلاینت از هیچ ریموت promisor که سرور استفاده میکند یا از آن آگاه است استفاده نکند، اصلاً نباید قابلیت "promisor-remote" را اعلان کند.
در این حالت، یا اگر کلاینت تمایلی به استفاده از هیچیک از ریموتهای promisor اعلانشده توسط سرور نداشته باشد، کلاینت نباید قابلیت "promisor-remote" را در پاسخ خود اعلان نماید.
در سمت سرور، گزینههای پیکربندی "promisor.advertise" و "promisor.sendFields" میتوانند برای کنترل آنچه اعلان میکند استفاده شوند. در سمت کلاینت، گزینه پیکربندی "promisor.acceptFromServer" میتواند برای کنترل آنچه میپذیرد، و گزینه "promisor.storeFields" برای کنترل آنچه ذخیره میکند، استفاده شود. برای اطلاعات بیشتر به مستندات این گزینههای پیکربندی در git-config(1) مراجعه کنید.
توجه داشته باشید که در آینده بسیار مطلوب خواهد بود اگر قابلیت پروتکل "promisor-remote" بتواند توسط سرور هنگام پاسخ به git fetch یا git clone استفاده شود تا ریموتهایی با اتصال بهتر را که کلاینت میتواند به عنوان ریموتهای promisor به جای این مخزن استفاده کند اعلان نماید، به طوری که کلاینت بتواند به صورت تنبل (lazily) اشیاء را از این ریموتهای با اتصال بهتر واکشی کند. این امر مستلزم آن است که سرور در پاسخ خود از ارسال اشیاء موجود در ریموتهای دارای اتصال بهتر که کلاینت پذیرفته است، صرفنظر نماید. با این حال این مورد هنوز پیادهسازی نشده است. بنابراین در حال حاضر این قابلیت "promisor-remote" تنها زمانی مفید است که سرور برخی از ریموتهای promisor را که از قبل برای قرض گرفتن اشیاء استفاده میکند، اعلان نماید.
گیت (GIT)
بخشی از مجموعه git(1)
یادداشتها (NOTES)
- 1.
- api-trace2
| 2026-06-29 | Git 2.55.0 |