<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jose Luis</title>
    <description>The latest articles on Forem by Jose Luis (@joseluiselizalde).</description>
    <link>https://forem.com/joseluiselizalde</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3703578%2Fb25179b0-e9f8-4c0c-85ee-6bb4771e2be0.jpeg</url>
      <title>Forem: Jose Luis</title>
      <link>https://forem.com/joseluiselizalde</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joseluiselizalde"/>
    <language>en</language>
    <item>
      <title>Gitflow Workflow: A Dynamic Guide for Development Teams</title>
      <dc:creator>Jose Luis</dc:creator>
      <pubDate>Mon, 19 Jan 2026 22:47:39 +0000</pubDate>
      <link>https://forem.com/joseluiselizalde/gitflow-workflow-a-dynamic-guide-for-development-teams-3ec</link>
      <guid>https://forem.com/joseluiselizalde/gitflow-workflow-a-dynamic-guide-for-development-teams-3ec</guid>
      <description>&lt;h1&gt;
  
  
  Introduction: Why Gitflow is still relevant?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1556075798-4825dfaaf498%3Fixlib%3Drb-4.0.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1280%26h%3D400%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1556075798-4825dfaaf498%3Fixlib%3Drb-4.0.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1280%26h%3D400%26q%3D80" alt="Gitflow" width="1280" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are working in a development team, you've probably heard about Gitflow. Maybe you even use it frequently. But, do you really know when to use it and when to avoid using it?&lt;/p&gt;

&lt;p&gt;In this article, I'm not just going to teach you the standard workflow, instead, I'll show you real-world case studies, modern alternatives, and how to implement it efficiently. As a developer who has worked both in agile startups and large corporations, I've seen Gitflow shine and also fail spectacularly. &lt;/p&gt;

&lt;h1&gt;
  
  
  What exactly is Gitflow?
&lt;/h1&gt;

&lt;p&gt;Gitflow is a branching strategy created by Vincent Driessen by 2010. It's not a tool from Git, but a convention about how to use branches. Its main structure includes:&lt;/p&gt;

&lt;h3&gt;
  
  
  Permanent branches:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;main/master &lt;span class="c"&gt;# Production - only stable&lt;/span&gt;
develop     &lt;span class="c"&gt;# Integration - next release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxpaa43z9nndd91m5zce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxpaa43z9nndd91m5zce.png" alt="Permanent branches" width="800" height="138"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Support branches:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feature/&lt;span class="k"&gt;*&lt;/span&gt;  &lt;span class="c"&gt;# New functionalities&lt;/span&gt;
release/&lt;span class="k"&gt;*&lt;/span&gt;  &lt;span class="c"&gt;# Getting ready for production&lt;/span&gt;
hotfix/&lt;span class="k"&gt;*&lt;/span&gt;   &lt;span class="c"&gt;# Urgent corrections in production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg775kcfpealqki7r6u2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg775kcfpealqki7r6u2j.png" alt="Support branches" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow step by step with Real Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Building a new feature:
&lt;/h4&gt;

&lt;p&gt;Scenario: Your team need to add authentication OAuth2  for the App.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#1. Create feature branch from develop&lt;/span&gt;
git checkout develop
git pull origin develop
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/oauth2-integration

&lt;span class="c"&gt;#2. Working in the feature (many commits)&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add Google OAuth2 basic setup"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Implement token refresh logic"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add user profile sync"&lt;/span&gt;

&lt;span class="c"&gt;#3. Finish feature&lt;/span&gt;
git checkout develop
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; feature/oauth2-integration
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; feature/oauth2-integration
git push origin develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Why &lt;code&gt;--no-ff&lt;/code&gt; (no fast-forward)?
&lt;/h5&gt;

&lt;p&gt;Preserve historical from branch feature as a logical group.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Preparing a Release:
&lt;/h4&gt;

&lt;p&gt;Scenario: Version 2.1.0 is ready for production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#1. Create release branch&lt;/span&gt;
git checkout develop
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; release/2.1.0

&lt;span class="c"&gt;#2. Prepare release (bump version, docs, etc)&lt;/span&gt;
&lt;span class="c"&gt;# Update version in package.json&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"Bump version to 2.1.0"&lt;/span&gt;

&lt;span class="c"&gt;#3. Merging main and develop&lt;/span&gt;
git checkout main
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; release/2.1.0
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v2.1.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Release version 2.1.0"&lt;/span&gt;

git checkout develop
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; release/2.1.0

&lt;span class="c"&gt;#4. Delete release branch&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; release/2.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Hotfix Urgent in Production.
&lt;/h4&gt;

&lt;p&gt;Scenario: Critic security error found in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#1. Create hotfix from main&lt;/span&gt;
git checkout main
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; hotfix/security-patch

&lt;span class="c"&gt;#2. Fix issue&lt;/span&gt;
&lt;span class="c"&gt;# Apply security fix&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"Fix SQL injection vulnerability"&lt;/span&gt;

&lt;span class="c"&gt;#3. Apply to main and develop&lt;/span&gt;
git checkout main
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; hotfix/security-patch
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v2.1.1 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Security hotfix"&lt;/span&gt;

git checkout develop
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; hotfix/security-patch

&lt;span class="c"&gt;#4. Delete hotfix branch&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; hotfix/security-patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gitflow in practice: Configuration and Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Initial configuration in repository
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Initialize repository&lt;/span&gt;
git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit"&lt;/span&gt;

&lt;span class="c"&gt;# 2. Create main branches&lt;/span&gt;
git branch develop
git checkout develop

&lt;span class="c"&gt;# 3. Configurate upstream(in remote)&lt;/span&gt;
git remote add origin &amp;lt;url&amp;gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbll8mj5gvlgyv4nw6w6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbll8mj5gvlgyv4nw6w6.png" alt="Complete workflow" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Automation scripts (package.json)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"feature:start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git checkout develop &amp;amp;&amp;amp; git pull origin develop &amp;amp;&amp;amp; git checkout -b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"feature:finish"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git checkout develop &amp;amp;&amp;amp; git merge --no-ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"release:start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"git checkout develop &amp;amp;&amp;amp; git checkout -b release/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hotfix:start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"git checkout main &amp;amp;&amp;amp; git checkout -b hotfix/"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  CI/CD Integration (Github Actions example)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Gitflow CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;develop&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;feature/*&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;release/*&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;hotfix/*&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
    &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
        &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;branch-type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;feature&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;hotfix&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Detect branch type&lt;/span&gt;
            &lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;branch-type&lt;/span&gt;
            &lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;if [[ ${{ github.ref }} == refs/heads/feature/* ]]; then&lt;/span&gt;
                    &lt;span class="s"&gt;echo "Type=feature" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;
                &lt;span class="s"&gt;elif [[ ${{ github.ref }} == refs/heads/release/* ]]; then&lt;/span&gt;
                    &lt;span class="s"&gt;echo "TYPE=release" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;
                &lt;span class="s"&gt;fi&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
            &lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;env.TYPE == 'feature'&lt;/span&gt;
            &lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test:unit&lt;/span&gt;

        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Integration tests&lt;/span&gt;
            &lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;env.TYPE == 'release'&lt;/span&gt;
            &lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run test:integration&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common patterns and best practices
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Nomenclature conventions
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Features: specific funcionality&lt;/span&gt;
feature/user-dashboard
feature/payment-processing

&lt;span class="c"&gt;# Releases: Semantic version&lt;/span&gt;
release/1.2.0
release/2.0.0-rc.1

&lt;span class="c"&gt;# Hotfixes:  short description&lt;/span&gt;
hotfix/login-error
hotfix/security-patch-cve-2024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optimal branch size
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Feature branches: 1-5 days max.&lt;/li&gt;
&lt;li&gt;Release branches: 1-2 weeks.&lt;/li&gt;
&lt;li&gt;Hotfix branches: Hours, not days.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: Gitflow 2026
&lt;/h2&gt;

&lt;p&gt;Gitflow's not death, but evolve. In 2026, I recommend:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using modified Gitflow for big enterprise projects.&lt;/li&gt;
&lt;li&gt;Automatize everything with scripts and CI/CD.&lt;/li&gt;
&lt;li&gt;Consider Feature Flags to reduce needing release branches.&lt;/li&gt;
&lt;li&gt;Evaluate every 6 months if the workflow is still optimized.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My personal recommendation: Start with Gitflow if your team is just starting with Git, but keep an open mind to evolve and change workflow to something new and simpler. &lt;/p&gt;

&lt;h3&gt;
  
  
  Additional resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;Original Gitflow from Vincent Driessen&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitextensions.github.io/" rel="noopener noreferrer"&gt;Git Extensions for Gitflow GUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sourcetreeapp.com/" rel="noopener noreferrer"&gt;SourceTree with integrated Gitflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/book/en/v2" rel="noopener noreferrer"&gt;Official Git Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gitflow</category>
      <category>git</category>
      <category>software</category>
    </item>
  </channel>
</rss>
