Chapters ▾ 2nd Edition

8.3 سفارشی‌سازی Git (Customizing Git) - هوک‌های Git (Git Hooks)

هوک‌های Git (Git Hooks)

مثل بسیاری از سامانه‌های کنترل نسخه دیگر، Git راهی دارد تا هنگام رخ‌دادن بعضی عملیات مهم، اسکریپت‌های سفارشی را اجرا کند. دو گروه از این هوک‌ها وجود دارد: سمتِ کلاینت و سمتِ سرور. هوک‌های سمتِ کلاینت با عملیاتی مانند commit و merge فعال می‌شوند، در حالی که هوک‌های سمتِ سرور هنگام عملیات شبکه‌ای مثل دریافت commitهای push شده اجرا می‌گردند. می‌توانید از این هوک‌ها برای اهداف گوناگون استفاده کنید.

نصب یک هوک (Installing a Hook)

همهٔ هوک‌ها در زیرپوشهٔ hooks در دایرکتوری Git ذخیره می‌شوند. در اکثر پروژه‌ها این مسیر .git/hooks است. وقتی یک مخزن جدید را با git init مقداردهی می‌کنید، Git پوشهٔ hooks را با مجموعه‌ای از اسکریپت‌های نمونه پر می‌کند که بسیاری از آن‌ها به‌خودی‌خود مفیدند؛ همچنین ورودی‌ها و پارامترهای هر اسکریپت را مستندسازی می‌کنند. تمام نمونه‌ها به‌صورت اسکریپت شل نوشته شده‌اند و برخی هم از Perl استفاده می‌کنند، اما هر اسکریپت اجرایی‌ای که نام مناسبی داشته باشد به‌خوبی کار خواهد کرد - می‌توانید آن‌ها را به Ruby یا Python یا هر زبانی که با آن راحت‌اید بنویسید. اگر می‌خواهید از اسکریپت‌های بسته‌بندی‌شده استفاده کنید، باید نام آن‌ها را تغییر دهید؛ نام فایل‌های آن‌ها همگی با .sample خاتمه یافته است.

برای فعال کردن یک اسکریپت هوک، فایلی در زیرپوشهٔ hooks پوشهٔ .git خود قرار دهید که نام آن به‌درستی انتخاب شده باشد (بدون پسوند) و قابل اجرا باشد. از آن زمان به بعد، این اسکریپت فراخوانی خواهد شد. در ادامه نام‌های فایلِ بیش‌ترین هوک‌های مهم را پوشش می‌دهیم.

هوک‌های سمتِ کلاینت (Client-Side Hooks)

هوک‌های سمتِ کلاینت زیادی وجود دارند. این بخش آن‌ها را به هوک‌های جریان کار commit، اسکریپت‌های جریان کار ایمیل، و سایر موارد تقسیم می‌کند.

یادداشت

مهم است بدانید که هوک‌های سمتِ کلاینت هنگام clone شدنِ مخزن کپی نمی‌شوند. اگر هدف‌تان از این اسکریپت‌ها اعمال یک سیاست است، احتمالاً می‌خواهید آن را در سمتِ سرور اعمال کنید؛ نمونه‌ای از این مورد را در یک نمونه سیاست اعمال شده توسط گیت (An Example Git-Enforced Policy) ببینید.

هوک‌های مرتبط با جریان کار (Committing-Workflow Hooks)

چهار هوک اول مربوط به فرایند commit هستند.

هوک pre-commit اولین هوکی است که اجرا می‌شود، حتی قبل از اینکه پیام کامیت را وارد کنید. این هوک برای بررسی اسنپ‌شاتی که قرار است کامیت شود به کار می‌رود؛ برای دیدن اینکه چیزی را فراموش نکرده‌اید، اطمینان از اجرای تست‌ها، یا بررسی هر چیزی که لازم است در کد بازدید شود. خروج با کد غیرصفر از این هوک باعث لغو کامیت می‌شود، اگرچه می‌توانید با استفاده از git commit --no-verify آن را دور بزنید. می‌توانید کارهایی مثل بررسی سبک کد (اجرای lint یا معادل آن)، بررسی فاصله‌های انتهایی سطرها (هوک پیش‌فرض دقیقاً همین را انجام می‌دهد)، یا بررسی مستندات مناسب برای متدهای جدید را انجام دهید.

هوک prepare-commit-msg قبل از باز شدن ویرایشگر پیام کامیت ولی پس از ساخته شدن پیام پیش‌فرض اجرا می‌شود. این امکان را به شما می‌دهد که پیام پیش‌فرض را قبل از اینکه نویسندهٔ کامیت آن را ببیند ویرایش کنید. این هوک چند پارامتر می‌گیرد: مسیر فایلی که تا کنون پیام کامیت در آن ذخیره شده، نوع کامیت، و SHA-1 کامیت در صورتی که این یک کامیت اصلاح‌شده (amended) باشد. این هوک معمولاً برای کامیت‌های معمولی مفید نیست؛ بلکه برای کامیت‌هایی مناسب است که پیام پیش‌فرض به‌صورت خودکار تولید می‌شود، مثل پیام‌های قالبی، کامیت‌های merge، کامیت‌های squash شده، و کامیت‌های اصلاح‌شده. می‌توانید آن را همراه با یک قالب پیام کامیت به‌کار ببرید تا اطلاعات را برنامه‌ریزی‌شده وارد کنید.

هوک commit-msg یک پارامتر می‌گیرد که آن هم مسیر یک فایل موقت است که پیام کامیت نوشته‌شده توسط توسعه‌دهنده را در خود دارد. اگر این اسکریپت با کد غیرصفر خارج شود، گیت فرایند کامیت را متوقف می‌کند، بنابراین می‌توانید از آن برای اعتبارسنجی وضعیت پروژه یا پیام کامیت پیش از اجازه‌دادن به انجام کامیت استفاده کنید. در بخش آخر این فصل، نشان خواهیم داد چگونه از این هوک برای بررسی تطابق پیام کامیت با یک الگوی موردنیاز استفاده کنید.

    پس از تکمیل کل فرایند کامیت، هوک `post-commit` اجرا می‌شود.
این هوک پارامتری نمی‌گیرد، اما به‌راحتی می‌توانید آخرین کامیت را با اجرای `git log -1 HEAD` بگیرید.
به‌طور کلی، این اسکریپت برای اعلان یا کارهای مشابه استفاده می‌شود.

قلاب‌های جریان کاری ایمیل (Email Workflow Hooks)

می‌توانید سه قلاب سمت کلاینت برای یک جریان کاری مبتنی بر ایمیل تنظیم کنید. همهٔ این‌ها توسط فرمان git am فراخوانی می‌شوند، بنابراین اگر از آن فرمان در جریان کاری‌تان استفاده نمی‌کنید، می‌توانید به‌راحتی به بخش بعدی بروید. اگر پچ‌هایی که از طریق ایمیل می‌گیرید را با git format-patch آماده می‌کنید، برخی از این قلاب‌ها ممکن است برایتان مفید باشند.

اولین قلابی که اجرا می‌شود applypatch-msg است. این قلاب یک آرگومان می‌گیرد: نام فایل موقتی که پیام کمیت پیشنهادی در آن قرار دارد. اگر این اسکریپت با کد خروجی غیرصفر پایان یابد، گیت پچ را لغو می‌کند. می‌توانید از این برای اطمینان از قالب صحیح پیام کمیت استفاده کنید یا با ویرایش پیام در محل توسط اسکریپت، آن را نرمال‌سازی کنید.

قلاب بعدی که هنگام اعمال پچ‌ها از طریق git am اجرا می‌شود pre-applypatch است. تا حدی گیج‌کننده است که این قلاب بعد از اعمال پچ ولی قبل از ساختن کمیت اجرا می‌شود، بنابراین می‌توانید از آن برای بررسی snapshot قبل از انجام کمیت استفاده کنید. می‌توانید با این اسکریپت تست‌ها را اجرا کنید یا درخت کاری را بررسی کنید. اگر چیزی کم است یا تست‌ها قبول نشدند، خروجی غیرصفر موجب لغو اسکریپت git am بدون ساختن کمیت می‌شود.

آخرین قلابی که در یک عملیات git am اجرا می‌شود post-applypatch است که بعد از انجام کمیت اجرا می‌شود. می‌توانید از آن برای اطلاع‌رسانی به یک گروه یا نویسندهٔ پچی که دریافت کرده‌اید استفاده کنید که آن را اعمال کرده‌اید. با این اسکریپت نمی‌توانید فرایند اعمال پچ را متوقف کنید.

هوک های دیگر کلاینت (Other Client Hooks)

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

قلاب post-rewrite توسط دستوراتی که کامیت‌ها را جایگزین می‌کنند اجرا می‌شود، مانند git commit --amend و git rebase (اما توسط git filter-branch اجرا نمی‌شود). آرگومان یکتای آن نشان‌دهنده‌ی دستوری است که بازنویسی را راه‌اندازی کرده و لیستی از بازنویسی‌ها را از طریق stdin دریافت می‌کند. این قلاب کاربردهای زیادی مشابه با قلاب‌های post-checkout و post-merge دارد.

پس از اجرای موفقیت‌آمیز git checkout، قلاب post-checkout اجرا می‌شود؛ می‌توانید از آن برای آماده‌سازی درست درخت کاری پروژه‌تان استفاده کنید. این ممکن است شامل انتقال فایل‌های باینری حجیم که نمی‌خواهید تحت کنترل نسخه باشند، تولید خودکار مستندات، یا کارهایی مشابه باشد.

قلاب post-merge پس از اجرای موفق merge اجرا می‌شود. می‌توانید از آن برای بازگرداندن داده‌هایی در درخت کاری که گیت قادر به دنبال کردنشان نیست مثل اطلاعات دسترسی (permissions) استفاده کنید. این قلاب همچنین می‌تواند وجود فایل‌های خارج از کنترل گیت را که می‌خواهید هنگام تغییر درخت کاری کپی شوند، اعتبارسنجی کند.

قلاب pre-push طی git push اجرا می‌شود، پس از اینکه رفرنس‌های ریموت به‌روزرسانی شدند اما قبل از انتقال هر شیء. نام و مکان ریموت را به‌عنوان پارامتر دریافت می‌کند و لیستی از رفرنس‌هایی که قرار است به‌روزرسانی شوند را از طریق stdin می‌گیرد. می‌توانید از آن برای اعتبارسنجی مجموعه‌ای از به‌روزرسانی‌های رفرنس پیش از انجام push استفاده کنید (خروجی با کد غیرصفر باعث لغو push می‌شود).

گیت گهگاه به‌عنوان بخشی از عملیات عادی خود جمع‌آوری زباله انجام می‌دهد، با فراخوانی git gc --auto. هوک pre-auto-gc درست پیش از انجام جمع‌آوری زباله فراخوانی می‌شود و می‌تواند برای اطلاع‌رسانی اینکه این کار در حال انجام است یا برای لغو جمع‌آوری در صورتی که الان زمان مناسبی نباشد، استفاده شود.

قلاب‌های سمت سرور (Server-Side Hooks)

علاوه بر قلاب‌های سمت کلاینت، می‌توانید به عنوان مدیر سیستم از چند قلاب مهم سمت سرور برای اجرای تقریباً هر نوع سیاستی برای پروژه خود استفاده کنید. این اسکریپت‌ها قبل و بعد از push به سرور اجرا می‌شوند. قلاب‌های قبل از اجرا می‌توانند در هر زمانی با خروج غیرصفر، فشار را رد کنند و همچنین پیام خطایی را به مشتری برگردانند؛ شما می‌توانید یک سیاست فشار را به هر اندازه که می‌خواهید پیچیده تنظیم کنید.

هوک قبل از دریافت (pre-receive)

اولین اسکریپتی که هنگام رسیدگی به push از سمت یک کلاینت اجرا می‌شود، pre-receive است. لیستی از مراجع را که از ورودی استاندارد (stdin) وارد می‌شوند، می‌گیرد؛ اگر با کد غیرصفر خارج شود، هیچ‌کدام از آن‌ها پذیرفته نمی‌شوند. می‌توانید از این قلاب برای کارهایی مانند اطمینان از اینکه هیچ یک از مراجع به‌روزرسانی‌شده غیرقابل پیشروی سریع نیستند، یا برای کنترل دسترسی به تمام مراجع و فایل‌هایی که با فشار تغییر می‌دهند، استفاده کنید.

هوک به‌روزرسانی (update)

اسکریپت update بسیار شبیه به اسکریپت pre-receive است، با این تفاوت که برای هر شاخه‌ای که push کننده سعی در به‌روزرسانی آن دارد، یک بار اجرا می‌شود. اگر فشاردهنده سعی دارد به شاخه‌های متعددی فشار وارد کند، pre-receive فقط یک بار اجرا می‌شود، در حالی که update به ازای هر شاخه‌ای که به آن فشار وارد می‌کند، یک بار اجرا می‌شود. به جای خواندن از ورودی استاندارد، این اسکریپت سه آرگومان می‌گیرد: نام مرجع (شاخه)، هش SHA-1 که مرجع قبل از push به آن اشاره می‌کرد، و هش SHA-1 که کاربر در حال تلاش برای push کردن آن است. اگر اسکریپت update با کد خروج غیرصفر به پایان برسد، فقط آن مرجع رد می‌شود؛ سایر مراجع همچنان می‌توانند به‌روزرسانی شوند.

هوک بعد از دریافت (post-receive)

قلاب post-receive پس از تکمیل کل فرآیند اجرا می‌شود و می‌تواند برای به‌روزرسانی سرویس‌های دیگر یا اطلاع‌رسانی به کاربران استفاده شود. داده‌های ورودی استاندارد (stdin) مشابه قلاب pre-receive را دریافت می‌کند. نمونه‌هایی از این موارد شامل ارسال ایمیل به یک لیست، اطلاع‌رسانی به سرور یکپارچه‌سازی مداوم یا به‌روزرسانی سیستم ردیابی تیکت است – حتی می‌توانید پیام‌های کامیت را تجزیه و تحلیل کنید تا ببینید آیا نیاز به باز کردن، اصلاح یا بستن تیکتی وجود دارد یا خیر. این اسکریپت نمی‌تواند فرآیند فشار را متوقف کند، اما کلاینت تا زمانی که کامل نشده است قطع نمی‌شود، بنابراین اگر سعی دارید کاری انجام دهید که ممکن است زمان زیادی طول بکشد، مراقب باشید.

نکته

اگر در حال نوشتن اسکریپت/هوک هستید که دیگران باید آن را بخوانند، نسخه‌های طولانی‌تر پرچم‌های خط فرمان را ترجیح دهید؛ شش ماه دیگر از ما تشکر خواهید کرد.

scroll-to-top