{"id":77517,"date":"2026-07-07T04:12:35","date_gmt":"2026-07-07T04:12:35","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=77517"},"modified":"2026-07-07T04:12:38","modified_gmt":"2026-07-07T04:12:38","slug":"gitflow-master-tutorial","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/gitflow-master-tutorial\/","title":{"rendered":"Gitflow Master Tutorial"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">From Basic to Advanced: A Complete One-Stop Guide to Gitflow Branching, Releases, Hotfixes, CI\/CD, and Governance<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1. What is Gitflow?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Gitflow<\/strong> is a structured Git branching model designed for teams that release software in planned versions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It uses several branch types, each with a specific job:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main \/ master\ndevelop\nfeature\/*\nrelease\/*\nhotfix\/*\nsupport\/* optional\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In simple words:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Gitflow is a release-focused branching strategy.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">It is especially useful when a team needs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>scheduled releases<\/li>\n\n\n\n<li>release stabilization<\/li>\n\n\n\n<li>hotfix handling<\/li>\n\n\n\n<li>version tags<\/li>\n\n\n\n<li>support for older versions<\/li>\n\n\n\n<li>QA cycles<\/li>\n\n\n\n<li>approval gates<\/li>\n\n\n\n<li>controlled production delivery<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The original Gitflow model was introduced by Vincent Driessen in 2010 as a branching strategy for developing and releasing version-based software. In his later 2020 note, he warned that teams should not treat Gitflow as a universal standard or dogma, and specifically suggested simpler workflows for continuously delivered web apps.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2. The simplest mental model<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow separates software work into five lanes:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">feature work     \u2192 feature\/*\nintegration      \u2192 develop\nrelease prep     \u2192 release\/*\nproduction       \u2192 main\nemergency repair \u2192 hotfix\/*\n<\/code><\/span><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;feature\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;release\/*]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;main \/ production]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;hotfix\/*]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The core idea:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Developers can continue building the next version while another branch is being stabilized for release.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">That is the magic of Gitflow.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3. Why Gitflow exists<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Without Gitflow, teams often struggle with this problem:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Some developers are building future features.\nQA wants to test the next release.\nProduction has a critical bug.\nCustomers still need old versions supported.\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Gitflow gives each problem a separate branch lane.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Problem<\/th><th>Gitflow solution<\/th><\/tr><\/thead><tbody><tr><td>New feature work<\/td><td><code>feature\/*<\/code><\/td><\/tr><tr><td>Shared next-release integration<\/td><td><code>develop<\/code><\/td><\/tr><tr><td>Release testing and stabilization<\/td><td><code>release\/*<\/code><\/td><\/tr><tr><td>Production-ready history<\/td><td><code>main<\/code> \/ <code>master<\/code><\/td><\/tr><tr><td>Emergency production fix<\/td><td><code>hotfix\/*<\/code><\/td><\/tr><tr><td>Older version maintenance<\/td><td><code>support\/*<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">AWS describes Gitflow as a model that uses multiple branches to move code from development to production, and says it works well for scheduled release cycles where a collection of features is grouped into a release.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4. Gitflow is not just \u201cmore branches\u201d<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Bad understanding:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Gitflow = create many branches\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Correct understanding:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Gitflow = separate development, release stabilization, production, and hotfix work\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">A branch in Gitflow must have a clear purpose.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">flowchart TD\n    A&#91;Need a branch?] --&gt; B{What is the purpose?}\n    B -- <span class=\"hljs-keyword\">New<\/span> feature --&gt; C&#91;feature<span class=\"hljs-comment\">\/*]\n    B -- Integrate next release --&gt; D&#91;develop]\n    B -- Stabilize release --&gt; E&#91;release\/*]\n    B -- Production code --&gt; F&#91;main]\n    B -- Emergency fix --&gt; G&#91;hotfix\/*]\n    B -- Old version support --&gt; H&#91;support\/*]\n    B -- No clear purpose --&gt; I&#91;Do not create branch]\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5. The full Gitflow branch family<\/h1>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">gitGraph\n    commit id: <span class=\"hljs-string\">\"v1.0.0\"<\/span>\n    branch develop\n    checkout develop\n    commit id: <span class=\"hljs-string\">\"dev work\"<\/span>\n    branch feature\/login\n    checkout feature\/login\n    commit id: <span class=\"hljs-string\">\"login 1\"<\/span>\n    commit id: <span class=\"hljs-string\">\"login 2\"<\/span>\n    checkout develop\n    merge feature\/login\n    branch release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span>\n    checkout release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span>\n    commit id: <span class=\"hljs-string\">\"release fix\"<\/span>\n    checkout main\n    merge release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span> tag: <span class=\"hljs-string\">\"v1.1.0\"<\/span>\n    checkout develop\n    merge release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span>\n    checkout main\n    branch hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>\n    checkout hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>\n    commit id: <span class=\"hljs-string\">\"prod fix\"<\/span>\n    checkout main\n    merge hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span> tag: <span class=\"hljs-string\">\"v1.1.1\"<\/span>\n    checkout develop\n    merge hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6. Main branches in Gitflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow has two long-lived primary branches:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main \/ master\ndevelop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The original Gitflow model used <code>master<\/code>; modern teams often rename it to <code>main<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6.1 <code>main<\/code> branch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>main<\/code> branch represents production-ready code.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main = production history\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Every commit on <code>main<\/code> should represent a production release or production-ready state.<\/li>\n\n\n\n<li>Releases are tagged on <code>main<\/code>.<\/li>\n\n\n\n<li>Direct pushes should be blocked.<\/li>\n\n\n\n<li>Only release branches and hotfix branches merge into <code>main<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Vincent Driessen\u2019s original model defines <code>origin\/master<\/code> as the branch where <code>HEAD<\/code> always reflects a production-ready state; in modern naming, this is usually <code>origin\/main<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6.2 <code>develop<\/code> branch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>develop<\/code> branch is the integration branch for the next release.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">develop = next release integration\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Feature branches merge into <code>develop<\/code>.<\/li>\n\n\n\n<li><code>develop<\/code> should be stable enough for integration testing.<\/li>\n\n\n\n<li>When <code>develop<\/code> has enough features for a release, create a <code>release\/*<\/code> branch.<\/li>\n\n\n\n<li>Hotfixes from production must eventually flow back into <code>develop<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The original model describes <code>develop<\/code> as the branch where the latest delivered development changes for the next release are integrated.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">7. Supporting branches in Gitflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow uses short-lived supporting branches.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">feature\/*\nrelease\/*\nhotfix\/*\nsupport\/* optional\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Vincent Driessen\u2019s original Gitflow article defines feature, release, and hotfix branches as supporting branches with limited lifetimes and strict rules about where they start and where they merge.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">8. Gitflow branch responsibility table<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Branch<\/th><th>Starts from<\/th><th>Merges into<\/th><th>Lifetime<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>main<\/code><\/td><td>none<\/td><td>none directly<\/td><td>permanent<\/td><td>production-ready releases<\/td><\/tr><tr><td><code>develop<\/code><\/td><td><code>main<\/code> initially<\/td><td>release\/hotfix merges back<\/td><td>permanent<\/td><td>next release integration<\/td><\/tr><tr><td><code>feature\/*<\/code><\/td><td><code>develop<\/code><\/td><td><code>develop<\/code><\/td><td>short<\/td><td>build new features<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td><code>develop<\/code><\/td><td><code>main<\/code> and <code>develop<\/code><\/td><td>temporary<\/td><td>stabilize release<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td><code>main<\/code><\/td><td><code>main<\/code> and <code>develop<\/code><\/td><td>very short<\/td><td>fix production urgently<\/td><\/tr><tr><td><code>support\/*<\/code><\/td><td>release tag \/ <code>main<\/code><\/td><td>depends<\/td><td>long<\/td><td>maintain old versions<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">9. Gitflow branch naming standard<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended naming<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">feature\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ticket<\/span>&gt;<\/span>-<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">short-description<\/span>&gt;<\/span>\nrelease\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>\nhotfix\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>-<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">short-description<\/span>&gt;<\/span>\nsupport\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version-or-line<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Examples<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">feature\/EVP-123-add-device-search\nfeature\/EVP-140-payment-retry\nrelease\/2.4.0\nrelease\/mobile-5.1.0\nhotfix\/2.4.1-login-crash\nhotfix\/2.4.2-security-token-rotation\nsupport\/1.9-lts\nsupport\/2.x\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Avoid<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">my-branch\ntest\n<span class=\"hljs-keyword\">final<\/span>\n<span class=\"hljs-keyword\">new<\/span>\nfix\nrajesh-work\nrelease-latest\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Good branch names should explain purpose before anyone opens the code.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">10. Gitflow lifecycle overview<\/h1>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">flowchart TD\n    A&#91;Start <span class=\"hljs-keyword\">from<\/span> develop] --&gt; B&#91;Create feature branch]\n    B --&gt; C&#91;Develop feature]\n    C --&gt; D&#91;Merge feature into develop]\n    D --&gt; E{Enough features <span class=\"hljs-keyword\">for<\/span> release?}\n    E -- No --&gt; B\n    E -- Yes --&gt; F&#91;Create release branch]\n    F --&gt; G&#91;QA \/ bug fixes \/ version bump]\n    G --&gt; H&#91;Merge release into main]\n    H --&gt; I&#91;Tag version]\n    I --&gt; J&#91;Merge release back into develop]\n    J --&gt; K&#91;Delete release branch]\n    H --&gt; L{Production issue?}\n    L -- Yes --&gt; M&#91;Create hotfix <span class=\"hljs-keyword\">from<\/span> main]\n    M --&gt; N&#91;Fix and test]\n    N --&gt; O&#91;Merge hotfix into main]\n    O --&gt; P&#91;Tag patch version]\n    P --&gt; Q&#91;Merge hotfix into develop]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">11. Step 1: Initialize a Gitflow-style repository<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Start with <code>main<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">git init\ngit checkout -b main\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"# My Project\"<\/span> &gt; README.md\ngit add README.md\ngit commit -m <span class=\"hljs-string\">\"chore: initial commit\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create <code>develop<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout -b develop\ngit push -u origin main\ngit push -u origin develop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Now your repository has:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main\ndevelop\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">12. Step 2: Feature branch workflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Feature branches are created from <code>develop<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;feature\/add-login]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;work + commits]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;pull request]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;merge into develop]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create a feature branch<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit checkout -b feature\/EVP-123-add-login\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Work and commit<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git add .\ngit commit -m <span class=\"hljs-string\">\"feat(auth): add login endpoint\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Push feature branch<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git push -u origin feature\/EVP-123-add-login\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Merge feature into <code>develop<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Option A: via pull request \/ merge request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Option B: command line.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff feature\/EVP-123-add-login\ngit push origin develop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The original Gitflow article uses <code>--no-ff<\/code> when merging finished feature branches into <code>develop<\/code> so the historical existence of the feature branch remains visible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Delete feature branch<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git branch -d feature\/EVP<span class=\"hljs-number\">-123<\/span>-add-login\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> feature\/EVP<span class=\"hljs-number\">-123<\/span>-add-login\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">13. Feature branch rules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Feature branches should:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>start from <code>develop<\/code><\/li>\n\n\n\n<li>be short-lived<\/li>\n\n\n\n<li>contain one feature or one logical change<\/li>\n\n\n\n<li>be reviewed before merging<\/li>\n\n\n\n<li>pass CI before merging<\/li>\n\n\n\n<li>merge only into <code>develop<\/code><\/li>\n\n\n\n<li>be deleted after merge<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Feature branches should not:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>start from <code>main<\/code><\/li>\n\n\n\n<li>merge directly into <code>main<\/code><\/li>\n\n\n\n<li>include multiple unrelated features<\/li>\n\n\n\n<li>live for months<\/li>\n\n\n\n<li>contain production hotfixes<\/li>\n\n\n\n<li>contain release-only version bumps<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">14. Step 3: Release branch workflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A release branch is created from <code>develop<\/code> when the team decides that the next release has enough features.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;release\/2.4.0]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;QA testing]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Bug fixes only]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Version bump \/ release notes]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;Merge to main]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;Tag v2.4.0]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;Merge back to develop]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create a release branch<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit checkout -b release\/2.4.0\ngit push -u origin release\/2.4.0\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Bump version<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Example file:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">VERSION=2.4.0\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Commit:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git add VERSION\ngit commit -m <span class=\"hljs-string\">\"chore(release): bump version to 2.4.0\"<\/span>\ngit push origin release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Fix release bugs<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git add .\ngit commit -m <span class=\"hljs-string\">\"fix(release): correct payment retry configuration\"<\/span>\ngit push origin release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Finish release<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Merge into <code>main<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit pull --ff-only origin main\ngit merge --no-ff release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span> -m <span class=\"hljs-string\">\"Release v2.4.0\"<\/span>\ngit push origin main v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Merge back into <code>develop<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff release\/2.4.0\ngit push origin develop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete release branch.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git branch -d release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The original Gitflow model says release branches start from <code>develop<\/code>, merge back into both <code>main<\/code> and <code>develop<\/code>, and are used for final release preparation such as minor bug fixes and release metadata.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">15. Release branch rules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Allowed on <code>release\/*<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">bug fixes\nversion bump\nrelease notes\ndocumentation correction\nsafe configuration correction\ntest fixes related to release\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Not allowed on <code>release\/*<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">new<\/span> features\nlarge refactors\nexperimental work\nunrelated cleanup\nrisky dependency upgrades\nmajor architecture changes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Important rule:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">A release branch is for stabilization, not innovation.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">16. Step 4: Hotfix branch workflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A hotfix branch is created when production is broken and cannot wait for the next scheduled release.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Production issue]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;Create hotfix from main]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;Fix issue]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Test]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Merge into main]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;Tag patch release]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;Merge into develop]<\/span>\n    <span class=\"hljs-selector-tag\">G<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;Delete hotfix branch]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create hotfix branch<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout main\ngit pull --ff-only origin main\ngit checkout -b hotfix\/2.4.1-login-crash\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Bump patch version<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">echo<\/span> \"2<span class=\"hljs-selector-class\">.4<\/span><span class=\"hljs-selector-class\">.1<\/span>\" &gt; <span class=\"hljs-selector-tag\">VERSION<\/span>\n<span class=\"hljs-selector-tag\">git<\/span> <span class=\"hljs-selector-tag\">add<\/span> <span class=\"hljs-selector-tag\">VERSION<\/span>\n<span class=\"hljs-selector-tag\">git<\/span> <span class=\"hljs-selector-tag\">commit<\/span> <span class=\"hljs-selector-tag\">-m<\/span> \"<span class=\"hljs-selector-tag\">chore<\/span>(<span class=\"hljs-selector-tag\">hotfix<\/span>): <span class=\"hljs-selector-tag\">bump<\/span> <span class=\"hljs-selector-tag\">version<\/span> <span class=\"hljs-selector-tag\">to<\/span> 2<span class=\"hljs-selector-class\">.4<\/span><span class=\"hljs-selector-class\">.1<\/span>\"\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Fix production bug<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git add .\ngit commit -m <span class=\"hljs-string\">\"fix(auth): prevent crash on expired login token\"<\/span>\ngit push -u origin hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Finish hotfix<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Merge into <code>main<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit pull --ff-only origin main\ngit merge --no-ff hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.1<\/span> -m <span class=\"hljs-string\">\"Hotfix v2.4.1\"<\/span>\ngit push origin main v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.1<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Merge into <code>develop<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff hotfix\/2.4.1-login-crash\ngit push origin develop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete branch.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git branch -d hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In the original model, hotfix branches start from <code>master<\/code>\/<code>main<\/code> and must merge back into both <code>master<\/code>\/<code>main<\/code> and <code>develop<\/code>; if a release branch currently exists, the hotfix should also be merged into that release branch so the release includes the fix.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">17. Hotfix branch rules<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Hotfix branches should:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>start from <code>main<\/code> or the production tag<\/li>\n\n\n\n<li>fix only the production issue<\/li>\n\n\n\n<li>be small<\/li>\n\n\n\n<li>be reviewed quickly<\/li>\n\n\n\n<li>run critical tests<\/li>\n\n\n\n<li>merge into <code>main<\/code><\/li>\n\n\n\n<li>be tagged as a patch release<\/li>\n\n\n\n<li>merge back into <code>develop<\/code><\/li>\n\n\n\n<li>merge into active <code>release\/*<\/code> branch if one exists<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Hotfix branches should not:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>include new features<\/li>\n\n\n\n<li>include refactoring<\/li>\n\n\n\n<li>include broad dependency upgrades<\/li>\n\n\n\n<li>include unrelated cleanup<\/li>\n\n\n\n<li>bypass source control<\/li>\n\n\n\n<li>remain open after deployment<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">18. What if a release branch exists during hotfix?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is a common Gitflow confusion.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Situation:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main = production v2.4.0\ndevelop = future v2.6.0 work\nrelease\/2.5.0 = currently in QA\nproduction has critical bug\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Flow:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;main]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;hotfix\/2.4.1]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;merge to main]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;tag v2.4.1]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;merge to release\/2.5.0]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;eventually release branch merges to develop]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;optionally merge to develop immediately if needed]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Practical rule:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Hotfix must reach every branch that still needs the fix.\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Usually:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>merge hotfix into <code>main<\/code><\/li>\n\n\n\n<li>merge hotfix into active <code>release\/*<\/code><\/li>\n\n\n\n<li>merge hotfix into <code>develop<\/code> now or via release branch later<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">19. Optional support branch workflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use support branches when older versions must be maintained.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">support\/1.9-lts\nsupport\/2.x\n<\/code><\/span><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;main latest]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;support\/2.x]<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;support\/1.9-lts]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;security fix]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create support branch<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout v1.9.0\ngit checkout -b support\/1.9-lts\ngit push -u origin support\/1.9-lts\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Backport fix<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">git checkout support\/1.9-lts\ngit cherry-pick <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">fix-commit-sha<\/span>&gt;<\/span>\ngit push origin support\/1.9-lts\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Tag support release<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">git<\/span> <span class=\"hljs-selector-tag\">tag<\/span> <span class=\"hljs-selector-tag\">-a<\/span> <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.9<\/span><span class=\"hljs-selector-class\">.7<\/span> <span class=\"hljs-selector-tag\">-m<\/span> \"<span class=\"hljs-selector-tag\">Support<\/span> <span class=\"hljs-selector-tag\">release<\/span> <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.9<\/span><span class=\"hljs-selector-class\">.7<\/span>\"\n<span class=\"hljs-selector-tag\">git<\/span> <span class=\"hljs-selector-tag\">push<\/span> <span class=\"hljs-selector-tag\">origin<\/span> <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.9<\/span><span class=\"hljs-selector-class\">.7<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use support branches only when the product genuinely needs long-term maintenance for older versions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">20. Gitflow with Semantic Versioning<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow works naturally with Semantic Versioning.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">MAJOR<\/span><span class=\"hljs-selector-class\">.MINOR<\/span><span class=\"hljs-selector-class\">.PATCH<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.0<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.1<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.1<\/span><span class=\"hljs-selector-class\">.1<\/span>\n<span class=\"hljs-selector-tag\">v2<\/span><span class=\"hljs-selector-class\">.0<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Semantic Versioning defines major versions for incompatible API changes, minor versions for backward-compatible functionality, and patch versions for backward-compatible bug fixes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mapping Gitflow to SemVer<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Gitflow action<\/th><th>Version effect<\/th><\/tr><\/thead><tbody><tr><td>feature merged into release<\/td><td>usually minor<\/td><\/tr><tr><td>bug fix in release branch<\/td><td>patch before release<\/td><\/tr><tr><td>hotfix from production<\/td><td>patch<\/td><\/tr><tr><td>breaking change<\/td><td>major<\/td><\/tr><tr><td>support branch fix<\/td><td>patch for old version<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">release\/2.4.0 \u2192 tag v2.4.0\nhotfix\/2.4.1-login-crash \u2192 tag v2.4.1\nsupport\/1.9-lts \u2192 tag v1.9.8\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">21. Gitflow with Conventional Commits<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Conventional Commits makes Gitflow cleaner because commit messages become meaningful for changelogs and release notes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Format:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">type<\/span>&gt;<\/span>(optional-scope): <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">description<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">feat(auth)<\/span>: add OAuth login\n<span class=\"hljs-attribute\">fix(payment)<\/span>: retry gateway timeout\n<span class=\"hljs-attribute\">chore(release)<\/span>: bump version to 2.4.0\n<span class=\"hljs-attribute\">docs(runbook)<\/span>: add hotfix process\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The Conventional Commits specification defines a lightweight structure for commit messages that gives human-readable and machine-readable meaning to commit history and aligns with SemVer concepts like features, fixes, and breaking changes.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">22. Gitflow commit type guide<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Type<\/th><th>Use in Gitflow<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>feat<\/code><\/td><td>feature branches<\/td><td><code>feat(auth): add SSO login<\/code><\/td><\/tr><tr><td><code>fix<\/code><\/td><td>bugfix, release, hotfix<\/td><td><code>fix(api): handle null vehicle id<\/code><\/td><\/tr><tr><td><code>chore<\/code><\/td><td>version bump, maintenance<\/td><td><code>chore(release): bump version<\/code><\/td><\/tr><tr><td><code>docs<\/code><\/td><td>documentation<\/td><td><code>docs: update release checklist<\/code><\/td><\/tr><tr><td><code>test<\/code><\/td><td>tests<\/td><td><code>test(payment): add retry tests<\/code><\/td><\/tr><tr><td><code>refactor<\/code><\/td><td>internal cleanup<\/td><td><code>refactor(auth): simplify token parser<\/code><\/td><\/tr><tr><td><code>perf<\/code><\/td><td>performance<\/td><td><code>perf(cache): reduce lookup latency<\/code><\/td><\/tr><tr><td><code>ci<\/code><\/td><td>pipeline changes<\/td><td><code>ci: add release branch workflow<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">23. Gitflow command cheat sheet<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Create <code>develop<\/code><\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout main\ngit checkout -b develop\ngit push -u origin develop\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create feature<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit checkout -b feature\/EVP-123-add-login\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Finish feature<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff feature\/EVP<span class=\"hljs-number\">-123<\/span>-add-login\ngit push origin develop\ngit branch -d feature\/EVP<span class=\"hljs-number\">-123<\/span>-add-login\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> feature\/EVP<span class=\"hljs-number\">-123<\/span>-add-login\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create release<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit pull --ff-only origin develop\ngit checkout -b release\/2.4.0\ngit push -u origin release\/2.4.0\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Finish release<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit pull --ff-only origin main\ngit merge --no-ff release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span> -m <span class=\"hljs-string\">\"Release v2.4.0\"<\/span>\ngit push origin main v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span>\n\ngit checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit push origin develop\n\ngit branch -d release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create hotfix<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout main\ngit pull --ff-only origin main\ngit checkout -b hotfix\/2.4.1-login-crash\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Finish hotfix<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit pull --ff-only origin main\ngit merge --no-ff hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.1<\/span> -m <span class=\"hljs-string\">\"Hotfix v2.4.1\"<\/span>\ngit push origin main v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.1<\/span>\n\ngit checkout develop\ngit pull --ff-only origin develop\ngit merge --no-ff hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit push origin develop\n\ngit branch -d hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit push origin --<span class=\"hljs-keyword\">delete<\/span> hotfix\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-32\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">24. Gitflow with pull requests<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Traditional Gitflow can be done with command-line merges, but modern teams should use pull requests or merge requests.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended PR flow<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;feature\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;PR to develop]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;release\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;PR to main]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;PR back to develop]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;hotfix\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;PR to main]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;PR to develop]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">PR targets<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Source branch<\/th><th>Target branch<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>feature\/*<\/code><\/td><td><code>develop<\/code><\/td><td>add feature to next release<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td><code>main<\/code><\/td><td>publish release<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td><code>develop<\/code><\/td><td>return release fixes<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td><code>main<\/code><\/td><td>fix production<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td><code>develop<\/code><\/td><td>keep future release fixed<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td>active <code>release\/*<\/code><\/td><td>include fix in in-progress release<\/td><\/tr><tr><td><code>support\/*<\/code><\/td><td>support branch<\/td><td>patch old version<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">25. Gitflow PR template<\/h1>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">## Summary<\/span>\n\nExplain what changed.\n\n<span class=\"hljs-comment\">## Branch type<\/span>\n\n- &#91; ] feature<span class=\"hljs-comment\">\/*\n- &#91; ] release\/*\n- &#91; ] hotfix\/*\n- &#91; ] support\/*\n\n## Target branch\n\n- &#91; ] develop\n- &#91; ] main\n- &#91; ] release\/*\n- &#91; ] support\/*\n\n## Why\n\nExplain the reason for this change.\n\n## Changes\n\n- Added:\n- Changed:\n- Fixed:\n- Removed:\n\n## Testing\n\n- &#91; ] Unit tests\n- &#91; ] Integration tests\n- &#91; ] Regression tests\n- &#91; ] Manual validation\n- &#91; ] Staging validation\n\n## Release impact\n\n- Version:\n- Release branch:\n- Changelog updated:\n- Migration required:\n\n## Risk\n\nLow \/ Medium \/ High\n\n## Rollback plan\n\nExplain how to revert, redeploy, or disable the change.\n\n## Checklist\n\n- &#91; ] CI passed\n- &#91; ] Review completed\n- &#91; ] No secrets committed\n- &#91; ] Version updated if needed\n- &#91; ] Release notes updated if needed\n- &#91; ] Hotfix merged back to develop if needed\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">26. Gitflow CI\/CD design<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow needs branch-aware CI\/CD.<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">flowchart TD\n    A&#91;Branch pushed] --&gt; B{Branch type?}\n    B -- feature\/* --&gt; C&#91;Run lint, unit tests, build]\n    B -- develop --&gt; D&#91;Full CI + deploy integration\/dev]\n    B -- release\/* --&gt; E&#91;Full regression + deploy staging\/UAT]\n    B -- main --&gt; F&#91;Build production artifact + tag release]\n    B -- hotfix\/* --&gt; G&#91;Critical CI + emergency validation]\n    B -- support\/* --&gt; H&#91;Version-specific tests]\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Recommended pipeline behavior<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Branch<\/th><th>Pipeline behavior<\/th><\/tr><\/thead><tbody><tr><td><code>feature\/*<\/code><\/td><td>lint, unit test, build<\/td><\/tr><tr><td><code>develop<\/code><\/td><td>full CI, integration tests, deploy dev\/test<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td>full regression, security scan, deploy staging\/UAT<\/td><\/tr><tr><td><code>main<\/code><\/td><td>production release pipeline<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td>critical tests, focused regression<\/td><\/tr><tr><td><code>support\/*<\/code><\/td><td>tests for old version compatibility<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">27. Gitflow environment mapping<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A common Gitflow environment mapping:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">feature\/*  \u2192 no deployment or ephemeral env\ndevelop    \u2192 dev \/ integration\nrelease\/*  \u2192 staging \/ UAT\nmain       \u2192 production\nhotfix\/*   \u2192 emergency staging + production\n<\/code><\/span><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;feature\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;local \/ preview env]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;dev \/ integration]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;release\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;staging \/ UAT]<\/span>\n    <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;main]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;production]<\/span>\n    <span class=\"hljs-selector-tag\">I<\/span><span class=\"hljs-selector-attr\">&#91;hotfix\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">J<\/span><span class=\"hljs-selector-attr\">&#91;emergency validation]<\/span>\n    <span class=\"hljs-selector-tag\">J<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">28. Branch protection rules for Gitflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use branch protection to enforce Gitflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">GitHub branch protection rules can require approving reviews and passing status checks before merging into protected branches. They can also control deletion, force pushes, and other requirements for important branches.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended protections<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Branch<\/th><th>Direct push<\/th><th>PR required<\/th><th>CI required<\/th><th>Review required<\/th><th>Force push<\/th><\/tr><\/thead><tbody><tr><td><code>main<\/code><\/td><td>no<\/td><td>yes<\/td><td>yes<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td><code>develop<\/code><\/td><td>no<\/td><td>yes<\/td><td>yes<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td>no<\/td><td>yes<\/td><td>yes<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td>no or restricted<\/td><td>yes<\/td><td>critical CI<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td><code>support\/*<\/code><\/td><td>no<\/td><td>yes<\/td><td>yes<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td><code>feature\/*<\/code><\/td><td>allowed for owner<\/td><td>PR to develop<\/td><td>basic CI<\/td><td>before merge<\/td><td>avoid<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><code>main<\/code> protection<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">- <span class=\"hljs-keyword\">Require<\/span> pull request\n- <span class=\"hljs-keyword\">Require<\/span> status checks\n- <span class=\"hljs-keyword\">Require<\/span> approval\n- <span class=\"hljs-keyword\">Require<\/span> CODEOWNERS <span class=\"hljs-keyword\">for<\/span> critical files\n- Block force push\n- Block deletion\n- <span class=\"hljs-keyword\">Require<\/span> signed tags <span class=\"hljs-keyword\">or<\/span> signed commits <span class=\"hljs-keyword\">if<\/span> needed\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">29. CODEOWNERS for Gitflow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-37\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\"># Platform and CI\/CD<\/span>\n\/.github\/workflows\/ @devops-team\n\/infrastructure\/ @platform-team\n\n<span class=\"hljs-comment\"># Services<\/span>\n\/services\/auth\/ @identity-team\n\/services\/payment\/ @payment-team\n\/services\/notification\/ @backend-team\n\n<span class=\"hljs-comment\"># Security-sensitive areas<\/span>\n\/security\/ @security-team\n\/database\/migrations\/ @backend-leads @platform-team\n\n<span class=\"hljs-comment\"># Release files<\/span>\n\/VERSION @release-managers\n\/CHANGELOG.md @release-managers\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-37\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Recommended:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Required owner<\/th><\/tr><\/thead><tbody><tr><td>CI\/CD pipelines<\/td><td>DevOps\/platform<\/td><\/tr><tr><td>Infrastructure<\/td><td>Platform<\/td><\/tr><tr><td>Database migrations<\/td><td>Backend + platform<\/td><\/tr><tr><td>Authentication<\/td><td>Identity\/security<\/td><\/tr><tr><td>Payment<\/td><td>Payment owner<\/td><\/tr><tr><td>Release version files<\/td><td>Release manager<\/td><\/tr><tr><td>Production config<\/td><td>Service owner<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">30. Gitflow release checklist<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before creating release branch:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- Planned features merged into develop\n- CI passing on develop\n- Known blockers reviewed\n- Version number agreed\n- Release owner assigned\n- Release scope frozen\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Before merging release into <code>main<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- Regression testing complete\n- Critical bugs fixed\n- Version bumped\n- Changelog updated\n- Release notes ready\n- Security scan passed\n- Deployment plan ready\n- Rollback plan ready\n- Approval completed\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">After release:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- Tag pushed\n- Production deployed\n- Monitoring checked\n- Release branch merged back to develop\n- Release branch deleted or archived\n- Release notes published\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">31. Gitflow hotfix checklist<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before hotfix:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- Production issue confirmed\n- Severity agreed\n- Correct production version identified\n- Hotfix owner assigned\n- Rollback path understood\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">During hotfix:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-38\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">- Branch <span class=\"hljs-keyword\">from<\/span> main or production tag\n- Fix only the production issue\n- Run focused tests\n- Open emergency PR\n- Get required approval\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-38\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">After hotfix:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">- Merge into main\n- Tag patch version\n- Deploy production\n- Validate recovery\n- Merge into develop\n- Merge into active release branch if needed\n- Delete hotfix branch\n- Create follow-up ticket\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">32. Gitflow with release candidates<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For formal release cycles, release candidates are useful.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-39\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">v2<\/span><span class=\"hljs-selector-class\">.4<\/span><span class=\"hljs-selector-class\">.0-rc<\/span><span class=\"hljs-selector-class\">.1<\/span>\n<span class=\"hljs-selector-tag\">v2<\/span><span class=\"hljs-selector-class\">.4<\/span><span class=\"hljs-selector-class\">.0-rc<\/span><span class=\"hljs-selector-class\">.2<\/span>\n<span class=\"hljs-selector-tag\">v2<\/span><span class=\"hljs-selector-class\">.4<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-39\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Flow:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-40\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;release\/2.4.0]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;tag v2.4.0-rc.1]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;QA finds bug]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;fix on release branch]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;tag v2.4.0-rc.2]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;QA approves]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;merge to main]<\/span>\n    <span class=\"hljs-selector-tag\">G<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;tag v2.4.0]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-40\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Commands:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-41\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span>-rc<span class=\"hljs-number\">.1<\/span> -m <span class=\"hljs-string\">\"Release candidate 1 for v2.4.0\"<\/span>\ngit push origin v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span>-rc<span class=\"hljs-number\">.1<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-41\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Final release:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-42\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit merge --no-ff release\/<span class=\"hljs-number\">2.4<\/span><span class=\"hljs-number\">.0<\/span>\ngit tag -a v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span> -m <span class=\"hljs-string\">\"Release v2.4.0\"<\/span>\ngit push origin main v2<span class=\"hljs-number\">.4<\/span><span class=\"hljs-number\">.0<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-42\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">33. Gitflow and database migrations<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow needs careful database migration discipline.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dangerous pattern<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-43\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">feature branch changes schema\nrelease branch stabilizes old app\nhotfix needs production fix\ndevelop expects <span class=\"hljs-keyword\">new<\/span> schema\nproduction still has old schema\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-43\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Tiny mess. Giant headache.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Safe pattern: expand \u2192 migrate \u2192 contract<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-44\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">LR<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;Expand schema]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;Deploy backward-compatible app]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;Backfill data]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Switch reads\/writes]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;Contract old schema later]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-44\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Rules<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Do not hide large migrations in feature branches.<\/li>\n\n\n\n<li>Release branches should receive only safe migration fixes.<\/li>\n\n\n\n<li>Destructive schema changes should be separated from feature rollout.<\/li>\n\n\n\n<li>Hotfixes should avoid schema changes unless absolutely necessary.<\/li>\n\n\n\n<li><code>develop<\/code>, <code>release\/*<\/code>, and <code>main<\/code> compatibility must be understood.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">34. Gitflow with feature flags<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow does not require feature flags, but feature flags make Gitflow safer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Without flags:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">unfinished feature stays in feature branch for weeks\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">With flags:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">feature can merge into develop safely but remain disabled\n<\/code><\/span><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-45\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;feature branch]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;code behind flag]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;merge to develop]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;release branch]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;deploy with flag off]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;enable gradually]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-45\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Feature flags are especially useful when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>release scope changes<\/li>\n\n\n\n<li>a feature is code-complete but not business-ready<\/li>\n\n\n\n<li>risky behavior needs gradual rollout<\/li>\n\n\n\n<li>rollback should be instant<\/li>\n\n\n\n<li>QA wants selective enablement<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">35. Gitflow with multiple teams<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow gets harder as team size grows.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problems<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Problem<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>develop<\/code> becomes unstable<\/td><td>too many features merged too early<\/td><\/tr><tr><td>release branch overload<\/td><td>many fixes during QA<\/td><\/tr><tr><td>unclear release scope<\/td><td>features sneak into release<\/td><\/tr><tr><td>hotfix back-merge forgotten<\/td><td>production bug returns later<\/td><\/tr><tr><td>long feature branches<\/td><td>huge conflicts<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Solutions<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Problem<\/th><th>Solution<\/th><\/tr><\/thead><tbody><tr><td>unstable <code>develop<\/code><\/td><td>protect <code>develop<\/code>; require CI<\/td><\/tr><tr><td>release chaos<\/td><td>release owner and scope freeze<\/td><\/tr><tr><td>forgotten hotfix<\/td><td>checklist and automation<\/td><\/tr><tr><td>long features<\/td><td>feature flags and smaller PRs<\/td><\/tr><tr><td>QA overload<\/td><td>release candidate discipline<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">36. Gitflow for mobile apps<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow fits mobile apps well because app releases often need QA, signing, approval, and staged rollout.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-46\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">A<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">B<\/span><span class=\"hljs-selector-attr\">&#91;release\/mobile-5.1.0]<\/span>\n    <span class=\"hljs-selector-tag\">B<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">C<\/span><span class=\"hljs-selector-attr\">&#91;QA]<\/span>\n    <span class=\"hljs-selector-tag\">C<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;Signed build]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">E<\/span><span class=\"hljs-selector-attr\">&#91;TestFlight \/ Internal testing]<\/span>\n    <span class=\"hljs-selector-tag\">E<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;App Store \/ Play Store approval]<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">G<\/span><span class=\"hljs-selector-attr\">&#91;Production rollout]<\/span>\n    <span class=\"hljs-selector-tag\">G<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;tag v5.1.0]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-46\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Recommended branches:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main\ndevelop\nfeature\/*\nrelease\/ios-5.1.0\nrelease\/android-5.1.0\nhotfix\/*\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Release branch is frozen except fixes.<\/li>\n\n\n\n<li>Version\/build numbers are bumped in release branch.<\/li>\n\n\n\n<li>Tags must match shipped builds.<\/li>\n\n\n\n<li>Hotfixes may require app-store patch releases.<\/li>\n\n\n\n<li>Backend APIs must remain backward compatible for older app versions.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">37. Gitflow for libraries and SDKs<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow can fit libraries and SDKs because versions matter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recommended branches:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main\ndevelop\nfeature\/*\nrelease\/*\nhotfix\/*\nsupport\/*\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Semantic Versioning.<\/li>\n\n\n\n<li>Tag every published package.<\/li>\n\n\n\n<li>Maintain support branches for old major versions.<\/li>\n\n\n\n<li>Breaking changes require a major version.<\/li>\n\n\n\n<li>Critical fixes may need backporting.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main \u2192 latest production release\ndevelop \u2192 next release\nsupport\/2.x \u2192 v2 maintenance\nsupport\/1.x-lts \u2192 v1 long-term support\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">38. Gitflow for SaaS and web apps<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow can be too heavy for fast web\/SaaS teams.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Driessen\u2019s 2020 reflection says web apps are often continuously delivered and usually do not need multiple versions of the software running in the wild; for such teams, he suggested a simpler workflow such as GitHub Flow instead of forcing Gitflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use Gitflow for SaaS only when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>releases are scheduled<\/li>\n\n\n\n<li>release approvals are mandatory<\/li>\n\n\n\n<li>customers need versioned releases<\/li>\n\n\n\n<li>staging\/UAT is formal<\/li>\n\n\n\n<li>compliance requires release evidence<\/li>\n\n\n\n<li>multiple versions must be supported<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Otherwise, GitHub Flow or trunk-based development is usually simpler.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">39. Gitflow vs trunk-based development<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Gitflow<\/th><th>Trunk-based development<\/th><\/tr><\/thead><tbody><tr><td>Core style<\/td><td>release branch model<\/td><td>single trunk\/main<\/td><\/tr><tr><td>Main branches<\/td><td><code>main<\/code> + <code>develop<\/code><\/td><td>mostly <code>main<\/code><\/td><\/tr><tr><td>Feature branches<\/td><td>common<\/td><td>very short-lived<\/td><\/tr><tr><td>Release branches<\/td><td>normal<\/td><td>optional\/rare<\/td><\/tr><tr><td>Hotfix branches<\/td><td>explicit<\/td><td>usually revert\/fix forward<\/td><\/tr><tr><td>Best for<\/td><td>scheduled\/versioned releases<\/td><td>continuous delivery<\/td><\/tr><tr><td>Complexity<\/td><td>higher<\/td><td>lower branch complexity<\/td><\/tr><tr><td>CI need<\/td><td>important<\/td><td>critical<\/td><\/tr><tr><td>Feature flags<\/td><td>useful<\/td><td>almost essential<\/td><\/tr><tr><td>Speed<\/td><td>medium<\/td><td>high<\/td><\/tr><tr><td>Governance<\/td><td>strong<\/td><td>automation-driven<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Atlassian notes that Gitflow assigns specific roles to different branches, including feature, release, and hotfix branches, and is suited to scheduled release cycles.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">40. Gitflow vs GitHub Flow<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Gitflow<\/th><th>GitHub Flow<\/th><\/tr><\/thead><tbody><tr><td>Branches<\/td><td>many branch types<\/td><td><code>main<\/code> + short branches<\/td><\/tr><tr><td>Release branch<\/td><td>yes<\/td><td>usually no<\/td><\/tr><tr><td><code>develop<\/code> branch<\/td><td>yes<\/td><td>no<\/td><\/tr><tr><td>Production branch<\/td><td><code>main<\/code><\/td><td><code>main<\/code><\/td><\/tr><tr><td>Release style<\/td><td>scheduled\/versioned<\/td><td>continuous\/frequent<\/td><\/tr><tr><td>Best for<\/td><td>mobile, desktop, SDK, enterprise release<\/td><td>SaaS, web apps, APIs<\/td><\/tr><tr><td>Complexity<\/td><td>high<\/td><td>low<\/td><\/tr><tr><td>Hotfix path<\/td><td>explicit<\/td><td>branch from main and merge<\/td><\/tr><tr><td>QA cycle<\/td><td>release branch<\/td><td>staging from main<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">41. Gitflow pros and cons<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Pros<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Benefit<\/th><th>Why it matters<\/th><\/tr><\/thead><tbody><tr><td>Clear release structure<\/td><td>Everyone knows how code reaches production<\/td><\/tr><tr><td>Good for scheduled releases<\/td><td>Release branches support QA and stabilization<\/td><\/tr><tr><td>Strong hotfix model<\/td><td>Production fixes are isolated<\/td><\/tr><tr><td>Version-friendly<\/td><td>Tags and release branches map well to versions<\/td><\/tr><tr><td>Supports old versions<\/td><td>Optional support branches<\/td><\/tr><tr><td>Good governance<\/td><td>Works with approvals and release managers<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Cons<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Cost<\/th><th>Why it hurts<\/th><\/tr><\/thead><tbody><tr><td>More complexity<\/td><td>More branches and merge paths<\/td><\/tr><tr><td>Slower delivery<\/td><td>More coordination<\/td><\/tr><tr><td>Merge conflicts<\/td><td>Long-lived branches drift<\/td><\/tr><tr><td><code>develop<\/code> instability<\/td><td>Can become a dumping ground<\/td><\/tr><tr><td>Overkill for continuous delivery<\/td><td>Too much process for fast web teams<\/td><\/tr><tr><td>Hotfix back-merge risk<\/td><td>Easy to forget merging back<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">42. When Gitflow is a good choice<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use Gitflow when you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>scheduled releases<\/li>\n\n\n\n<li>formal QA cycle<\/li>\n\n\n\n<li>versioned products<\/li>\n\n\n\n<li>mobile apps<\/li>\n\n\n\n<li>desktop apps<\/li>\n\n\n\n<li>firmware<\/li>\n\n\n\n<li>SDKs\/libraries<\/li>\n\n\n\n<li>enterprise release approval<\/li>\n\n\n\n<li>multiple supported versions<\/li>\n\n\n\n<li>customer-specific release windows<\/li>\n\n\n\n<li>production hotfix requirements<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">AWS also positions Gitflow as suitable for teams with scheduled release cycles and a need to define a collection of features as a release.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">43. When Gitflow is the wrong choice<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid Gitflow when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>you deploy many times per day<\/li>\n\n\n\n<li><code>main<\/code> is always deployable<\/li>\n\n\n\n<li>feature flags are mature<\/li>\n\n\n\n<li>CI\/CD is fast and reliable<\/li>\n\n\n\n<li>releases are continuous<\/li>\n\n\n\n<li>you do not support old versions<\/li>\n\n\n\n<li>release branches create bureaucracy<\/li>\n\n\n\n<li><code>develop<\/code> becomes unstable<\/li>\n\n\n\n<li>PRs sit for too long<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For many web apps, Gitflow is like wearing a three-piece suit to eat instant noodles. Technically possible. Weird energy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">44. Gitflow anti-patterns<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-pattern 1: <code>develop<\/code> is always broken<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">All features merge into develop, but CI is ignored.\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-47\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Protect develop.\n<span class=\"hljs-keyword\">Require<\/span> CI.\n<span class=\"hljs-keyword\">Require<\/span> review.\nKeep develop releasable enough <span class=\"hljs-keyword\">for<\/span> integration.\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-47\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-pattern 2: release branch accepts new features<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">release\/2.4.0 becomes feature playground\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Only fixes, version bump, release notes, and stabilization changes.\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-pattern 3: hotfix not merged back<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Production fixed in main.\nDevelop never receives fix.\nBug returns in next release.\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Every hotfix must merge into main and develop.\nAlso merge into active release branch if one exists.\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-pattern 4: feature branches live for months<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-48\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">feature\/<span class=\"hljs-keyword\">new<\/span>-platform lives forever\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-48\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-49\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Split work.\n<span class=\"hljs-keyword\">Use<\/span> <span class=\"hljs-title\">feature<\/span> <span class=\"hljs-title\">flags<\/span>.\n<span class=\"hljs-title\">Use<\/span> <span class=\"hljs-title\">branch<\/span> <span class=\"hljs-title\">by<\/span> <span class=\"hljs-title\">abstraction<\/span>.\n<span class=\"hljs-title\">Merge<\/span> <span class=\"hljs-title\">smaller<\/span> <span class=\"hljs-title\">slices<\/span>.\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-49\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Anti-pattern 5: too many release branches<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Problem:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">release\/2.1\nrelease\/2.2\nrelease\/2.3\nrelease\/2.4\nall active, all drifting\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-50\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Keep only necessary active release\/support branches.\nArchive\/<span class=\"hljs-keyword\">delete<\/span> old release branches after tagging unless needed.\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-50\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">45. Gitflow metrics<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Measure Gitflow health.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Metric<\/th><th>Healthy signal<\/th><\/tr><\/thead><tbody><tr><td>Feature branch age<\/td><td>usually under one week<\/td><\/tr><tr><td>Release branch age<\/td><td>predictable and limited<\/td><\/tr><tr><td>Hotfix frequency<\/td><td>decreasing over time<\/td><\/tr><tr><td>Merge conflict frequency<\/td><td>low<\/td><\/tr><tr><td>CI pass rate on <code>develop<\/code><\/td><td>high<\/td><\/tr><tr><td>Release branch bug count<\/td><td>manageable<\/td><\/tr><tr><td>Time from release branch to production<\/td><td>predictable<\/td><\/tr><tr><td>Back-merge failures<\/td><td>near zero<\/td><\/tr><tr><td>Stale branch count<\/td><td>low<\/td><\/tr><tr><td>Production rollback frequency<\/td><td>low<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">46. Gitflow governance policy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use this as a company standard.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-51\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Gitflow Policy\n\n<span class=\"hljs-number\">1.<\/span> main represents production-ready code.\n<span class=\"hljs-number\">2.<\/span> develop represents the next release integration branch.\n<span class=\"hljs-number\">3.<\/span> feature branches start <span class=\"hljs-keyword\">from<\/span> develop and merge back into develop.\n<span class=\"hljs-number\">4.<\/span> release branches start <span class=\"hljs-keyword\">from<\/span> develop and merge into main and develop.\n<span class=\"hljs-number\">5.<\/span> hotfix branches start <span class=\"hljs-keyword\">from<\/span> main and merge into main and develop.\n<span class=\"hljs-number\">6.<\/span> support branches exist only <span class=\"hljs-keyword\">for<\/span> maintained older versions.\n<span class=\"hljs-number\">7.<\/span> main, develop, release<span class=\"hljs-comment\">\/*, and support\/* must be protected.\n8. CI must pass before merge.\n9. At least one review is required before merge.\n10. Release branches accept only stabilization changes.\n11. Hotfix branches accept only production emergency fixes.\n12. Every production release must be tagged.\n13. Hotfixes must be merged back to develop and active release branches.\n14. Merged branches must be deleted unless they are support branches.\n15. Release notes and changelog must be updated for releases.\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-51\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">47. Gitflow branch protection policy<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Branch<\/th><th>Protection<\/th><\/tr><\/thead><tbody><tr><td><code>main<\/code><\/td><td>strongest protection<\/td><\/tr><tr><td><code>develop<\/code><\/td><td>strong protection<\/td><\/tr><tr><td><code>release\/*<\/code><\/td><td>strong protection<\/td><\/tr><tr><td><code>hotfix\/*<\/code><\/td><td>fast-track but protected<\/td><\/tr><tr><td><code>support\/*<\/code><\/td><td>strong protection<\/td><\/tr><tr><td><code>feature\/*<\/code><\/td><td>normal branch rules<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Recommended:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main:\n  - no direct push\n  - PR required\n  - CI required\n  - approval required\n  - no force push\n  - no deletion\n\ndevelop:\n  - no direct push\n  - PR required\n  - CI required\n  - approval required\n\nrelease\/*:\n  - PR required\n  - release manager approval\n  - full CI\/regression required\n\nhotfix\/*:\n  - emergency PR required\n  - critical CI required\n  - service owner approval\n\nsupport\/*:\n  - PR required\n  - compatibility tests required\n  - maintainer approval\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">48. Gitflow release manager responsibilities<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">A release manager owns the release branch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Responsibilities:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>decide release scope<\/li>\n\n\n\n<li>create release branch<\/li>\n\n\n\n<li>freeze new features<\/li>\n\n\n\n<li>coordinate QA<\/li>\n\n\n\n<li>approve release fixes<\/li>\n\n\n\n<li>ensure version bump<\/li>\n\n\n\n<li>ensure changelog<\/li>\n\n\n\n<li>ensure release notes<\/li>\n\n\n\n<li>merge release to <code>main<\/code><\/li>\n\n\n\n<li>tag release<\/li>\n\n\n\n<li>merge release back to <code>develop<\/code><\/li>\n\n\n\n<li>delete\/archive release branch<\/li>\n\n\n\n<li>coordinate production deployment<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">49. Gitflow developer responsibilities<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Developers should:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>branch from <code>develop<\/code><\/li>\n\n\n\n<li>keep feature branches small<\/li>\n\n\n\n<li>rebase\/merge from <code>develop<\/code> regularly<\/li>\n\n\n\n<li>write clear commits<\/li>\n\n\n\n<li>open PRs early<\/li>\n\n\n\n<li>respond to review<\/li>\n\n\n\n<li>add tests<\/li>\n\n\n\n<li>avoid mixing features<\/li>\n\n\n\n<li>avoid release branch changes unless fixing release bugs<\/li>\n\n\n\n<li>never push directly to <code>main<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">50. Gitflow reviewer responsibilities<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Reviewers should check:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>correct target branch<\/li>\n\n\n\n<li>small change scope<\/li>\n\n\n\n<li>test coverage<\/li>\n\n\n\n<li>backward compatibility<\/li>\n\n\n\n<li>release impact<\/li>\n\n\n\n<li>migration safety<\/li>\n\n\n\n<li>security impact<\/li>\n\n\n\n<li>rollback path<\/li>\n\n\n\n<li>changelog\/version updates for release\/hotfix<\/li>\n\n\n\n<li>hotfix back-merge path<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">51. Gitflow for DevOps\/IaC repositories<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow is usually not the best default for Terraform\/IaC.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Why?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Infrastructure often benefits from:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main + feature branches + plan checks + environment workspaces\/folders\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use Gitflow for IaC only when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>releases of infrastructure modules are versioned<\/li>\n\n\n\n<li>consumers pin module versions<\/li>\n\n\n\n<li>release branches are genuinely needed<\/li>\n\n\n\n<li>old module versions are supported<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For normal environment infrastructure repos, prefer:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main\nfeature\/*\nhotfix\/*\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">with Terraform plan checks.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">52. Gitflow for Kubernetes manifests<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">For Kubernetes GitOps, Gitflow is often too heavy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Better structure:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main\nfeature\/*\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">with directories:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">environments\/\n  dev\/\n  staging\/\n  production\/\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use release branches only when application release packaging requires stabilization.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">53. Gitflow decision tree<\/h1>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-52\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">flowchart TD\n    A&#91;Should we use Gitflow?] --&gt; B{Do you have scheduled\/versioned releases?}\n    B -- No --&gt; C&#91;Prefer GitHub Flow or trunk-based]\n    B -- Yes --&gt; D{Do you need release stabilization branches?}\n    D -- No --&gt; E&#91;Use release branch lite or GitLab Flow]\n    D -- Yes --&gt; F{Do you need hotfixes <span class=\"hljs-keyword\">from<\/span> production?}\n    F -- Yes --&gt; G&#91;Gitflow is a good fit]\n    F -- No --&gt; H{Do you support old versions?}\n    H -- Yes --&gt; I&#91;Gitflow + support branches]\n    H -- No --&gt; J&#91;Gitflow or release branch model]\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-52\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">54. Complete Gitflow example<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Scenario:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-53\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">Current<\/span> <span class=\"hljs-selector-tag\">production<\/span>: <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.0<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<span class=\"hljs-selector-tag\">Next<\/span> <span class=\"hljs-selector-tag\">planned<\/span> <span class=\"hljs-selector-tag\">release<\/span>: <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.1<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<span class=\"hljs-selector-tag\">Emergency<\/span> <span class=\"hljs-selector-tag\">hotfix<\/span>: <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.0<\/span><span class=\"hljs-selector-class\">.1<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-53\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Initial state<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-54\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">main<\/span>: <span class=\"hljs-selector-tag\">v1<\/span><span class=\"hljs-selector-class\">.0<\/span><span class=\"hljs-selector-class\">.0<\/span>\n<span class=\"hljs-selector-tag\">develop<\/span>: <span class=\"hljs-selector-tag\">next<\/span> <span class=\"hljs-selector-tag\">release<\/span> <span class=\"hljs-selector-tag\">work<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-54\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Feature work<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-55\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout develop\ngit checkout -b feature\/add-reporting\ngit commit -m <span class=\"hljs-string\">\"feat(reporting): add export endpoint\"<\/span>\ngit push -u origin feature\/add-reporting\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-55\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Merge to develop:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit merge --no-ff feature\/add-reporting\ngit push origin develop\n<\/code><\/span><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Create release<\/h2>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">git checkout develop\ngit checkout -b release\/1.1.0\ngit push -u origin release\/1.1.0\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Fix release bug:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-56\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git commit -m <span class=\"hljs-string\">\"fix(reporting): correct CSV header order\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-56\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Finish release:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-57\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit merge --no-ff release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span>\ngit tag -a v1<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.0<\/span> -m <span class=\"hljs-string\">\"Release v1.1.0\"<\/span>\ngit push origin main v1<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.0<\/span>\n\ngit checkout develop\ngit merge --no-ff release\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.0<\/span>\ngit push origin develop\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-57\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Emergency hotfix<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-58\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit checkout -b hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit commit -m <span class=\"hljs-string\">\"fix(auth): prevent crash on expired session\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-58\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Finish hotfix:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-59\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">git checkout main\ngit merge --no-ff hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit tag -a v1<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.1<\/span> -m <span class=\"hljs-string\">\"Hotfix v1.1.1\"<\/span>\ngit push origin main v1<span class=\"hljs-number\">.1<\/span><span class=\"hljs-number\">.1<\/span>\n\ngit checkout develop\ngit merge --no-ff hotfix\/<span class=\"hljs-number\">1.1<\/span><span class=\"hljs-number\">.1<\/span>-login-crash\ngit push origin develop\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-59\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">55. Gitflow visual summary<\/h1>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-60\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">flowchart<\/span> <span class=\"hljs-selector-tag\">TD<\/span>\n    <span class=\"hljs-selector-tag\">F<\/span><span class=\"hljs-selector-attr\">&#91;feature\/*]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span><span class=\"hljs-selector-attr\">&#91;develop]<\/span>\n    <span class=\"hljs-selector-tag\">D<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">R<\/span><span class=\"hljs-selector-attr\">&#91;release\/*]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">M<\/span><span class=\"hljs-selector-attr\">&#91;main]<\/span>\n    <span class=\"hljs-selector-tag\">R<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span>\n    <span class=\"hljs-selector-tag\">M<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">H<\/span><span class=\"hljs-selector-attr\">&#91;hotfix\/*]<\/span>\n    <span class=\"hljs-selector-tag\">H<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">M<\/span>\n    <span class=\"hljs-selector-tag\">H<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">D<\/span>\n    <span class=\"hljs-selector-tag\">M<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">T<\/span><span class=\"hljs-selector-attr\">&#91;version tag]<\/span>\n    <span class=\"hljs-selector-tag\">S<\/span><span class=\"hljs-selector-attr\">&#91;support\/* optional]<\/span> <span class=\"hljs-selector-tag\">--<\/span>&gt; <span class=\"hljs-selector-tag\">ST<\/span><span class=\"hljs-selector-attr\">&#91;support tags]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-60\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">56. One-page Gitflow standard<\/h1>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Gitflow Standard\n\nPermanent branches:\n- main\n- develop\n\nTemporary branches:\n- feature\/*\n- release\/*\n- hotfix\/*\n\nOptional long-term branches:\n- support\/*\n\nRules:\n- feature\/* starts from develop and merges into develop.\n- release\/* starts from develop and merges into main and develop.\n- hotfix\/* starts from main and merges into main and develop.\n- support\/* starts from release tag or maintained version line.\n- main contains production-ready code only.\n- develop contains next-release integration code.\n- release branches allow bug fixes, version updates, and release notes only.\n- hotfix branches allow urgent production fixes only.\n- every production release is tagged.\n- every hotfix is tagged.\n- all protected branches require PR, CI, and review.\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">57. Final recommendation<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Use Gitflow when the release process itself needs structure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gitflow is excellent for:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">mobile apps\ndesktop apps\nfirmware\nSDKs\nlibraries\nenterprise products\nscheduled releases\nQA-heavy releases\nmulti-version support\nregulated delivery\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Avoid Gitflow when the team is better served by:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">main + short-lived branches\ncontinuous deployment\nfeature flags\nfast CI\/CD\ntrunk-based development\nGitHub Flow\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Final principle:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Gitflow is not a religion.\nGitflow is a release-management tool.\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use it when it matches the product\u2019s release reality.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The best Gitflow implementation is not the one with the most branches.<br>It is the one where every branch has a clear purpose, every release is traceable, every hotfix returns to future development, and production can be repaired without stopping the whole team.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>From Basic to Advanced: A Complete One-Stop Guide to Gitflow Branching, Releases, Hotfixes, CI\/CD, and Governance 1. What is Gitflow? Gitflow is a structured Git branching model&#8230; <\/p>\n","protected":false},"author":1,"featured_media":77518,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[11138],"tags":[],"class_list":["post-77517","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-tools"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77517","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=77517"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77517\/revisions"}],"predecessor-version":[{"id":77519,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77517\/revisions\/77519"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media\/77518"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=77517"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=77517"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=77517"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}