I've been reading the gitworkflows page of the git-scm docs and am confused about some parts of the workflow. My current understanding is this:
- maint is the oldest integration branch and is intended for hotfixes for the previous release.
- master contains commits going out for the current release
- next contains experimental patches being regression tested.
- seen contains patches that have been viewed in the mailing list by the maintainer. (if I'm incorrect, please elaborate).
All patches graduate from unstable to more stable, with master or maint being the most stable branches. As a general rule, integration happens upwards. This use of upwards here is confusing, but assuming that we don't want to regress, upwards means something like maint -> master -> next -> seen, where maint is merged into master, master is then merged into next, etc. This is further supported by the following quote:
If you notice that you have applied a fix to e.g. master that is also required in maint, you will need to cherry-pick it (using git-cherry-pick) downwards.
If cherry-picking from master to maint is considered merging downwards, then I think my understanding of upwards merging is correct.
Topic branches, the rule to not merge downstream unless necessary, and throw away integration branches make sense to me. It's all about keeping branches focused and clean while also providing means to test many changes together outside of the next branch.
One area I'm still unsure about is the documentation on Maintenance branch management after a feature release. It claims that master is a superset of maint, meaning that master contains all commits in maint. It then fast-forwards on the maint branch to master after each release. But how is this possible? If maint is for hotfixes for the previous release, wouldn't adding any hotfixes on top of it force a merge commit instead of a fast-forward when updating the maint branch when master is updated with the next release? Wouldn't the below merge command fail in that case?
git checkout maint
git merge --ff-only master
I know this merge can still be done with a merge commit, but it seems like the overall flow has been focused on clarity and ensuring history linearity. Having merge commits seems to muddy that clarity a bit (despite being more accurate in terms of how changes are introduced). Is my understanding of git.git's worflow correct?
CodePudding user response:
Some time after a release, we have this situation:
o--o--o <- master
/
--o <- maint
Then comes a hot-fix for maint. First, the fix is applied to (or merged into) maint, then maint is immediately merged into master, hence, we have, this situation:
o--o--o--M <- master
/ /
--o--------F <- maint
This is so that the master branch can also take advantage of the hot-fix. Later, when a new release is cut, maint can be fast-forwarded to master:
o--o--o--M--o--o <- master, maint
/ /
--o--------F
No new merge commit is needed for git checkout maint; git merge master
.
but it seems like the overall flow has been focused on clarity and ensuring history linearity
Not at all. Linear history is by no means a goal with this workflow; see the situation after the hot-fix. On the contrary, it takes advantage of Git's abilitiy to cope with merges. In fact, in the examples above, you can consider every o
as well as F
to be a merge commit that merges a topic branch.