I'm using GitFlow in my git repository, so I have a master
, develop
and (temporary) release
branch.
Workflow
develop
(e.g. fix/fix-the-bug
)fix/fix-the-bug
branch into develop
release/x.y.z
branch from develop
release/x.y.z
branch and tag that commitrelease/x.y.z
into master
, I get merge conflicts. It seems like master
does not understand that commits are already present in master
release/x.y.z
branch gets merged into develop
release/x.y.z
Few things to notice, not sure if they are all correct:
master
indicating the version number, but not sure if that would work correctly if I squash the commits.Question
I'm now wondering:
I squash my commits into one commit when merging into master
It sounds like you're using git merge --squash
when you merge to master
. This is not standard gitflow practice; you would just do a normal merge.
The entire difference between a regular merge and a squash merge is that a squash merge does not record the relationship between the new commit on the branch you're merging into (i.e. master
in this case) and the original commits on the source branch; that's why subsequent merges don't understand that the content on master
already corresponds to a previous state of develop
.
The "downside" to using a regular merge is that git's default output, when logging master
for example, would include all the individaul commits instead of just a list of the release commits on master
; but you can fix that by using the --first-parent
option.
To put this into visuals, you start with a blank repo
o <--(master)
Without creating commits, you start the develop
branch, and then a fix
branch on which you do some work
o <--(master)(develop)
\
A <--(fix)
You merge to dev
o <--(master)
|
|- M <--(develop)
\ /
A <--(fix)
You might do more fixes
o <--(master)
|
|- M - M2 <--(develop)
| / \ /
| | B <--(fix2)
\ |
A <--(fix)
Now if you squash merge to master, you'll get something like
o -------- AB <--(master)
|
|- M - M2 <--(develop)
| / \ /
| | B <--(fix2)
\ |
A <--(fix)
and AB
contains all the changes that A
and B
introduced, but as far as git is concerned, that's coincidental; and once develop
contains additonal changs, even the fact that the changes are "the same" will be lost, and conflicts (as you've experienced) result.
So instead you do a regular merge - just leave out the --squash
option, assuming you were using squash merges in the first place:
o ------- AB <--(master)
| /
|- M - M2 <--(develop)
| / \ /
| | B <--(fix2)
\ |
A <--(fix)
This is how git means for merges to work; now future merge attempts will "know" that M2
(and everything it entails) is already included in master
and only changes after M2
will be included as "their changs" in the merge calculation.
This also is how gitflow intends things to be done.