نوشتهی اصلی از Natalie Pina
خیلی از برنامهنویسها اوایل آشنایی و بکارگیری Git در درک روال کار آن دچار مشکل میشوند. این مسئله به خصوص در برخورد با پیامهایی که برای کامیتها باید نوشت نمود پیدا میکند. بسیاری در مورد اینکه تغییراتی که روی کد خود اعمال کردهاند و دلایل این تغییرات را چگونه میتوانند به خوبی در چند سطر خلاصه کنند دچار تردید میشوند.
این نوشته سعی میکند راههایی برای نوشتن پیامهای بهتر را به شما نشان دهد؛ البته با این فرض که مبانی و روال کار گیت را میشناسید. در غیر این صورت، بهتر است ابتدا به سراغ منابعی مانند Git Handbook بروید.
ذکر این نکته نیز ضروریست که اعضای تیمهای برنامهنویسی باید پیش از هر چیز از قواعد و قراردادهای تیم خود پیروی کنند. اما شاید پس از مطالعهی این نکات، که حاصل پژوهش و برآیند تجربهی جامعهی بزرگی از برنامهنویسان با پیشزمینههای مختلف میباشند، شما نیز راهکارهایی برای پیشنهاد به تیم خود و بهبود روند کاری خود داشته باشید.
حتما برای خیلی از ما پیش آمده است که در محیط کاری یا پروژههای شخصی به کدهایی برخوردهایم که، با وجود اینکه همین چند ماه پیش خود ما آنها را نوشتهایم، هیچ ایدهای در مورد کاربرد و نحوهی کار آنها نداشتهایم. بدتر این که در بسیاری از موارد چنین کدهایی نه کامنتی دارند و نه سرنخی در هیچ یک از مستندات و دستنوشتهها. اینجاست که کوچکترین تغییری تبدیل به ریسکی بزرگ میشود و چه بسا منجر به از کار افتادن کل برنامه!
به سادگی و با نوشتن پیامهای مناسب برای کامیتها میتوان از بسیاری مشکلات آتی و تلف شدن ساعتها وقت چندین نفر برای سر درآوردن از تغییرات ایجاد شده و آزمون و خطا روی آنها پیشگیری کرد.
بدون شک وقت بیشتری که روی فکر کردن در مورد پیام کامیت و نوشتن آن به صورت نامهای به خود در آینده گذاشته میشود، با مرور زمان ارزشی چندین برابر پیدا خواهد کرد. در پروژههای بزرگ چنین مستندسازیهایی ضروری و بلکه حیاتی میباشند.
همکاری و ارتباطات بیشترین اهمیت را در تیمهای مهندسی دارند. پیامهای کامیتهای گیت نمونهی بارز این مسئله میباشند. به شدت پیشنهاد میشود در صورتی که در تیم خود قراردادی دربارهی نحوهی نوشتن پیام برای کامیتها ندارید در اولین فرصت چنین قواعدی را تنظیم و اعمال کنید.
پیام ساده:
git commit -m <message>
پیام دارای جزئیات:
git commit -m <title> -m <description>
به طور خلاصه میتوان این راهنما را به این صورت بیان کرد:
Add fix for dark mode toggle state
روزنامهنگاران و نویسندگان برای اطمینان از اینکه نوشتههایشان دارای جزییات کافی، سرراست، و پاسخدهندهی تمام پرسشهای خوانندگان هست سوالاتی، از قبیل چه کسی؟ چه چیزی؟ چه زمان و مکانی؟ چرا و چگونه؟، را از خود میپرسند و سعی میکنند در نوشتهی خود آنها را پاسخ دهند.
در مورد پیامهای کامیتها حتما باید به پرسشهای چه و چرا پاسخ داد. برای رسیدن به پیامی خوشساخت و فکر شده برای کامیت خود باید این موارد را در نظر گرفت:
همیشه باید فرض کرد مخاطب (خوانندهی کد و پیام) قادر به درک تغییرات ایجاد شده طی کامیت نیست، و به داستان (User Story) بیان کنندهی دلیل و زمینهی تغییرات نیز دسترسی ندارد. نباید کد خود را بدیهی و بینیاز از توضیح دانست.
حتی در مورد تغییراتی که ممکن است آنها را واضح و بدیهی تصور کنید، از قبیل تغییراتی عینی مثل بروزرسانی CSS یا تغییراتی که نسبت به دلایل نیاز به آنها اشراف و آگاهی کامل دارید، بعید است پس از گذشت چند وقت و بدون نوشتن پیامی مناسب بتوانید آنها را از میان صدها کامیت ایجاد شده تشخیص دهید و به یاد آورید.
همیشه چرایی ایجاد هر تغییر را روشن و میزان اهمیت و تاثیر آن بر عملکرد برنامه را مشخص کنید.
دو پیام زیر را مقایسه کنید:
git commit -m 'Add margin'
git commit -m 'Add margin to nav items to prevent them from overlapping the logo'
ناگفته پیداست کدام یک برای مخاطبان آتی مناسب و سودمند خواهد بود.
همواره تصور کنید که در حال نوشتن یک مقالهی مهم خبری هستید. عنوانی را ارائه دهید که آنچه رخ داده و آنچه مهم است را به صورتی خلاصه بیان کند. سپس، جزییات بیشتر را در بدنهی پیام و به شکلی سازمان یافته ارائه دهید.
در فیلمسازی که عناصر بصری به عنوان رسانهی ارتباطی و به جای توضیح کلامی آنچه در حال رخ دادن است به کار گرفته میشوند از اصطلاح "نشان بده، نگو" استفاده میشود. اما در زمینهی مبحث ما باید گفت "بگو، [فقط] نشان نده" - گرچه ما نیز برخی عناصر بصری مثل مرورگر در اختیار داریم، اما بخش زیادی از اطلاعات و جزییات از خواندن کدها بدست میآید.
افزونههایی از قبیل Git Blame، Git History و GitLens در VSCode اطلاعات مربوط به هر کامیت، اعم از کسی که تغییرات را اعمال کرده، تاریخ و زمان ایجاد تغییرات و نیز پیام نوشته شده برای کامیت را به صورت کامنت درون کد نشان میدهد. تصور کنید این کار چقدر میتواند در ریشهیابی ایراد رخ داده یا تغییرات اعمال شده راهگشا باشد. این نمونهی خوبی برای نمایش زمانیست که پیامهای کامیتها به برنامهنویسهای آتی کمک میکند و مفید واقع میشوند.
اکنون که ساختار پایهی یک پیام خوب برای کامیت را بررسی کردهایم، بهتر است برای کمک به ارائهی جزییاتی بیشتر در نوشتن پیامهایی مطمئن و یکپارچه با Conventional Commits آشنا شویم.
Conventional Commits یک قرارداد قالببندیست که مجموعهای قوانین برای بیان قاعدهمند ساختاری یکدست برای پیامهای کامیت ارائه میکند. برای نمونه:
<type>[optional scope]: <description> [optional body] [optional footer(s)]
نوع (type) کامیت الزامیست و میتواند شامل موارد زیر باشد:
feat
– تغییرات شامل یک ویژگی جدید میباشند fix
– تغییراتی که شامل رفع یک ایراد میباشندchore
– تغییراتی که مربوط به ویژگی یا ایرادی نمیباشند و فایلهای منبع و تست را نیز تغییر نمیدهند (برای مثال بروزرسانی وابستگیها)refactor
– بازآرایی کد که نه ایرادی را رفع و نه ویژگی جدیدی را اضافه میکندdocs
– readme تغییرات مربوط به بروزرسانی مستنداتی مانند فایلstyle
– تغییراتی که تاثیری روی معنای کد ندارند، و عمدتا مربوط به قالببندی کد از قبیل فضاهای خالی و سطرهای فاصله و سمیکولونهای جامانده و غیره میباشندtest
– تغییراتی که شامل ایجاد آزمونی جدید یا تصحیح آزمونهای قبلی میباشندperf
– تغییراتی که برای بهبود کارایی میباشندci
– (continuous integration) تغییراتی که مربوط به یکپارچه سازی مداوم میباشندbuild
– (build system) تغییراتی که مربوط به سیستم ساخت یا وابستگیهای بیرونی میباشندrevert
– بازگردانی یکی از کامیتهای پیشینموضوع (description) نیز الزامیست و باید تماما با حروف کوچک نوشته شود و دارای محدودیت کاراکتری باشد تا کاربر را به خلاصهنویسی وادار و تشویق کند.
بدنهی پیام (body) که اختیاریست باید برای ارائهی جزییاتی که در محدودیت کاراکتر موضوع نمیگنجند به کار رود. همچنین این بخش جای مناسبیست که به صورت زیر تغییری شکننده (breaking change) که در کامیت وجود دارد را تشریح و دلیل آن را بیان کرد:
BREAKING CHANGE: <description>
پاورقی (footer) نیز اختیاریست. میتوان از آن برای مشخص کردن شناسهی داستانهایی (User Story) که در نتیجهی این تغییرات بسته میشوند استفاده کرد.
fix: fix foo to enable bar This fixes the broken behavior of the component by doing xyz. BREAKING CHANGE Before this fix foo wasn't enabled at all, behavior changes from <old> to <new> Closes D2IQ-12345
برای اطمینان از اعمال این قرارداد روی تمامی کامیتها، میتوان با استفاده از ابزارهایی مانند Commitizen این قواعد را در محیط برنامهنویسی اعمال کرد تا هر کامیت پیش از ثبت توسط آنها بررسی شود.
همچنین برای کمک به پذیرش و اشتراک این قرارداد میان برنامهنویسان، بهتر است این قواعد را در یک فایل مخصوص یا فایل readme در پروژه ثبت کرد.
Conventional Commits به ویژه در هماهنگی با نسخهزنی معنایی (semantic versioning)، که بر اساس نوع کامیت نسخهی مناسب برای عرضه (release) را بروزرسانی میکند، عملکرد بسیار خوبی دارد. برای مطالعهی بیشتر در مورد Conventional Commits میتوانید به اینجا مراجعه کنید.
پیامهای زیر را بررسی کنید و سعی کنید قواعد رعایت شده در هر یک را تشخیص دهید.
خوب
feat: improve performance with lazy load implementation for images
chore: update npm dependency to latest version
Fix bug preventing users from submitting the subscribe form
Update incorrect client phone number within footer body per client request
بد
fixed bug on landing page
Changed style
oops
I think I fixed it this time?
نوشتن پیامهای مناسب برای کامیتها مهارتی بسیار سودمند است که تقویت و بهرهگیری آن به ارتباط و همکاری بهتر میان اعضای تیم کمک میکند. کامیتها بایگانی تغییرات میباشند، اما میتوانند مانند یک نسخهی خطی تاریخی ما را در رمزگشایی گذشته و تصمیمگیری منطقی در آینده یاری کنند.
مجموعهی بزرگی از استانداردهای مورد وفاق عمومی وجود دارند که میتوان از هر یک از آنها پیروی کرد. اما فارغ از نوع قرارداد، همین که تیمی روی یک قرارداد توافق داشته باشد و آن قرارداد به خوبی مخاطبان آتی تیم را در نظر بگیرد و پیامهایی روشن برای آنها ثبت کند، آن تیم از مزایای بلندمدت پیامهای مناسب خود بهرهمند خواهد بود.