در این مطلب ترجمه پست A successful Git branching model از Vincent Driessen را گذاشتم
چرا گیت؟
برای بحث جامع درباره مزایا و معایب گیت نسبت به سیستمهای مرکزی کنترل کد منبع، به اینترنت مراجعه کنید. در آنجا بسیاری از نظرات و نقدهای جدی مطرح شده است. به عنوان یک توسعهدهنده، من گیت را به عنوان بهترین ابزار در مقایسه با سایر ابزارها ترجیح میدهم. گیت واقعاً نحوه تفکر توسعهدهندگان در مورد ادغام و شاخهزنی را تغییر داده است. در دنیای کلاسیک CVS/Subversion که از آنجا آمدهام، ادغام/شاخهزنی همیشه به عنوان یک موضوع ترسناک (“از تداخلهای ادغام بپرهیزید، آنها شما را میگزنند!”) و چیزی بود که فقط یک بار در هر مدت انجام میدادید.
اما با گیت، این اقدامات بسیار ارزان و ساده هستند و واقعاً یکی از بخشهای اصلی جریان کار روزانهتان محسوب میشوند. به عنوان مثال، در کتابهای CVS/Subversion، ادغام و شاخهزنی در فصلهای آخر (برای کاربران پیشرفته) بحث میشود، در حالی که در هر کتاب گیت، این موضوع در فصل ۳ (مبانی) پوشش داده شده است.
به عنوان نتیجهای از سادگی و تکراری بودن آن، ادغام و شاخهزنی دیگر چیزی برای ترس از آن نیست. ابزارهای کنترل نسخه باید به تشعشع ادغام/شاخهزنی بیشتر از هر چیز دیگری کمک کنند.
دستههای اصلی
در اساس، مدل توسعه به شدت تحت تأثیر مدلهای موجود است. مخزن مرکزی دو شاخه اصلی با عمر نامحدود دارد:
- master
- develop
شاخه master در origin برای هر کاربر گیت باید آشنا باشد. به عنوان موازی با شاخه master، شاخه دیگری به نام develop وجود دارد.
ما origin/master را به عنوان شاخه اصلی در نظر میگیریم که کد منبع HEAD همیشه وضعیتی آماده برای تولید دارد.
همچنین ما origin/develop را به عنوان شاخه اصلی در نظر میگیریم که کد منبع HEAD همیشه وضعیتی را بازتاب میدهد که آخرین تغییرات توسعه داده شده برای نسخه بعدی است. برخی این را “شاخه ادغام” مینامند. اینجاست که هر ساخت خودکار شبانه از آنجا ایجاد میشود.
زمانی که کد منبع در شاخه develop به یک نقطه پایدار میرسد و آماده برای انتشار میشود، تمام تغییرات باید به نحوی به شاخه master ادغام شوند و سپس با یک شماره انتشار تگ شوند. چگونگی انجام این کار به تفصیل بحث خواهد شد.
به همین دلیل هر بار که تغییرات به شاخه master ادغام میشوند، این به معنای یک انتشار تولیدی جدید است. ما تمایل داریم که در این مورد بسیار سخت باشیم تا در نظریه، میتوانیم از یک اسکریپت هوک گیت برای به طور خودکار ساخت و راهاندازی نرمافزارمان بر روی سرورهای تولید ما هر بار که یک commit در master وجود داشته باشد.
شاخههای پشتیبانی
علاوه بر شاخههای اصلی master و develop، مدل توسعه ما از انواع مختلفی از شاخههای پشتیبانی برای کمک به توسعه موازی بین اعضای تیم، آسانتر کردن پیگیری ویژگیها، آمادهسازی برای انتشارهای تولید و کمک به به سرعت رفع مشکلات تولید زنده استفاده میکند. بر خلاف شاخههای اصلی، این شاخهها همیشه عمر محدودی دارند، زیرا در نهایت حذف خواهند شد.
انواع مختلفی از شاخههایی که ممکن است استفاده کنیم عبارتند از:
- شاخههای ویژگی
- شاخههای انتشار
- شاخههای Hotfix
هر یک از این شاخهها مقصود خاص خود را دارند و به قوانین دقیقی در مورد شاخههای مبدأ و مقصد ادغام آنها مرتبط هستند. در لحظه حال از هرکدام به تفصیل صحبت خواهیم کرد. شاخههای ویژگی
ممکن است از شاخههای ویژگی (یا گاهی هم به آنها شاخههای موضوعی میگویند) برای توسعه ویژگیهای جدید برای انتشار آتی یا آینده دور استفاده کرد. هنگام شروع به توسعه یک ویژگی، ممکن است در آن لحظه نامعلوم باشد که این ویژگی در کدام انتشار جا به جا خواهد شد. جوانمردی یک شاخه ویژگی این است که تا زمانی که ویژگی در حال توسعه است، وجود دارد، اما در نهایت باید به شاخه develop ادغام یا در صورت یک آزمایش ناامیدکننده، از بین برود.
شاخههای ویژگی به طور معمول تنها در مخازن توسعهدهنده وجود دارند و در origin وجود ندارند.
ایجاد شاخه ویژگی
هنگام شروع به کار روی یک ویژگی جدید، از شاخه develop بنشینید.
$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
سپس توسعه ویژگی را آغاز کنید.
ادغام یک ویژگی تمامشده با develop
ویژگیهای تمامشده ممکن است به شاخه develop ادغام شوند تا به طور قطعی به انتشار آتی افزوده شوند:
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop
پرچم –no-ff باعث میشود ادغام همیشه یک شیء commit جدید ایجاد کند، حتی اگر ادغام با یک fast-forward قابل انجام باشد. این از از دست دادن اطلاعات در مورد وجود تاریخی یک شاخه ویژگی جلوگیری میکند و تمام commitهایی که با هم ویژگی را اضافه کردهاند، گروهبندی میشوند.
شاخههای انتشار
شاخههای انتشار از انتشار یک انتشار تولیدی جدید پشتیبانی میکنند. آنها به دنبال آخرین نکات i و t در مرحله آخرین اصلاح ویژگی هستند. علاوه بر این، آنها به اصلاحات جزئی و آمادهسازی متادیتا برای یک انتشار (شماره نسخه، تاریخهای ساخت و غیره) اجازه میدهند. با انجام تمام این کارها در یک شاخه انتشار، شاخه develop برای دریافت ویژگیهای انتشار بعدی پاک میشود.
زمان کلیدی برای گرفتن یک شاخه انتشار جدید از develop زمانی است که develop (تقریباً) وضعیت مطلوب انتشار جدید را بازتاب میدهد. حداقل تمام ویژگیهایی که هدف آنها ادغام شدن در انتشار به ساخته میشوند، باید در این لحظه به develop ادغام شوند. همانطور که در این لحظه شاخه develop تغییرات “برای انتشار بعدی” را بازتاب میدهد، اما نامعلوم است که آیا این “انتشار بعدی” در نهایت ۰٫۳ یا ۱٫۰ خواهد شد تا زمانی که شاخه انتشار شروع میشود. این تصمیم در ابتدای شاخه انتشار گرفته میشود و با توجه به قوانین پروژه، نسخهبندی صورت میگیرد.
ایجاد یک شاخه انتشار
شاخههای انتشار از شاخه develop ایجاد میشوند. به عنوان مثال، فرض کنید نسخه ۱٫۱٫۵ انتشار تولیدی فعلی است و ما یک انتشار بزرگ داریم. حالا وضعیت develop آماده “برای انتشار بعدی” است و ما تصمیم گرفتهایم که این نسخه ۱٫۲ خواهد شد (به جای ۱٫۱٫۶ یا ۲٫۰). بنابراین، ما شاخهای را ایجاد میکنیم و به آن اسمی میدهیم که نسخه جدید را نشان میدهد:
$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
۱ files changed, 1 insertions(+), 1 deletions(-)
بعد از ایجاد یک شاخه جدید و سوئیچ به آن، شماره نسخه را بالا میبریم (ممکن است این را با ابزارها و اسکریپتهای مختلف انجام دهیم). سپس تمام تغییرات را commit میکنیم تا در تاریخ مشخص شده ایجاد شده باشد.
همچنین ممکن است به این شاخه از شاخه develop، تغییراتی که باید در انتشار آینده بهجای یک ویژگی جدید اضافه شوند را اضافه کنیم. به عنوان مثال، اگر یک اصلاح در این لحظه برای انتشار بعدی لازم باشد، میتوانیم آن را در این شاخه اضافه کنیم.
اتمام یک انتشار
زمانی که انتشار آماده برای ارائه است، یک سری اقدامات باید انجام شود تا این انتشار بر روی master ادغام شود و همچنین برچسبگذاری شود:
$ git checkout master Switched to branch 'master' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes) $ git tag -a 1.2
در اینجا، ما از اسکریپت اجرایی میکنیم تا شماره نسخه را در تگ بیاوریم. حتماً یک گزینه -a برای نشانگذاری با توضیحات استفاده کنید تا اطلاعات مربوط به این انتشار (تغییرات کلیدی، افزودنها، حذفها، و …) در توضیحات تگ قرار گیرد.
سپس این تغییرات را به شاخههای master و develop ادغام میکنیم:
$ git checkout develop Switched to branch 'develop' $ git merge --no-ff release-1.2 Merge made by recursive. (Summary of changes)
مطمئن شوید که تغییرات به شاخههای master و develop با هم ادغام شوند تا همهچیز همگام باشد.
سپس شاخه انتشار را پاک کنید:
$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).
و تغییرات را به origin ارسال کنید:
$git push origin –tags
$git push origin --tags
اگر شما (یا تیم شما) از سیستمهای مدیریت انتشار یا استقرار استفاده میکنید، این تگها به طور خودکار به آنها افزوده خواهد شد و یک انتشار جدید آماده خواهد کرد. این کارها به طور کامل در یک یا چند اسکریپت اجرایی میشوند تا فرآیند را سادهتر کنند.
شاخههای Hotfix
شاخههای Hotfix معمولاً برای تعمیر مشکلات اساسی (مثل باگهای که مانع از انتشار محصول میشوند) استفاده میشوند. زمان برای ایجاد یک شاخه Hotfix هنگامی است که شاخه develop حاوی تغییرات آینده نیست. بنابراین، هر آنچه در شاخه develop وجود دارد، باید در شاخه Hotfix هم وجود داشته باشد.
ایجاد یک شاخه Hotfix
شاخههای Hotfix از شاخه master ایجاد میشوند. همانند ایجاد یک شاخه انتشار، شاخه Hotfix نیاز به شمارهبندی دقیق دارد تا بتوانیم بر چسبی که بعداً برای تولید یک انتشار جدید از master استفاده میشود، اعتماد کنیم.
$git checkout -b hotfix-1.2.1 master
$./bump-version.sh ۱٫۲٫۱Files modified successfully, version bumped to ۱٫۲٫۱٫
$git commit -a -m "Bumped version number to ۱٫۲٫۱"
$git checkout -b hotfix-1.2.1 master
$./bump-version.sh ۱٫۲٫۱Files modified successfully, version bumped to ۱٫۲٫۱٫
$git commit -a -m "Bumped version number to ۱٫۲٫۱"
اتمام یک Hotfix
زمانی که تغییرات در شاخه Hotfix انجام شده و آماده برای ادغام با master است، آنها را به شاخه master ادغام کرده و سپس به شاخه master تغییرات را به شاخه develop نیز ادغام میکنیم:
$git checkout master
$git merge --no-ff hotfix-1.2.1
$git tag -a ۱٫۲٫۱
$git checkout develop
$git merge --no-ff hotfix-1.2.1
$git checkout master
$git merge --no-ff hotfix-1.2.1
$git tag -a ۱٫۲٫۱
$git checkout develop
$git merge --no-ff hotfix-1.2.1
سپس شاخه Hotfix را حذف کنید:
$git branch -d hotfix-1.2.1
$git branch -d hotfix-1.2.1
تغییرات را به origin ارسال کنید:
$git push origin --tags
$git push origin --tags
این فرآیند به طور کلی مدیریت شاخهها را برای یک پروژه گیت را پوشش داده و فرآیند کار با انواع مختلف شاخهها را نشان داده است. در هر مرحله از توسعه نرمافزار، این شاخهها کمک میکنند تا انتشارها را مدیریت کنیم، ویژگیها را توسعه دهیم و اصلاحات مهم را به سرعت در اختیار کاربران بگذاریم.
Speak Your Mind