Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid duplicate commits in Git when applying hotfixes using the develop branch Git flow development model?

We are using the develop branch development model in one of our projects.

o - - - A - o - o - o - o  master
| \   /
 \  o  hotfix1
  \   \
    o - B - o - o - o develop

In the above diagram a hotfix1 is required and we apply (merge) it in both the master and the develop branch. This results in 2 different commit IDs A and X.

At a later point we need a new hotfix which again is applied in master resulting in commit C:

o - - - A  ...  A - - - C  master
| \   /           \   / 
 \  M  hotfix1       N  hotfix2
  \   \               \
    o - X - o - o - o - ?(A, N)? develop

But merging hotfix2 into the develop branch, we get the following list of commits in the Merge Request (GitLab terminology):

N
A

This has several drawbacks:

  • the code reviewer will see much more changes than in the commit N even if all these changed are already in develop (via commit X). This makes it more complicated to review.
  • after a merge, in develop we see both X and the newly brought A (via merging of N). Like this we have the same changes and the same git commit messages (git log) in two different commits.

How can we avoid this duplication of commits in master and develop? We would like to continue using the develop branch model.

like image 646
4 revs, 2 users 76% Avatar asked Apr 05 '19 15:04

4 revs, 2 users 76%


2 Answers

Instead of merging the hotfix (branch) in develop, you can cherry-pick (git cherry-pick <commitHash>) the commit(s) containing the fixes, it would create the following:

o - - - A  ...  A - - - C  master
| \   /           \   / 
 \  M  hotfix1       N  hotfix2
  \   \
   o - X - o - o - o - N' develop

N' would have the same content as N, but not the same parents, therefore not the same hash, but also, not having the same parents means that in your merge request, A will not be present.

like image 166
padawin Avatar answered Oct 20 '22 23:10

padawin


This is why I advocate hotfixing bugs by branching from the commit that introduced the error. There's two parts to a hotfix: the code that should have been written in the first place, and what the current code would look like as a result. When you only branch from a current tip, you only get the second part, which may not apply cleanly to other tips and might, as it does here, not be cleanly separable from unrelated work you don't want applied elsewhere.

The minimum clean-hotfix base is the merge base of all tips with the bug, to which that hotfix might ever need to be merged. Anything past that merge base means your hotfix history includes other content you didn't want to merge yet anyway.

But for accountability and cleanliness, I think it's best to go back and find the commit that introduced the bug, branch from there, commit what should have been there, merge from the current merge base to resolve all common conflicts (keeping separation of the bugfix and integration work), then merge from that to each tip that needs hotfixing.

like image 26
jthill Avatar answered Oct 20 '22 23:10

jthill