7 ms·
Regarding the original git-flow model: I've never had anyone able to explain to me why it's worth the hassle to do all the integration work on the "develop" bra
by m12k 8mo ago
Regarding the original git-flow model: I've never had anyone able to explain to me why it's worth the hassle to do all the integration work on the "develop" branch, while relegating the master/main branch to just being a place to park the tag from the latest release. Why not just use the master/main branch for integration instead of the develop branch - like the git gods intended - and then not have the develop branch at all? If your goal is to have an easy answer to "what's the latest release?", you have the tags for that in any case. Or if you really want to have a whole branch just to double-solve that one use-case, why not make a "release-tags" branch for that, instead of demoting the master/main branch to that role, when it already has a widely used, different meaning?
It's a pity that such a weird artifact/choice has made its way into a branching model that has become so widely implemented. Especially when the rest of it is so sensible - the whole "feature-branch, release-branch, hotfix" flow is IMO exactly right for versioned software where you must support multiple released versions of it in the wild (and probably the reason why it's become so popular). I just wish it didn't have that one weirdness marring it.
- choeger 8mo agoI am working with main/master for years now, and there's one problem you don't have with develop: Whenever you merge something into master, it kind of blocks the next release until its (non-continuous) QA is done. If your changes are somewhat independent, you can cherry-pick them from develop into master in an arbitrary order and call that a release whenever you want to.
- embedding-shape 8mo ago> Whenever you merge something into master, it kind of blocks the next release until its (non-continuous) QA is done. That's what tags are for, QA tests the tagged release, then that gets released. Master can continue changing up until the next tag, then QA has another thing to test.
- dsego 8mo agoCan I tag a bugfix that goes in after a feature was already merged into main? Basically out of order. Or do I need to tag the bugfix branch, in which case the main branch is no longer the release, so we need to ensure the bugfix ends up in the remote main branch as well as the release. Seems like it could cause further conflicts.
- embedding-shape 8mo agoI'm not sure what you mean, what does "tag a bugfix", "tag the bugfix branch" or "ensure the bugfix ends up in the remote main branch as well as the release" even mean? What are you trying to achieve here, or what's the crux? I'm not 100% sure, but it seems you're asking about how to apply a bug fix while QA is testing a tag, that you'd like to be a part of the eventual release, but not on top of other features? Or is about something else? I think one misconception I can see already, is that tags don't belong to branches, they're on commits. If you have branch A and branch B, with branch B having one extra commit and that commit has tag A, once you merge branch B into branch A, the tag is still pointing to the same commit, and the tag has nothing to do with branches at all. Not that you'd use this workflow for QA/releases, but should at least get the point across.
- franktankbank 8mo agoIt means you need a bugfix on your release and you don't want to carry in any other features that have been applied to master in the meantime.
- embedding-shape 8mo agoUsually what I've seen is one of two solutions, the former (usually) being slightly favored: A) hide any new feature behind feature flags, separate "what's in the code" from "how the application works" essentially or B) have two branches, one for development (master) and one for production. The production branch is what QA and releasers work with, master is what developers work with, cherry-picking stuff and backporting becomes relatively trivial.
- Gigachad 8mo agoI worked at a place that had Gitlab review apps set up. Where the QA people could just click a button and it would create an instance of the app with just that PR on it. Then they could test, approve, and kill the instance. Then you can merge to master and it's immediately ready to go.
- ncphillips 8mo agoYeah same. The idea that you'd be merging code to `main` that isn't ready to deploy is crazy to me, but that doesn't mean you need a `develop` and `prod` branch. The main + 1-layer of branches has generally been totally sufficient. We either deploy to branch-preview environment or we just test it locally.
- globular-toast 8mo agoYes, you have to include QA in the continuous integration process for it to work. That means at any time you can just tag the top of the master branch to cut a release, or do continuous delivery if it makes sense (so no tags at all). It sounds like you are doing a monorepo type thing. Git does work best and was designed for multiple/independent repos.
- WorldMaker 8mo agoEven in a monorepo you can tag releases independently in git. git doesn't proscribe any particular version tag naming scheme and stores tags similarly to refs in a folder structure that many (but not all) UIs pay attention to. You can tag `project-a/v1.2.0` and `project-b/v1.2.0` as different commits at different points in the repo as each project is independently versioned. It makes using `git describe` a little bit more complicated, but not that much more complicated. You just need to `--match project-a/` or `--match project-b/` when you want `git describe` for a specific project.
- tremon 8mo agoThat's true, but git also doesn't have tags that apply to a subset of the repository tree. You can easily check out `project-b/v1.2.0` and build project-a from that tree. Of course, the answer to that is "don't do that", but you still have the weird situation that the source control implementation doesn't match the release workflow; your `git describe` example is but one of the issues you will face fighting the source control system -- the same applies to `git log` and `git diff`, which will also happily give you information from all other projects that you're not interested in. For me, the scope of a tag should match the scope of the release. That means that a monorepo is only useful if the entire source tree is built and released at the same time. If you're using a monorepo but then do partial releases from a subtree, you're using the wrong solution: different repo's with a common core dependency would better match that workflow. The common core can either be built separately and imported as a library, or imported as a git submodule. But that's still miles ahead of any solution that muddles the developers' daily git operations.
- 8mo ago
- mort96 8mo agoWhat's the difference between what you describe, and continuously merging things into main and cutting releases from a branch called stable?
- estimator7292 8mo agoThey're the same strategy with different branch names.
- secretazianman8 8mo agoAre you using feature flags in your workflow pattern? These can be used to gate releases into your production environment while still allowing development work to be continuously integrated to trunk without blocking. This also means that the release to prod happens post-integration by means of turning the feature flag on. Which is arguably a higher quality code review than pre-integration.
- deleted 8mo ago[deleted]
- UqWBcuFx6NV4r 8mo ago[flagged]
- m12k 8mo agoI'll try to respond to your comment in good faith, even though I find it to have a rather aggressive, ad-homimen tone: > If this pattern is so pervasive, and so many people care enough to attempt to explain it to you, yet you remain unconvinced, I’m not sure how you reach the conclusion that you are right, and correct, and that it’s such a shame that the world does not conform to how you believe that things should be. The reason nobody has convinced me otherwise isn't that I haven't listened, but because the people I talked to so far didn't actually have arguments to put forth. They seemed to be cargo-culting the model without thinking about why the branching strategy was what it was, and how that affected how they would work, or the effort that would be put into following each part of the model vs the value that this provides. It seemed to me that the main value of the model to them was that it freed them from having to think about these things. Which honestly, I have no problem with, we all need to choose where to put our focus. But also, all the more reason why I think it's worth caring about the quality of the patterns that these guys follow unquestioningly. > Besides a bit of a puritan argument about “git gods”, you haven’t really justified why this matters at all, let alone why you care so much about it. Apart from that (apparently failed) attempt at humor, I did in fact attempt to justify later in my comment why it matters: "instead of demoting the master/main branch to that role, when it already has a widely used, different meaning?" To expand on that, using the same names to describe the same things as others do has value - it lowers friction, allows newcomers (e.g. people used to the github branching model) to leverage their existing mental model and vernacular, and doesn't waste energy on re-mapping concepts. So when the use case for the master/main branch is already well-established, coming up with a different name for the branch you do those things on ("develop") and doing something completely different on the branch called master/main (tagging release commits), is just confusing things for no added benefit. On top of that, apart from how these two branches are named/used, I also argue that having a branch for the latter use case is mostly wasted effort. I'm not sure I understand why it needs to be spelled out that avoiding wasted effort (extra work, more complexity, more nodes in the diagram, more mental load, more things that can go wrong) in routine processes is something worth caring about. > On the other hand, the model that you are so strongly against has a very easy to understand mental model that is analogous to real-world things. What do you think that the flow in git flow is referring to? "very easy to understand mental model"s are good! I'm suggesting a simplification (getting rid of one branch, that doesn't serve much purpose), or at least using naming that corresponds with how these branches are named elsewhere, to make it even easier to understand. You say it's a model that I'm "so strongly against". Have you actually read my entire comment? It says "Especially when the rest of it is so sensible - the whole feature-branch, release-branch, hotfix flow is IMO exactly right for versioned software". I'm not strongly against the model as a whole. I think 80% of it is spot on, and 20% of it is confusing/superfluous. I'm lamenting that they didn't get the last 20% right. I care exactly because it's mostly a good model, and that's why the flaws are a pity, since they keep it from being great. As for "flow", I believe it refers to how code changes are made and propagated, (i.e. new feature work is first committed on feature branches, then merged onto develop, then branched off and stabilized on a release branch, then merged back to develop AND over onto master and tagged when a release happens). Why do you bring this up? My proposal is to simplify this flow to keep only the valuable parts (new feature work is first committed on feature branches, then merged onto master, then branched off and stabilized on a release branch, then tagged and merged back to master when a release happens). Functionally pretty much the same, there's just one less branch to manage, and develop is called master to match its naming elsewhere. > I’m sorry that you find git flow so disgusting but I think your self-righteousness is completely unjustified. Again, I don't know where you get this from. I don't find the model disgusting, I find it useful, but flawed. I don't know why you think suggesting these improvements justifies making remarks about my character.
- Aerolfos 8mo agoIt's useful if your integration work takes some time - easy to run into with open source. Imagine you have multiple contributors with multiple new features, and you want to do a big release with all of them. You sit down a weekend and merge in your own feature branch, and then tell everyone else to do so too - but it's a hobby project, the other guys aren't consistently available, maybe they need two weekends to integrate and test when they're merging their work with everyone else's, and they don't have time during the weekdays. So, the dev branch sits there for 2-3 weeks gradually acquiring features (and people testing integration too, hopefully, with any fixes that emerge from that). But then you discover a bug in the currently live version, either from people using it or even from the integration work, and you want that fix live during the week (specific example: there's a rare but consistent CTD in a game mod, you do not want to leave that in for several weeks). Well, if you have a branch reflecting the live status you can put your hotfix there, do a release, and merge the hotfix into dev right away. Speaking of game mods, that also gives you a situation where you have a hard dependency on another project - if they do a release in between your mods releases, you might need to drop a compat hotfix ASAP, and you want a reflection of the live code where you can do that, knowing you will always have a branch that works with the latest version of the game. If your main branch has multiple people's work on it, in progress, that differs from what's actually released, you're going to get a mess. And sure you could do just feature branches and merge feature branches one by one into each other, and then into main so you never have code-under-integration in a centralized place but... why not just designate a branch to be the place to do integration work? You could also merge features one by one into main branch but again, imagine the mod case, if the main code needs X update for compatibility with a game update, why do that update for every feature branch, and expect every contributor to do that work? Much better to merge a feature in when the feature is done, and if you're waiting on other features centralize the work to keep in step with main (and the dependency) in one place. Especially relevant if your feature contributors are volunteers who probably wouldn't have the time to keep up with changes if it takes a few weeks before they can merge in their code.
- layer8 8mo agoIt can be beneficial if there is no mechanism that ensures that develop is always in a working state, but there is one that ensures that master is. The immediate benefit is that a new feature branch can always be started off master from a known-good state. Of course, there are ways to enforce a known-good state on master without a dedicated develop branch, but it can be easier when having the two branches. (I just dislike the name “develop”, because branch names should be nouns.)
- simianwords 8mo agoProd deployments usually have a tag associated
- deleted 8mo ago[deleted]
- layer8 8mo agoProd deployment isn’t the same as known-good. The latter can be “passes all automated quality controls”; that doesn’t automatically mean that it’ll be deployed. Release/deploy cadences can be much slower than merge-into-master, and usually depend on actual feature (set) completion.
- iainmerrick 8mo agoYou’re right. I think what you’re describing is “trunk based development” and it’s much better. Maybe I’m overly cynical but I think git-flow was popular largely because of the catchy name and catchy diagram. When you point out that it has some redundant or counter-productive parts, people push back: “it’s a successful model! It’s standard! What makes you think you can do better?” There’s a nice write-up of the trunk-based style at https://trunkbaseddevelopment.com/ https://trunkbaseddevelopment.com/ that you can point to as something better.
- disruptiveink 8mo agoCorrect. If you can always either fix it forwards or roll back, which you should be able to unless you're building software that needs to go out in releases with versions tracked separately that need to keep getting fixes, trunk-based development simplifies everyone's lives greatly. I've never seen an organisation that insists on release branches and complicated git merge flows to release their web-based software gain any actual benefit from it that isn't dwarfed by the amount of tooling you need to put around it to make it workable to the dev team, and even then, people will routinely screw it up and need to reach out to the 5% of the team that actually understands the system so they can go back to doing work.
- QuercusMax 8mo agoI've done branchy development to good effect for user-installable software, where we committed to maintain e.g. 3.2.x for a certain time period, so we had to keep release branches around for a long while. But for continuously deployed SaaS or webapps, there's no point.
- dcrazy 8mo agoUntil you have a customer that must stay on v.previous for extra time for some reason.
- QuercusMax 8mo ago
- globular-toast 8mo agoYeah, I actually think that diagram and "git-flow" has caused a lot of harm. It shows a complete misunderstanding of both continuous integration and what tags are for. I've successfully purged git-flow and dragged developers, kicking and screaming, to a simple master branch, tags and maintenance branch model a few times now.
- abustamam 8mo agoWhen I first got started programming, the "git flow" method was the one that popped up and was referred to most when I googled how does git work. And so I thought that git flow was the canonical way to use git. I tried adhering to it at my first job but I guess I didn't understand git flow well enough because people just thought I was making random branches for fun.
- bandrami 8mo agoThe model works well if you're developing version 3.2 (which is not ready yet) but also non-trivially maintaining 3.1.
- tremon 8mo agoExactly. As soon as you're working with multiple active releases, the branching model becomes a distinction without a difference. You will always be working with multiple (tagged) release branches, a default branch on which developers base their new work, and an integration branch where development work is gathered and tested to cut the next release. Whether the default and integration branch are identical or separate is mostly immaterial to the developer workflow. The only meaningfully different model is when you have a continuously-releasable trunk and never do fixes on older releases (quite common for internal tools).
- jeffwask 8mo agoThis, the only times I have used this were to patch over other bad decisions like maintaining 3-4 active releases of a SAAS product simultaneously or other decisions that forced us into a complex branching scheme. If you fix the downstream and upstream issues, you can usually simplify down to an easier branching model but if you are managing hotfixes and releases across many versions this works and keeps it sanish.
- bandrami 8mo agoMy last job was COTS where we still sent out physical DVDs to customers (because some were on air-gapped computers) so we weren't just maintaining LTS branches but had to actually make patch installers for all of them. A big benefit was that we could put the specific releng stuff in each specific branch (HEAD never had any releng and it got put on every release branch).
- bombcar 8mo ago"git-flow" makes a lot more sense when you realize the "develop" branch doesn't have to be a branch "on the git server" and instead is your master branch you're fuddling with.
- taeric 8mo agoThe difference here will almost certainly come down to how you release your work? For product based teams that have a very specific place to plant the tag of what was released, development branches reflect their ability to know exactly what has been shipped to customers. And this is more than just knowing the exact commit. Which, fair, that that is all that you truly need. Having it on a branch, though, reflects that hot fixes and similar can still be applied, and though the tag will remain at what was released, the branch will be what it currently looks like.
- pragma_x 8mo agoI can't say that I've used gitflow in hate. That said, I always saw the full complexity of the approach to address tracking multiple concurrent releases of a product. It's extremely uncommon in our increasingly SaaS world, but I imagine having so many branches with commits moving laterally between them to be invaluable for backporting security fixes and the like. For the rest of us, trunk-based development with feature/fix branches is more than enough.
- dec0dedab0de 8mo agohaving a main branch allows a casual observer(management) to browse your project in the gui and see what is currently live. I like the opportunity to force a second set of testing, and code review. Especially if the team is big enough that you can have different people doing code review for each branch. You can also have your CI/CD do longer more thorough testing while merging to main vs development. If it's a project with a single deployment, version tagging is kind of pointless, it's much easier to just use a branch to reflect what is live, and roll back to a merge commit if you have to. Then you can still merge directly to main in the event of a hotfix.
- nazcan 8mo ago> having a main branch allows a casual observer(management) to browse your project in the gui and see what is currently live. I never found this very compelling. What is main in that world is not the source of truth, and it's rare to have a system atomically in one state or the other - but normally there are progressive rollouts. And if you ever need to rollback in production, I assume no one is changing where main is. > I like the opportunity to force a second set of testing, and code review. Especially if the team is big enough that you can have different people doing code review for each branch. To be explicit for code review, do you mean there is (1) main, (1) development, and then a bunch feature branches - and that there is review when merging into development and main? Having a two-tiered review process seems extremely difficult to do - versus just having more reviewers on the first merge - especially dealing with merge conflicts and needing to merge again into development. > You can also have your CI/CD do longer more thorough testing while merging to main vs development. I think it's fair to do more testing later. I think the equivalent I'm used to (which is pretty close, so not a huge difference), is only building releases from the commit that passed the bigger/slower tests. But also, assuming there are multiple deployments coming from one repo, if you block merging into main, that means you'd be blocking on all tests passing - while release branches for a given product can select a subset of tests when deciding on release candidates. > If it's a project with a single deployment, version tagging is kind of pointless, it's much easier to just use a branch to reflect what is live, and roll back to a merge commit if you have to. Then you can still merge directly to main in the event of a hotfix. I think it's worth maintaining the flexibility of how many releases come from a repo. Needing to fork repos just because you want another deployable release in the future seems painful to me.
- deleted 8mo ago[deleted]
- keithnz 8mo agoThe branching strategy we use is features are branched off master, as features are finished we then pick what ones we want to bundle into a release, create a release branch from master, merge features into it, we go through QA, when that release is ready, we merge to master. Meanwhile new features are still being worked on based off master. This works really well as it gives you a lot of control over when things get released and manage testing impact / user impact. This also makes it really easy to back out of a feature without it polluting a "develop" branch that other features have branched off. All features are based on code that is actually deployed.
- 4ndrewl 8mo agonvie said as much in 2020 and stuck a big disclaimer at the top of the post https://nvie.com/posts/a-successful-git-branching-model/ https://nvie.com/posts/a-successful-git-branching-model/
- fooker 8mo agoWhat you described works when you have small repo with a few developers. Unfortunately the trend nowadays is towards giant monorepos with many many people changing random things.
- GuB-42 8mo agoThe only thing that you seem to argue about is the naming of the branches. If you call the git-flow "develop" branch "master" and the "master" branch "release-tags" it will be exactly as you describe. The names of the branches don't really matter in practice, so much that they could just decide to use "main" instead of "master" by default without much problems. Maybe what bothers you is that you have a branch for tags, yeah, that's an extra level of indirection, but this lets you separate between user facing information in the master branch commits and developer facing information in the release branches commits. Having the master (default) branch only contain releases let users who pull the project without knowledge of the process get a release version and not a possibly broken development version, which I think is nice. Anyways, these are just details, I don't think the "git gods" (Linus) care about how you organize your project. There is only one sacred rule I am aware of: don't destroy other people history. Public branches you pushed that others have pulled is other people history.
- creshal 8mo ago> Maybe what bothers you is that you have a branch for tags, yeah, that's an extra level of indirection, but this lets you separate between user facing information in the master branch commits and developer facing information in the release branches commits. That's such a marginal niche use case to build your entire organization around… why would you make this the default approach?
- db48x 8mo agoMany, probably most, projects do exactly that. But if you do want a branch where every commit is a merge between the previous release and the current release then it really doesn’t matter whether you call it master or anything else. The names are irrelevant, as long as everyone understands their purpose.
- just6979 8mo agoThe dev branch can be useful with larger team sizes where there might be lots of overlapping work being done. Or a shop that isn't fully into automated continuous delivery, ie: a human needs to press the button to actually deploy to prod. Not unheard of for high security things or anything where the accountability chain needs to be very explicit. The dev branch allows you to go full CI-CD-automation-everywhere to get changes into dev/sandbox deployment quickly, and then once it's fully and completely vetted there it can be merged to main and deployed to prod. It can certainly be done without the dev branch, but you usually end up with lots of extra rules around merges and [ab]uses tags like branches in weird way. And it's way harder to revert things if it comes down to that. In short, if you need a semi-waterfall, less devops-ish, release process, the dev branch can assist that. If not, then it's just extra merges to manage and adds a bunch of work on keeping things in sync, especially with any kind of hotfixes in the picture.