ایدهی اصلی گردشکار شاخهی فیچر (Feature Branch) این است که توسعهی فیچرها باید بر روی شاخهی اختصاصی دیگری غیر از شاخهی مستر (master) صورت بگیرد. جداسازی توسعهی فیچرها سبب میشود که چندین دولوپر، بدون درگیر و شلوغ کردن شاخهی مستر، بتوانند بر روی یک یا چند فیچر کار کنند. همچنین با این رویکرد هرگز روی شاخهی مستر شاهد کدهای خراب یا ناقص نخواهیم بود. این خود یک مزیت برای محیطهای ادغام مداوم (continuous integration environments) به حساب میآید.
مجزاسازی روند توسعهی فیچرها از کد اصلی، بحث پیرامون هر شاخه را با استفاده از درخواست pull آسانتر میکند. درخواست pull این امکان را به سایر دولوپرها میدهد که قبل از ادغام یک فیچر جدید با کد اصلی، بتوانند آن را بررسی کنند. همچنین اگر به عنوان دولوپر در میانهی توسعهی یک فیچر با مشکلی مواجه شدید، میتوانید یک درخواست pull برای همکارانتان باز کنید تا بتوانند پیشنهادات خود را به شما ارائه دهند. درخواست pull تبادل نظر دولوپرها در مورد کدهای یکدیگر را فوقالعاده آسان میکند.
گردشکار شاخهی فیچر را میتوان با سایر گردشکارهای سطحبالا در گیت ترکیب کرد. این گردشکار در واقع یک مدل متمرکز بر شاخهسازی است، به این معنا که یک چارچوب راهنما جهت ایجاد و مدیریت شاخهها را فراهم میآورد. بعضی از گردشکارها مانند Gitflow و Git Forking نیز در مدل شاخهسازی خود، به طور سنتی از گردشکار شاخهی فیچر بهره میبرند.
گردشکار شاخهی فیچر چگونه کار میکند؟
در گردشکار شاخهی فیچر از یک مخزن مرکزی استفاده میشود. در مخزن مرکزی شاخهای به نام شاخهی مستر (master) وجود دارد که تاریخچهی رسمی پروژه بر روی آن ثبت میشود. با این حال، در این گردشکار دولوپرها به جای اینکه کدهای خود را مستقیماً بر روی شاخهی مستر ثبت (commit) نمایند، برای توسعهی هر فیچر جدید یک شاخه ی مجزا ایجاد میکنند. برای هر شاخهی فیچر باید یک نام توصیفی در نظر گرفته شود، مانند animated-menu-items یا issue-#1061. دلیل این نحوهی نامگذاری این است که هدف از ایجاد هر شاخه کاملاً واضح و روشن باشد. نکتهی مهم این است که از نظر فنی هیچ تفاوتی بین شاخهی مستر و شاخههای فیچر وجود ندارد. بنابراین دولوپرها میتوانند روند استاندارد ویرایش (edit)، نمایش (stage) و ثبت (commit) را مثل شاخهی مستر بر روی شاخههای فیچر نیز اعمال کنند.
علاوه بر این، شاخههای فیچر میتوانند (و در نهایت باید) به مخزن مرکزی منتقل شوند. انتقال این شاخهها به مخزن مرکزی باعث میشود تا بدون دستکاری کد اصلی پروژه، فیچرها با سایر دولوپرها به اشتراک گذاشته شوند. از آنجا که شاخهی مستر تنها شاخهی اختصاصی موجود در مخزن مرکزی است، ذخیره کردن شاخههای فیچر متعدد در این مخزن مشکلی ایجاد نمیکند. البته انتقال شاخههای فیچر به مخزن مرکزی میتواند روش بسیار خوبی برای پشتیبانگیری از کدهای ذخیرهشده در مخزنهای محلی دولوپرها نیز باشد.
در ادامه فرآیند ایجاد یک شاخهی فیچر را مورد بررسی قرار میدهیم.
همه چیز از شاخهی مستر آغاز میشود
تمام شاخههای فیچر بر اساس آخرین نسخه پروژه ایجاد میشوند. در این مقاله فرض میکنیم که این نسخه در شاخهی مستر نگهداری و به روزرسانی میشود.
git checkout master
git fetch origin
git reset --hard origin/master
با وارد کردن دستورات بالا آخرین تغییرات ثبت شده در مخزن مرکزی، دریافت (pull) شده و در مخزن محلی کپی و بازنشانی میشوند.
ایجاد یک شاخهی جدید
برای کار کردن بر روی هر فیچر یا موضوع، باید یک شاخهی مجزا ایجاد کنید. دقت کنید که این شاخه باید در مخزن محلی ایجاد شود زیرا تمام کارهایی که در خصوص این فیچر انجام میدهید روی این شاخه ثبت خواهد شد.
git checkout -b new-feature
دستور بالا یک شاخه به نام new-feature را از شاخهی مستر منشعب میکند. دنبالهی b به گیت میگوید اگر شاخه new-feature از قبل وجود ندارد، آن را ایجاد کن.
ایجاد و ثبت تغییرات روی شاخهی جدید
در شاخهی ایجاد شده، به منظور توسعهی فیچر مورد نظر، میتوان روند معمول گیت (ویرایش، نمایش و ثبت) را بارها و به دفعات مورد نیاز تکرار نمود. بعد از تکمیل توسعهی فیچر، میتوانید با دستورات زیر آن را به مخزن مرکزی انتقال دهید.
git status
git add <some-file>
git commit
انتقال شاخهی فیچر به مخزن راهدور
انتقال شاخهی فیچر به مخزن مرکزی (مخزن راهدور) روش مناسبی برای ایجاد یک نسخهی پشتیبان است. علاوه بر این، وقتی چند دولوپر به طور همزمان بر روی یک فیچر کار میکنند، هر دولوپر با انتقال کدهای خود به مخزن مرکزی میتواند آنها را با همکاران خود به اشتراک بگذارد.
git push -u origin new-feature
دستور بالا شاخهیnew-feature را به مخزن مرکزی (central) یا مخزن مبداء (origin) انتقال میدهد. دنبالهی u که پس از دستور push آمده است، به گیت میگوید که شاخهی new-feature را به عنوان یک شاخه قابل ردیابی از راهدور (remote-tracking branch) به مخزن مرکزی اضافه کند. بعد از اینکه new-feature به این صورت به مخزن مرکزی اضافه شد، در بروزرسانیهای بعدی این شاخه میتوان دستور git push را بدون هیچ مؤلفهی اضافهای مورد استفاده قرار داد.
اگر میخواهید قبل از ادغام new-feature با کد اصلی، از همکاران خود بازخورد گرفته و مطمئن شوید که فیچر درست کار میکند، باید در یکی از ابزارهای مدیریت مخزن (مانند Bitbucket Cloud یا Bitbucket Server) یک درخواست pull برای آن ایجاد کنید (همچنین در GitLab میتوانید این کار را با merge request انجام دهید). با ایجاد درخواست pull، این فیچر در اختیار سایر اعضای تیم قرار میگیرد تا کیفیت و کارایی آن را بررسی کنند.
بررسی و اعمال بازخوردها
اکنون همتیمیهای شما میتوانند فیچر جدید را مورد آزمون قرار داده و دیدگاههای خود را مطرح نمایند. شما به عنوان توسعهدهندهی این فیچر باید دیدگاهها را بررسی نموده و در صورت لزوم، آنها را در مخزن محلی خود اعمال و ثبت کنید. سپس این تغییرات را به مخزن مرکزی انتقال دهید. این بروزرسانیها در همان درخواست pull که پیش از این ایجاد نموده بودید، اعمال و ظاهر خواهند شد.
ادغام درخواست pull
قبل از ادغام، باید مغایرتهای احتمالی موجود بین مخزن مرکزی و کدهای جدید را برطرف نمایید. وقتی کدهای بروزرسانی شده در درخواست pull، مورد تائید قرار گرفت و دیگر مغایرتی با مخزن مرکزی نداشت، میتوایند آنها را به شاخهی مستر مخزن مرکزی اضافه نموده و ادغام کنید.
سخنی کوتاه دربارهی درخواستهای pull
شاخهها علاوه بر امکان مجزا کردن توسعهی فیچرها، امکان بحث و تبادل نظر در مورد کدها و تغییرات آنها را نیز با استفاده از درخواستهای pull فراهم میآورند. هنگامی که یکی از دولوپرها فیچری را تکمیل نمود، بلافاصله آن را در شاخهی مستر ادغام نمیکند. در عوض آن را به شاخهی فیچر بر روی سرور مرکزی فرستاده و یک درخواست pull برای اضافه نمودن تغییرات به شاخهی مستر ایجاد نماید. به این ترتیب، قبل از اینکه کدهای این دولوپر جزئی از کد اصلی پروژه شود، دولوپرهای دیگر این امکان را دارند که کدها و تغییرات جدید را مرور و بررسی کنند.
امکان بررسی کدها قبل از ادغام، یک مزیت بزرگ درخواستهای pull است. این درخواستها در واقع به عنوان راهی برای گفتگو و تبادل نظر در مورد کدها طراحی شدهاند. میتوان هر درخواست pull را یک جلسهی مباحثه در مورد یک شاخهی خاص در نظر گرفت. بنابراین، حتی قبل از اینکه توسعهی یک فیچر کامل شود نیز میتوان از درخواست pull بهره برد. به عنوان مثال، اگر دولوپری در مورد یک فیچر نیاز به کمک داشته باشد تمام کاری که باید بکند این است که یک درخواست pull ایجاد نماید. این موضوع به صورت خودکار به اعضای تیم اطلاعرسانی شده و آنها میتوانند دقیقاً در کنار کدهای آن فیچر، سوالات دولوپر را نیز ببینند و به آنها پاسخ دهند.
بعد از اینکه درخواست pull مورد پذیرش قرار گرفت، ادامهی فرآیند انتشار مشابه گردشکار متمرکز خواهد بود. بنابراین، قبل از هر چیز باید مطمئن شوید که شاخهی مستر محلی شما با شاخهی مستر مخزن مرکزی همگامسازی شده و بهروز شده باشد. سپس باید شاخهی فیچر را به شاخهی مستر منتقل نموده و بعد از آن، شاخهی مستر بهروزشده را دوباره به مخزن مرکزی ارسال نمایید.
همانطور که پیش از این اشاره شد، ابزارهای مدیریت مخزن مانند Bitbucket Cloud یا Bitbucket Server میتوانند استفاده از درخواستهای pull را آسانتر کنند.
یک مثال
در ادامه، یک سناریو در مورد کار تیم کوچکی را مطرح میکنیم که از گردشکار شاخهی فیچر استفاده میکنند. در این سناریو سه دولوپر به نامهای مریم، بهرام و جواد مشغول کار خود هستند و در عین حال همکاریهایی نیز با هم دارند. آنها با استفاده از یک درخواست pull، کدهای یک فیچر جدید را مورد بررسی قرار میدهند. این مثالی است از تمام موقعیتهای مشابهی که این گردشکار میتواند مورد استفاده قرار گیرد.
الف- مریم توسعهی یک فیچر جدید را آغاز میکند
مریم قبل از این که توسعهی فیچر جدید خود را آغاز نماید، باید یک شاخهی مجزا برای این کار ایجاد کند. او میتواند با استفاده از دستور زیر یک شاخهی جدید ایجاد کند.
git checkout -b marys-feature master
دستور checkout بررسی میکند که آیا شاخهای به نام marys-feature از شاخهی مستر منشعب شده است یا خیر. دنبالهی b که بعد از دستور checkout آمده است، به گیت میگوید که اگر شاخهای با این نام از قبل وجود ندارد، آن را ایجاد کن. مریم در این شاخه میتواند با استفاده از دستورات زیر و طبق روند استاندارد گیت، فرآیندهای ویرایش، نمایش و ثبت را هرچند بار که لازم باشد انجام دهد و توسعهی فیچر خود را پیش ببرد.
git status
git add <some-file>
git commit
ب- مریم برای صرف ناهار میرود
از صبح تا قبل از وقت ناهار، مریم مشغول کار بر روی فیچر خود بوده و چند قطعه کد جدید را به آن اضافه نموده است. قبل از اینکه مریم برای صرف ناهار دست از کار بکشد، بهتر است کدهای ثبتشده روی شاخهی فیچر محلی خود را به مخزن مرکزی انتقال دهد تا به عنوان یک نسخهی پشتیبان در آنجا نگهداری شود. همچنین اگر در توسعهی این فیچر مریم با دولوپرهای دیگری همکاری داشته باشد، با انتقال این شاخه به مخزن مرکزی، کدهای خود را با همکاران خود به اشتراک میگذارد.
git push -u origin marys-feature
دستور بالا شاخهی marys-feature را به مخزن مرکزی (origin) انتقال میدهد. دنبالهی u که بعد از دستور push آمده است به گیت میگوید که این شاخه را به عنوان یک شاخهی قابل ردیابی از راه دور، به مخزن مرکزی اضافه کند. بعد از اضافه شدن این شاخه و در دفعات بعد، برای انتقال کدها و بروزرسانی این شاخه در مخزن مرکزی، دیگر نیازی به استفاده از دنبالهی u نخواهد بود.
پ- مریم توسعهی فیچر خود را کامل میکند
مریم پس از صرف ناهار، دوباره مشغول کار شده و فیچر خود را تکمیل میکند. قبل از ادغام این شاخه با شاخهی مستر، مریم باید با ایجاد یک درخواست pull به سایر دولوپرها اجازه دهد تا فیچر تکمیل شده را بررسی کنند. اما پیش از آن باید مطمئن شود که آخرین نسخهی این فیچر را به مخزن مرکزی انتقال داده است. بنابراین از دستور زیر استفاده میکند:
git push
سپس به منظور ادغام شاخهی marys-feature با شاخهی مستر، مریم در رابط کاربری گیت درخواست pull خود را ثبت میکند. ثبت این درخواست خود به خود به اعضای تیم اطلاع داده میشود. نکتهی جالب در مورد درخواستهای pull این است که نظرات اعضای تیم دقیقاً در کنار کدهای مورد نظر نمایش داده میشود. بنابراین سوال پرسیدن در مورد یک بخش خاص از کد بسیار آسان خواهد بود.
پ- بهرام درخواست pull را دریافت میکند
بهرام درخواست pull مریم را دریافت نموده و نگاهی به فیچر مریم میاندازد و تصمیم میگیرد که پیش از ادغام با نسخهی رسمی پروژه، تغییراتی در این فیچر ایجاد کند. به همین دلیل بین مریم و بهرام درخواست pull چند بار رد و بدل میشود.
ت- مریم تغییرات لازم را ایجاد میکند
مریم برای ایجاد تغییرات دقیقاً از همان روشی استفاده میکند که قبلاً برای توسعهی همین فیچر استفاده کرد، یعنی ویرایش، نمایش و ثبت. سپس کد بهروزشده را به مخزن مرکزی انتقال میدهد. تمام کارهایی که مریم در این رابطه انجام میدهد در درخواست pull نمایش داده میشود و بهرام همچنان این امکان را دارد که دیدگاههای خود را در همین درخواست اعلام کند. همچنین اگر مایل باشد، میتواند marys-feature را به مخزن محلی خود انتقال داده و خودش روی آن کار کند. در این صورت، تغییراتی که بهرام ایجاد میکند نیز در درخواست pull ظاهر میشوند و مریم و سایر دولوپرهای تیم میتوانند آنها را ببینند.
ث- مریم فیچر خود را منتشر میکند
بعد از اینکه بهرام درخواست pull را پذیرفت، یک نفر باید این فیچر را با کد اصلی پروژه ادغام کند (هم بهرام و هم مریم میتوانند ادغام را انجام دهند):
git checkout master
git pull
git pull origin marys-feature
git push
دستورات بالا اغلب به منظور ادغام کدها مورد استفاده قرار میگیرند. اما اگر میخواهید پروژه یک تاریخچهی خطی داشته باشد، میتوانید قبل از ادغام، فیچر را بر اساس آخرین بروزرسانی شاخهی مستر بازنشانی (rebase) و سپس دستور merge را اجرا نمایید. این کار فرآیند ادغام را تسریع میکند.
در بعضی از رابطهای کاربری گرافیکی، با کلیک بر روی دکمهی Accept، فرآیند پذیرش درخواستpull و اجرای تمام دستورات بالا به صورت خودکار انجام میشود. اگر رابط کاربری مورد استفادهی شما این قابلیت را ندارد حداقل باید بتواند پس از ادغام شاخهی فیچر با شاخهی مستر، درخواست pull را به صورت خودکار ببندد.
ج- همزمان جواد هم مشغول کار خود است
در حالی که مریم و بهرام مشغول کار بر روی فیچر مریم هستند، دولوپری به نام جواد درگیر توسعهی فیچر دیگری است و دقیقاً همین فرآیندها را بر روی فیچر خود انجام میدهد. با مجزا کردن فیچرها در شاخههای جداگانه هر دولوپری میتواند به صورت مستقل بر روی فیچر خود متمرکز شود و در عین حال، امکان به اشتراک گذاشتن کدها و مشورت خواستن از دیگران را نیز خواهد داشت.
سخن پایانی
در این مقاله، گردشکار شاخهی فیچر در گیت مورد بررسی قرار گرفت. همچنین با طرح یک سناریو، قابلیتهای این گردشکار تشریح شد.
گردشکار شاخهی فیچر سازماندهی و پیگیری فیچرها را آسان میکند. در ترکیب با سایر گردشکارهای مبتنی بر مخزن گیت مانند Git Forking و Gitflow نیز میتوان از قابلیتهای این گردشکار به منظور مدیریت مدل شاخهسازی استفاده کرد. سه ویژگی مهم این گردشکار عبارتند از:
- تمرکز بر الگوهای شاخهسازی
- قابلیت ترکیب و بهکارگیری در سایر گردشکارهای مخزن محور
- افزایش همکاری اعضای تیم با استفاده از درخواستهای pull و بررسی کدها پیش از ادغام با کد اصلی.
شما تا چه اندازه با گردشکارهای مختلف گیت و به ویژه گردشکار شاخهی فیچر آشنایی دارید. تجربیات و دیدگاههای خود را در بخش نظرات با ما به اشتراک بگذارید.