{"id":87493,"date":"2020-07-02T15:18:20","date_gmt":"2020-07-02T15:18:20","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=87493"},"modified":"2022-04-24T21:04:16","modified_gmt":"2022-04-24T21:04:16","slug":"getting-started-with-gitflow","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/devops\/tools\/getting-started-with-gitflow\/","title":{"rendered":"Getting Started with GitFlow"},"content":{"rendered":"<p>Chances are that you already work with Git as your default versioning system, and it\u2019s even more likely if you\u2019re an experienced developer. The importance of this technology to the global software community is undeniable, regardless of what programming language you use, your preferences and your experience. Massive open source communities like the ones inhabiting GitHub are possible today thanks to Git.<\/p>\n<p>However, even with all the power Git brings up to enable parallel contributions among dozens (sometimes hundreds) of users over the same repositories, it\u2019s still hard to embrace all the different team behavioral compositions out there.<\/p>\n<p>Models and standards were born trying to address these situations. As there are so many distinct forms and conditions, there\u2019s no silver bullet to solve all realities at once. You\u2019ll have to analyze your project\/team context and, together, decide what\u2019s best.<\/p>\n<p>This article takes a closer look at the <a href=\"https:\/\/nvie.com\/posts\/a-successful-git-branching-model\/\">GitFlow<\/a> workflow. It demonstrates how to create a new GitHub repository and play around with the workflow so you can check it out in practice.<\/p>\n<h2>The GitFlow Model<\/h2>\n<p>In 2010, Vincent Driessen proposed a Git model based on branching. It was innovative because it proposed a smooth solution for things like:<\/p>\n<ul>\n<li><em>Parallel development<\/em>, where many developers can work simultaneously in different tasks using <em>feature branches<\/em> for each one of them. Even the same developer can work in more than one task at a time, which means more than one <em>feature<\/em> branch at a time. When the work is done and passed all the team\u2019s validation phases, it can be merged into the central development branch (the <em>develop<\/em>).<\/li>\n<li><em>Team\u2019s Collaboration<\/em>, by allowing different developers to work at the same time in the same task (so in the same branch). Only commits related to that task are allowed, the developers take turns to validate each other\u2019s commits through <em>Pull Requests<\/em>, and you keep track of changes via commit history.<\/li>\n<li><em>Release Staging Phase<\/em>, when a bulk of features have been finished, they must all be merged into one single branch, your <em>develop<\/em> branch. This is not yet the final production release, but the starting point in which the team decides on the health of all the features and goes for a new releasing process.<\/li>\n<li><em>Emergency Fixes<\/em>. This is also particularly important, the so-called <em>hotfix branches<\/em>. You can create <em>hotfix<\/em> branches from the <em>master<\/em> and urgently change something for production.<\/li>\n<\/ul>\n<p>GitFlow, however, is not the perfect choice for every scenario. Vincent himself states that it was thought to help with building software that is explicitly versioned, i.e., that needs multiple versions to exist (or coexist) at the same time in the world.<\/p>\n<p>If you work with web applications (which is basically the highest percentage of developers nowadays), for example, where the deliveries are continuous, where there is no need to roll back nor to keep different versions alive at the same time, then GitFlow is not the best option for you and your team.<\/p>\n<h2>How Does It Really Work?<\/h2>\n<p>For you to understand the flow better, I\u2019ll make use of the git-flow toolset. It is an auxiliary tool that facilitates the job of working with GitFlow by providing some useful commands.<\/p>\n<p>To install it, run the following command (on macOS):<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">brew install git-flow<\/pre>\n<p>If you have a Windows, just <a href=\"https:\/\/git-scm.com\/download\/win\">download<\/a> and install Git SCM. GitFlow commands come with it.<\/p>\n<p>For Linux users, depending on your version, check <a href=\"https:\/\/github.com\/nvie\/gitflow\/wiki\/Linux\">this link<\/a> out.<\/p>\n<p>Don\u2019t worry; this tool won\u2019t mess up anything in your current Git flow. It\u2019s just a helper that creates and deletes branches, etc.<\/p>\n<p>The first step is to understand the roles of the <strong>develop<\/strong> and <strong>master<\/strong> branches and how they communicate with the versions of your code. These branches are the most important ones and the key to GitFlow.<\/p>\n<p>Take a look at the following diagram:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1298\" height=\"637\" class=\"wp-image-87494\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image.png\" \/><\/p>\n<p><strong>Figure 1. Simple example of branches flow.<\/strong><\/p>\n<p>GitFlow works primarily with two main branches:<\/p>\n<ul>\n<li>The <em>master<\/em> branch (in blue) stores all the released features until the date, receives the incoming new features from the <em>develop<\/em> (and only from it), as well as the hotfix changes (you\u2019ll see more in a minute).<\/li>\n<li>The <em>develop<\/em> branch (in orange), which has as the only role receiving the changes from the <em>feature<\/em> branches and centralizing them before any further merge. It\u2019s here where the teams usually customize the agile process with steps like validations, code review, definitions of done, etc.<\/li>\n<\/ul>\n<h2>Creating the GitHub Example Repo<\/h2>\n<p>Start with the creation of a new GitHub repo to hold the workflow example. For this, go to your GitHub account, create a new repo, and fill it with the following options:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"783\" height=\"775\" class=\"wp-image-87495\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/tela-de-computador-com-texto-preto-sobre-fundo-bra.png\" alt=\"Tela de computador com texto preto sobre fundo branco\n\nDescri\u00e7\u00e3o gerada automaticamente\" \/><\/p>\n<p><strong>Figure 2. Creating a new GitHub repository.<\/strong><\/p>\n<p>Next, create a new folder on your local computer with the same repository name (<em>st-git-flow<\/em>) and then navigate to the folder via the command line.<\/p>\n<p>Then, run the following commands, substituting your repository URL:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">echo # Hello World, GitFlow! &gt;&gt; index.md\r\ngit init\r\ngit add .\r\ngit commit -m \"first commit\"\r\ngit remote add origin https:\/\/github.com\/diogosouza\/st-git-flow.git\r\ngit push -u origin master<\/pre>\n<p>The first command creates a new Markdown file, with a hello world message. You\u2019ll make use of a <em>.md<\/em> file because it\u2019s universal and helpful to track the historical changes. After that, you initialize the Git repo, adding all the files as Git files, and committing.<\/p>\n<p>The two last commands take care of adding the remote origin and pushing the <em>master<\/em> branch to the remote repo. The remote origin can be seen right after the repo creation in GitHub:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1003\" height=\"158\" class=\"wp-image-87496\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-1.png\" \/><\/p>\n<p><strong>Figure 3. Checking out the Git origin value.<\/strong><\/p>\n<p>Now\u2019s time to run the <code>git flow init<\/code> command.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">$ git flow init <\/pre>\n<p>When it finishes, this is the output you may see:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"639\" height=\"378\" class=\"wp-image-87497\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-2.png\" \/><\/p>\n<p>It\u2019s a very straightforward command. It creates the <em>master<\/em> and <em>develop<\/em> branches, and asks for the respective names of each <em>feature<\/em>, <em>release<\/em>, <em>hotfix,<\/em> and <em>support<\/em> branches. You can leave them as they are, and press enter until the end except for the version tag prefix.<\/p>\n<p>(In order to compare Git Flow to Git, I\u2019ll provide the equivalent Git commands throughout the article.) The equivalent Git command to achieve this is:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout -b develop master<\/pre>\n<p>Whenever a developer is going to start a new feature, the <em>feature<\/em> branch must be created from the <em>develop<\/em>. This is the branch that hosts the \u201cnext release\u201d development.<\/p>\n<p>Some team\u2019s Git administrators even block the possibility of generating new branches from the <em>master<\/em> branch for security reasons. However, git-flow doesn\u2019t push the <em>develop<\/em> branch to the remote origin. This is something you must do manually:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git push -u origin develop<\/pre>\n<h2>The Feature Branches<\/h2>\n<p>Pay attention to the two new <em>feature<\/em> branches below:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1298\" height=\"793\" class=\"wp-image-87498\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-3.png\" \/><\/p>\n<p><strong>Figure 4. Diagram with two new <em>feature<\/em> branches.<\/strong><\/p>\n<p>There\u2019s no right due date for a task; it can take one day or two months to complete. It\u2019s up to the team to decide the maximum time they\u2019re going to need for any feature.<\/p>\n<p>Feature #2, for example, was started before #1, and finished first, too. Not just this, it has finished in the middle of task #1. For GitFlow, it doesn\u2019t matter how many features you\u2019re developing at the same time; the flow guarantees that they\u2019ll get to the <em>develop<\/em> and, in the next release, to the <em>master<\/em>.<\/p>\n<p>If you merge feature #2, for example, and some breaking changes were introduced (i.e., if it adds code that conflicts with the code being developed in feature #1), then feature #1\u2019s merge will fail.<\/p>\n<p>In this type of situation, which is very common by the way, it\u2019s normal to have the developers talking to each other when merge fixing, to analyze if what one has done is going to break the code of the other.<\/p>\n<p>Create your first <em>feature<\/em> branch with this command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow feature start ST-TASK01<\/pre>\n<p>And this is the result:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"155\" class=\"wp-image-87499\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-4.png\" \/><\/p>\n<p>Without git-flow, this would be the command to achieve the same:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout -b feature\/ST-TASK01 develop<\/pre>\n<p>It\u2019s also a best practice to use tag prefixes in your <em>feature<\/em> branch names, in order to identify them among the others. Some tracking tools, like Confluent Jira, use that information to keep track of the correlated branches of your repositories.<\/p>\n<p>Since you\u2019re on the branch, you may perform all the needed code changes, and commit them.<\/p>\n<p>Update the index.md file, for example, to the following:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\"># Hello World, GitFlow!\r\n- This is my `task-01` commit.<\/pre>\n<p>The feature changes are within a new list in which each bullet point contains the respective task id. This way, it\u2019s going to be easier to track the changes history.<\/p>\n<p>Commit the changes:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git add .\r\ngit commit -m \"Updating my feature branch st-task01\"<\/pre>\n<p>Remember, however, that your commits are only local. You must explicitly tell git-flow to publish the branch to the remote origin. For this, you just run the command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow feature publish ST-TASK01<\/pre>\n<p>Without git-flow, you\u2019d have to run the following:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout feature\/ST-TASK01\r\ngit push origin feature\/ST-TASK01<\/pre>\n<p>Now, your branch is live. You can check it going directly to the GitHub repo:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"355\" class=\"wp-image-87500\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-5.png\" \/><\/p>\n<p><strong>Figure 5. Your GitHub remote branches.<\/strong><\/p>\n<p>You can even see a GitHub warning at the top of the page stating that a new branch was recently pushed. It also enables the option to create a new pull request, which is not necessary.<\/p>\n<p>Once you\u2019re done with the feature development, you might merge it to the <em>develop<\/em> branch, or do it via git-flow:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow feature finish ST-TASK01<\/pre>\n<p>These are the list of actions taken by this command:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"555\" height=\"249\" class=\"wp-image-87501\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-6.png\" \/><\/p>\n<p>And these are the equivalent vanilla Git commands to achieve the same result:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout develop\r\ngit merge --no-ff feature\/MYFEATURE\r\ngit branch -d feature\/MYFEATURE<\/pre>\n<p>The <em>&#8211;no-ff<\/em> flag prevents the <em>git merge<\/em> command from performing a fast-forward if Git detects that your HEAD falls short of the commit being merged for security reasons.<\/p>\n<p>Great, now you have the code merged onto the <em>develop<\/em> branch. This, however, is not remote yet. GitFlow works basically at a local level; all the decisions to send the changes over the remote repositories depend on you.<\/p>\n<p>Run the command to push things up:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git push origin --all<\/pre>\n<p>This command pushes everything that changed locally (branches, tags, etc.) to the remote origin. You\u2019ll make use of it a bit in order to guarantee the git-flow changes are always in sync with the remote.<\/p>\n<p>You may now go to GitHub and check the develop contents.<\/p>\n<h2>The Release Branches<\/h2>\n<p>The <em>release<\/em> branch is the branch you\u2019ll create from the <em>develop<\/em> when you and your team are ready to publish a release.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1298\" height=\"740\" class=\"wp-image-87502\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-7.png\" \/><\/p>\n<p><strong>Figure 6. Creating a new release branch.<\/strong><\/p>\n<p>After a <em>release<\/em> branch is created, no more features can be added to it (and this must be a rigorous policy within your team). Of course, things like bug and hot fixes, docs and urgent changes can be discussed and carefully added. It\u2019s up to the team defining the boundaries.<\/p>\n<p>When everything\u2019s ready, the branch is merged into the <em>master,<\/em> and a tag is generated. Usually, this process is automated to avoid human errors. The numbering you\u2019re using for the versions also takes place here.<\/p>\n<p>After that, the <em>develop<\/em> should also receive the release contents, because some important changes (like bug and hot fixes) may be needed by the <em>feature<\/em> branches. Again, automation would be useful here.<\/p>\n<p>This is an important step of the workflow because many factors can delay the release process, for example, if your company depends on a shipping calendar or the approval of another team. This way, you release (the name speaks for itself) the <em>develop<\/em> branch so the developers may continue to work in the features, while the release code is safe.<\/p>\n<p>This code creates the first <em>release<\/em> branch:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow release start 0.1.0<\/pre>\n<p>And here\u2019s the result:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"558\" height=\"214\" class=\"wp-image-87503\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-8.png\" \/><\/p>\n<p>Without git-flow, you\u2019d have to run the following command to create the same <em>release<\/em> branch:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true \">git checkout -b release\/0.1.0 develop<\/pre>\n<p>Next, update the Markdown file with the following:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\"># Hello World, GitFlow!\r\n- This is my `task-01` commit.\r\n- Our project is going to be released. Version 0.1.0<\/pre>\n<p>Then, commit the changes:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git add .\r\ngit commit -m \"Adding release version\"<\/pre>\n<p>And publish the branch to the remote origin:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow release publish '0.1.0'<\/pre>\n<p>Here are the equivalent commands for vanilla Git:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout release\/0.1.0\r\ngit push origin release\/0.1.0<\/pre>\n<p>This remotely updates the list of branches as well as the warning messages:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"996\" height=\"448\" class=\"wp-image-87504\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-9.png\" \/><\/p>\n<p><strong>Figure 7. Remote branches, including the release one.<\/strong><\/p>\n<p>Finally, release it with the following command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow release finish '0.1.0'<\/pre>\n<p>This command does a lot. Without the power of git-flow, you\u2019d have to go through all these Git commands to get to the same result:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout master\r\ngit merge --no-ff release\/0.1.0\r\ngit tag -a 0.1.0\r\ngit checkout develop\r\ngit merge --no-ff release\/0.1.0\r\ngit branch -d release\/0.1.0<\/pre>\n<p>The git-flow <em>release<\/em> command prompts a cmd window for you to add a releasing message. Fill it with the following and save it through the shortcut <em>:x! <\/em>+<em> Enter <\/em>(be aware that you first need to press <em>Esc<\/em> to lose focus on the typing before entering the shortcut).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"550\" height=\"222\" class=\"wp-image-87505\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-10.png\" \/><\/p>\n<p><strong>Figure 8. Leaving a release message.<\/strong><\/p>\n<p>This would be the output:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"701\" height=\"266\" class=\"wp-image-87506\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-11.png\" \/><\/p>\n<p>Here, some interesting things are happening. First, due to git-flow\u2019s local nature, you must push the changes manually to the remote.<\/p>\n<p>The <em>release<\/em> branch had changes that were merged onto the <em>master<\/em>; git-flow also back-merges the same commits against the <em>develop<\/em> branch. Plus, a new tag was generated: <em>ST0.1.0<\/em>. You must push all these updates through the following command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise \">git push origin \u2013-all\r\ngit push origin \u2013-tags<\/pre>\n<p>This way, when you revisit GitHub, you\u2019d see the following:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"990\" height=\"323\" class=\"wp-image-87507\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-12.png\" \/><\/p>\n<p><strong>Figure 9. New tag remotely created.<\/strong><\/p>\n<p>The tags work as snapshots of your code repo. Whenever you want to consult for a specific spot in time, check the respective tag out.<\/p>\n<p>Another tip would be about the GitHub commits history. If you enter the <em>develop<\/em> branch, for example, and click in the link with the number of commits above the warning\u2019s box, you can refer to all the changes until now:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1040\" height=\"413\" class=\"wp-image-87508\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-13.png\" \/><\/p>\n<p><strong>Figure 10. Develop\u2019s commits history.<\/strong><\/p>\n<p>Enter each commit, and you may see the change\u2019s diff.<\/p>\n<h2>The Hotfix Branches<\/h2>\n<p>Every big company can have emergencies and need urgent fixes. With a bunch of people working in the same code while others try to fix a code snippet to ship to production quickly, the whole scenario can get messy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1298\" height=\"740\" class=\"wp-image-87509\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-14.png\" \/><\/p>\n<p><strong>Figure 11. Creating a new hotfix branch.<\/strong><\/p>\n<p><em>Hotfix<\/em> branches come to the rescue by allowing the teams to create a new temporary branch upon the <em>master<\/em>. When done with fixes, you must merge the branch into <em>master<\/em> again, the <em>develop<\/em> branch, and the <em>release<\/em> branch (if there is any).<\/p>\n<p>That\u2019s why it\u2019s important to always merge a <em>release<\/em> branch into the <em>develop<\/em>, because you can\u2019t track all the changes, especially if you\u2019re working with many and large teams.<\/p>\n<p>This is the command to create the first <em>hotfix<\/em> branch:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow hotfix start ST-TASK01<\/pre>\n<p>And here you have the output:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"561\" height=\"239\" class=\"wp-image-87510\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-15.png\" \/><\/p>\n<p>The equivalent non-git-flow command would be:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true\">git checkout -b hotfix\/ST-TASK01 master<\/pre>\n<p>Now, change something in the Markdown file:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\"># Hello World, GitFlow!\r\n- This is my `task-01` commit.\r\n- Our project is going to be released.\r\n- This is my `hotfix` commit.<\/pre>\n<p>And, again, commit the changes:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git add .\r\ngit commit -m \"hotfix changes\"<\/pre>\n<p>Then, send it to the remote origin by running:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow hotfix publish ST-TASK01<\/pre>\n<p>Notice that it\u2019s not necessary to inform the full name of a branch. If it is a <em>hotfix<\/em> branch, git-flow understands that by the current command you\u2019re issuing.<\/p>\n<p>With Git only, you\u2019d need to run the following:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true \">git checkout hotfix\/ST-TASK01\r\ngit push origin hotfix\/ST-TASK01<\/pre>\n<p>You may see in GitHub that the new branch was pushed:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1003\" height=\"398\" class=\"wp-image-87511\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-16.png\" \/><\/p>\n<p><strong>Figure 12. Published hotfix branch.<\/strong><\/p>\n<p>Also, since you\u2019ve committed the changes before pushing the branch, these same changes are sent over to the remote origin too &#8212; no need for a further push here.<\/p>\n<p>To finish it, issue the following command:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git flow hotfix finish 'ST-TASK01'<\/pre>\n<p>The git-flow\u2019s <em>hotfix<\/em> command is another example of a great shortcut command. It does a lot. These are the Git equivalent commands:<\/p>\n<pre class=\"theme:vs2012-black lang:tsql decode:true  \">git checkout master\r\ngit merge --no-ff hotfix\/ST-TASK01\r\ngit tag -a ST-TASK01\r\ngit checkout develop\r\ngit merge --no-ff hotfix\/ST-TASK01\r\ngit branch -d hotfix\/ST-TASK01<\/pre>\n<p>Once again, you will be prompted to write a message. Write it and finish with the shortcut <em>:x!<\/em> + <em>Enter<\/em>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"532\" height=\"198\" class=\"wp-image-87512\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-17.png\" \/><\/p>\n<p><strong>Figure 13. Writing a hotfix message.<\/strong><\/p>\n<p>Again, push the <em>master<\/em>, <em>develop<\/em> and the tags to the remote origin:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">git push origin --all\r\ngit push origin --tags<\/pre>\n<p>There you can see the new generated tag: <em>STST-TASK01<\/em>. This is how the final <em>index.md<\/em> will look:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"999\" height=\"298\" class=\"wp-image-87513\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/07\/word-image-18.png\" \/><\/p>\n<p><strong>Figure 14. index.md final look.<\/strong><\/p>\n<h2>Conclusion<\/h2>\n<p>You can find the original post which started it all <a href=\"https:\/\/nvie.com\/posts\/a-successful-git-branching-model\/\">here<\/a>. It has more details over the principles and thinking behind GitFlow. Again, GitFlow is not a religion, nor a panacea. It\u2019s a style, a paradigm. It works well for others; it doesn\u2019t fit the reality of other types of projects.<\/p>\n<p>There are other workflows too, like the <a href=\"https:\/\/guides.github.com\/introduction\/flow\/\">GitHub flow<\/a>, the <a href=\"https:\/\/docs.gitlab.com\/ee\/topics\/gitlab_flow.html\">GitLab flow<\/a>, the <a href=\"https:\/\/www.endoflineblog.com\/gitflow-considered-harmful\">One flow<\/a>, among others.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, Diogo Souza explains GitFlow, a branching model for Git. He demonstrates how to work with GitFlow to create and deploy a feature and a hotfix to GitHub.&hellip;<\/p>\n","protected":false},"author":320401,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143521],"tags":[95506],"coauthors":[60461],"class_list":["post-87493","post","type-post","status-publish","format-standard","hentry","category-tools","tag-automate"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87493","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/320401"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=87493"}],"version-history":[{"count":9,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87493\/revisions"}],"predecessor-version":[{"id":87532,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/87493\/revisions\/87532"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=87493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=87493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=87493"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=87493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}