Hotfix branches are created to fix specific bugs in production environment which were introduced after deploying previous release branches. The main difference between hotfix and release branch is, hotfix branch branches off from master branch so it ignores everything (new features, code modifications, fixes, new files etc.) in develop branch. After finishing hotfix branches, they get merged back into develop and master branches so as a result both of these branches will have the fix immediately. We will see that below.



When working with hotfix branches, you should open up a "pull request" in GitHub so that your team members can see what you're preparing to fix. This is considered as the best practise! Also pay attention to "Summary of actions" notes in code.


Scenario


A few days after releasing release tag 0.1.0, I introduced some new files and features to develop branch. This is all normal for now. I suddenly realised that the message in 'one.txt' is wrong so I urgently need to change it.


Preparation


These steps are compulsory before start working on a new hotfix branch because our local branch might be behind remote copy.


Step 1


Make sure we're on develop branch.


$ git branch
* develop
master

Step 2


Fetch all remote updates.


$ git remote update
Fetching origin
Inans-MBP:gitflow inanzzz$ git pull origin develop

Step 3


Update local develop branch so it is up-to-date with remote copy.


$ git pull origin develop
From github.com:inanzzz/gitflow
* branch develop -> FETCH_HEAD
Already up-to-date.

Step 4


Checkout to master branch.


$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

Step 5


Update local master branch so it is up-to-date with remote copy.


$ git pull origin master
From github.com:inanzzz/manual
* branch master -> FETCH_HEAD
Already up-to-date.

Create hotfix branch


Step 1


Check the current git status. As you can see below, master branch is behind develop branch at the moment.


$ git branch -avv
develop af6ea41 [origin/develop] Feature hello-mars commit
* master 8aa2add [origin/master] I merged release 0.1.0
remotes/origin/develop af6ea41 Feature hello-mars commit
remotes/origin/master 8aa2add I merged release 0.1.0


As you can see above, right after release tag 0.1.0*, there has been some development took place and it was merged back into develop branch which is fine because hotfix is not interested in what we have in develop branch.


Step 2


Start hotfix branch.


$ git flow hotfix start 0.1.1
Switched to a new branch 'hotfix/0.1.1'

Summary of actions:
- A new branch 'hotfix/0.1.1' was created, based on 'master'
- You are now on branch 'hotfix/0.1.1'

Follow-up actions:
- Start committing your hot fixes
- Bump the version number now!
- When done, run:

git flow hotfix finish '0.1.1'

As you can see below, hotfix branch is branched off from local master branch.


$ git branch -avv
develop af6ea41 [origin/develop] Feature hello-mars commit
* hotfix/0.1.1 8aa2add I merged release 0.1.0
master 8aa2add [origin/master] I merged release 0.1.0
remotes/origin/develop af6ea41 Feature hello-mars commit
remotes/origin/master 8aa2add I merged release 0.1.0

Step 3


Fix the bug and commit to it.


$ cat one.txt 
feature/hello-world

$ echo 'feature/hello-inanzzz' > one.txt
$ git add --all
$ git commit -m 'I just fixed a bug'
[hotfix/0.1.1 2a0bb96] I just fixed a bug
1 file changed, 1 insertion(+), 1 deletion(-)

$ cat one.txt 
feature/hello-inanzzz

Step 4


Publish hotfix branch to remote repository.


$ git flow hotfix publish 0.1.1
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 316 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:inanzzz/gitflow.git
* [new branch] hotfix/0.1.1 -> hotfix/0.1.1
Branch hotfix/0.1.1 set up to track remote branch hotfix/0.1.1 from origin.
Already on 'hotfix/0.1.1'
Your branch is up-to-date with 'origin/hotfix/0.1.1'.

Summary of actions:
- The remote branch 'hotfix/0.1.1' was created or updated
- The local branch 'hotfix/0.1.1' was configured to track the remote branch
- You are now on branch 'hotfix/0.1.1'

Step 5


If you go to GitHub, there will be a notification bar that will ask you to open a new "pull request" for the hotfix branch you've just pushed. Open it by comparing it to master branch, writing a subject and a description for it.




Step 6


At this point "peer review" takes place against the "pull request" in GitHub. If everyone in your team is happy with the work you've done in hotfix branch, there is nothing to worry about otherwise you keep working to make everyone happy. This process just shows everyone what will be fixed.


$ git branch -avv
develop af6ea41 [origin/develop] Feature hello-mars commit
* hotfix/0.1.1 2a0bb96 [origin/hotfix/0.1.1] I just fixed a bug
master 8aa2add [origin/master] I merged release 0.1.0
remotes/origin/develop af6ea41 Feature hello-mars commit
remotes/origin/hotfix/0.1.1 2a0bb96 I just fixed a bug
remotes/origin/master 8aa2add I merged release 0.1.0

Step 7


Finish hotfix branch.


$ git flow hotfix finish 0.1.1
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Merge made by the 'recursive' strategy.
one.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Switched to branch 'develop'
Your branch is up-to-date with 'origin/develop'.
Merge made by the 'recursive' strategy.
one.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
To git@github.com:inanzzz/gitflow.git
- [deleted] hotfix/0.1.1
Deleted branch hotfix/0.1.1 (was 2a0bb96).

Summary of actions:
- Hotfix branch 'hotfix/0.1.1' has been merged into 'master'
- The hotfix was tagged '0.1.1'
- Hotfix tag '0.1.1' has been back-merged into 'develop'
- Hotfix branch 'hotfix/0.1.1' has been locally deleted; it has been remotely deleted from 'origin'
- You are now on branch 'develop'

As you can see below, local branches are ahead of remote branches so in next steps we'll push them to remote repository.


$ git branch -avv
* develop 4ef055f [origin/develop: ahead 3] I merged hotfix 0.1.1
master 158948f [origin/master: ahead 2] I merged hotfix 0.1.1
remotes/origin/develop af6ea41 Feature hello-mars commit
remotes/origin/master 8aa2add I merged release 0.1.0

Step 8


Push develop branch to remote repository.


$ git push origin develop
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 695 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To git@github.com:inanzzz/gitflow.git
af6ea41..4ef055f develop -> develop

Step 9


Push master branch to remote repository.


$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:inanzzz/gitflow.git
8aa2add..158948f master -> master


Step 10


Verify that the tag has been created.


$ git tag
0.1.0
0.1.1

Step 11


Push the tags to remote repository. If you go to GitHub, you'll see the tag under "Release" tab.


$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 180 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:inanzzz/gitflow.git
* [new tag] 0.1.1 -> 0.1.1


Step 12


Check current git status. All seems to be good!


$ git branch -avv
* develop 4ef055f [origin/develop] I merged hotfix 0.1.1
master 158948f [origin/master] I merged hotfix 0.1.1
remotes/origin/develop 4ef055f I merged hotfix 0.1.1
remotes/origin/master 158948f I merged hotfix 0.1.1

Step 13


If you go to GitHub, you'll should see cases below happened.



Deployment


In the case deployment, you should checkout into tag number and deploy it.


$ git remote update
$ git checkout 0.1.1
$ git pull origin 0.1.1
$ cap production deploy

Overview


In short terms, this is what we did above.


# 1. Checked out into develop branch
git checkout develop

# 2. Fetched all remote updates
git remote update

# 3. Update local develop branch with remote copy
git pull origin develop

# 4. Checked out into master branch
git checkout master

# 5. Update local master branch with remote copy
git pull origin master

# 6. Created a hotfix branch that tracks master
git flow hotfix start 0.1.1

# 7. Did some fixes and committed to it

# 8. Published hotfix branch to remote repository
git flow hotfix publish 0.1.1

# 9. Opened a "pull request" in GitHub for team to verify the hotfix

# 10. Finished hotfix branch
git flow hotfix finish 0.1.1

# 11. Push develop branch
git push origin develop

# 12. Push master branch
git push origin master

# 13. Pushed the tags to remote repository
git push origin --tags