این آموزش همه اون چیزی هست نیاز دارید تا کامیتهای گیت بهتری داشته باشید.
من یه لیست ۱۰ تایی براتون تهیه کردم از مواردی که باعث میشه کامیت مسیجهای حرفهای داشته باشید:
اولین و مهمترین قانون برای یک کامیت گیت همین مورد هست! هر کامیت مسیج باید یک پیام کامل، معنادار و مستقل داشته باشه. کامیت مسیج باید برای خوانندهی اون ارزشمند باشه. وقتی به گیتلاگ شما نگاه میکنم و کامیت مسیجهاتون رو میبینم باید همهچیز شفاف باشه و با خوندن فقط و فقط کامیت مسیجهای شما بفهمم توی هر کامیت چه اتفاقی افتاده! بدون انجام هیچ کار اضافهای!
من چندتا مثال از کامیت مسیجهای بد براتون تهیه کردم و پایین هرکدوم هم دلیل بد بودنش رو توضیح دادم. بریم ببینیم:
❌ First commit
چرا این مسیج بده؟
برای کسی که کامیت مسیج شما رو میخونه اهمیتی نداره که ببینه توی متن کامیت شماره کامیت رو نوشتید. چون این مساله رو میتونه با نگاه کردم به گیتلاگ خودش متوجه بشه. همینطور شما هیچ توضیحی در مورد اتفاقات رخ داده توی کامیت ندادید و در نتیجه خواننده اون هم هیچ ایدهای نداره!
❌ Add some codes
چرا این مسیج بده؟
وقتی که دارید روی پروژه و کدبیس کار میکنید، شما یا در حال اضافه کردن کد هستید، یا در حال حذف کردن کد یا تغییر دادن کد و هیچ بلای دیگهای جز این موارد نمیتونید سر کدتون بیارید! بنابراین این کامیت مسیج هیچ فایدهای نداره و دردی رو دوا نمیکنه٬ شما باید بگید چی اضافه کردید نه اینکه فقط بگید کد اضافه کردید!
❌ Refactoring and cleaning codes
چرا این مسیج بده؟
من با خوندن این مسیج چطوری بفهمم که کدوم بخش کدبیس تغییرات و ریفکتور داشته؟ یا مثلا چطوری حدس بزنم چه نوع از ریفکتوری (مثلا کد اضافه حذف شده، پرفورمنس بالا رفته، خوانایی کد بیشتر شده یا ...) روی کدبیس اعمال شده؟ کامیت مسیج شما باید جواب این سوالات رو توی خودش داشته باشه!
❌ Bug resolved
چرا این مسیج بده؟
چه باگی برطرف شده؟ آیا باید حدس بزنم؟! طبیعتا نه، واسه همین لطفا لطفا صراحتا بگید چه باگی برطرف شده.
❌ I added a new feature
چرا این مسیج بده؟
به تکیه به مثالهای قبلی، ما توی این مثال همچنان هیچ دیدی نسبت به تغییرات اتفاق افتاده توی کدبیس نداریم! ضمنا، نیازی نیست که اشاره کنید کی فیچر جدید اضافه کرده که ضمیر من اول کامیتتون استفاده کردید. خود گیت ثبت میکنه که صاحب هرکامیت کی هست. پس شما دوباره کاری نکنید!
اگه قصد دارید یه پیام معنادار برای کامتتون بنویسید، از نوشتن توضیحات طولانی خودداری کنید. همینطور بیش از حد هم خلاصه توضیح ندید. یکی از نشونههای کامیت مسیج خوب، داشتن طول مناسب هست (نه همیشه ولی اکثرا اینطوریه). شاید براتون سوال باشه که خب چرا توضیح کوتاه یا بلند خوب نیست؟ خیلیم عالی، بذارید با یه مثال براتون جا بندازم.
فرض کنید رفیقم میخواد ازم پول قرض کنه. (مثلا من خیلی پول دارم :))))) )
❌ Please lend me money!
خب این مثال نمونه توضیح کوتاهه. توی این مثال رفیقم داره بهم میگه لطفا پول بهم قرض بده. همین! خب وقتی انقدر کوتاه و خلاصه این درخواست رو میگه بهم، من یسری سوالات برام به وجود میاد. مثلا اینکه چقدر پول میخواد؟ یا اینکه چه موقع پولمو برمیگردونه؟ اون باید خودش توی درخواستش این موارد رو بگه و منو مطلع کنه که من لازم نباشه ازش بپرسم.
❌ Hey Ahmad, get on the bus as soon as it arrives at the bus station. Then go to your bank, fill out a form, and then get the money from the bank and lend me $20. I'm going to return it in three weeks.
خب متن بالا هم نمونه یه درخواست طولانی و بلنده. رفیقم بهم میگه احمد برو ایستگاه اتوبوس، هروقت انوبوس اومد سوارش شو و برو بانک. بعدش فرم بگیر، فرم رو پر کن، از حسابت پول برداشت کن و بهم ۲۰ میلیون بده (متن اصلیش بیست دلاره ولی مارو چه به دلار اون فقط مثاله). پولتم تا سه هفته آینده بهت برمیگردونم.
خب میبینید که چقدر خسته کننده و غیر ضروری بوده نحوه درخواستش. لازم نبود بگه چطوری پولش رو جور کنم دیگه در اون حد بلدم!
✅ Ahmad, please lend me 20 dollars. I will return it in 3 weeks
خب اینم مثال آدمیزادی و درست و درمون. مختصر و کوتاهه، ولی جای سوال خاصی باقی نمیمونه.
نکته کلیدی
متن کامیت مسیج شما، باید لُب مطلب و چکیده اتفاقات اصلی کامیت شما باشه.
نکته کلیدی
اگه فکر میکنید که واقعا هیچجوره راه نداره که با یه پیام غیر طولانی چکیده کامیتتون رو توضیح بدید، به احتمال زیاد شما یه کامیت گنده دارید که باید به ۲ یا تعداد بیشتری کامیت کوچیک تقسیمش بکنید.
وقتی میخواید کامیت مسیج بنویسید، فرض کنید که دارید به گیت دستور میدید. ازش درخواست نکنید یا بهش اطلاع رسانی نکنید. فقط مستقیما بهش دستور بدید!
برای مثال فرض کنید یه تابع پیادهسازی کردید که قراره حروف کوچیک رو به حروف بزرگ تبدیل کنه:
❌ Implementing a function that transform letters to upper case.
ترجمه مثال بالا: پیادهسازی تابعی که حروف کوچیک رو به بزرگ تبدیل میکنه.
❌ I added a function to transforming letters to upper case.
ترجمه مثال بالا: من تابعی پیادهسازی کردم که حروف کوچیک رو به بزرگ تبدیل میکنه.
❌ A function to transforming letters to upper case has been added.
ترجمه مثال بالا: تابعی اضافه شد که حروف کوچیک رو به بزرگ تبدیل میکنه.
✅ Implement a function to transform letters to upper case
ترجمه مثال بالا: تابعی پیادهسازی کن که حروف کوچیک رو به بزرگ تبدیل میکنه.
این قانون هم مکمل قانون دوم (نه کم نه زیاد) هست. لازم نیست همه چیز و همه جزئیات رو بگید. همیشه یادتون باشه که شما توی کامیت مسیج باید توضیح بدید که چه چیزی و چرا رو اضافه/حذف کردید یا تغییر دادید. نیازی نیست که بگید چطور این کار رو کردید. همچنین نیاز نیست تغییرات کم اولویت و خیلی کوچیک رو توی کامیت مسیج بنویسید.
برای مثال، فرض کنید که تابعی به اسم getUser رو میخواید ریفکتور کنید. بعد از اینکه ریفکتورش کردید، متوجه میشید که یه متغیر بدون استفاده داخل تابعتون دارید. بنابراین طبیعتا اون متغیر رو حذف میکنید. خب اینجا دیگه نیازی نیست که حذف کردن این متغیر هم توی کامیت مسیجتون گفته بشه. مثل مثال زیر که یه مثال بد هست:
❌ Refactor the 'getUser' function and delete an unused variable in its related file.
واسه چی نیازی نیست که به حذف این متغیر اشاره بشه؟ چون حذف این متغیر از تابع، هدف اصلی این کامیت نبوده. در واقع یه تغییر کوچیک بوده که ما در طول کار اصلی و هذف اصلی کامیتمون، اعمال کردیم. البته شما میتونید این متغیر رو توی یه کامیت جداگانه حذف کنید. یا اینکه مثالا میتونید یه تسک جدید تعریف بکنید برای حذف کردن تمام متغیرهای بلااستفاده تو کدبیس و بنابراین میتونید همه اونا رو توی یه کامیت از کدبیستون حذف بکنید.
خب از بحث اصلی دور نشیم. توی مثالی که زدم، من این کامیت مسیج رو ترجیح میدم به کامیت مسیج بالایی:
✅ Refactor the 'getUser' function
این مورد یه چیز اختیاریه که اگه دوست داشتید میتونید ازش استفاده بکنید. چون باعث میشه کامیت مسیجهای خوانا و قدرتمندی داشته باشید. برحسب اینکه توی کامیت مربوطه، چه نوع تغییراتی توی کدبیس اعمال کردید، میتونید از یه پیشوند مناسب و درخور براش استفاده کنید. پیشوندها همونطور که از اسمشونم مشخصه، معمولا اول کامیت مسیج استفاده میشن.
من یه لیست از پیشوندهای معروف رو که خیلی زیاد دیدم و خودمم استفاده میکنم براتون مینویسم:
[BUGFIX]
: برای مواردی که باگی توی کدبیس برطرف شده استفاده میشه.[TEST]
: برای وقتایی که تست نویسی کردیم (حالا هر نوع تستی مثل یونیت تست، یوزراستوری و ...)[FEATURE]
: اینم واسه وقتی که یه فیچر جدید به کدبیس اضافه میشه.[REFACTOR]
: این پریفیکس وقتی استفاده میشه که کدبیس رو ریفکتور کردیم. حالا چه در راستای خوانایی، چه بهبود عملکرد و ... .[UPDATE]
: برای وقتایی که یک کتابخونه یا وابستگی رو آپدیت میکنیم. همچنین واسه وقتایی که یه فیچر موجود رو، بخاطر آپدیت شدن داکیومنتها، آپدیت میکنیم و تغییرات روش اعمال میشن.[BASE]
: برای نصب کتابخونهها و وابستگیهای پروژه. یا برای وقتایی که یسری زیرساختهای پروژهای رو تنظیم و اعمال میکنیم. مثل ست کردن تنظیمات پروژه و کتابخونهها و ... .[DOCS]
: برای وقتای که میخوایم به داکیومنتهامون چیزی اضافه کنیم یا تغییرشون بدیم.
موارد بالا فقط یسری پیشوندهای پیشنهادی بودن و هیچ اجباری برای استفاده از اونها نیست. ولی من اینارو توی خیلی از پروژهها دیدم. ضمن اینکه انصافا اسماشون خیلی ساده و بدیهیه. حالا شما اگه حال نکردید باهاشون، میتونید پیشوندهای خودتون رو داشته باشید!
نکته کلیدی
حروف پیشوندها میتونن همشون حروف کوچیک باشن. فقط لطفا یه یه قاعده ثابت پیروی کنید. برای مثال اگه از حروف کوچیک استفاده کردید، تا آخر داستان ریپازیتوریتون، فقط ار حروف کوچیک استفاده بکنید برای پیشوندها.
اخیرا زیاد دیدم که توسعهدهندهها از اموجی توی کامیت مسیجهاشون استفاده میکنن. این کار اصلا خوب نیست. میگید چرا؟ به دو دلیل:
- اونا معنا و پیام کاملا مشخص و ثابتی ندارن.
- اموجیها از یونیکدهای خاصی استفاده میکنن. بنابراین ممکنه یه روزی ما با ترمینالی کار بکنیم که الزاما تمام یونیکدهارو پشتیبانی نمیکنه و بنابراین، توی اون ترمینال ما نمیتونیم اموجیها رو ببینیم.
یکی از همکارهای من نظر مخالف داره و میگه که استفاده از اموجی خوبه. اون معتقده که هر اموجی واقعا یه معنا ثابت و خاصی داره و بنابراین میشه ازشون تو کامیت مسیج استفاده کرد. برای مثال اون اموجی یه کرم رو (🐛) بهم نشون داد و گفت همه میدونن که معنی اموجی کرم یعنی باگ! من بهش گفتم باشه قبوله. اما برای تست۷ فیچر، ریفکتور و ... از چه اموجیهایی باید استفاده کرد؟ اون یه وبسایت بهم معرفی کرد که توی اون کلی اموجی معرفی کرده بودن و برای هر کدوم هم یه توضیح و معنی خاص و متفاوت با بقیه ارائه کرده بودن.
این آدرس اون سایته:
اما من با همکارم مخالفم چون سایت بالا یه رفرنس برای کامیتهای گیت نیست. این سایت محصول یه کمپانی معروف با استاندارهای بالا نیست. فقط یه آدم خوش ذوق یکسری اموجی معرفی کرده و طبق سلیقه خودش برای هرکدوم یه معنی نوشته. همین و نه بیشتر!
اگه یه روزی ترمینالها از عکسها هم پشتیبانی کنن و بشه تو اونها عکس هم نشون داد، من میتونم یه سایت درست کنم برای استفاده از عکس توی کامیت مسیجها! مثلا یه عکس میذارم از مردی که ترسیده و توضیحات عکسشم بنویسم که این عکس به باگ اشاره میکنه! خب این که نشد استاندار :)
این موردم شبیه به مورد شماره پنج (پیشوندهای مفهومی) هست با یه فرق اساسی: پیشوندهای ارجاعدهنده یه معنی مستقیم و واضح دارن که دیدنشون میشه فهمید اون کامیت حول چه چیزی (باگ، تست، فیچر و ...) بوده. ولی پیشوندهای اجراعدهنده به توضیحات خارجی اشاره میکنن. مثلا به یه تسک روی جیرا، به یه کارت ترلو یا یک ایشو روی گیتلب یا هرچیز دیگهای. پیشوندهای ارجاعی معمولا تو تیمهای بزرگ و تیمهای بر پایهی اسکرام استفاده میشه.
برای استفاده از یه پیشوند ارجاعی راههای مختلفی هستن. من چند استایل پر استفاده و معروف رو اینجا مینویسم:
[#<CARD-NUMBER>]
,[#<ISSUE-NUMBER>]
or[#<TASK-NUMBER>]
[<CARD-NUMBER>]
,[<ISSUE-NUMBER>]
or[<TASK-NUMBER>]
(<CARD-NUMBER>)
,(<ISSUE-NUMBER>)
or(<TASK-NUMBER>)
یه مثال از موارد بالا:
[#217] Resolve the bug of 'fetchUsers' function that causes some users be missed
اون [#217] که اول کامیت نوشته شده، میتونه به این اشاره داشته باشه که این کامیت متعلق به تسک شماره ۲۱۷ هست. حالا اهمیتی نداره که شما از چه سرویس مدیریتی برای تسکهاتون استفاده میکنید. در هرصورت شما میتونید از این پیشوندها برای اشاره به یک تسک/باگ/کارت از تسک منیجرتون اشاره کنید.
نکته کلیدی
شما میتونید از پیشوندهای مفهومی و پیشوندهای ارجاعدهنده کنار همدیگه استفاده کنید. این به تصمیم شما بستگی داره.
من چندتا مثال از استفاده پیشوندهای مفهومی و ارجاعدهنده کنار همدیگه آماده کردم:
-
[#REFACTOR](217) Use Array's methods like 'forEach' and 'map' instead of simple 'for' and 'while' loops in the codebase
-
[REFACTOR-217] Use Array's methods like 'forEach' and 'map' instead of simple 'for' and 'while' loops in the codebase
-
[#217][REFACTOR] Use Array's methods like 'forEach' and 'map' instead of simple 'for' and 'while' loops in the codebase
همه مثالهای بالا فقط یه الگو هستن برای درک بهتر شما. پس یه قاعده دقیق و الزامی نیستن. شما میتونید اونهارو به هر شکلی که خواستید کنار همدیگه استفاده کنید. ولی موارد بالا چیزایی بودن که من بیشتر به چشمم خورده که شرکتها و تیمها ازشون پیروی میکردن.
بعضی وقتا کامیت مسیجها به اسم یه متغیر، تابع، متد یا کلاس اشاره میکنن یا اینکه یه کلمه یا اصطلاح تخصصی توشون نوشته میشه. توی همچین مواقعی که نیاز دارید همچین چیزایی توی کامیت مسیجتون باشه، نام اون متغیر، تابع، کلاس، متد، اصطلاح تخصصی یا هرچیز مشابه رو بین بکتیک یا کوتیشن قرار بدید تا از بقیه کلمات عادی تفکیک و تمیز داده بشن.
❌ Upgrade Jest and React Testing Library to the latest versions
✅ Upgrade 'Jest' and 'React Testing Library' to the latest versions
❌ Use for-in loop instead of for-of loop inside calculatePrice function
✅ Use 'for-of' loop instead of 'for-in' loop inside the 'calculatePrice' function
- همیشه کامیت مسیجهاتون رو فقط و فقط و فقط به انگلیسی بنویسید و نه هیچ زبان دیگهای!
- آخر کامیت مسیجهاتون نقطه نذارید.
- حرف اول کامیت مسیجهاتون رو بزرگ بنویسید.
- تعداد کاراکترهای کامیت مسیجتون بیشتر از ۷۲ تا نشه. (البته که همیشه استثنا وجود داره)
- از لینک و یوآرال توی کامیت مسیجتون استفاده کنید.
اگه یه چرخی تو خیلی از ریپازیتوریهای معروف بزنید، میبینید که بعضا خیلی تفاوتهای فاحشی بین کامیت مسیجها وجود داره. برای مثال، یسریاشون پیشوند دارن یسریا نه، یسریاشون جملاتشون حالت دستوری داره، یسریاشون خبری، یسریاشون حرف اول بزرگه، یسریاشون نه، یسریاشون اموجی دارن یکسری نه و ... .این اتفاق معمولا به این دلیل رخ میده که افراد و تیمها قوانین مشخصی رو پیروی نمیکنن. همیشه یه راهنمای جامع و شفاف برای خودتون و اعضای تیمتون داشته باشید. با رعایت این مساله، شما میتونید از جلوی کامیت های غیر همسان و جورواجور رو بگیرید.
همچنین میتونید از یسری ابزارهای خارجی و لینترها کمک بگیرید تا کامیتهاتون رو به قول معروف دبلچک بکنید (دوبار چک بکنید). لینترها و ابزارهای خارجی تضمین میکنن که کامیت مسیجهاتون تداخلی با قواعدی که براشون اعمال کردید نداشته باشن. در واقع اونا شما و تیمتون رو مجبور میکنن که از قوانین مشخصی برای کامیت مسیجهاتون پیروی بکنید.
اگه این ریپازیتوری بهتون کمک کرد، ستاره دادنو فراموش نکنید ;)