Forked merge commits seem drawn incorrectly
Hello, and thank you for the brilliant SVG generator as well as the Orthogonal Git Workflow article, which is very well written and contains a wealth of good ideas.
I'd like to ask specifically about Figure 3.1 in the article, which seems to not correspond well with the text in the article. However, the article also appears incomplete with respect to the "bugfix after feature freeze" section:
The figure shows the bugfix/W-43_fix-crash branch forked from the master branch at the v.2.11.0-rc1 tag; the bugfix branch is then merged into a v2.10 branch. The text describes the scenario as a bug in v.2.10.0 being fixed, but the diagram, as drawn, suggests that the features from develop that the new release branch v.2.10 will contain v.2.11.0-rc1 features.
Furthermore, as drawn, the bugfix/W-43_fix-crash branch is based on v.2.11.0-rc1, not on v.2.10.0 where the bug was supposedly found, if my interpretation of the article is correct.
The question is:
- Was the
bugfix/W-43_fix-crashmeant to be drawn as forking fromv.2.10.0instead ofv.2.11.0-rc1 - If so, where is the problem, in the input to the Grawkit script, or in Grawkit's interpretation of the input?
Maybe the issue is that in this scenario the bugfix/W-43_fix-crash would be fast-forwardable, and this confuses the awk script?
I'd also love to see your finished thoughts on the "bugfix after feature freeze" topic, which you describe as an "extraordinary measure".
Would it not make sense to branch bugfix/W-43_fix-crash from v.2.10.0, hard-reset master to v.2.10.1, thus abandoning v.2.11.0-rc1, and then merge develop into the new master, tagging it v.2.11.0-rc2 ? Alternately, having a staging branch where the -rc versions go, and merging staging into master only at release points would allow the master to contain only versions usable in production, and also allow bugfixes to be applied at any stage, before or after the feature freeze?
I assume steering the production systems to use a release from the non-master branch named v.2.10 branch is what makes this solution an "extraordinary measure".
Thank you again for your amazing work. I plan on using the script for creating some documentation of my own.
Hi @drok, thank you for the kind feedback and for your keen eye here -- you're entirely correct that Figure 3.1 is incorrect as per the article itself: the bugfix branch is supposed to be created starting from the last stable tag on master.
It seems that this is due to PEBKAC, as the source file for the SVG reveals: https://deuill.org/post/orthogonal-git-workflow/feature-freeze-after.git (open as a text file) -- the git tag v.2.11.0-rc1 command should appear after the git branch bugfix/VV-43_fix-crash command. I'll fix this!
It's probably worth expanding on this in the post itself, but the main assumption here is that tags have some connection to an underlying release process (probably driven by CI): any tagged release on master will be pushed to the production environment if not ending in -rc[0-9]+, and a pre-production/staging environment in any case.
Pushing tagged releases on other branches will therefore require manual intervention, hence why the process might be considered "extraordinary" -- this might range from some arcane command-line invocation to simply pointing CI to this other branch.
Alternative processes do exist, as you say, though I'd generally steer away from rewriting history on public, commonly used branches, as this can cause quite a lot of issues when attempting to reconcile with locally cloned copies and/or systems which may be pointing to the now-orphaned commits. A secondary branch would allow for keeping -rc tags off of master, and therefore make production fixes simpler, but would complicate merge strategies for most cases; whether or not this tradeoff is acceptable is, I guess, up to the individual team.
One way to think of this is: process is only as good as what it helps you achieve, and friction can be a positive component in process if it aligns with those same goals.
In this case, the workflow advocates for separate branches for the integration and deployment of features (develop and master, respectively) because of the "feature freeze" stage of the process, which is a central part of ensuring correctness in the soon-to-be production code. It is also because of this additional stage that the "extraordinary measure" of having to deploy against a dedicated release branch is also considered unlikely.
If, however, this stage of the process isn't necessary, then -rc tags aren't necessary either and we can instead deploy to pre-production/staging as branches are merged into develop.
I've worked with both processes, and I'll say that, these days, I tend to lean toward the more straightforward approach of having tagged commits in master always correspond to what we want in production, and all commits in develop be deployed to pre-production automatically, simply because it's easier to reason about in a smaller project. Indeed, the benefits of the orthogonal approach tend to become more apparent in larger code-bases with a steady pace of contributions.