top | item 47058892

(no title)

m12k | 11 days 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.

discuss

order

iainmerrick|11 days ago

You’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/ that you can point to as something better.

whoknowsidont|11 days ago

> but I think git-flow was popular largely because of the catchy name and catchy diagram.

It was because Git showed up in the era of SVN / CVS where those branching models were created because of the uh... let's just call it technical mishaps of those source control systems.

Git did not have the hang ups of SVN / CVS / etc but people stuck with what was familiar.

disruptiveink|11 days ago

Correct. 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.

whurley23|10 days ago

I'm in an environment where the work consist of multiple streams. There are long running tasks, major features that can go for months, require multiple rounds of review and approval, and a sustained amp of back-and-forth. Then there are smaller ones that are typically accomplishable within a typical iteration time period. And then you have hot fixes, security or emergency changes.

These all have separate QA, integration, and release timelines that can -- and often do -- change during the process. As a result, what goes into any given release is sometimes being changed almost right up until we hit the button. Having the ability to roll a release branch from different feature branches and not get miscellaneous work from things that aren't ready is important.

Now, this could also be done with clever use of feature flags, but the platform doesn't play nicely with that concept. Plus, then there would be the work of going back and removing them or leaving in place a mess of conditional statements littered around.

Doing it in version control is architecturally simpler, integrates better with our task and version management tools and is easier to standardize on. There is a cost in how to handle merge conflicts, but that is manageable and can be offset by good task planning and careful work. And the occasional reset

mort96|11 days ago

If what they described is "trunk based development", then "git flow" is just "trunk based development where the trunk is called develop and there's a branch which always has the latest release". Is that it?

choeger|11 days ago

I 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|11 days 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.

Gigachad|11 days ago

I 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.

mort96|11 days ago

What's the difference between what you describe, and continuously merging things into main and cutting releases from a branch called stable?

secretazianman8|11 days ago

Are 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.

globular-toast|11 days ago

Yes, 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.

Aerolfos|11 days ago

It'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.

GuB-42|11 days ago

The 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|10 days 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?

layer8|11 days ago

It 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|11 days ago

Prod deployments usually have a tag associated

bandrami|11 days ago

The model works well if you're developing version 3.2 (which is not ready yet) but also non-trivially maintaining 3.1.

tremon|11 days ago

Exactly. 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|11 days ago

This, 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.

taeric|11 days ago

The 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.

just6979|10 days ago

The 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.

pragma_x|11 days ago

I 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|11 days ago

having 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|11 days 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.

globular-toast|11 days ago

Yeah, 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|11 days ago

When 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.

keithnz|11 days ago

The 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.

fooker|11 days ago

What 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.

db48x|11 days ago

Many, 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.

bombcar|11 days 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.

UqWBcuFx6NV4r|11 days ago

[deleted]

m12k|11 days ago

I'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.