قبلا در رابطه با گیت و دستورات آن در مقاله ای صحبت کردم و دستورات کاربردی آن را در یک مقاله نسبتا طولانی نوشتم که به مرور بروزرسانی شد و تجربیات خودم را هم به آن اضافه کردم.
اما موضوعی که در این مقاله میخواهم در رابطه با آن صحبت کنم، تعریف یک مدل یا 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.
Git Flow چگونه کار میکند؟
به جای اینکه یک برنچ 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 نیز ایجاد میشود :
Feature Branches
هر ویژگی که به پروژه اضافه میشود روی یک برنچ با نام ویژگی توسعه داده میشود در واقع هر Feature یک Branch برای خود دارد که همه Feature Branchها از Develop به عنوان والد خود تبعیت میکنند و زمانی که یک Feature تکمیل میشود با develop مرج میشود. ( هیچ وقت از برنچهای Feature مرج با master صورت نمیگیرد )
توجه کنید که هر Feature Branch از آخرین ورژن develop branch ساخته میشود در حالیکه همزمان با توسعه هر feature توسعه برنچ develop متوقف نمیشود و امکان توسعه و Merge سایر branchها وجود دارد.
ایجاد feature 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
زمانی که ویژگیهای لازم اضافه شدند و feature branch تکمیل شد باید آن را با برنچ develop مرج کنیم.
اگر بدون استفاده از Git Flow آن را Merge کنیم به صورت زیر اقدام میکنیم:
git checkout develop
git merge feature_branch
ولی اگر از Git Flow استفاده کنیم به صورت زیر Merge را انجام میدهیم:
git flow feature finish feature_branch
Release Branches
از نظر من 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'
Hotfix Branches
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 بر روی آن تاکید دارد این است که :
- workflow یک محیط عالی برای محصولات release-based است که در زمانبندیهای مشخص میتوانید Releaseهای زمانبندی شده داشته باشید.
- Git Flow پیشنهاد میکند که یک برنچ و مسیر مشخص برای hotfix از محصول نهایی داشته باشیم.
روند اجرای کلی Git Flow به صورت زیر است :
- develop branch از master branch ساخته میشود.
- release branch از develop branch ساخته میشود.
- Feature branches از develop branch ساخته میشود.
- زمانیکه یک feature تکمیل میشود با develop branch مرج میشود.
- زمانیکه یک release branch انجام میشود با master branch و develop branch مرج میشود.
- وقتیکه یک باگ شناسایی میشود یک hotfix branch از master branch ساخته میشود.
- وقتیکه hotfix رفع شد با برنچهای master و develop مرج میشود.
نکته: وقتی که پروژه خود را روی لوکال clone میکنید و مطابق دستورات git flow پیش میروید به احتمال زیاد ورژن تگهایی که وارد میکنید را روی گیتهاب یا گیت لب نبینید! برای اینکه ورژن تگها هم push شوند دستور زیر را اجرا کنید:
git push --tags
همچنین اگر روی لوکال git flow را اجرا کرده باشید و قبل آن برنچ develop را ایجاد نکرده باشید با توجه به اینکه همه Releaseها روی برنچ release روی master قرار میگیرند به احتمال زیاد برنچ develop هم روی gitlab یا github شما وجود ندارد! برای اینکه همه تغییرات لوکال برنچها روی ریپازیتوری قرار بگیرند دستور زیر را اجرا کنید:
git push --all -u
برای مطالعه بیشتر میتوانید مقالات زیر را مطالعه کنید:
Using git-flow to automate your git branching workflow
A successful Git branching model
ویدیو A short introduction to Git Flow
What is Git Flow? – An introduction to Git Flow
Continuous Delivery Workflows With the Branch-per-Issue Model