استفاده از MailMap در Git

یکی از مشکلات رایجی که حین استفاده از Gitوجود داره ، رعایت نکردن تنظیم درست Author هاست که به هنگام داده کاوی های مختلف روی ریپازیتوری دردسرهایی رو به وجود میاره. در این پست به شرح مشکل و راه حلش می پردازیم.

استفاده از MailMap در Git

وقتی که دارید تغییرات پروژه هاتون رو Commit می کنید ، نه تنها تغییرات توی کد ها و فایل هاتون ثبت میشه ، بلکه در کنار اونها مشخصات Author یا کسی که این تغییرات رو هم اعمال کرده ثبت میشه. پس از نصب Git روی سیستم یا سرور خودتون اولین کاری که باید انجام بدید تعریف یک Author میشه که با استفاده از این دستورات انجامش میدین :

git config --global user.name "Arash Hatami"
git config --global user.email "hello@arash-hatami.ir"

پس از این هر Commit شما چنین ساختاری پیدا می کنه :

commit aeaeb9e927592e907ae1a7f5c381876e05109a80
Author: Arash Hatami <hello@arash-hatami.ir>
Date:   Tue March 30 12:30:40 2021 +0330
Your commit message

تا وقتی که از Git برای مدیریت و کنترل نسخه پروژه های خودتون استفاده کنید نیاز نیست توجه خاصی به این موضوع داشته باشید. کدهاتون رو می نویسید ، تغییرات رو Commit کرده و در نهایت همه شون رو Push می کنید و همه چیز هم درست کار می کنه. ولی مشکل وقتی پیش میاد که بخواید کمی داده کاوی روی ریپازیتوری ها انجام بدید و اطلاعات مختلفی از هرکدوم به دست بیارید. اینجاست که باید کمی دقیق تر رفتار کنید.

مشکل کجاست ؟

نام و آدرس ایمیلی که به عنوان یک Author ثبت می کنید خب مسلما متغییری از نوع رشته ( String ) هست و مشکلات خاص خودش رو هم داره. از اونجایی که Git به بزرگ و کوچک بودن حروف حساسه وقتی شما نام خودتون رو ثب میکنید مسلما arash با Arash تفاوت داره و اینجا دو نام مختلف و در نتیجه دو Author متفاوت شناسایی میشه. حالا همین مورد رو هم برای آدرس ایمیل در نظر بگیرید. و تازه این برای یک نفر اتفاق میوفته. فرض کنید ریپازیتوری دارید که 10 نفر همزمان دارن روش کار می کنن. اگر هر فرد حداقل با 2 تا سیستم هم تغییرات رو Commit کنه و به این مسئله توجه نکنه ، بعد از چندماه متوجه میشید که تیم 10 نفره شما اینجا شده 25 نفر !!!

git shortlog -se
   130  = <info@arash-hatami.irm>
   789  Arash Hatami <hello@arash-hatami.ir>
   648  hatamiarash7 <info@arash-hatami.ir>

در مثال بالا که واقعی است و روی یکی از ریپازیتوری های قدیمی خودم اجرا کردم متوجه شدم که سه Author مختلف ثبت شده. در صورتی که هر 3 نفر یکسان بوده و تفاوتی باهم ندارن. این پروژه طی چند سال توسعه داده شده و مسلما روی سیستم های مختلف روش کار کردم.

شاید سوال براتون پیش بیاد که خب اتفاق خاصی نیوفتاده ، مگه چیه ؟ مشکل وقتی شروع میشه که بخواید بدونید هر نفر چند Commit ثبت کرده یا در مجموع چند نفر روی پروژه کار کردن و خیلی مسائل دیگه. حتی اگر همین الان هم من روی تمام سیستم ها و سرور هام user.name و user.email رو یکسان ثبت کنم باز هم مشکل پابرجاست چون Commit ها قبلا ثبت و Push شده.

راه حل چیه ؟

در حال حاضر با وجود چنین شرایطی هر دستوری هم که بخواید اجرا کنید در نهایت باید به صورت دستی تعداد Author های درست رو بشمارید که خب کار زیادی میطلبه. خوشبختانه قابلیتی به اسم MailMap وجود داره که اینجا به کمک ما میاد.

استفاده از mailmap. برای ادغام نویسنده ها

اگر شما یک فایل .mailmap در ریپازیتوری خودتون داشته باشید ، Git قبل از به نمایش گذاشتن و پردازش هرچیزی اول به اون مراجعه می کنه تا Author ها رو بررسی کنه. این فایل چنین ساختاری داره :

Name you want to keep <email> Name you no longer want <email>
قوانین مختلف

به ازای هر فردی که در ریپازیتوری مشارکت داشته و اسامی یا آدرس های ایمیل متفاوتی ثبت کرده باید یک Rule بنویسید. در ابتدای هر قانون اطلاعاتی که باید نمایش داده بشه رو نوشته و در ادامه اطلاعاتی که نیاز ندارید. برای مثال فایل .mailmap ریپازیتوری خودم چنین چیزی میشه :

Arash Hatami <hello@arash-hatami.ir> = <info@arash-hatami.irm>
Arash Hatami <hello@arash-hatami.ir> hatamiarash7 <info@arash-hatami.ir>

من میخوام تمام داده های من با نام Arash Hatami و آدرس ایمیل hello@arash-hatami.ir نمایش داده بشه. پس با توجه به قوانینی که در بالا تعریف کردم این مورد به راحتی انجام میشه و 2 مورد اضافه که به اشتباه Author متفاوتی ثبت شدن وجود نخواهند داشت.

اگر یک بار دیگه دستور shortlog رو اجرا کنم چنین خروجی به من میده :

git shortlog -se
   1567  Arash Hatami <hello@arash-hatami.ir>

تمامی Author ها باهم ادغام شده و به عنوان یک مورد واحد نمایش داده میشه. همچنین تعداد Commit ها هم جمع میشه.

البته باید توجه داشته باشید که این مورد مشکلات رو برطرف میکنه ولی خب نکته کوچکی هم وجود داره. دستور shortlog به صورت خودکار فایل .mailmap رو میخونه و داده ها رو پردازش میکنه در صورتی که باقی دستورات ممکنه اینطور عمل نکنن. برای چنین دستوراتی از آرگومان --use-mailmap باید استفاده کنید. برای مثال دستور log :

git log --use-mailmap

نتیجه

استفاده از MailMap وقتی کاربرد داره که اعضای تیم شما روی دستگاه های مختلف یا کلاینت های Git متفاوتی کار کرده و تغییرات رو Commit می کنن. با استفاده از یک فایل ساده و چند خط قانون می تونید ریپازیتوری خودتون رو مرتب تر کنید و در صورتی که یک عضو جدید به تیم اضافه شد یا مشکل کوچکی از این قبیل رخ داد فقط کافیه یک Rule جدید به فایل اضافه کنید.

این کارها وقتی فایده خودش رو نشون میده که از Git فراتر از بحث کنترل نسخه استفاده کنید.