چندی قبل که درگیر ci/cd برای یک پروژه عریض و طویل شده بودم با مشکلات و چالش هایی روبرو شدم که حل آنها بدون استاندارد مناسب و راه حل خوب مشکل بود در آن زمان نا خود آگاه خروجی کار تقریبا شبیه به استاندارد git flow شده بود بدون اینکه بدونم چنین استانداردی وجود دارد اما باز هم کامل نبود و با چالش های زیادی روبرو بود به عنوان مثال بزرگترین مشکل این بود که یک تیم توسعه مستقل از تیم رفع باگ کار می کرد و تیم رفع باگ مستقیما روی master branch کار میکرد و باگ های اصلی سیستم رو رفع می کرد به طوری که مدیریت این مسئله که باگ های رفع شده باید با develop و feature ها مرج شود دشوار بود و فرایند ci/cd را با چالش اساسی روبرو کرد اما امروز با این استاندارد مواجه شدم و دیدم که چقدر کار رو راحت کرده به همین دلیل مطلب زیر رو با ذکر منبع در این جا به اشتراک میزارم و بعدا در مطلبی دیگر ترکیب آن با ci/cd را نیز منتشر خواهم کرد.
موضوعی که در این مقاله میخواهم در رابطه با آن صحبت کنم، تعریف یک مدل یا Road map برای مدیریت یک پروژه روی ورژن کنترلی مثل گیت است.
اگر قبلا تجربه کار کردن به صورت تیم را داشته باشید حتما به مشکلاتی همچون Merge Conflict و تداخل و همزمانی توسعه ویژگیها و… برخورد کردید که گاهی وقتها وقت زیادی رو از ما میگیره تا برنچهای مختلف را با هم ادغام و در نهایت Deploy کنیم.
به عبارتی Git Flow یک Branch Model است یا بهتره بگم یه مفهوم برای مدیریت برنچها و تیم توسعه است که بدون مشکل بتوانیم پروژههایمان را توسعه دهیم و به صورت همزمان بتوانیم Feature هایی که میخواهیم را به بخشهای مختلف پروژه اضافه کنیم بدون اینکه استرسی بابت مرج و لانچ بخشهای مختلف داشته باشیم.
Gitflow is ideally suited for projects that have a scheduled release cycle. This workflow doesn’t add any new concepts or commands beyond what’s required for the FeatureBranch Workflow. Instead, it assigns very specific roles to different branches and defines how and when they should interact. In addition to feature
branches, it uses individual branches for preparing, maintaining, and recording releases. Of course, you also get to leverage all the benefits of the Feature Branch Workflow: pull requests, isolated experiments, and more efficient collaboration.
در واقع Git Flow یک ایده ای برای مدیریت محیط توسعه است و مشخص میکند که چه Branch هایی ساخته شوند و چگونه این Branchها با هم Merge شوند.
در ابتدا گیت را نصب کنید و سپس با اجرای دستور git flow init میتوانید از آن در پروژه خود استفاده کنید. Git-flow ریپازیتوری شما را تغییر نمیدهد و همراه با Git استفاده میشود.
git-flow is a wrapper around existing git commands, so the init
command doesn’t change anything in your repository other than creating branches for you. If you don’t want to use git-flow anymore, there’s nothing to change or remove, you just stop using the git-flow commands.
به جای اینکه یک برنچ master داشته باشیم و یا برنچهای مختلف با نامهای مختلف داشته باشیم در این شیوه ۲ برنچ به نامهای master , develop داریم که برنچ masterهمان نسخه لانچ شده پروژه است و برنچ develop نسخه ای از پروژه است که همه feature ها و تغییرات نهایی روی آن قرار میگیرند و پس از تست با برنچ master مرج میشوند. ( من شخصا در همه پروژههایی که داشتم برنچ develop را همان برنچ تست نهایی درنظر گرفتم به طوریکه این برنچ روی یک دامین تست فعال است و بعد از اضافه شدن هر Feature ابتدا روی دامین تست بررسی و سپس Release انجام میشود. )
نکته: با استفاده از tag ها بعد از هر بار لانچ Master Branch را ورژن بندی میکنیم.
برای ایجاد develop branch یا در محیط کنترل ورژن آن را ایجاد میکنیم و یا اینکه با استفاده از دستور زیر روی ریپازیتوری لوکال آن را ایجاد و push میکنیم.
git branch develop git push -u origin develop
زمانی که از Git Flow استفاده میکنیم، با اجرای دستور git flow init روی ریپازیتوری ای که وجود دارد develop branch نیز ایجاد میشود البته قبل از آن میبایست با اجرای دستور apt-get install git-flow
آن را نصب کنید.
هر ویژگی که به پروژه اضافه میشود روی یک برنچ با نام ویژگی توسعه داده میشود در واقع هر Feature یک Branch برای خود دارد که همه Feature Branchها از Develop به عنوان والد خود تبعیت میکنند و زمانی که یک Feature تکمیل میشود با develop مرج میشود. ( هیچ وقت از برنچهای Feature مرج با master صورت نمیگیرد )
توجه کنید که هر Feature Branch از آخرین ورژن develop branch ساخته میشود در حالیکه همزمان با توسعه هر feature توسعه برنچ develop متوقف نمیشود و امکان توسعه و Merge سایر branchها وجود دارد.
اگر بخواهیم بدون استفاده از git-flow یک feature branch بسازیم به صورت زیر اقدام میکنیم:
git checkout develop git checkout -b feature_branch
ولی اگر از Git Flow استفاده کنیم به صورت زیر feature branch را ایجاد میکنیم:
git flow feature start feature_branch
زمانی که ویژگیهای لازم اضافه شدند و feature branch تکمیل شد باید آن را با برنچ develop مرج کنیم.
اگر بدون استفاده از Git Flow آن را Merge کنیم به صورت زیر اقدام میکنیم:
git checkout develop git merge feature_branch
ولی اگر از Git Flow استفاده کنیم به صورت زیر Merge را انجام میدهیم:
git flow feature finish feature_branch
از نظر من Release branch یکی از جذابترین قسمتهای Git Flow است، در ابتدا تصور من این بود وقتی develop برنچ را داریم و این برنچ را میتوانیم با برنچ master مرج کنیم چه نیازی است برنچهای جدیدی به نام release branch ایجاد کنیم!
زمانی که برنچ develop به اندازه ای توسعه داده شد و feature های لازم با آن Merge شدند میتوانیم آن را release کنیم و یک fork از develop برای release میگیریم. زمانی که برنچ release ایجاد میشود در واقع از این نقطه یک چرخه حیات برای آن برنچ ایجاد میشود و حتی اگر feture جدیدی هم با برنچ develop مرج شوند و تغییراتی صورت بگیرد شامل این نسخه از release نمیشود و این باعث میشود که تیمهایی که به صورت مستقل روی featureهای مختلف کار میکنند هیچ تداخلی با هم نداشته باشند. در واقع هیچ ویژگی جدیدی نمیتواند به این برنچ اضافه شود به استثنای bug fixها و موارد حیاتی که روی این برنچ انجام میشوند.
زمانیکه برنچ release آماده انتشار شد با master branch همراه تگ ورژن آن مرج میشود. همچنین لازم و ضروری است بعد از آن دوباره با develop branch مرج شود تا اگر موارد مهمی در این برنچ رفع شده بود و تغییراتی اعمال شده بود به برنچ develop نیز انتقال داده شود.
زمانیکه از Release branchها استفاده میکنیم در واقع تیمها به راحتی باهم بر روی توسعه ویژگیهای مختلف کار میکنند و همچنین میتوان پروژه را مطابق فاز بندی پیش برد به طوریکه به راحتی میتوانیم بگوییم مثلا این هفته ورژن ۴.۰ پروژه را لانچ میکنیم.
از توضیحات فوق مشخص است که Release Branchها هم مانند Feature Branch ها بر مبنای develop branch ایجاد میشوند. برای ایجاد Release Branch به صورت زیر اقدام میکنیم:
بدون استفاده از Git Flow :
git checkout develop git checkout -b release/0.1.0
با استفاده از Git Flow :
$ git flow release start 0.1.0 // Switched to a new branch 'release/0.1.0'
زمانی که نخستین Release آماده شد با برنچهای master و develop مرج میشود و پس از آن Release Branch حذف میشود. خیلی مهم است که Release Branch با develop branch مرج شود تا تغییرات مهم داخل release branch به develop branch منتقل شود و feature branch ها هم از آن استفاده کنند.
برای اتمام release branch موارد زیر را انجام میدهیم.
بدون استفاده از Git Flow :
git checkout develop git merge release/0.1.0 git checkout master git checkout merge release/0.1.0
با استفاده از Git Flow :
git flow release finish '0.1.0'
برنچ Maintenance یا hotfix branch برای نگهداری و رفع سریع باگهای محصول نهایی است ( patch production releases ).
در واقع Hotfix branches بسیار شبیه Release branch و Feature branch هستند با این تفاوت که hotfix branchها از master branch گرفته میشوند. Hotfix branch تنها branchی است که به طور مستقیم از master و بدون واسطه Fork میگیرد، پس از رفع باگ موردنظر با master branch و develope branch مرج میشود. ( همچنین اگر Release branch وجود داشته باشد که در حال اجرا باشد با آن نیز Merge میشود. ) پس از مرج، master branch ورژن تگ خود را آپدیت میکند.
وجود یک مسیر و برنچ جدا برای bug fix این امکان را به تیم میدهد که منتظر Release بعدی و رفع باگ نباشند و هر تیم روی feature یا Release خود کار کند و پس از اتمام، آخرین آپدیت را دریافت میکند. در واقع میتوانیم به این صورت تصور کنیم که hotfix یک برنچ با وظایف مشخص است که به طور مستقیم با master branch فعالیت میکند و تداخلی با روند اجرای فعالیتهای تیم ندارد.
بدون استفاده از Git Flow :
git checkout master git checkout -b hotfix_branch
با استفاده از Git Flow :
git flow hotfix start hotfix_branch
مشابه Release Branch برنچ hotfix هم باید با master branch و develop branch مرج شود.
بدون استفاده از Git Flow :
git checkout master git merge hotfix_branch git checkout develop git merge hotfix_branch git branch -D hotfix_branch
با استفاده از Git Flow:
git flow hotfix finish hotfix_branch
برای اینکه نشان دهیم یک Feature Branch به چه صورتی کار میکند با فرض اینکه ما آخرین آپدیتهای master را داریم و میخواهیم روی feature جدید کار کنیم :
git checkout master git checkout -b develop git checkout -b feature_branch # work happens on feature branch git checkout develop git merge feature_branch git checkout master git merge develop git branch -d feature_branch
هنگام کار روی hotfix branch به صورت زیر اقدام میکنیم:
git checkout master git checkout -b hotfix_branch # work is done commits are added to the hotfix_branch git checkout develop git merge hotfix_branch git checkout master git merge hotfix_branch
در این مقاله در مورد Gitflow Workflow صحبت کردیم، Git Flow یکی از استایلها و سبکهایی از Gitflow Workflow است که شما میتوانید توی تیم خودتون از آن استفاده کنید.
نکات مهمی که Git Flow بر روی آن تاکید دارد این است که :
روند اجرای کلی Git Flow به صورت زیر است :
نکته: وقتی که پروژه خود را روی لوکال clone میکنید و مطابق دستورات git flow پیش میروید به احتمال زیاد ورژن تگهایی که وارد میکنید را روی گیتهاب یا گیت لب نبینید! برای اینکه ورژن تگها هم push شوند دستور زیر را اجرا کنید:
git push --tags
همچنین اگر روی لوکال git flow را اجرا کرده باشید و قبل آن برنچ develop را ایجاد نکرده باشید با توجه به اینکه همه Releaseها روی برنچ release روی master قرار میگیرند به احتمال زیاد برنچ develop هم روی gitlab یا github شما وجود ندارد! برای اینکه همه تغییرات لوکال برنچها روی ریپازیتوری قرار بگیرند دستور زیر را اجرا کنید:
git push --all -u
منبع : http://mekaeil.me/git-flow-great-solution-for-project-management/