حرفه‌ای‌ها پیام کامیت گیت را چطور می نویسند؟

پیامی که برای یک کامیت گیت می نویسید بسیار ارزشمند است! توسعه‌دهندگانی که در تولید پروژه‌های بزرگ سهیم هستند، می دانند که بهترین راه انتقال مفاهیم فضای آن پروژه به یک تازه وارد یا حتی برای آینده خودشان، همین توضیحاتی است که درباره تغییرات کد نوشته می‌شود. اگر برای پیدا کردن یک تغییر قدیمی در کد‌ها، تجربه‌ی ساعت‌ها کار با `git log` و ابزار‌های جانبی را داشته باشید، قطعا قدر همکاری که پیام کامیت‌ها را با دقت نوشته‌است را به خوبی می دانید و برعکس!

کامیت‌هایی از جهنم: نمونه‌ای از پیام‌های ناکارآمد در یک پروژه شخصی
کامیت‌هایی از جهنم: نمونه‌ای از پیام‌های ناکارآمد در یک پروژه شخصی

چرا پیام کامیت مهم است؟

موفقیت یک پروژه در بلندمدت به نگهداری و مدیریت آن بستگی دارد که به عهده‌ی مشارکت‌کنندگان اصلی آن است. مهم‌ترین ابزاری که آن‌ها در اختیار دارند، لاگ تغییرات کدها است. تنها با وجود پیام‌‌های دقیق و استاندارد است که دستور‌های `revert`، `blame`، `git rebase` و `log` کاربرد پیدا می‌کنند و بررسی کامیت‌های دیگر مشارکت‌کنندگان ممکن می‌شود. حتی فهمیدن تغییری که ماه‌ها یا سال‌ها پیش افتاده است نه تنها ممکن، بلکه به شکل بهینه‌ای انجام خواهد شد.

در بیشتر زبان‌های برنامه‌نویسی و پلتفرم‌ها اسنادی تهیه شده‌است که چگونگی نوشتن کد‌، نامگذاری متغییرها، فاصله‌ها و ... را به عنوان قراردادهایی (codding style) بیان می‌کند. حتی میان اعضای یک تیم کوچک هم قراردادهایی برای حفظ یکپارچگی کد در نظر گرفته می‌شود. شیوه‌ی نوشتن پیام کامیت‌ هم از این قاعده پیروی می‌کند. برای داشتن یک تاریخچه‌ی موثر از کامیت‌ها، وجود یک قالب استاندارد که سه ویژگی زیر در آن رعایت شده‌باشد، ضروری است:

۱. ساختار: شامل قواعد دستوری، فاصله، حاشیه و نشانه‌گذاری است.

۲. محتوا: چه اطلاعاتی به عنوان توضیح یک کامیت مورد نیاز است؟

۳. متادیتا (metadata): اطلاعات اضافه‌ای که برای ارجاع به ایشیو (issue)، پول ریکوست (pull request) یا یک کامیت دیگر ذکر می‌شود.


هفت قانون طلایی

قواعد نوشتن پیام استاندارد برای یک کامیت در ۷ مورد خلاصه می‌شود

۱. حرف اول عنوان بزرگ نوشته شود

Simplify PCM open/close callbacks

۲. طول عنوان بیشتر از ۵۰ حرف نباشد

امکان نوشتن عنوان بیش از ۵۰ حرف وجود دارد، اما عایت این قانون برای اطمینان از نوشتن یک عنوان کوتاه و خوانا است.

Change resized buffers atomically
Avoid superfluous usb_set_interface() calls
Check PCM state at xfern compat ioctl

۳. عنوان به صورت امری نوشته شود

نوشتن عنوان به صورت امری در نگاه اول عحیب به نظر می رسد! اما خود گیت هم از این شکل برای نوشتن پیام‌ها استفاده می‌کند:

Merge pull request #123 from someone/somebranch

۴. یک خط فاصله میان عنوان و متن باشد

Fix races at MIDI encoding in snd_virmidi_output_trigger()

The sequencer virmidi code has an open race at its output trigger
callback: namely, virmidi keeps only one event packet for processing
while it doesn't protect for concurrent output trigger calls.
snd_virmidi_output_trigger() tries to process the previously
unfinished event before starting encoding the given MIDI stream, but
this is done without any lock.  Meanwhile, if another rawmidi stream
starts the output trigger, this proceeds further, and overwrites the
event package that is being processed in another thread.  This
eventually corrupts and may lead to the invalid memory access if the
event type is like SYSEX.

۵. در انتهای عنوان نیازی به نشانه‌گذای نیست

حتی یک حرف هم ارزشمند است و نیازی به استفاده از نشانه‌هایی مانند `!?.` نیست

۶. طول خطوط در متن کمتر از ۷۲ حرف باشد

برای اطمینان از خوانا بودن و نمایش یکسان متن کامیت، پیشنهاد می‌شود که خود نویسنده در هر خط با رسیدن تعداد حروف به حدود ۷۲، با زدن کلید enter به خط بعد برود. نرم‌افزارهای ویرایشگر متن در این مورد دارای تنظیمات مختلفی هستند و حتی خود گیت هم محدودیتی در نمایش طول خطوط متن در نظر نمی‌گیرد.

۷. در متن پیام به جای توصیف چگونگی انجام تغییرات، دلیل کامیت را توضیح دهید

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


jfs: Fix usercopy whitelist for inline inode data

Bart Massey reported what turned out to be a usercopy whitelist false
positive in JFS when symlink contents exceeded 128 bytes. The inline
inode data (i_inline) is actually designed to overflow into the "extended
area" following it (i_inline_ea) when needed. So the whitelist needed to
be expanded to include both i_inline and i_inline_ea (the whole size
of which is calculated internally using IDATASIZE, 256, instead of
sizeof(i_inline), 128).

$ cd /mnt/jfs
$ touch $(perl -e 'print "B" x 250')
$ ln -s B* b
$ ls -l >/dev/null

[  249.436410] Bad or missing usercopy whitelist? Kernel memory exposure attempt
detected from SLUB object 'jfs_ip' (offset 616, size 250)!

Reported-by: Bart Massey <bart.massey@gmail.com>
Fixes: 8d2704d ("jfs: Define usercopy region in jfs_ip slab cache")
Cc: Dave Kleikamp <shaggy@kernel.org>
Cc: jfs-discussion@lists.sourceforge.net
Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>

متادیتا

گیت‌هاب با دیدن یک کلمه کلیدی و شماره ایشیو مانند `close #123` در متن پول ریکوست یا کامیت، به صورت خودکار بین پول ریکوست و ایشیو ارتباط برقرار می‌کند و با تایید تغییرات و ادغام شدن آن در مخزن کد، به صورت خودکار ایشیو مربوطه را با برچسب closed نشانه‌گذاری می‌کند. لیست عبارت‌هایی که گیت‌هاب در پیام کامیت به دنبال آن‌ها می‌گردد، در زیر آمده‌است:

close
closes
closed
fix
fixes
fixed
resolve
resolves
resolved

در مثال قانون شماره ۷، از یک نمونه متادیتا برای بستن ایشیو شماره `8d2704d` استفاده شده‌است.


و در آخر، مشتاقانه منتظر شنیدن دیدگاه شما هستم...

منابع

  1. https://chris.beams.io/posts/git-commit/
  2. https://github.com/torvalds/linux/commits/master
  3. https://help.github.com/articles/closing-issues-using-keywords/