9 ms·
I don't quite understand why people don't keep it simple. Use short lived branches, and merge to master. Need to do a release? Master is your release. Tag the r
by dastx 6y ago
I don't quite understand why people don't keep it simple. Use short lived branches, and merge to master. Need to do a release? Master is your release. Tag the release when it's ready. Need to make a hot fix onto the current deployed version? Create a release branch from the tag, and then create a new tag and merge back to master.
This combined with semver gets you far. I've yet to find any downsides with this approach.
- AlphaSite 6y agoTry doing that with a long lived product, where people don’t upgrade. You need to be able to backport fixes for that customer who pays your bills, but is 6 versions behind.
- cfstras 6y agoThis is an entirely different problem - your customer doesn’t install releases, but they do install fixes? What is the reason for that?
- kingosticks 6y agoOur customers don't want to spend vast amounts of time qualifying an entire new release when they can accept an isolated fix instead and do more focused testing. They might need the fix for some critical part of their product. If I was them I'd do the same - if the rest ain't broke, why risk fixing it?
- cfstras 6y agoIf the qualifying process is long and expensive, doing a one-off fix does seem more logical. This is assuming you can be sure the fix really is isolated. I do feel like a lot of companies over-exaggerate the need for multiple supported releases.
- Cthulhu_ 6y agoRisk mitigation and investment; my employer's software does critical mobile network infrastructure, if they have an outage it affects millions of people. So, if our customers upgrade the software, they want to do their due diligence in their particular use case (it's a flexible system). That said though, software should be built to allow for fast and painless upgrades. Backwards compatibility and many use cases should be tested automatically and constantly. But, it's a big investment to have software like that, and you need to resist a lot of younger, eager developers that want to e.g. introduce a new language or make sweeping changes.
- magicalhippo 6y agoWe have a complex product with many aspects that our customers use, and almost all with some customized integrations. A bugfix to the integration is typically low risk and high impact, and so the client will want to install that ASAP. For example it could be they suddenly changed the values in a single field in an XML file we read, due to upgrades elsewhere in the organization yay, halting the integration. So we push a fix where we handle the new values, and they want that installed ASAP. What they do not want pushed out into prod without lots of testing is all the new things we've added elsewhere in our product, or larger changes to existing features.
- jfkebwjsbx 6y agoThe Linux kernel manages to do it with versions many years behind.
- Phlogistique 6y agoNo. The Linux Kernel uses release branches. This thread is specifically about rejecting the use of release branches.
- jfkebwjsbx 6y agoReleases are created off the master. Only if something is supported for long a branch is created where only fixes are backported, no development happens there. What the GP suggested I assume is one master-like branch for every deployed version. Otherwise it makes no sense.
- Phlogistique 6y agoThe point remains. The Linux branching workflow is vastly more complicated than what GP advocates.
- oweiler 6y agoAKA the github flow. I had the impression that most teams use that branching model.
- jfkebwjsbx 6y agoIt is the normal Git flow. GitHub just made it into a web.
- thaumaturgy 6y agoYep. What you're describing was used at GitHub [1], at least for a while. I've had a lot of success pitching it to small dev shops that have struggled with more complicated branching models, including git flow. I'm pretty sure git flow became popular just because it was the top search result for "how to git". Other criticisms of git flow and alternative branching procedures have come up over the years [2] and been discussed here [3][4][5]. A good, simple metric for whether your team is using git well or not is how often a developer is forced to play Guitar Hero [6] just to fix up a bad merge or rebase. The ideal answer is "never"; if it's happening more than a couple times a year, something's wrong. [1]: https://gist.github.com/jbenet/ee6c9ac48068889b0912 https://gist.github.com/jbenet/ee6c9ac48068889b0912 [2]: https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/ https://barro.github.io/2016/02/a-succesful-git-branching-mo... [3]: https://news.ycombinator.com/item?id=9744059 https://news.ycombinator.com/item?id=9744059 [4]: https://news.ycombinator.com/item?id=22485489 https://news.ycombinator.com/item?id=22485489 [5]: https://news.ycombinator.com/item?id=11190310 https://news.ycombinator.com/item?id=11190310 [6]: https://twitter.com/HenryHoffman/status/694184106440200192 https://twitter.com/HenryHoffman/status/694184106440200192
- donmcronald 6y agoThat guitar hero thing is hilarious. Git flow is something I spent a lot of time theory crafting about years ago. I’d say wasted time, but learning is never a waste and one of the things I learned is the value of deferring complexity whenever possible, especially if there’s no downside. Using a trunk and tag (that’s what I call it) workflow today doesn’t prevent you from adopting something more complex if the need arises, so it makes a ton of sense for it to be the default on new projects, especially for new developers IMO.
- Traubenfuchs 6y agoOverengineering addiction. And often times it is hard to debate against someone "smart" wanting to introduce overengineered approaches. After all we are all solving hard problems and if the solution is super simple that would mean the problems we solve aren't hard enough to require the more complex solution...
- reallydontask 6y ago> Overengineering addiction. I think that is quite a good description of a common problem in software development these days. Needless to say that I have been guilty of indulging in it
- pythonaut_16 6y agoIt's probably not just a "these days" problem though. Thinking through my own experience and various anecdotes it seems like fighting over-engineering and complexity are staples of software development. Consider also that sometimes complexity/engineering really is warranted; either by the domain or by the tooling. In other words, avoiding complexity-domain mismatch isn't just a "these days" problem, it's a constant consideration in software development.
- berkes 6y agoThe difference is that "git flow" is there, documented, often already familiar with engineers. As opposed to something, however simple, that you design yourself. I don't think the term "overengineering" applies when you take an industry practice off the shelf. If anything is overengineered, it would be the simple solution that you "engineer" in house.
- jayd16 6y agoIf you merge into master then it can be unstable from bugs introduced in the merge. If master can be unstable then you can't seamlessly release and must test. If you need to keep master stable then it can't be easily merged into by developers. (testing a tag is not enough because iterations with have other changes in the mean time.) People attempt to skip these issues by embracing the chaos with CI/CD but that's outside the scope of the branching strategy. Maybe the simple flow is the best but it has clear stumbling blocks you will hit.
- lbriner 6y agoBugs can always be introduced into master. The question is where do you want to discover them? You either run tests against the feature branch before merging or you have to gate your master branch into a version on a test system before it is promoted to production. CI/CD can be chaos but the Facebook philosophy is that we would rather you delivered 1000 features per day and be able to quickly fix anything you might break in the process rather than release 1 thing a day that is fully tested. Might not work for your system but it makes sense to them.
- jayd16 6y ago>Bugs can always be introduced into master. Or you can cut a release branch, test, and iterate on that branch and be secure knowing only those release iterations are being made. Its fine for master to have bugs if you're on a release branch. That's why people use them.
- wwright 6y agoYou can avoid “bugs introduced by the merge” by requiring a fast forward/semi-linear merge (ie, the source branch must be a superset of the destination branch). Any testing or validation of the source branch is therefore valid for the result branch, as the contents of the source and result are identical.
- jayd16 6y agoTo actually ensure a fast forward merge you need to get your testing done while no changes can be made to master. If you were to actually enforce this it can really lock up development. If you're doing any manual testing its untenable. This is why release streams and hotfixes are used.
- Phlogistique 6y agoHi, This flow works under some conditions only: * You have working CI/CD that you can trust * You do not have to support old versions of the software Example of some situations where these conditions are not met: * Installs of your software are not reachable over the Internet * Your software needs manual testing or qualification before deployment * You do not handle your software's deployment; your client does. In those situations, you may need to maintain release branches, and backport fixes, etc.
- ollyculverhouse 6y agoWe perform manual testing and qualification on feature branches (but deployed to a qa or staging environment). The thing that really helped us was separating the idea of environments and branches.
- rakoo 6y agoNot the one you're replying to, but there are a few points: - This flow applies more for a service or a website, where there is no problem of distribution: the distribution is done the moment your user reaches your website/service. - In the case of a website there is one website. In the case of services there may be multiple versions, but they exist together in the same file tree. Fixing an issue on an old version means fixing the issue on specific files; when they're pushed on master the users will get the fix - An alternative flow of having to manage multiple versions in parallel is to use feature-flags to compartmentalize sections of code that aren't tested yet or not even functional yet. That way you can have everything on a single branch and make all the code aware of each other. Feature flags can be activated gradually in qa environment, then in staging, then in some customers only, etc... to iron out the bugs as deployment goes. Note that this way of doing is also adapted for traditional installable software, see Firefox and Chrome and their myriads of activation flags.
- Silhouette 6y agoAn alternative flow of having to manage multiple versions in parallel is to use feature-flags to compartmentalize sections of code that aren't tested yet or not even functional yet. The advantages of feature flags over feature branches are mostly an illusion, though. Sure, if you're updating your code in co-ordination with updating some external system, such as a database migration, then sometimes deploying in stages with multiple versions of some functionality running concurrently during some of the intermediate stages is more-or-less the only way you can do it without incurring downtime. But otherwise, even if you have 10 teams and each hides their changes behind a flag and pushes to master instead of a feature branch, you still have an exponentially growing number of combinations and they're still not all being tested in arbitrary combinations. Turning the feature flag on is then little different to merging in a feature branch: it's still a time when things can go wrong. It's just that now they're going wrong on your master branch and screwing things up for everyone else, too.
- Cthulhu_ 6y agoI agree, and I strive to make this work in everything I do now. However, in practice you'll have to deal with legacy software (that doesn't even have to be that legacy), with colleagues that aren't aligned with it, and with people being afraid. Currently I'm working in a company that mainly does nightly builds and manual testing, but I'm working in a new project and trying to make it work like you say. I am constrained though, they have Jenkins as CI which is a bit painful to work with (as in it'll take me a lot of work to get things where I want them to be). Working with pre-commit, pre-push hooks and a solid IDE goes a long way though.
- kjagiello 6y agoWhat sucks about the tags on GitHub is that there is no way of controlling who can create them. Ideally I would love to see a flow similar to the one for PRs. You could then require approval of other team members and also run GitHub actions that could for example verify the tag format and ensure correct format of the tag message.
- Aeolun 6y agoAh yes, no more people manually creating tags and seeing ‘tag already exists’ when you run the release script.
- simiones 6y agoMost people raised the problem of maintaining old releases beyond just hotfixes, which is valid. Another problem my organization has hit with this approach is that, unless you somehow maintain 0 bugs level, you get to a point where you need to do 2 separate things: fix bugs on features that are already "done", while still developing new features, while integrating those in rapid succession. This is mostly true when preparing for a release while still having to work on features for future releases. This can lead to the need to have two separate "main" branches, one that is used for stabilization, and another that is used for active development.
- ddevault 6y agoTo maintain old releases, I just cut a branch before I tag. Merge to master, short-lived feature branches, and when it's release time, git checkout -b v1.5, git tag -a 1.5.0, and then cherry pick bugfixes onto that branch when it's time for 1.5.1. If you need more time to stabilize for 1.5.0, just add some time & development between cutting the branch and tagging it.
- cmurphycode 6y agoThis is close enough to what we do -- and it works -- but since we support multiple releases at a time, it often ends up feeling like merging is pointless. Merging a dev branch into trunk feels good, but honestly most git interactions involve cherry-picking sets of commits to old releases, or to create hotfixes (So much, in fact, that we built some tooling around it to make it easier to not screw up). So then, you start to wonder, why am I special casing this one situation and using merge to trunk, and using cherry pick everywhere else.
- ddevault 6y agoI cherry pick (or rebase, usually) to master, too. I only merge when I'm actually merging divergent histories.
- __turbobrew__ 6y agoThis is what we do as well and it works fine. We do data processing and have a mix of processing which needs to completed in near real time and other processing which we have a bit more leeway on the time. The real time processing runs on stable releases which are tags created off of a stable branch (as you have suggested) and all the other processing runs off the tip of master.
- alkonaut 6y agoThat works if - There is only one released version in flight at any time - You don't need to do a lot of validation before release. E.g. if you release on physical media, or need certification, or shoot the program into space and can't patch it. Basically, it works for web software where you want (or can have) continuous deployment. For any scenario that doesn't do "continuous deployment", I think having multiple release/maintenance branches is inevitable. In that case, master is the vNext development branch, and each major version will have a branch for stabilization/validation point releases.
- berkes 6y agoAdditional, practical issues that teams have to overcome, regardless of "continuous" delivery, are: * what is being tested by QA/Product Owner/clients etc right now? What do we do when they actually have feedback that needs fixing? * how to keep your modifications/patches to SomeUpsTreamSoftware manageable? * How to deal with parallel development by a team of four? Of twelve? Should all work halt until your PR is merged? What if there are conflicts? How to handle longer lived development? All of these are hardly ever covered by "keep it simple". Turning that "keep it simple" model into a giant mess of rules, guidelines, scripts and whatnots. Basically a very poor version of Git flow. Yes. Git flow is often overengineered for CD types of workflows. But it does have all the cases and situations covered that you will eventually run into, and that your homebuilt "simple" flow has not. Edit: to be clear: there are solutions for all my points in your Simple Workflow, certainly. But here's how git-flow helps: * release-branches are ideal for putting work in front of stakeholders before release. Allowing improvements on the release. Even in a CD workflow, having something that is separated from "mainline" during the release-window is a good idea. A release-branch is just that. having a separate mainline where during that time new releases can be made is smart too: you don't want to be forced to wait for feature X to land before you can roll out some important fix. I.e. release, master and hotfix branches. * support- branches in addition to feature branches allow easy rebasing when upstream changes and you need time to re-apply your patches and customisations. You can e.g. branch off a "support-3.1.4" off the 3.1.4 release from upstream and apply your feature/awesome-hack-x on that. * feature branches are ideal for parallel development. Being able to merge into a branch that does not immediately release (separated from mainline) is smart, because it allows multiple team members to merge to and then make a release. i.e. "development" and "feature"
- Aeolun 6y agoThere’s no downsides, except if you have multiple different releases going to multiple different environments from the same codebase. Just having one release branch per version was still generating too many errors, so now we have one per version per environment. This would work much better if the company would get it’s head around continuous deployment, but they just don’t want to release anything without a full round of manual regression testing.
- _ZeD_ 6y agoso basically trunk based development[0] [0] https://trunkbaseddevelopment.com/ https://trunkbaseddevelopment.com/
- rkangel 6y agoThis is exactly what I have instituted for my team. I think that actually is Gitlab Flow though. If you don't use the optional parts of Gitlab Flow like a production branch, what you are left with is feature branches merged to master, and then release tags made from master. The only difference is that both of us don't make the release branch unless it's necessary, we just make the tag.
- kkapelon 6y agoThere are several scenarios in enterprise companies where you have multiple releases of your product (and all of them are live at the same time) as well as the need to backport fixes to older versions. Git-flow is the answer in most of those scenarios and the only way to keep your sanity. What you describe is the happy path scenario.
- bob1029 6y agoThis is precisely what we do. In our model: > Each issue in GitHub is 1:1 with a PR that resolves it. > All normal work is branched directly off latest master. > Every branch is rebased against master prior to merging. > Feature flags are heavily used to gate the activation of functionality which is not applicable, not ready, or otherwise in need of being configured per environment+client. > Checkbuilds complete with success before we merge to master. Nothing is allowed to merge which could impact production without a feature flag or other gatekeeping mechanism in place. We have a labeling system to track which issue+client pair needs a feature flag configured in a certain way so this can be managed at deployment time. > Hotfixes are managed by branching off the commit deployed to the client+environment of concern. We have a system (in house developed) that tracks all of the current client+environment+hash tuples so it is very easy to know where to stick the shovel every time. > We effectively consider the commit hash to be the version of our software. Our releases are extremely granular due to the feature set we support for our customers, so commit hash is the best way to manage this. That said, it is not unusual for multiple client+environment pairs to share a common commit hash depending on our release timing (this is purely asynchronous and managed by our project group). That's about it. There is only 1 permanent master branch. No work branch ever sits longer than ~2 weeks in our development model. We merge code ASAP so that we can iterate on the results. For reference, we merge to master ~10-30 times per day. I have some plans in the pipeline for implementing a technique that would allow for pushing hundreds or thousands of commits per day if we ever got to that point.
- globular-toast 6y agoThat's exactly what I do. When I joined my current company there was a mix of git flow going on and one project that had three eternal branches which were supposed to correspond to different environments (staging, prod etc.). Nobody really understood what was going on with these repos. The histories were all spaghetti. There were CI pipelines in place that automatically created tags from the source code. It was a complete mess. I spent quite a long time unwinding it all and forcing people to unlearn these silly habits. Each project now has one master branch and, possibly, one or more maintenance branch. Releases are triggered by the addition of a tag. At first I think people doubted that it could be so simple. It's like they'd been forced to learn something incredibly complex and just assumed they weren't clever enough to know any better. A kind of Stockholm syndrome maybe? We've been running the simplified system for more than a year now and everyone is happy. Not once have we ever needed anything even remotely like git flow again.
- gonational 6y ago+100 This is what we do at work. Unless there is some major database or library or language version change in a feature branch, once that branch is tested and QA’d, the M.O. becomes “merge any feature branches that we’re ready to put live into master and release”. Long-lived branches are a mess, and rebase flow is crushed by them. If you can fit this kind of simple Git workflow into your development workflow, I recommend it.