11
votes

I'm trying to understand GitLab's suggested flow on http://docs.gitlab.com/ee/workflow/gitlab_flow.html. But, I'm not really sure about this statement:

If you need to cherry-pick a commit with a hotfix it is common to develop it on a feature branch and merge it into master with a merge request, do not delete the feature branch. If master is good to go (it should be if you a practicing continuous delivery) you then merge it to the other branches.

Does it mean, there will be more than 1 commit in the master? For example, the first commit (actually merge request) is to test whether the fix is working, the second commit is when the first commit fails.

The other thing is, (given that we have a production branch) if we merge the hotfix into master, I think we have to deploy the other features on the master, isn't it? Otherwise, we do cherry pick the hotfix commits in the master into the production branch.

Actually the suggested flow is not as detail as another flow in http://nvie.com/posts/a-successful-git-branching-model/. So, it's a bit confusing.

4

4 Answers

7
votes

The key in this workflow is to create a bugfix branch from the correct point. Suppose this your current history:

master o-------o-----o
               \-----o
                 br1

Now you must hotfix the master branch. To do this, create a feature branch starting from master that will merge both into master and br1 if needed:

master o-------o-----o--o
               \-----o--+
               | bf1    |
               \-----o--o
                 br1

With this workflow, you keep track of the bugfix, and can apply it on any needed branch.

The mistake to avoid is to create the bugfix branch starting from branch br1, because if you merge it into master, then the branch br1 will also be merged:

master o-------o-----o-------o
               \-----o      /
                 br1 \-----/
                       bf1
7
votes

I experimented with the hotfix process in a test-hotfix repo available at https://github.com/oldsj/test-hotfix/commits/master

Basically as long as the hotfix branch is created from the prod branch it the process seems fairly straightforward, even if master is ahead of imp/prod.

Note: imp is what we refer to as "pre-production"

master (dev branch)

git init
echo "Hello wolrd" > hello.txt
git add -A .
git commit -m "add hello.txt"
git log
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (HEAD -> master)

cat hello.txt
Hello wolrd

git checkout -b imp
git checkout -b prod

Prod shows typo

cat hello.txt
Hello wolrd

git log
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (HEAD -> prod, master, imp)

Let's add some commits to master, ahead of prod

git checkout master
git log
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (HEAD -> master, prod, imp)

echo "new stuff" >> newstuff.txt
git add -A .
git commit -m "add newstuff.txt"
git log
commit df1ca012262c26ab3a29d81b5cb6d46f6c1fc3cc (HEAD -> master)
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (prod, imp)

A user reported the typo in prod, let's hotfix by creating a new branch off of the prod branch:

git checkout prod
git log
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (HEAD -> prod, imp)

git checkout -b hotfix
Switched to a new branch 'hotfix'
git log
commit 66b1a08080f0db548da85471b4673c5a9f6d703f (HEAD -> hotfix, prod, imp)

echo "Hello world" > hello.txt
git add -A .
git commit -m "fix typo"
git log
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d (HEAD -> hotfix)

cat hello.txt
Hello world

Cool our typo is fixed in the hotfix branch, lets merge to master and test in dev

git checkout master
git merge hotfix
git log
commit 2672d5059a55472132f02178c7f51d8b1af0f8ea (HEAD -> master)

> cat hello.txt
Hello world

Looks good in dev! Lets merge to imp and prod

git checkout imp
git merge hotfix
git log
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d (HEAD -> imp, hotfix)
cat hello.txt
Hello world

git checkout prod
git merge hotfix
git log
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d (HEAD -> imp, hotfix)
cat hello.txt
Hello world

git branch -D hotfix

Typo's fixed in prod after testing in lower environments by merging the "PR" to those environment branches Now let's promote dev changes up (commit df1ca012262c26ab3a29d81b5cb6d46f6c1fc3cc)

git checkout master
git log
commit 2672d5059a55472132f02178c7f51d8b1af0f8ea (HEAD -> master, imp)
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d (prod)
commit df1ca012262c26ab3a29d81b5cb6d46f6c1fc3cc
commit 66b1a08080f0db548da85471b4673c5a9f6d703f

git checkout imp
git merge master
git log
commit 2672d5059a55472132f02178c7f51d8b1af0f8ea (HEAD -> imp, master)
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d (prod)
commit df1ca012262c26ab3a29d81b5cb6d46f6c1fc3cc
commit 66b1a08080f0db548da85471b4673c5a9f6d703f

cat newstuff.txt
new stuff
cat hello.txt
Hello world

git checkout prod
git merge imp
git log
commit 2672d5059a55472132f02178c7f51d8b1af0f8ea (HEAD -> prod, master, imp)
commit 1243123edc75e0abf349e1bb154d39c9f25dab2d
commit df1ca012262c26ab3a29d81b5cb6d46f6c1fc3cc
commit 66b1a08080f0db548da85471b4673c5a9f6d703f

dev changes are now in imp and prod, along with the hotfix

cat hello.txt
Hello world
cat newstuff.txt
new stuff
5
votes

From the docs at https://docs.gitlab.com/ee/workflow/gitlab_flow.html

If you need to cherry-pick a commit with a hotfix it is common to develop it on a feature branch and merge it into master with a merge request, do not delete the feature branch. If master is good to go (it should be if you are practicing continuous delivery) you then merge it to the other branches. If this is not possible because more manual testing is required you can send merge requests from the feature branch to the downstream branches.

I think the point is, you always merge "downhill". What that means is that it goes from master -> staging -> production, but never a hotfix to production and then to master. If you want to "cherry-pick" a hotfix, you do it as a feature branch. Then that feature branch is merged to master without closing it. It's tested, if needed, and then that feature branch is good to be merged on down the line to staging and then production.

0
votes

It is not really an answer to the question. More a "rebound".

I'm actually using Gitlab flow with master and production branch : * master is deployed on staging * production is deployed on preprod * tags on production are deployed in production

For hotfix, my understanding was :

  • create a branch from master (HEAD). Fix. Commit.
  • create a merge request into master
  • when test passed, cherry-pick the merge request to production
  • and finally create a new tag to release the hotfix.

But I recently comes to one problem :

  • I created a hotfix branch from master to fix a file that was differing from production (updated by a feature merged in master but not yet in production.
  • I merged it to master without issues.
  • But the cherry-pick into production was conflicting. So I need to resolve conflict with my hands and go on.

This make me think the following :

What if I've created the hotfix branch from production one and cherry-pick down to master?