
Please stop recommending Gitflow - gortok
https://georgestocker.com/2020/03/04/please-stop-recommending-git-flow/
======
simonw
The approach that has worked best for me is pretty simple.

Master should always be in a deployable state.

Any commit that lands on master must include unit tests that demonstrate that
it works (or at least doesn't break anything).

Incomplete features that will take more than a week or so to develop should be
merged to master early protected by feature flags. This avoids long running
branches.

I like squash commits: build a feature iteratively in a branch + pull
requests, squash to master once it has the tests and documentation bundled
together with the implementation. This gives you linear history.

People who prefer to review smaller commits can do so in the pull request -
it's only the finished item that gets squashed into a larger commit.

~~~
gouggoug
> I like squash commits: build a feature iteratively in a branch + pull
> requests, squash to master once it has the tests and documentation bundled
> together with the implementation. This gives you linear history

I disagree with squashing commits when merging to master, here's why:

Your commit history is what you will use later down the line (think 6 months,
a year, 2 years later) to find a very nasty yet incredibly subtle bug in your
application.

Imagine said bug was introduced by a feature that took about 1 full month to
code, introducing 1000 lines and removing 500.

That feature was probably made of many small commits (say, 25 commits total),
on a feature branch called "super-feature".

If your developer cared at all about making "atomic" meaningful commits, each
one of those commit will be introducing a small very well defined subset of
the entire "super-feature".

The "super-feature" will in the end be the result of all of those commits
together.

Squashing that history of 25 commits, will create one giant commit of 1500
changes. Have fun finding where in those 1500 changes that little nasty bug
was introduced!

Instead, if you hadn't squashed, you simply use `git bisect` and find in no
time that the bug was introduced by the 12th commit of that branch, which
itself was a small commit of 1 little change:

    
    
      diff --git a/statistics.php b/statistics.php
      index 69e435aa9f..46666daa93 100644
      --- a/statistics.php
      +++ b/statistics.php
      @@ -8,7 +8,7 @@
    
      - a = b + c
      + a = b - c
    
    

If you want a very linear history, enforce a:

    
    
      git rebase master super-feature
      git merge super-feature --no-ff
    

This will rebase your branch on top of master, but, when merging, the `--no-
ff` option will tell git to create a merge commit. This merge commit will make
it very clear that the code branched off and was later merged back into
master, yet, it will keep the history linear.

=======

TL;DR: Your commit history is _as important as_ your code! Don't squash it
away! I wish github never introduced that feature and instead developers were
taught how to create a meaningful history of commits.

=======

~~~
bArray
> Squashing that history of 25 commits, will create one giant

> commit of 1500 changes. Have fun finding where in those

> 1500 changes that little nasty bug was introduced!

100% agree, the only purpose of this is to make "pretty graphs" at the cost of
destroying the history of the code changes.

I prefer to write small commits with simple messages that explain exactly what
that change does. Sometimes it costs some time in Git Gui selecting the lines
that make up the commit, but ultimately it's worth it.

~~~
mcv
I notice that some people seem to care more about pretty history than about
useful history. I'm not a big fan of rebasing for this very reason: it changes
history, which can misinform about what was really done. It can introduce bugs
in commits that didn't initially contain them.

Though I will say that git has one big glaring problem with merge commits:
they are effectively black boxes, and when you've have a big merge conflict,
many git tools don't tell you how that was resolved in that merge. I recently
came across a merge that wiped out some of my changes with no clear reason
why. I redid that merge and there was no merge conflict at all, so it's still
a mystery what happened there.

Still, rebasing has caused far more problems in my experience. It's only
suitable for trivial, local cases and never on commits that have already been
shared (pushed).

~~~
mdtusz
I think a lot of the fear of rebasing comes from not fully grokking what it
does, and not rebasing often enough.

My workflow typically involves rebasing my local branches on master every time
I switch a branch or start a work session, so typically conflicts that need to
be resolved are very clear and small things (e.g. someone else adds a case to
a switch statement in the same place your branch does).

The biggest benefit to this that I see is that your diffs are then much more
clear in what they're doing, and you have the option to update the commit
message to reflect the conflict resolution if required.

That said, if you have a big feature branch and try to rebase it after a month
vacation, you're gonna have a bad time.

~~~
mcv
Daily local rebase on master is really the only acceptable use I know for
rebasing. It's not just after a month of vacation, but simply when your local
branch has a lot of commits, that rebasing can become very painful, as you may
have to resolve the same conflict over and over and over again. That must be
the circle of hell where programmers end up.

Basically you'd have to rebase after every single commit. That would keep it
the most painless, I guess. But I can also just do a single merge and I'm
done.

~~~
AstralStorm
Git-rerere and smart merge tool like p4merge help a lot with this rebasing
problem.

These are essential if you work with forced rebase mode like in Gerrit. (ugh)

You still have to be moderately careful and read the code again.

------
ryanackley
This cycle seems to repeat endlessly in our industry:

* Early adopter independently comes up with an idea that works well for his/her team.

* Writes an innocent well-written article or book.

* Idea somehow becomes dogmatic. Even for situations that don't make sense.

* After some time, people rebel against dogma because they realize it doesn't make sense for every situation.

* Original idea now considered anti-pattern even though it may still make sense for some people or situations.

~~~
Dirlewanger
Yup. It's a byproduct of software not being grounded in anything compared to,
say, every other engineering discipline. They all have the laws of physics.
Software has...a bunch of different mantras and paradigms, and for every one
out there, there's one that is its direct opposite.

~~~
btrettel
> It's a byproduct of software not being grounded in anything compared to,
> say, every other engineering discipline. They all have the laws of physics.

I think experimental evidence helps, but if you look at the physical sciences
more closely, you'll find tons of similar narratives. This is a fairly
universal human behavior unfortunately. Nonsense becomes "canonized" as I put
it, and then continues to be repeated by people until someone finally looks
into it and realizes it's nonsense and publishes an article saying so. But
unfortunately that's not always the end of the nonsense. Even things which
have been debunked can continue to be cited and used. One great example (not
engineering but the point stands):

[https://www.youtube.com/watch?v=WRoe3xXFtmM](https://www.youtube.com/watch?v=WRoe3xXFtmM)

> In one sense we won. We got our points across. People now understand that
> this research is wrong. But this 2005 article by Fredrickson and Losada gets
> citations today at 3 times the rate of our article that demonstrated that it
> was just utter rubbish.

(Note that I'm using "nonsense" as an example here, but the top level comment
was more general in that it mentions practices which apply in some situations
erroneously being applied for all situations.)

------
autarch
The author says:

> While I hesitate to say “Worrying about merge conflicts” is a valid reason
> not to pursue a branching strategy like gitflow

I do not hesitate! This is _very good_ reason to avoid gitflow.

Merge conflicts by definition require human intervention. And human
intervention means an opportunity for human error. Resolving merge conflicts
properly ranges from trivial to nearly impossible, depending on the specific
changes you're trying to merge.

Often none of the authors involved in the conflict are in a good position to
understand why it happened. One person makes a small bug fix change to a few
lines of code. But that fix required hours of research and a solid
understanding of the problem. Meanwhile, someone else is doing a refactoring
of that same code in another branch, unaware of the bug.

Neither of these two people may be in a good position resolve the conflict.
The bug fixer doesn't understand the refactoring, so they don't know how to
apply the bug fix in the new code. The refactorer doesn't understand the
subtleties of the bug fix and the code being fixed is just gone in the
refactor. It's going to require the two of them working together to fix this,
and it may took several more hours and they still may not get it right. And
that's the best case! Realistically, one person will muddle through the merge
and hope that things still work properly.

Of course, merge conflicts are a fact of life in _any_ version control scheme
without exclusive locks (remember RCS?), but minimizing them is a very valid
goal.

~~~
mumblemumble
I don't just worry about merge conflicts. I worry about merges that generate
no merge conflicts, but still create bugs because of the way changes on two
different branches end up interacting with each other at run time.

In general, I feel a lot more confident with using feature flags and the like
to keep work in progress from prematurely going live than I do using branches
to do the job.

Or, if I could take a stab at saying it pithily: Having your code be
continuously integrated is a prerequisite of doing continuous integration.

~~~
Polylactic_acid
I'm not sure feature flags fully solve this either since someone doing work on
another feature is just going to ignore the path of a not ready flag.

~~~
mumblemumble
No, it's certainly not perfect. But, not being aware of a solution that's
perfect, I've had to content myself with something that's merely better than
anything else I've tried.

------
alexhutcheson
It's honestly crazy how much time we as a community of software developers
spend thinking about Git. We spend time training new engineers how to use it,
we spend time researching how to un-wedge ourselves when we run into problems,
we spend time standardizing preferred workflows and giving feedback when
someone doesn't follow them, and we seem to spend time debating the proper
branching workflows within each team or company once every couple years. When
all those costs are added up, I felt more productive using svn. I can't be the
only one.

Ultimately I think the problem is that Git solves too many problems - it
provides a very general data structure that can be used in a lot of different
ways, but the tooling itself is mostly agnostic to how you want to use that
data structure. Teams can define preferred workflows on top of that, but the
tooling itself doesn't enforce the workflow, or provide any specific
affordances that help you properly comply with the workflow. Instead, every
developer is supposed to keep the workflow in their head, and make judgement
decisions every time they interact with it.

The cost of this is huge. We're sorely in need of opinionated tooling that
sits above Git's data structures and makes real-world workflows simple to
follow correctly, and difficult to mess up.

~~~
PaulStatezny
> It's honestly crazy how much time we as a community of software developers
> spend thinking about Git.

It's funny, I can't remember the last time I had to give serious thought about
how to use git.

Sure, there's a learning curve. When I was just starting out, I didn't get it
all right away. But it's been years since I've thought much about branching
strategies and stuff. And I don't get myself into "terrible messes" that take
hard thought to get out of.

Not saying you're 100% wrong. But it doesn't line up with my experience.

~~~
Supermancho
If you've never had a git commit FAIL (eg [https://github.com/okonet/lint-
staged/issues/565](https://github.com/okonet/lint-staged/issues/565)) you
aren't very experienced with git. By your description, you've probably just
used it casually a lot. You don't do anything complicated and conclude that
git isn't complicated. Given the history of working with:

* Submodules

* Binaries

* Large Repositories/branches

* A disparate set of development platforms/clients

* Git auth/credentials

~~~
alasdair_
>If you've never had a git commit FAIL (eg [https://github.com/okonet/lint-
staged/issues/565](https://github.com/okonet/lint-staged/issues/565)) you
aren't very experienced with git.

I follow Linux kernel posts on vger.kernel.org and I've yet to see Linus
complain about a git commit failing. I guess he isn't very experienced either?

~~~
tryauuum
You could be very correct! I think Linus might not be an experienced "git for
Windows" user

------
cryptonector
+1e6.

Rebase workflows are the best. We used them at Sun long before anyone called
it rebasing, long before even any VCSes had the feature in any way. It's the
only workflow that works in large codebases (monorepos, repo forests) with
thousands of developers. Merges stop being interesting very quickly once
you've got a) a large number of developers, and b) a high rate of commits on
the same codebase -- it's just too much metadata.

Linear history works like a charm and is super easy to understand (because
it's linear).

Nobody cares about the internal history of a feature branch that has
delivered. One should only care about what mainline bugs were fixed and what
features were added -- bugs that never made it to the mainline are simply not
interesting at all to developers on the mainline (though admittedly they might
be to someone studying developer performance, but then, feature branch history
can be kept and archived, just not on the mainline).

~~~
jmiserez
I find it interesting that many people don't seem to know the "git rerere"
option [1], even experienced devs. With long lived feature branches that takes
away 95% of the frustration people have with rebasing.

Theoretically, one could also use merges on the feature branch and rebase once
at the end of development (as git will auto-remove all merge commits during
rebase), but that only works well if you have just a single commit between
merges on the feature branch.

[1] [https://git-scm.com/book/en/v2/Git-Tools-Rerere](https://git-
scm.com/book/en/v2/Git-Tools-Rerere)

~~~
cryptonector
My fastrebase script is even better[0].

[0]
[https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee650...](https://gist.github.com/nicowilliams/ea2fa2b445c2db50d2ee6509c3526297)

------
trixie_
I'm in the camp that rebasing is unnecessary and useless for large projects. I
work in a code base with 50 other devs, no one is reading the commit log line
by line, there are 100 commits per day. We use JIRA and have to prefix our
commits with TICKET-<ID>. If I want to see the commits for a ticket, I filter
the git log on that. If I want to see the combined diff for the commits, I
open up the PR in JIRA.

Squashing public commits I'm also against. People say it 'cleans' the history.
I would say it erases it. Who, when, why - all gone. For what? to save a few
commit lines? Like I said, our commits are tagged with the ticket number
already, if you want a summary of what the changes were and all the commits
that were part of it, you open the ticket, or filter the git log on the
ticket. No need to move commits around in the history, they show in the same
order when you apply a filter.

~~~
jsnk
I'm curious how your commit history looks. Doesn't it have tons of useless
commits like "removing comments", "forgot semicolon" etc?

Here's Linus Torvalds' thoughts on rebasing.
[https://yarchive.net/comp/linux/git_rebase.html](https://yarchive.net/comp/linux/git_rebase.html)

~~~
trixie_
I agree with Linus, "you really shouldn't rebase stuff that has been exposed
anywhere outside of your own private tree"

I have no problem if you want to locally squash your commits. Just don't
rewrite public history. It's not worth it. At our commit rate, no one is
reading the combined history logs without filters first.

~~~
nickysielicki
You never run git log on a single file or directory?

~~~
Kwantuum
That would qualify as a filter...

------
iamleppert
I agree 100%. I too tried Gitflow on many different projects, with different
skill levels of teams and we ended up pulling the plug on it and going back to
"master is always deployable/production". Developers work in feature branches
that are small and atomic, with frequent merges into master with corresponding
deployments. Breaking master is a critical blocker issue. There's no need for
tags, complicated release schedules or processes following this model and it
scales from a team of 1 to a team of 1000, I've seen it done.

Gitflow doesn't work in a CI environment on a modern software application that
has good testing culture and systems that are resilient to failure.

Tools and processes work a lot better when they work for you, not the other
way around. KISS.

~~~
jmvoodoo
I have used gitflow successfully for some time (starting when it was first
announced and there wasn't anyone complaining about it). I've always done
"develop is always deployable to production" and the only thing we used master
for was rolling back (extremely rare), and the only thing we used release
branches for was demos or documentation before a release went out. We had CI
built against develop but also every feature branch and every PR. We also
leveraged static analysis the same way, and at one company even ran automated
pen tests on develop and PRs.

I don't know if I fundamentally misunderstood gitflow but this was my take on
it from the beginning and I've never had issues with it that made me want to
jump ship.

We didn't use hotfix or support branches, and we never really used tags for
anything either. Not using them didn't cause any noticeable overhead.

The nice thing about git-flow in my opinion is that you can implement it
without all of the CI stuff, then add that later over time. This is a godsend
when you take over a legacy product with little to no test coverage and no CI
pipelines.

I've also never run into a ton of merge conflicts, but the largest team I've
had is 70 people so maybe it breaks down at some point that I haven't
experienced yet.

~~~
ulisesrmzroche
How can develop be always deployable to production? That doesn’t even make
sense in English.

~~~
rovr138
Simple. It’s either the wrong label or we are missing info on the setup.

In my setup I have a develop branch and the idea is that anything in it can be
deployed to prod. Of course, that is if nothing fails.

If nothing fails, it merges with master (what’s actually on prod).

~~~
ulisesrmzroche
You need to learn English. What’s the definition of in development?

------
tootie
I don't understand the argument here at all. Git flow seems pretty orthogonal
to concept of branching lifespan. We did the "merge early, merge often"
approach with SVN 15 years ago and it was fine. We do git flow now and it's
fine. It meshes perfectly with agile development where you work on the
smallest feature set that adds incremental value. That means your branch only
ever lives long enough to do one tiny thing and it gets merged as soon as it's
working and no sooner. I've been following this approach for years with dozens
of teams and it's very successful. And I've never run a rebase on purpose in
my entire life.

~~~
contractor8
What sort of repository and deployment structure are you using right now in
which it works fine? I think that will influence the outcome a lot.

I just was working with a client that used something like git-flow, where
develop was deployed to staging in order to test, master was always
production, and the codebase is largely a monorepo. Then there were a couple
other legacy repos, which also are using git-flow. It... "works", but it also
is a needless source of pain. You need to PR to develop, then PR develop into
master, and I'd inevitably get bitten with merge conflicts in the process. All
that for what gain? I saw no upside to it. Maybe if you have steady release
cycles, but git-flow never seemed to fit the whole disposable branches, master
is good to deploy dozens of times per day sort of workflow I've gotten used
to.

~~~
gwright
Continuous deployment triggered by a merge into develop is basically a
degenerate case of gitflow where there is an automated release associated with
every merge into develop.

So if you are doing full gitflow or if you are doing this degenerate case of
gitflow you still shouldn't be getting merge conflicts when releasing develop
(merging develop into master). This should basically be a fast-forward with
perhaps a merge commit for record keeping. The only way to get conflicts in
this case is if there is some other process that is changing master
independent of the "releases" from develop.

In gitflow those other changes are managed through the hotfix branching rules,
which ensures that you resolve the conflict when you close the hotfix and back
merge it into develop.

------
elyobo
I have two long lived branches, develop and master.

* major features are done in feature branches, w/rebasing prior to merge

* minor stuff directly in develop

* master is auto deployed following successful CI, whenever we merge develop in to it

* we merge frequently, but not automatically

* we tag releases manually when we do merge

It's a more minimal version of git flow. Small teams so not much problem.

We could probably just drop the develop / master split and still be fine, but
would force all changes to be in feature branches instead.

~~~
pmoleri
> * major features are done in feature branches, w/rebasing prior to merge

Rebase in a feature branch, that can be long-lived and have many commits,
seems like a painful experience to me.

You can end up solving the same conflict more than once, or even solving
conflicts that don't exist in the final result. no-ff merge commits are
usually easier to solve.

Am I missing something? Is there an easier rebase strategy?

~~~
Double_a_92
Same. I think people just have different ideas of what "long lived" means. To
some it might be a few days of work, to some weeks.

We actually merge the master into our long lived feature branches first. Then
run all the tests on that branch, if it's good it can be directly merged into
master (master is locked, and you need permission to commit anything to it).

~~~
pmoleri
I think so. Sometimes we have long-lived branches with multiple contributors
for new features. Is this some kind of anti-pattern? We don't use feature
flags, they seem hard to maintain and restrictive in terms of what you can do
(e.g. structural changes). OTOH, because we're a small team, when there's a
lot of work in a new feature branch there's little work on master, so there's
little hassle there too.

------
honkycat
In my opinion the problem with GitFlow and a lot of other git workflows is you
end up holding a bunch of state inside of your git branches which is hard to
decipher, complicated to manage, creates work for people ( with merge
conflicts, and managing feature branches that need to be merged ), and is
capable of losing progress.

My solution: USE FEATURE FLAGS. Keep the list of features and refactors you
want deployed in a format that is easy to audit and reason about.

I like the Microsoft branching strategy: [https://docs.microsoft.com/en-
us/azure/devops/repos/git/git-...](https://docs.microsoft.com/en-
us/azure/devops/repos/git/git-branching-guidance?view=azure-devops)

Basically:

* Create feature branches.

* Merge into master when the feature is done. For long lived branches: Don't keep them around. Merge them into master and put them behind a feature flag.

* Deploy to environments using release branches.

* USE FEATURE FLAGS. Do not hold state in your github repo/branch merge status. Do not control features and refactors inside of your git branches, only merging the code you want to be deployed. Instead, put them behind feature flags and activate them using code.

There is a good book on the topic of feature flags titled "Effective Feature
Management" that is a good overview. Feature flags do not have to only protect
features. You can put refactors behind feature flags as well, or really
anything.

~~~
jon889
I've never understood how Feature Flags can be used like that. For example say
I have a button component that needs to be refactored and it used in hundred
of places throughout the codebase. How can I use feature flags to prevent a
long running branch? (Serious question :))

Do I keep both implementations around and everywhere a button is used switch
on a flag, that seems quite messy, and I have to go and delete the switches on
the flag everywhere when I'm finished. Or I could abstract that out into a
function or use dependency injection to choose the right button, but that just
seems to be adding another layer of complication, that some future dev is
going to wonder why exists when there is only one implementation of the
button.

Compared to having a long running branch that I periodically merge the main
branch into to keep up to date with the current development without impacting
the code that is due to released in 2 days (as it is every 2 weeks)

~~~
gwright
Regarding your button question:

You do need some sort of seam at the point of use so that the feature flag
logic can be hidden behind a lookup function. For example in Rails you might
include your button code via a partial template. You could use a view helper
to provide the name of the partial and that helper could respond with
different names depending on the feature flag:

    
    
        <%= render partial: primary_button %>
    
        def primary_button
          feature_flag_enabled ? "new_button" : "button"
        end
    

Obviously the particulars are going to be different in different frameworks.

------
CurtBurbinger
"Any branching model you choose is ultimately meant to make humans work
together more easily to produce software"

There are things in this article I agree with, and things that I don't, but
the quoted point is something that I wish could be universally understood.
Some developers commit to the dogma of one blog post or another and forget
about the fact that the whole thing is for the _people_ who are writing the
code. Branching strategy should help to optimize workflows and minimize
friction, regardless of how badly bastardized your approach is vs. its source
material.

~~~
hinkley
I can't seem to get people to agree on the point of unit tests either.

Nowhere is this more apparent than when we argue about test coverage %'s.
There's a whole bimodal distribution of people very wrong for very different
reasons.

~~~
gumby
I find about half the people don't see the point (mainly can't be bothered). I
can cut that group by about a third by telling them "the tests keep other
people from breaking your code"

(Personally I think tests keep _me_ from breaking my and others' code, but I
don't tell them that)

~~~
gwright
Always helpful to think about your future self as that other person.

------
contingencies
_We don 't use any branching._ Git is complicated enough to explain to non-
software engineers without branching. We treat all commit versions equally for
CI/CD. As most people are not software engineers, this seems a reasonable
course of action if a project encompasses non software elements. We have non
CI/CD testing anyway (nontrivial hardware projects require much more external
process).

 _For releases we assign versions without tags_ , instead using replication of
a subdirectory tree under a version number. This ensures all versions are
available locally to all users without adding any access complexity.

This is basically optimizing for simplicity for the users.

------
_hao
At work we were using TFS when I joined. I managed to win the battle and
migrated everything we have to Git, but for some reason they wanted us to
follow Gitflow (other parts of the business were on Git and were using it). A
couple of horrible releases, regressions and lost functionality (merge errors)
later I managed to push everyone into using Microsoft's Release Flow[1]. We
haven't had a single regression since then and everything in the process is
more or less smooth.

The funny thing is I've used Gitflow successfully before in another job, but
nowadays I'm mostly scratching my head how it ever worked correctly. It's so
overly complicated. It would never be my process of choice.

[1] [https://docs.microsoft.com/en-
us/azure/devops/learn/devops-a...](https://docs.microsoft.com/en-
us/azure/devops/learn/devops-at-microsoft/release-flow)

~~~
twhitmore
I've seen Git Flow fail in even relatively small software houses.

I've seen sensible trunk-based development with feature & release branches
(equiv to what MS call 'Release Flow') work well from small to huge (400+
devs) environments.

------
kunglao
Something that really surprised me is how anyone has issues with git work
flows. Git is one of my favourite software and I think it solves version
control and collaboration issues beautifully. I can unhesistently say only one
of the teams used git recall really well and we didn't agree on a work flow or
no one was dogmatic about it. Each seemed to just know what they were doing.

I think just create your own branch always for your work is a good idea. Use
merges to take or give contributions (reduce using complex things like
rebases). If branching on sub branches, try not to squash merge. You can't
avoid conflicts all the time but just sticking to branching and merging
reduces this problem quite a lot. Team size has been about 12 engineers not
sure how it'll impact team of much larger projects. But I have also
contributed to open source projects using this same techniques without an
issue.

------
erik_landerholm
We implemented Gitflow almost exactly how it was described in the original
blog post a while ago. It was simple and we built continuous deployment around
it and it posed 0 challenges in that department. It was much harder to change
culture and build a process and systems to actually do the continuous
deployment than Gitflow ever caused. I disagree with about everything in this
article.

------
bavell
It seems to me that most of the authors objections stem from 100% strict
adherence to git flow, which IMO is the wrong approach.

I loved the concept of git flow when I first read that legendary blog post. I
learned a lot and adapted it into my own development workflow. I've bounced
back and forth over the years in how strictly I adhered to the One True Way
(tm) based on how well it worked for me in actual projects.

IME I think the best approach to git flow is to learn and understand it and
then adapt it to your project's workflow, as opposed to strictly adhering to
every tenet of git flow. I have multiple projects using different "amounts" of
git flow - e.g. a large project with dev, qa, hotfix and release branches vs a
small personal project with only master and dev.

~~~
dvdgsng
> 100% strict adherence to git flow, which IMO is the wrong approach.

I agree, as with most things, there certainly is room for flexibility here.

One problem I've seen repeatedly occur when migrating to git flow is a
misconceptions about 'bugfix/' branches, which are intended to be used when
stabilizing a 'release/' branch. However devs use that prefix for every bug
they find which is not related to a story/feature. And to be honest, they are
right to do so. The naming is just bad here, since the term 'bugfix' is so
generically used, it's not very intuitive to use it only for release branches.
So I've come to the point where I would agree to use 'bugfix/' for regular
bugfixing if the team/company is comfortable with it, even though it is
opposed to original gitflow.

------
jconley
In my opinion this is one of those "pick the right tool for the job" problems.
If you have a constraint that forces you to have multiple versions in
development and maintenance simultaneously then Gitflow works well. This is
especially true for things with long QA cycles. If you have a SaaS business
and pushed code can go straight to production after automated tests, then
don't bother with the management overhead of the versions.

In personal experience... We use Gitflow for our software that ships on our
IoT device where we do monthly releases and multiple weeks of QA/reliability
testing. Of course, this is coupled with a slow rolling canary release process
-- nobody wants customers to be forced return a device due to a bug that can't
be fixed over the air.

We also use it on our mobile app and it works well. Again, this is a situation
where we have to have multiple versions in development simultaneously. One in
"release mode" doing critical bug fixes only as it goes through QA and
internal in-home acceptance testing and one for "v-next".

Some 20 years ago we used to do roughly this same process for releasing
software on CD's. But, no git back then so no "Gitflow"...

We don't use it for various services and internal tools that can get by
without such rigor around versioning. Just simple branch -> PR -> automated
test -> merge to master from PR -> automated test -> deploy.

Use the tool/process with the least overhead that manages what you need
managed.

~~~
alasdair_
>If you have a constraint that forces you to have multiple versions in
development and maintenance simultaneously then Gitflow works well.

Because of the way App Store approval works, and the fact that it can take
weeks from initial submission to full rollout, and that many users never
upgrade their versions, strongly implies that using something like gitflow
would work well for teams delivering appstore binaries.

------
deckar01
Most of that blog post's workflow seems like pretty normal merge request
development. Separating develop and master is where most of the complexity
arises. The reported advantage is "the develop branch is cleared to receive
features for the next big release". I have never ran into a problem with
features needing to land in master before a release is cut, likely because I
have never scheduled releases and I think most projects don't. Even if they
did, the project has to be pretty massive to have a feature ready, but
scheduled for a future release and also be blocking the development of another
scheduled feature... If your project is that busy, it is seems like a
reasonable workflow. Everyone else can probably just treat master as their
develop branch and everything else in the article is pretty good advice.

The only other oddity I see is treating hot patches different than feature
branches. In my experience, hot patches are no different than feature branches
in projects that use master as the branch to deploy from. In projects that
perform manual QA, I use a branch for each deploy environment to stagger
rollouts, the final branch being for the production environment. In that case
it makes sense to start a merge request on the production branch before
master.

------
daenz
Speaking for myself, git flow _is_ intuitive. It is something you also have to
practice discipline to adhere to. That is not simply "additional cognitive
load", it is just like any other process worth following.

Their criticism about "tripling the number of merge conflicts" because of the
number of branches doesn't make any sense. As long as developers are doing
development work and committing, regardless of what branch they're committing
to, there is potential for conflict. It might not be a "merge" conflict in the
sense of two separate branches, but it will manifest as a merge conflict in
pushing the local to the remote. The potential for conflicts stay the same.
What git flow gets right here is it isolates logical workflows from each
other, so people working can work for as long as necessary without conflict.

>Gitflow abandons rebasing

Rebasing is a nightmare for distributed work, and in my opinion, only makes
sense in limited circumstances where your code is not already pushed and
pulled in multiple locations.

>Continuous delivery is a practice where the team release directly into
production with each “check-in” (in reality, a merge to master), in an
automated fashion. Look at the mess that is gitflow and explain to me how
you’re going to be able to continuously deliver _that_?

Every modern CI/CD framework can run automated jobs after a merge into master,
so I'm not sure what the criticism here is?

>Have you ever _tried_ a complex branching model like gitflow with multiple
teams, and hoped for everyone to be on the same page? Can’t happen.

That is less a criticism of git flow and more a criticism of any software
organization that tries to have repeatable deployments with many services.
It's a difficult problem in general, and not one that git flow is attempting
to solve in the first place. You will have that problem regardless of if you
use git flow or not.

I could go on but there's a lot here. It sounds like the author is very
frustrated and annoyed with git flow, and perhaps is used to cowboying code
(the desire for frequent rebasing give me a hint to this) without regard for
the impact on other developers. I've worked with people like this, and they
often provide no alternative solutions, just frustration and resistance to
following an imperfect process. It's a rant without much substance.

~~~
zokier
> Every modern CI/CD framework can run automated jobs after a merge into
> master, so I'm not sure what the criticism here is?

The criticism (and the one thing I can sort of agree on) is that with git flow
you are not merging to "master" on a _continuous_ basis. Select quotes from
the nvie post describing gitflow:

> When the source code in the develop branch reaches a stable point and is
> ready to be released, all of the changes should be merged back into master
> somehow and then tagged with a release number

> The essence of a feature branch is that it exists as long as the feature is
> in development, but will eventually be merged back into develop (to
> definitely add the new feature to the upcoming release)

> By doing all of this work [release prep] on a release branch, the develop
> branch is cleared to receive features for the next big release.

------
Buttons840
> If you pursue gitflow, you’re gonna have to give up rebasing. Remember,
> rebasing does away with the merge commit — the point where you can see two
> branches coming together.

I disagree with this. You can rebase your branch and then do a "no fast
forward" merge. You'll end up with something like:

    
    
        * Merge commit
        |\
        | * My branch commit 3
        | * My branch commit 2
        | * My branch commit 1
        |/
        * Base
    

Notice I have not "done away with the merge commit".

When you rebase your branch on top of "Base", and then try to merge, git will
by default do a fast-forward merge, but you can prevent it from doing so.

It is as though you created your branch, did your work, and then merged it
back in so quickly that no other branches were created in the meantime, and if
we ignore what I personally did on only my own computer, then I am still
following Gitflow.

~~~
giancarlostoro
I dont even get why people rebase for a merge. I never did this and I get the
entire history not a distorted version of it. On top of which I can go back
between commits and even revert a very specific commit.

Reality is everyone prefers to organize code differently I prefer to have all
the commit history. It is more meaningful to see all the files involved in a
single stage of a commit than potentially multiple changes in one PR all
blended together.

~~~
alasdair_
I hate rebases because they create multiple hashes for the same logical
commit. It confuses the crap out of me sometimes. Also, they tend to involve
more manual processing, and thus human error, then merges.

~~~
jmvoodoo
This. I've had to spend time fixing history after a Jr engineer did a bad
rebase. After a few episodes of that I decided I had to either stop hiring Jr
engineers, have them always supervised by a Sr engineer, or stop rebasing.

I stopped rebasing.

~~~
Buttons840
You'd be better off blaming the force push rather than the rebase. A rebase I
do on my computer will not affect you unless I force push.

I think it's completely reasonable to ask all developers to get a second
opinion before force pushing.

------
an-allen
Source repositories are all about managing complexity. The more unmerged code
you have from your releasable branch... the more complexity you have being
held in the source repository.

In the field I've seen git-flow lend itself to having trouble handling
releasing some features and not others that have already been merged into a
release or environment branch. This leads to cherry picking or more complex
merging trees. With trunk based development, once a thing is merged to master
it is shipped.. so it keeps the complexity being held in unmmerged branches to
a minimum.

------
oweiler
git flow never made sense for me. Because of the complexity some devs would
always mess things up or ignore the branching altogether. Merging all the
related branches into master when doing a release took multiple days and often
introduced subtle bugs.

Switched at some point to GitHub flow and never looked back.

~~~
combatentropy
> Merging all the related branches into master when doing a release ...

\--- doesn't sound like Gitflow. In Gitflow, the topic branches have been
merged into the develop branch first, as they were finished. In contrast,
merging into master is a merge from a single branch. You branch from develop
into a release branch. Then you merge the release branch into master.

~~~
alkonaut
What if you have multiple ongoing release (maintenance) branches whose changes
should all be merged to master and develop? It quickly becomes messy (but to
be fair so does most alternatives).

------
aaanotherhnfolk
My company uses gitflow and releases daily from a monorepo with a team of 40
devs. Some of us rebase. Everyone is happy.

I think that disproves just about every point in the blog post.

I have no idea what non-obvious thing, if any, we're doing to make this work.
Then again I don't think gitflow is complicated either.

~~~
IanSanders
I think the main point here is that it doesn't work for everyone, and is not a
silver bullet. (Which is evident from comments)

------
combatentropy
Gitflow didn't just pop into the head of Vincent Driessen. It seems he curated
an opinionated selection of the options from the book _Pro Git_ ([https://git-
scm.com/book/](https://git-scm.com/book/)) and I wouldn't be surprised if many
projects were already using something like it to various degrees.

I went for many years with only a master branch and sometimes a develop
branch, because I often worked alone. It took me years to venture into
branching at all. Before Git I used Subversion. I don't think we branched
once. But easy branching is one of Git's distinguishing features. For me,
branching was like learning a programming language. At first it's mindbending
and intimidating. But with reading, practice, re-reading, and more practice,
it can eventually become second nature. The crazy diagram that George Stocker
holds up makes perfect sense to me now.

I was forced to adopt Gitflow when I joined a bigger team. But now that I have
learned it, I kind of like to use it even when working alone. Topic branches
remind me of functions, in that they are small and encapsulated. I can
concentrate on a narrow range of code and feel safe. The eventual merge might
have conflicts, but they are soluble. And the way that feature branches stem
from develop while bug-fix branches stem from master, and how you have a
release branch to freeze features without freezing work --- I don't know, it
feels very safe and structured.

However, yeah, like Stocker says, it may be too much ceremony, especially if
you're just starting out. I like to tell people to ease into it. Stop when it
hurts.

~~~
shagie
From my days working at a perforce shop... Advanced SCM Branching Strategies
was something that I was familiar with.
[https://www.vance.com/steve/perforce/Branching_Strategies.ht...](https://www.vance.com/steve/perforce/Branching_Strategies.html)
(from '98).

The essence of it is establishing different roles for different branches.
mainline, development, maintenance, accumulation and packaging.

With those roles in mind, when I was introduced to git flow it made sense -
mainline is develop branch; development and maintenance roles are done in
feature branches. Accumulation isn't one that is seen too often but should be
kept in mind, and the release branch is the packaging role.

These ideas have probably been realized time and time again.

The conclusion of the paper:

> Planning and analysis are critical to the success of any SCM system. A
> branching strategy motivated by a risk-based analysis of the organization's
> development needs will provide a strong foundation. Incorporating the
> concepts of branch roles, codeline policy and codeline ownership will assist
> in performing the required analysis. Application of the principles of
> branchpoint, merge policy and branch life span will ensure that the
> parameters governing codeline policy are properly and completely addressed.

> Once the branching strategy has been formulated, the organization can
> implement the customizations required to make the SCM tool suit its
> environment. Until SCM systems have reached sufficient maturity to address
> the larger issues of policy, adopting the practices put forth in this and
> other papers will help an organization achieve success in their software
> development endeavors.

------
phodge
I've never liked git flow due to:

A) the way it abuses the commit DAG: you never merge master directly back to
develop, and so your tags don't become ancestors of the commits on develop
until some timer later when an unrelated hotfix is branched from master. E.g.,
you can't rely on "git branch --contains v1.0.1" to tell you which branches
do/don't contain the 1.0.1 hotfix because the hotfix branch was merged to
develop, but not the merge commit that was tagged as 1.0.1.

B) its blatant disregard for one of the most basic software development
principles: when you want to deploy a new version of your software, you test a
specific a revision of your code and that's the revision that you deploy. With
Git Flow, you go to great lengths to ensure your release branch is isolated
from other work for testing, but then you merge to master and deploy the merge
commit instead of the commit you just tested.

------
snapetom
When I first researched git, this blog post came up. It's been around forever.

My first thought when reading it, though, was, "huh, we seem to be doing that
with SVN already." Indeed, gitflow just seems to be a popular SVN flow ported
to git.

Looking at the diagrams, there seems to be a lot of branching and merging, but
in practice, it's far less than merge early, merge often. In using SVN,
though, you can see why. SVN thrived in a day with more large, monolithic
codebases. Further, branching in SVN was _heavy._. It made a copy of the
entire codebase. It wasn't fun because it took so long. Gitflow emerged from
an SVN world.

Nowadays with microservices, modular codebases, and CI/CD, a merge early,
merge often approach with git makes more sense. There isn't nearly the
overhead or pains of branching and merging with git as there is with SVN.

------
Myrmornis
100% agreed. The workflow suggested in the viral blog post is far too
complicated, even for experienced teams. But in practice what happens is that
the teams who are most likely to base their git practices off some random blog
post instead of off their own experience are the least experienced teams.

------
earthboundkid
I recommended avoiding Gitflow back in 2018:

> There are more complicated systems for branching like Git flow that have a
> separate “develop” branch and distinguish between “features” and “hot
> fixes”. These systems are fine if they fit your use case, but if a project
> releases code quickly, the level of complexity involved in Git Flow is
> unnecessary.

> Ideally, branches should be short lived. One strategy to allow merging a
> branch before a large feature is fully completed is to create a feature flag
> that lets the production system have the new code in it but in an inactive
> state.

[https://blog.carlmjohnson.net/post/2018/git-
gud/](https://blog.carlmjohnson.net/post/2018/git-gud/)

------
tomerv
The article claims that "gitflow abandons rebasing", but this is simply not
true!

In my team we use gitflow with rebasing. In fact, the original gitflow
implementation comes with rebasing support built-in (as a flag for the "git
flow feature finish" command). We just modified the script to enable it by
default.

Another thing we changed is dropping the "master" branch, since it didn't
provide anything useful.

Now, you could claim that this means we're not really using gitflow, due to
all these modifications. But the fact is, I still give this article as
mandatory reading for new developers in our team, and it's still a great
introduction for working with feature branches. I'll continue to recommend
gitflow.

~~~
Silhouette
_Another thing we changed is dropping the "master" branch, since it didn't
provide anything useful._

This is the one thing about Git Flow that I never quite understood. Feature
branches, great. Main develop line, sure. Release branches, OK. But what is
the advantage of maintaining a master branch that gets some nominal end point
for releases merged in and tagged?

In reality, one of the main advantages of a Git Flow style of workflow is that
it doesn't assume you can just conveniently forget history, maintain a single
current version of your product, and deploy changes on a whim. Instead, you
can maintain a normal process for new development, but also keep control of
old releases and of release processes that might involve significant extra
steps. But all of the latter benefits come from using release branches, not
the odd way of merging from those branches to master, which isn't at all used
in the conventional way in Git Flow.

Indeed, the master branch implies a linearity of releases that probably
doesn't make much sense for a lot of projects. You might need to push out
something like a security fix for several older versions, which is easily
represented by making a new tagged public release from each of the earlier
release branches, but then what even should be merged to master according to
Git Flow?

------
ses1984
Git flow is complicated. So is software. If you work at a place that still
ships software instead of just running services, you need something more than
continuous delivery and a trunk based workflow. If you provide services, you
need to care about at most 3 versions of your software at the same time: the
version running in production, the version before it, and the version after.

If you ship software you might have to care about every version you ever
released to in the last 2 years plus that one super old version your second
customer is still using because they refuse to upgrade and shit you need to
fix a critical vulnerability that was just published in it.

Trunk based dev doesn't cut it in that world.

------
ramzyo
The most salient points for me were actually made in the last paragraph. IMO
would have improved the article to put this at the top rather than at the
bottom.

> The crucial point I’m making is to is ask questions of your team: What
> problems will this branching model help us solve? What problems will it
> create? What sorts of development will this model encourage? Do we want to
> encourage that behavior? Any branching model you choose is ultimately meant
> to make humans work together more easily to produce software, and so the
> branching model needs to take into account the needs of the particular
> humans using it, not something someone wrote on the internet and claimed was
> ‘successful’.

------
hinkley
I used a watered down version of gitflow on a project with heavy customer
involvement.

Instead of doing the whole thing, we had feature branches (which I still
hate), master, and one more branch for the stuff we were showing to the
customer. Who sometimes would decide they didn't like what they asked for and
please don't push this to production.

With the exception of hotfixes, master was always just a certain number of
commits behind the working branch.

Very aggressive use of dark launching of features could also solve this
problem, but we've had our share of problems with that strategy too (Sprint-
obsessed thinking makes it difficult to go back and clear out old conditionals
once they've settled)

------
zokier
One would think by simply looking at the picture that gitflow is not well
suited for processes that do not involve distinct releases. In other news,
SaaS is not the only model in the world and CD is not always possible.

------
freetime2
My team uses git flow as the basis for our branching strategy. We’ve
streamlined things a bit over the years as we’ve found we didn’t need all the
flexibility/complexity in that model, but we’re still using a develop branch,
feature branches, release branches, tagging our releases, etc.

It works fine for us, and we spend very little effort on branching or merging.
I wouldn’t hesitate to recommend git flow as a starting point to any team.
Just make sure you don’t follow it dogmatically... if there are tweaks that
you can identify to better serve your team, go ahead and make them.

------
411111111111111
I disagree with the article. there are pitfalls you can fall into using
gitflow, but they're not inherent to that strategy.

pointing out the obvious: a master branch is technically redundant for
gitflow. you just need to create a tag. it however makes it easier to
visualize and think about the flow in regard to hotfixes.

next obvious point: you're just not releasing quick enough if merge conflicts
become an issue with gitflow. personally, i think release branches are just
quick snapshots you can use to safely run all tests against while other
developers keep pushing features on develop. this gives you a short timeframe
to merge bugfixes into the release branch, but it really shouldn't exist for >
2 days (one day to identify issues and fix them, another to verify that
they're gone).

nor do i see any issue with continues integration, honestly... gitflow just
formalizes the way code goes into production. if anything, it makes it easier!
now you can automatically spin up new environments for release/* branches to
automatically trigger a system test suite, appending the result to the
release.

i dont get his issue of multiple repositories either... each microservice
surely has a different version, no? so for what conceivable reason would
gitflow create any issue here?

if you're a three man team, gitflow is probably unnecessary though. its meant
for bigger projects with lots of developers pushing at the same time.

------
Kaotique
We use a variant of Gitflow without a develop branch and without release
branches.

Gitflow has 2 major problems: \- develop branch that will always become a mess
over time \- release branches are never completely accepted. It is much easier
to accept features branches.

We try to merge feature/bugfix branches directly to master when they are
approved.

We have testing/staging branches that can be thrown away and re-created from
master and re-merge any feature/bugfix branches that have to be checked.

This has worked very well for the last 5 years or so and we have used it in
dozens of projects every year.

The fact that testing/staging contains no commits (except merge commits) of
its own is very useful. You can drop these branches regularly and remove any
old feature branches that became stale for some reason.

Lastly, I have seen a lot of teams that want to apply complicated Git
strategies from day one of a project where it would be much better to just
work on one master branch because too much code changes at the same time. This
will create complicated conflicts. The history at the start of the project is
not interesting. Git history only becomes useful when the project is live and
you want gradually add features or fixes.

------
photoangell
Please stop using "Please stop..." in the title of blog posts. It has a
passive aggressive, techbro culture, holier than thou ring to it. Which I find
grating.

That aside, there's not much in this article anyway. Despite trashing it in
the title, he goes on to say it might work in large organisations or those
with a long release cycle, but otherwise can't recommend an alternative.

Ok then.

~~~
StevePerkins
You would prefer:

 _" Gitflow considered harmful"_,

 _" Why I don't use Gitflow"_,

or any of the other dozen clickbait variants, then?

At the end of the day, people enjoy writing contrarian posts, and people enjoy
reading them. They have to be named something. People who use title templates
are no more annoying than people who code things they dislike as masculine.

------
bArray
I think Gitflow is the larger picture, but I think most teams can afford to
merge parts together.

I run a small team and we typically will just use "feature" and the master
branch. If it compiles and passes the basic tests, it's master worthy. If it
passes more heavy testing then it's tag worthy. Features can sometimes be bug
fixes depending on the size.

Typically we try to merge branches in less than two weeks to prevent some kind
of merge hell.

The assumption that master is somehow perfect is wrong and it shouldn't be
treated as such. In my opinion tags are really for commenting that there's
something interesting about a commit (i.e. "we ran this for 2 weeks at full
load and no issues observed"). Again, tags also don't say there are no issues,
it just says there was something note worthy.

------
rckoepke
I really wish the article covered some alternatives styles.

~~~
numbsafari
I highly recommend Trunk Based Development:

[https://trunkbaseddevelopment.com](https://trunkbaseddevelopment.com)

"A source-control branching model, where developers collaborate on code in a
single branch called ‘trunk’, resist any pressure to create other long-lived
development branches by employing documented techniques. They therefore avoid
merge hell, do not break the build, and live happily ever after."

In my experience, new/small teams do well if they stick the "Scaled Trunk-
Based Development" model until a legitimate reason to deviate is discovered
(e.g. needing to back-port changes to an older release may imply making
commits to non-trunk/master branches...).

------
rawoke083600
I use:

1\. Master should be always deployable:

2\. All features are a separate branch BUT, when merged into master they
should also have a config for ON/OFF. This has the benefit of quickly
switching between old and new behaviour(feature) as well as forcing a "module-
based-architecture" for the code.

~~~
borplk
One problem with #2 is many types of changes are impossible to toggle on/off
(I mean "change to codebase" not "product feature").

~~~
rawoke083600
True, #2 is not always feasible, but lol the dev can damn well try :P

------
globular-toast
At my current job when I started people were doing git flow. It was
horrendously complicated. I got rid of it and now everyone is happier.

The idea is really simple. You have one eternal branch, "master", which is
your integration branch. This is set to be the upstream of all other branches
during development. That means it's really easy to keep rebasing on master
every day. When your branch is ready it's merged into master (I do fast-
forward only, but that doesn't matter). When you want to release, just tag a
commit on master. If you want to maintain releases, make release branches for
these and cherry pick fixes from master. Reset the maintenance branches to
whatever release you are maintaining. It's easy.

------
Ace17
GOTO 2017 • Feature Branches and Toggles in a Post-GitHub World:
[https://www.youtube.com/watch?v=lqRQYEHAtpk](https://www.youtube.com/watch?v=lqRQYEHAtpk)

TL;DW: integrate continuously, don't use branches, use feature toggles.

------
jrumbut
I recall converging toward something a lot like git-flow because, especially
when there were hot fixes, you might get conflicts rebasing the feature branch
and conflicts again merging the feature branches, doing the work twice at
least. Additionally, it was so important everyone used the same procedure to
accomplish merges or whatnot or else there would be all kinds of problems.

Sometime ago I noticed I hadn't seen this in a while. Is this anyone else's
experience? Have people just gotten better at git or was there a major
improvement in how git handles this scenario?

If it was about improvements, has anyone written those changes up? It would be
fascinating to know how it was done.

------
Ace17
> While I hesitate to say “Worrying about merge conflicts” is a valid reason
> not to pursue a branching strategy like gitflow

Being worried about merge conflicts might be a sign that your continuous
integration might not be continuous enough.

------
Olipro
I implemented a variety of GitFlow, but with an emphasis on automation.
Normally you branch off of develop; hotfixes will be a branch off of master.

Feature branches are combined with develop before being built and tested. If
it passes, it becomes mergeable in GitLab.

all builds of develop that pass are taggable; you go into the CI interface and
specify a tag. Once deployed, master is updated by the CI to point to that
tag.

The most valuable part of this is the CI pipeline and having a solid body of
tests to ensure that changes which don't necessarily conflict in Git will most
likely be caught during test, prior to it being allowed for merge.

------
HelloNurse
Some of the criticism in the article is unfair.

Most obviously, the boundaries of source code repositories should be aligned
with released modules: if "the system becomes a manifest of the different
revisions of the different repositories" the repositories are too fragmented
(or the releases too monolithic), if "teams are independent and microservices
should be independently deployable" disparate components should not share a
monorepo, and in both cases the difficulties are consequences of bad
architectural choices, not of branching models.

------
federalemployee
Funny, I always interpreted the gray branches in that diagram to mean short
lived branches.

I just have dev and master with all my projects. Everything else is short
lived. And short lived branches are rebased and squashed. Also, all devs work
with forks to keep upstream pristine.

And there are those dogmatic about trunk development. I think if you follow
the rule of thumb of don’t let dev and master get too out of sync you don’t
need to do trunk.

------
readme
The author claims that "rebasing does away with the merge commit."

It's true that if you rebase you won't _need_ a merge commit, but rebasing is
compatible with the idea of having a point of reference between where branches
come together, and you can accomplish that by introducing a merge commit with
"git merge --no-ff" so the rebased branch doesn't fast forward on top of the
target branch.

------
heelix
We use several branching strategies - all depends on the size of the codebase
and the number of teams involved. Some work just fine with a trunk based
workflow, some need that extra bit of layers.

What I don't get is the infatuation with GitOps, where someone insists on
replacing a process with a source code repository and webhooks. Starting to
see excessive scripting/bots to talk with GIT bots...and it is so kludgy.

------
6510
In my ignorance I once pondered a model where [rather than teams] everyone
gets their own object named after them. Something like JohnDoe.sortTable(foo)

(Besides from being a stupid idea on so many levels) it seems fun to reason
about: _John doesn 't sort the table properly._ When John gets hit by the bus
you have a really good idea what you've lost. You also get to identify the
productive and unproductive.

------
sergiotapia
For the very longest time I thought I was doing gitflow (I skimmed the article
back in the day). I wasn't.

What we do is master is always green, prod ready. Good To Go. Auto shipped to
prod by our CI/CD.

Develop _should_ always be good to go. Green. Auto shipped to staging by our
CI/CD.

Then we have feature/ch1238-foobar-baz branches for every feature. Go crazy in
there, deliver a completed feature.

Is there a need for more process than this?

------
cs02rm0
I think gitflow _might_ be suited to mature product work where development is
ongoing.

It keeps coming up in my consultancy work, usually on short term projects that
either die or generally just get left to tick over where it's wildly
unsuitable. Mostly because of the way it violates that principle of short
lived branches.

------
89vision
Anecdotally, it's worked well for my current project as any other branching
model I've worked with. It allows release validation to happen while
developers continue to work on features.

The author seems to bash the workflow without offering up any solution or
alternative.

------
u801e
Gitflow is really meant for software that multiple released versions. It
allows for applying bug and security fixes to older released versions. For a
project that has a single released version, it really doesn't provide any
benefit.

------
brigandish
> Take a look at this image and tell me it’s immediately intuitive

I'm using Git, there's nothing intuitive to be found here.

On a possibly related note, I watched a talk by D. Richard Hipp (I don't
remember which one - edit: probably "Richard Hipp - Git: Just Say No"[1])
where he compared it with Git (a lot) and explained how Fossil keeps
everything, there's no throwing away of history, no need for rebasing (at
least as a workflow). It sounded nice - refreshing, even. I'm going to start
using it for some projects and see how I get on, because frankly, I'm tired of
Git and this need to strategise _saving copies of my work_ , because that's
basically what it does.

Sometimes I even pine for the days I used to version zip files…

[1]
[https://www.youtube.com/watch?v=ghtpJnrdgbo](https://www.youtube.com/watch?v=ghtpJnrdgbo)

------
artellectual
On the contrary my team and I have been having great luck with git-flow.

When I onboard a new team member I watch them struggle with git-flow and for
me that's a great thing to see because I see them learning an efficient way to
work.

Once they 'get it' everything flows smoothly, and everyone has the same way of
working which makes it very easy to see and help debug when things happen.
Communication is also consistent across all team members partly because of the
git-flow branching model. We as a team understand why / when to use feature
branch, when to use hotfix, when to cut a release etc... That's what I expect
from a team. Git flow has been great for our team and workflow.

To each their own. I guess I will continue recommending git-flow.

~~~
crehn
> I watch them struggle with git-flow and for me that's a great thing to see
> because I see them learning an efficient way to work

Maybe they're struggling because it's _not_ efficient, or intuitive?

~~~
artellectual
No they struggle because they don’t know the workflow which is what gitflow
teaches them. Once they learn it things work very well and they go on to teach
other people.

------
stared
IMHO GitFlow often works, as is a decent baseline.

When people don't use GitFlow (i.e. people starting their adventure with git,
with no supervision), very often they report to one of the above:

\- one master, and SVN-style

\- personal branches, and marges in all directions

\- even more mess

Sure, they may be projects in which a different commit/branch/merge workflow
is better. (In many projects I did some adaptations for GitFlow, depending on
the project scope, scale and skill of programmers.)

However, the original author, after a long criquite recommends nothings (to my
disappointment). So, what's the point? Going back to this "anyting marges with
anything" branch Wild West, as a baseline?

------
ptah
> Ok, so my team shouldn’t use gitflow. What should we use? I can’t answer
> that.

this article is worse than useless. it's just a rant about inconveniences
without any solutions

~~~
gortok
Thank you for that feedback!

I purposefully didn't provide any solutions in that blog post because the
entire point of the blog post is for a team to figure out what works for them,
in their context, culture, and constraints.

There are lots of different workflows:

> Feature branches

> Merge to Master

> GitHub Flow

> GitLab Flow

> GitFlow

I've also seen weird mutations where each developer reuses a branch and just
does new pull requests from that an nukes the remote each time. it's
problematic, but some teams swear by it (they also don't do any pairing or
code reviews by pulling down branches).

This isn't the first time I've heard this bit of feedback, so I think i may
put together a blog post on the different styles and their uses (and
limitations). But again, it's up to you and your team to figure out what works
in your culture, context, and with your constraints.

------
luord
While I wouldn't give as much weight to microservices—because 99% of teams
shouldn't be using them—he makes quite a few good points.

------
sitzkrieg
funny thing about git flow is that working with nvie (who coined/created it)
at gitprime, they did NOT like it in practice. we just used feature branches
go figure

------
pgporada
We use a rebase heavy workflow and I love it.

------
m3kw9
Without looking at how Gitflow works it seems like it’s some Adhoc branch
system a lot of company uses in one form or another.

------
AzzieElbab
Gitflow was just a silly blog. I can't even begin to understand how it became
dogma

~~~
shagie
One of the challenges of git a decade ago was that people created branches
everywhere and it became difficult to reason about what branches were doing
and what work should be done in them.

Git flow, at that time was the most reasonable model for git branching.

By reasonable I mean "able to be reasoned about". If I see a feature branch, I
know what should be in it. I know what should be in a release branch. I know
what the state production is in.

It isn't the best branching model - but when faced with the contemporary other
branching models, git flow let was an attempt to put some order to that.

It also works fairly well. It isn't so much that its dogma, but rather that it
is consistent and understood across different teams. The problems that it
solves in communication are more important in many places than the ones that
it causes in other parts of the workflow. Coming up with a new workflow isn't
hard - just that one now needs to solve a different set of problems and most
people don't want to have to solve those problems... and so git flow is an
acceptable default.

------
mariust
can I double vote this? :))

------
mcv
Most of this article is nonsense. It's true, gitflow is not a silver bullet
for every single situation, and if you've got a more complex situation than a
single team working on a single project, you're probably going to need
something that takes the complexity of your situation into account. It's also
true that gitflow might be a bit too detailed and complex for simpler
situations, but you can easily drop parts of it. It's not a universal solution
to everything, but it's a decent basis to start from, particularly if you have
no idea how else to organise your git workflow. Because everybody using their
own approach without any coordination is definitely going to be worse.

> _" Gitflow abandons rebasing"_

It doesn't entirely do that, but it does abandon rebasing in situations where
it should be abandoned. Rebasing is dangerous. Rebasing changes your history,
and as any time-traveler knows, messing with history is risky. If you change
history that you already shared, you can end up duplicating it and making a
mess.

Rebasing is only ever fine for local changes, and you can still use it there
in gitflow. But if you merge a feature that took some time to develop, into
the develop branch, rebasing is a terrible idea, and it should really be done
with a merge.

> _" Gitflow violates the “Short-lived” branches rule"_

Is that a rule? Some features really do take time to develop. Any workflow has
to account for longer lived branches. Also, if code has to be reviewed before
it can be merged, that also extends the lifetime of branches. Fortunately big
merge conflicts are easily prevented by regularly pulling the latest develop
into the feature branch.

And any situation where you have multiple people potentially changing the same
file, is going to lead to merge conflicts no matter what git workflow you use.

> " _Gitflow makes Continuous Delivery Improbable_ "

Nonsense. Once code has been merged into develop, it's ready to deploy. Well,
I suppose this one is correct if you consider dropping even the tiniest part
of gitflow as completely abandoning gitflow; all continuous delivery teams
I've seen, don't use explicit release branches; they just deploy develop (or
merge to master and then auto-deploy that).

The only argument the article uses here is "look at all those lines and dots!
this can never work!" Well, it can and does.

I've worked in teams that use short release cycles, up to daily, and use a
workflow that's pretty close to gitflow. It's a decent default to start from,
but if you're working in a more complex environment, with multiple teams
working on the same code base, parts of which need to be releasable
independently from the rest, then yes, gitflow might not fit your need. So
adapt.

See gitflow as a starting point, not as a silver bullet. There are no silver
bullets.

~~~
gortok
> Well, I suppose this one is correct if you consider dropping even the
> tiniest part of gitflow as completely abandoning gitflow;

Thank you for that feedback.

It's important to note that my blog post rails against Git-flow as described
by that blog post, not necessarily as practiced by teams. If teams drop the
problematic parts of Gitflow, of course they'd be able to use Continuous
delivery!

But the point of Git-flow is very much to _not_ practice Continuous delivery
(the textbook example; again if someone practices what they call CD but it
isn't what the textbook says "Continuous Delivery" is, I can't help that.

> See gitflow as a starting point, not as a silver bullet. There are no silver
> bullets.

Now you're getting to the crux of my issue with the original (has since been
updated) blog post. The Gitflow the OP described is problematic for all the
reasons I laid out in my post (And more that I didn't list, that others have
captured in the comments). It necessarily stands to reason that if you don't
take gitflow at face-value, you'll be better off -- but that's not what I'm
arguing against. I'm arguing against practicing Gitflow as laid out by the OP.

------
justlexi93
Gitflow might work for some projects/teams but it shouldn't be treated as a
reasonable default.

------
platz
As far as I can tell, the only difference between git flow and not git flow is
whether you have a Develop branch or not

------
eindiran
I've been swayed to the side of believing that rebase should rarely be used,
so that's not much of a downside. See: [https://www.fossil-
scm.org/fossil/doc/trunk/www/rebaseharm.m...](https://www.fossil-
scm.org/fossil/doc/trunk/www/rebaseharm.md)

------
Ixio
Are people really calling this specific model of git branching THE Gitflow
model ? For me this was a gitflow amongst others, a gitflow being a git
workflow.

In the original article "A successful Git branching model" I don't see a
single mention telling people they should call this specific model Gitflow.

For me the word gitflow has the useful meaning of a git branching model, am I
in the minority ? Using it as a noun for a specific model seems like a waste
of the word.

In regards to the article, sure this gitflow is one of the most shared images
on the subject. However I recommend that every team use whatever gitflow makes
the most sense for them and their project. I was not aware that our industry
had a problem with teams cargo culting that specific git workflow.

~~~
daxelrod
Interesting. I have only ever heard "gitflow" used to refer to the specific
model described in [https://nvie.com/posts/a-successful-git-branching-
model/](https://nvie.com/posts/a-successful-git-branching-model/) . The author
also wrote a tool, "git-flow", to assist with this model
[https://github.com/nvie/gitflow](https://github.com/nvie/gitflow) .

I have heard the terms "git branching model" or "git workflow" used for the
concept that you call "gitflow".

~~~
danw1979
nvie/gitflow is a long dead project. There's an active fork at
[https://github.com/petervanderdoes/gitflow-
avh](https://github.com/petervanderdoes/gitflow-avh)

~~~
Ixio
Thanks for the link, at the very least Jeff Kreeftmeijer in 2010 already used
the name git-flow for that specific model. I somehow missed all of that.

Plus nvie.com updated its 10-year old post with a notice yesterday and also
uses the name git-flow there.

I guess I'd better use the term git workflow in the future.

------
cpascal
> Have you ever _tried_ a complex branching model like gitflow with multiple
> teams, and hoped for everyone to be on the same page?

My company does exactly this and I am happy to report there have been no
issues. I think the key reason we don't have issues is we are strict about
maintaining backwards compatibility between services and also try to maintain
forwards compatibility where possible.

> “What’s in production” becomes an existential question, if you’re not
> careful.

We solved this by embedding the SHA's of a build's constituent repos in the
build artifact.

------
somacert
I will admit I would not know the difference between gitflow and a hole in the
ground. But that diagram looks an awful lot like the workflow you tend to pick
up when using fossil.

    
    
      * The primary dev branch
      * branch and merge for feature development
      * long term branch for each release.
    

The authors only real concern appeared to be no rebase, and rebase is already
a big no-no in any sort of distributed development, just adopt that attitude
for your personal development.

~~~
cryptonector
> rebase is already a big no-no in any sort of distributed development

You are ill-informed on this subject, and I have a proof-by-existence.

Sun Microsystems, Inc., used a rebase workflow from the mid-90s all the way
until the end, at least for the codebases that made up Solaris (OS/Net and
other consolidations), and it did so while using a VCS that did not support
rebase out of the box (Teamware, over NFS). It was essentially a git rebase
workflow years before Larry McVoy created BitKeeper, and even more years
before Git was created, and even more years before the rebase vs. merge
workflow controversies.

When I was at Sun we had ~2,000 developers on mainline Solaris. The rebase
workflow worked fantastically well.

Large projects had their own repositories that were rebased periodically, and
team members would base their clones on the project's clone (known as a
"gate").

Large projects' gates would get archived for archeological interest.

All history upstream was linear. No. Merge. Commits. (We called them "merge
turds", and they were a big no-no.)

Solaris development was undeniably distributed development.

------
gwbas1c
There's nothing wrong with gitflow... The problem comes with how it's managed.
The problem comes when a risk-averse manager wants to follow a 1990s release
cycle, and release and feature branches live forever.

Release branches should be created shortly before release, and shouldn't
deviate too much from develop. Feature branches also shouldn't last very long.

If a feature is going to be under very heavy development before shipping, a
better strategy is to #ifdef the feature. This helps avoid accumulating merge
conflicts that happen when there are long lived branches.

~~~
ulisesrmzroche
There’s a lot wrong with gitflow. For one, the very existence of a release
branch.

~~~
crgwbr
In real world software dev, I fail to see how a release branch is a flaw. It’s
completely reasonable to want to test something in a “gold-master” state
before shipping it to prod. Regardless of how many tests you have, that’s just
a good idea.

~~~
dhimes
Yeah it's what we call staging. I have a project now that doesn't have a
staging environment that's well integrated and it's very nerve-racking. I use
hg but it's the same idea.

~~~
ulisesrmzroche
Staging corresponds to master, tags are branches.

~~~
dhimes
We have a branch called “live”. That’s on our production server. Staging is
testing to make sure our dev is worthy of moving to live.

