GIT-RECEIVE-PACK(1) دستورات عمومی کاربر GIT-RECEIVE-PACK(1)

git-receive-pack - دریافت موارد ارسال‌شده (push) به مخزن

git receive-pack <git-dir>

توسط git send-pack فراخوانی می‌شود و مخزن را با اطلاعات دریافت‌شده از سمت راه دور به‌روزرسانی می‌کند.

این دستور معمولاً مستقیماً توسط کاربر نهایی فراخوانی نمی‌شود. رابط کاربری این پروتکل در سمت git send-pack قرار دارد و این جفت برنامه برای ارسال به‌روزرسانی‌ها به یک مخزن راه دور استفاده می‌شوند. برای عملیات دریافت (pull)، به git-fetch-pack(1) مراجعه کنید.

این دستور امکان ایجاد و هدایت سریع (fast-forward) ارجاع‌های sha1 (شاخه‌ها/برچسب‌ها) را در سمت راه دور فراهم می‌کند (به بیان دقیق، git-receive-pack در سمت محلی اجرا می‌شود، اما برای کاربری که در سمت send-pack نشسته است، این دستور در حال به‌روزرسانی مخزن راه دور است. گیج شدید؟)

نمونه‌های دنیای واقعی دیگری از استفاده از قلاب‌های update و post-update در پوشه Documentation/howto یافت می‌شود.

دستور git-receive-pack به گزینه پیکربندی receive.denyNonFastForwards احترام می‌گذارد؛ این گزینه تعیین می‌کند آیا در صورتی که به‌روزرسانی‌های یک ارجاع به‌صورت fast-forward نباشند، باید رد شوند یا خیر.

تعدادی دیگر از گزینه‌های پیکربندی *receive برای تنظیم دقیق رفتار آن در دسترس هستند، به git-config(1) مراجعه کنید.

<git-dir>

مخزنی که باید با آن همگام‌سازی شود.

--p-backend-info-refs

توسط git-http-backend(1) برای پاسخگویی به درخواست‌های $GIT_URL/info/refs?service=git-receive-pack استفاده می‌شود. به --p-backend-info-refs در git-upload-pack(1) مراجعه کنید.

--ip-connectivity-check

بررسی‌های اتصال را که وجود تمام اشیاء در بستار متعدی (transitive closure) اشیاء قابل دسترسی را اعتبارسنجی می‌کند، دور می‌زند. این گزینه برای مدیران سروری در نظر گرفته شده است که می‌خواهند اعتبارسنجی اتصال اشیاء را خارج از گیت پیاده‌سازی کنند. این گزینه در مواردی مفید است که سمت سرور اطلاعات اضافی در مورد نحوه استفاده از گیت دارد و بنابراین می‌تواند به تضمین‌های خاصی برای محاسبه کارآمدتر اتصال اشیاء تکیه کند که خود گیت قادر به انجام آن نیست. استفاده از این گزینه بدون یک سازوکار خارجی قابل اعتماد برای اطمینان از اتصال کامل اشیاء قابل دسترسی، خطر خراب شدن مخزن را در پی دارد و نباید در حالت عمومی استفاده شود.

قبل از به‌روزرسانی هر ارجاع، اگر فایل $GIT_DIR/hooks/pre-receive وجود داشته و قابل اجرا باشد، یک بار بدون پارامتر فراخوانی می‌شود. ورودی استاندارد این قلاب برای هر ارجاعی که قرار است به‌روزرسانی شود، شامل یک خط خواهد بود:

sha1-old SP sha1-new SP refname LF

مقدار refname نسبت به $GIT_DIR سنجیده می‌شود؛ به عنوان مثال برای شاخه master این مقدار "refs/heads/master" است. دو مقدار sha1 قبل از هر refname، نام اشیاء برای آن refname قبل و بعد از به‌روزرسانی هستند. ارجاع‌هایی که ایجاد می‌شوند دارای sha1-old برابر با 0{40} خواهند بود، در حالی که ارجاع‌هایی که حذف می‌شوند دارای sha1-new برابر با 0{40} هستند؛ در غیر این صورت sha1-old و sha1-new باید اشیاء معتبری در مخزن باشند.

هنگام پذیرش یک ارسال امضاشده (push امضا‌شده، به git-push(1) مراجعه کنید)، گواهی push امضاشده در یک blob ذخیره می‌شود و متغیر محیطی GIT_PUSH_CERT را می‌توان برای یافتن نام شیء آن بررسی کرد. برای دیدن یک مثال، توضیحات قلاب post-receive را مشاهده کنید. علاوه بر این، گواهی با استفاده از GPG اعتبارسنجی می‌شود و نتیجه آن در متغیرهای محیطی زیر صادر می‌گردد:

GIT_PUSH_CERT_SIGNER

نام و نشانی ایمیل صاحب کلیدی که گواهی ارسال را امضا کرده است.

GIT_PUSH_CERT_KEY

شناسه کلید GPG مربوط به کلیدی که گواهی ارسال را امضا کرده است.

GIT_PUSH_CERT_STATUS

وضعیت اعتبارسنجی GPG گواهی ارسال، با استفاده از همان کدهای حروفی استفاده‌شده در قالب %G? خانواده دستورات git log (به git-log(1) مراجعه کنید).

GIT_PUSH_CERT_NONCE

رشته نانس (nonce) که فرآیند از امضاکننده درخواست کرده تا در گواهی ارسال بگنجاند. اگر این مقدار با مقدار ثبت‌شده در هدر "nonce" در گواهی ارسال مطابقت نداشته باشد، ممکن است نشان دهد که گواهی معتبری است اما از یک نشست دیگر "git push" بازپخش شده است.

GIT_PUSH_CERT_NONCE_STATUS

UNSOLICITED

دستور "git push --gned" یک نانس ارسال کرد در حالی که ما درخواستی برای ارسال آن نداده بودیم.

MISSING

دستور "git push --gned" هیچ هدر نانسی ارسال نکرد.

BAD

دستور "git push --gned" یک نانس جعلی یا نامعتبر ارسال کرد.

OK

دستور "git push --gned" همان نانسی را ارسال کرد که ما درخواست کرده بودیم.

SLOP

دستور "git push --gned" نانسی متفاوت از آنچه اکنون خواسته‌ایم ارسال کرد، اما این نانس مربوط به یک نشست قبلی بوده است. به متغیر محیطی GIT_PUSH_CERT_NONCE_SLOP مراجعه کنید.

GIT_PUSH_CERT_NONCE_SLOP

دستور "git push --gned" نانسی متفاوت از آنچه اکنون خواسته‌ایم ارسال کرد، اما مربوط به نشستی دیگر است که زمان شروع آن به این تعداد ثانیه با نشست فعلی تفاوت دارد. تنها زمانی معنادار است که GIT_PUSH_CERT_NONCE_STATUS مقدار SLOP داشته باشد. همچنین درباره متغیر receive.certNonceSlop در git-config(1) بخوانید.

این قلاب قبل از به‌روزرسانی هر نام ارجاعی و قبل از انجام هرگونه بررسی fast-forward فراخوانی می‌شود.

اگر قلاب pre-receive با وضعیت خروج غیر صفر خارج شود، هیچ به‌روزرسانی انجام نخواهد شد و قلاب‌های update، post-receive و post-update نیز فراخوانی نخواهند شد. این امر می‌تواند برای انصراف سریع در مواردی که به‌روزرسانی پشتیبانی نمی‌شود، مفید باشد.

یادداشت‌های مربوط به محیط قرنطینه در زیر را مشاهده کنید.

قبل از به‌روزرسانی هر ارجاع، اگر فایل $GIT_DIR/hooks/update وجود داشته و قابل اجرا باشد، به ازای هر ارجاع یک بار با سه پارامتر فراخوانی می‌شود:

$GIT_DIR/hooks/update refname sha1-old sha1-new

پارامتر refname نسبت به $GIT_DIR سنجیده می‌شود؛ به عنوان مثال برای شاخه master این مقدار "refs/heads/master" است. دو آرگومان sha1 نام اشیاء برای آن refname قبل و بعد از به‌روزرسانی هستند. توجه داشته باشید که این قلاب قبل از به‌روزرسانی refname فراخوانی می‌شود، بنابراین یا sha1-old برابر با 0{40} است (به این معنی که هنوز چنین ارجاعی وجود ندارد)، یا باید با آنچه در refname ثبت شده مطابقت داشته باشد.

قلاب در صورتی که بخواهد مانع به‌روزرسانی ارجاع نام‌برده شود، باید با وضعیت خروج غیر صفر خارج شود. در غیر این صورت باید با وضعیت صفر خارج گردد.

اجرای موفقیت‌آمیز (وضعیت خروج صفر) این قلاب تضمین نمی‌کند که ارجاع واقعاً به‌روزرسانی خواهد شد، بلکه تنها یک پیش‌نیاز است. به همین دلیل ارسال اعلان‌ها (مانند ایمیل) از این قلاب ایده خوبی نیست. در عوض از قلاب post-receive استفاده کنید.

پس از اینکه تمام ارجاع‌ها به‌روزرسانی شدند (یا تلاش شد که به‌روزرسانی شوند)، اگر به‌روزرسانی حداقل یک ارجاع موفقیت‌آمیز بوده باشد، و اگر فایل $GIT_DIR/hooks/post-receive وجود داشته و قابل اجرا باشد، یک بار بدون پارامتر فراخوانی می‌شود. ورودی استاندارد این قلاب برای هر ارجاعی که با موفقیت به‌روزرسانی شده، یک خط خواهد بود:

sha1-old SP sha1-new SP refname LF

مقدار refname نسبت به $GIT_DIR سنجیده می‌شود؛ به عنوان مثال برای شاخه master این مقدار "refs/heads/master" است. دو مقدار sha1 قبل از هر refname، نام اشیاء برای آن refname قبل و بعد از به‌روزرسانی هستند. ارجاع‌هایی که ایجاد شده‌اند دارای sha1-old برابر با 0{40} خواهند بود، در حالی که ارجاع‌هایی که حذف شده‌اند دارای sha1-new برابر با 0{40} هستند؛ در غیر این صورت sha1-old و sha1-new باید اشیاء معتبری در مخزن باشند.

متغیرهای محیطی GIT_PUSH_CERT* را می‌توان همانند قلاب pre-receive، پس از پذیرش یک ارسال امضا‌شده بررسی کرد.

با استفاده از این قلاب، تولید ایمیل‌هایی که به‌روزرسانی‌های مخزن را شرح می‌دهند بسیار آسان است. این اسکریپت نمونه، برای هر ارجاع یک پیام ایمیل شامل فهرست کامیت‌های ارسال‌شده به مخزن می‌فرستد، و گواهی‌های ارسال‌های امضاشده با امضای معتبر را در یک سرویس ثبت لاگ ذخیره می‌کند:

#!/bin/sh
# mail out commit update information.
while read oval nval ref
do
        if expr "$oval" : '0*$' >/dev/null
        then
                echo "Created a new ref, with the following commits:"
                git rev-list --retty
"$nval"
        else
                echo "New commits:"
                git rev-list --retty
"$nval" "^$oval"
        fi |
        mail -s "Changes to ref $ref" commit-list@mydomain
done
# log signed push certificate, if any
if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G
then
        (
                echo expected nonce is ${GIT_PUSH_NONCE}
                git cat-file blob ${GIT_PUSH_CERT}
        ) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain
fi
exit 0

کد خروج حاصل از فراخوانی این قلاب نادیده گرفته می‌شود، با این حال یک کد خروج غیر صفر پیام خطایی ایجاد خواهد کرد.

توجه داشته باشید که ممکن است هنگام اجرای این قلاب، refname مقدار sha1-new را نداشته باشد. این حالت زمانی به راحتی رخ می‌دهد که کاربر دیگری ارجاع را پس از به‌روزرسانی توسط git-receive-pack اما قبل از اینکه قلاب بتواند آن را ارزیابی کند اصلاح نماید. توصیه می‌شود که قلاب‌ها به‌جای مقدار فعلی refname به sha1-new تکیه کنند.

پس از تمام پردازش‌های دیگر، اگر حداقل یک ارجاع به‌روزرسانی شده باشد، و اگر فایل $GIT_DIR/hooks/post-update وجود داشته و قابل اجرا باشد، post-update همراه با فهرستی از ارجاع‌های به‌روزرسانی‌شده فراخوانی خواهد شد. این امر می‌تواند برای پیاده‌سازی هرگونه عملیات پاک‌سازی در کل مخزن استفاده شود.

کد خروج حاصل از فراخوانی این قلاب نادیده گرفته می‌شود؛ در آن نقطه تنها کاری که برای git-receive-pack باقی مانده خروج است.

این قلاب می‌تواند به عنوان مثال برای اجرای git update-server-info در صورتی که مخزن بسته‌بندی شده و از طریق یک پروتکل انتقال ساده ارائه می‌شود، استفاده گردد.

#!/bin/sh
exec git update-server-info

هنگامی که receive-pack اشیاء را دریافت می‌کند، آن‌ها در یک پوشه موقت "قرنطینه" داخل پوشه $GIT_DIR/objects قرار می‌گیرند و تنها پس از اتمام موفقیت‌آمیز قلاب pre-receive به مخزن اصلی اشیاء منتقل می‌شوند. اگر ارسال قبل از آن با شکست مواجه شود، پوشه موقت به‌طور کامل حذف می‌گردد.

این امر چند اثر و نکته قابل مشاهده برای کاربر دارد:

1.ارسال‌هایی که به دلیل مشکل در بسته دریافتی، اشیاء مفقود، یا به دلیل قلاب pre-receive با شکست مواجه می‌شوند، هیچ داده‌ای روی دیسک باقی نخواهند گذاشت. این ویژگی معمولاً برای جلوگیری از پر شدن دیسک بر اثر ارسال‌های ناموفق مکرر مفید است، اما می‌تواند عیب‌یابی را دشوارتر کند.
2.هر شیئی که توسط قلاب pre-receive ایجاد شود، در پوشه قرنطینه ایجاد خواهد شد (و تنها در صورت موفقیت منتقل می‌گردد).
3.قلاب pre-receive نباید هیچ ارجاعی را طوری به‌روزرسانی کند که به اشیاء قرنطینه‌شده اشاره کنند. سایر برنامه‌هایی که به مخزن دسترسی دارند قادر به دیدن این اشیاء نخواهند بود (و اگر قلاب pre-receive شکست بخورد، آن ارجاع‌ها خراب می‌شوند). برای ایمنی، هرگونه به‌روزرسانی ارجاع از داخل pre-receive به‌طور خودکار رد می‌شود.

git-send-pack(1), gitnamespaces(7)

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

2026-06-29 Git 2.55.0