
A successful Git branching model (2010) - gandalfar
http://nvie.com/posts/a-successful-git-branching-model/
======
mabbo
I've got a much nicer branching model- try not to have one. Everyone works off
master, and you aren't allowed to check in code that won't run in production.
Hide unfinished features behind feature flags, and never merge/push a change
that won't pass tests/CI.

The chaos of huge feature merges (a key source of bugs I've experienced) is
minimized. You deploy fixes hourly, not weekly (or later monthly when it just
won't seem to pass CI). The time between code being written and a bug being
seen can be reduced to minutes and hours, making finding the root cause a
breeze.

Just my preference, but very open to debate.

~~~
sillysaurus3
Feature flags are a nice idea, but nobody outside of Facebook seems to be
embracing them. The tooling just isn't there. Some concrete questions:

\- How do you prevent your codebase from becoming if-statement spaghetti?

\- How do you prevent new features from being leaked to the user? They'll see
the new features in the front end source code. At many companies this isn't an
acceptable tradeoff. So do you preprocess the release code and strip out the
disabled feature flags? With what?

\- What do you use to control feature flags? Just a json file filled with
`"foo-bar-feature": true/false`, or something more sophisticated like a
control panel that you can use to say "10% of our users will see this
feature"?

~~~
hoorayimhelping
> _Feature flags are a nice idea, but nobody outside of Facebook seems to be
> embracing them_

I worked at Etsy from early 2012 to late 2015 and I used feature flags every
day I was there.

> _How do you prevent your codebase from becoming if-statement spaghetti?_

You remove the feature flag checking code when you turn off or turn on the
feature. It's an extra deploy, but it needs to be part of the prod/eng
process. This is the most salient issue of feature flagging in my experience
and something you need to get ahead of from the get-go.

> _How do you prevent new features from being leaked to the user?_

You branch at the server/request level, not the client level, so there is no
set of features that gets displayed, it's just what the server returns.

> _What do you use to control feature flags?_

You can use a service like LaunchDarkly or Optimizely or you can write your
own service, or you can have a file in memory. Usually it starts simple with
boolean toggles and evolves into a ramp up system that let's you selectively
target users. The important part is that you need to be able to change
features without redeploying code.

~~~
sillysaurus3
_You remove the feature flag checking code when you turn off or turn on the
feature. It 's an extra deploy, but it needs to be part of the prod/eng
process. This is the most salient issue of feature flagging in my experience
and something you need to get ahead of from the get-go._

I don't understand. I was asking about the development source code, not the
code delivered to the user. The dev source code isn't stripped of if-
statements, right? That's where the feature flag toggling lives. But then it
seems like it's easy to devolve into spaghetti.

 _You branch at the server /request level, not the client level, so there is
no set of features that gets displayed, it's just what the server returns._

Ok, but how? I'm not playing dumb. Assume an express server. You want to put a
feature flag into your codebase. What is step #1 (and #2 and ... #N) to
achieve this?

I looked up LaunchDarkly. $299/mo for basic team support. Uhh... That's almost
the cost of WeWork office space.

Are feature flags really so nascent that there isn't a FOSS solution for it?

~~~
dahart
> The dev source code isn't stripped of if-statements, right?

When I use a feature flag as an alternative to branching, then I delete the if
statements once the feature becomes permananent and gets released to all
users. It's analogous to merging a branch. Obviously I'd leave it there during
QA and A/B testing, but once toggling is no longer necessary, I remove the
toggle.

> Ok, but how? Assume an express server.

You probably have feature flags already and just didn't call them that. But
normally in any given project, there are multiple ways to wrap a feature in a
toggle.

Here are a couple of examples I use:

\- I use handlebars for my frontend templating. When I have a feature that
needs to serve or withhold some HTML to/from the user, I put the feature flag
in my JSON file of variables that get passed to handlebars. Handlebars has a
way to wrap HTML with a boolean test.

\- I use the Google Closure compiler to optimize, uglify, and minify my code.
When I need a feature flag that is code only, and I don't want users to
accidentally get exposed, I use a boolean @define in JavaScript, and wrap
feature code in an if statement. When the Boolean is false, Closure compiler
removes that block from the output code.

\- I set up my own JSON file of config constants that are injected into the
code during build. If I have a feature flag to A/B test something, or that I
do want released to users but has a secret switch to enable, then I put the
constant in the JSON file, and write UI code to toggle the flag. This one
usually generates more code than the two above, but whenever I decide that the
feature is either dead or permanent, I remove all the code to enable and
disable the feature.

\- For fully dynamic toggling, I put my boolean config variable into my
database. I use Firebase which is a giant pub-sub, so I wrap the toggle in a
subscription to the database variable, which might then (for example) inject
some HTML and/or toggle the CSS display attribute of some things on my page.

> Are feature flags really so nascent that there isn't a FOSS solution for it?

No, feature flags have always been around, since long before branching. There
isn't a FOSS solution for it separate from your framework(s) because how they
work depends entirely on your stack. They're also normally really simple,
adding the dependencies of another project just to have a boolean in your
config file or in your code is usually overkill. That said, there are FOSS and
commercial solutions for A/B testing, which is usually a feature flag
workflow, but it comes with lots of other stuff you might not need, like the
reporting, analytics and statistics parts.

~~~
xorcist
> I delete the if statements once the feature becomes permananent

Right. In theory. Does this really scale when there's more than a dozen
developers touching the same code paths? It's not just you scratching off your
own TODOs, it's multiple entagled condiditionals. Can you really delete your
flags with confidence that this does not affect any other code path?

Which brings me to my real question: How you you guys test this stuff? When I
have experimented with feature flags before this has been to much detriment
for testing. Suddenly the new payment API our provider will launch in June
needs to be tested with the new backend we'll launching Tuesday, and with the
new asynchronous database driver our DBAs wants us to migrate to. And so on.
The complexity explodes. Especially when the features have dependencies
external to you.

When everything is in master and everything must be in shippable condition you
need to test everything with everything else, while previously the new payment
API in June could live in it's own branch and test on their own schedule and
not bother everyone else everytime the payment provider's test environment
took a nosedive for some reason.

So you either end up with brittle tests that can take days to execute, or you
end up scratching a lot of the less pressing combinations. Which brings us to
the situation above. How can you then be confident to remove conditionals
without testing the newly exposed code paths?

It is so far my suspicion that most people who speak of feature flags as an
alternative to branches either work with trivial products where most
developers fit in a small room (in which you are not the use case for these
things) or talk out of some theoretical conviction which has yet to meet with
reality. These things are hard, because of all those details which seem small
if you squint enough.

~~~
dahart
To be clear, I personally use branching a lot (e.g., for sprint-sized
features) and I create new feature flags rather infrequently (for multi-sprint
sized features or for A/B tests), and only for pretty large features. But I
can see reasons why some teams/environments do go, or want to go, feature-flag
always. Before git, feature toggles were more widespread as a workflow.

As far an entanglement with other code, I would evaluate this wrt branching.
If it's entangled, the branching analogy is a merge conflict. The most common
case is you can delete the toggle without conflict, and occasionally you have
to spend ten or twenty minutes untangling. Every once in a rare while it gets
messier.

For testing, the prod tests run the prod config, which is likely with all
optional feature toggles turned off. My team would run our own tests with our
feature toggles turned on, but not with other teams' feature toggles. I don't
run all combinations of features. Usually, a feature toggle will also wrap new
tests that belong to that feature.

Again, the same question you ask applies to a branch workflow. Do you run all
possible branches at the same time? Is it an exponential combinatorics problem
to have multiple branches? Not really, each team runs the tests for the
features they work on. Same either way.

The great thing about feature flags for testing is that you have greater
control over who is exposed to your new feature. With a feature toggle, you
can expose some teams in your company outside of your own, without exposing
the whole company. You can expose 10% of your customers and do testing without
inflicting bugs you didn't forsee on 100% of your customers. If there's an
emergency, you can limit the damage radius with a well designed feature flag.
Branches can do this only to the extent that the merge structure allows it,
and they can't help with customer testing.

> It is so far my suspicion that most people who speak of feature flags as an
> alternative to branches either work with trivial products [...] or talk out
> of some theoretical conviction which has yet to meet with reality

I think I know why you feel that way, but that sounds (to me) like you haven't
been exposed to (and so can't imagine) workflows outside of git branching. I
mean no insult, but you are jumping to conclusions from lack of experience.
Feature toggles as a pseudo-branching workflow predate git by decades, they
are used on the largest codebases in the world -- did you miss the comments in
this thread from MS and Google?

Feature flags are used in nearly all repos where branching exists. It's not
one or the other, you can use both workflows at the same time. A/B testing is
based on feature toggles, and all sizable websites on the web are doing A/B
testing constantly. Chances are high that you use them already and just
haven't yet recognized that they're the same thing we're talking about. If you
have config files for your project, then you have feature toggles. If you ever
change a value in one of them, then you could instead branch your code, remove
the config variable and rewrite the code that used to reference the feature
flag to be hard coded instead. Is that making sense?

FWIW, just to put some specifics and back up my own 'conviction' with real
world examples, I've been on teams that used feature toggles to test and ship
features during the production of several animated films, movies you probably
saw. When I worked in film, it predated git. We had a hierarchical repo, but
there were no branches, only pushing to master and feature flags.

When I worked in games, the team I lead used feature flags to support cross-
team testing on a $1B console franchise.

At a certain web company, in addition to constant A/B testing, my team shipped
features to customers who signed up to be on the 'beta' versions of features
before they were rolled out to all of the >1M users. We used feature flags to
control which teams internally could see & test certain features, and we used
feature flags for either long-running or large cross-team features when
branching & merging would cause undue amount of branch noise.

And at my own startup now, I prefer to wrap my features in feature flags even
when I'm branching. That way I can back out a feature when it causes problems
or has bugs without having to do git surgery or even risk a merge conflict.
With a few thousand active customers, this has saved my ass multiple times.

~~~
xorcist
> If it's entangled, the branching analogy is a merge conflict.

I like this observation. As long as two developers touch the same code, you
will have a conflict. Now your choice will be where to best place that
conflict. In an SCM, in conditional statements, or somewhere else.

> For testing, the prod tests run the prod config, which is likely with all
> optional feature toggles turned off.

I don't understand this. If you are going to activate a new feature in prod,
surely you test it first? Or do you start testing all over again before you
switch on a new codepath? Feature toggles must also include externalities such
as backend systems changing their APIs. Even if you are forwards compatible,
you must take care so your application doesn't break when that happens, and
that means testing in advance.

If you really follow the master-is-production branch free model all merging
must cease before you activate a feature in prod? That doesn't sound very
practical.

> Do you run all possible branches at the same time? Is it an exponential
> combinatorics problem to have multiple branches? Not really, each team runs
> the tests for the features they work on.

A team can not be responsible for testing only their own development work,
they must also know that it works with other people's changes that might
activate before theirs does. That cross team communication is hard enough
using branches, but at least teams do not disturb each other's testing. That
enables asynchronous development. In a master must always be production model,
which seems to be what most branchless development people seems to advocate,
every combination is blocking. That's the difference.

> The great thing about feature flags for testing is that you have greater
> control over who is exposed to your new feature.

Right. I'm not saying that feature flags are useless. I'm just questioning
that it can be used instead of branching in non-trivial projects. There are a
lot of use cases where it makes sense, for example user interface stuff where
branching unnecessary.

As you point out, feature flags are just a new term for application
configuration. We've had that forever. It is as an alternative to developing
in branches I question it. We generally don't celebrate making everything an
option.

> I mean no insult, but you are jumping to conclusions from lack of
> experience. Feature toggles as a pseudo-branching workflow predate git by
> decades, they are used on the largest codebases in the world -- did you miss
> the comments in this thread from MS and Google?

Oh, absolutely. I type this because I want to hear from people with
experience. What I meant by "my suspicion so far" is that the experience with
branchless development I've heard so far is either trivial or theoretical.
There's a lot of pointing at Facebook as a good example but not much in way of
first hand knowledge.

And yes, I did notice the comments. The Microsoftie called it "if-statement
hell", the Google commenter said it "impacted developer velocity" primarily
because of the testing requirements. The former can perhaps be explained with
culture, but the latter matches my experience exactly. These comments
concerned feature flags in general however, not branchless development which
is a special case of it.

Your examples from the game and film industry sounds like it could be made
workable, but I imagine that development looks different from the average ERP
system or backend service. Certainly with smaller startups you shouldn't
overcomplicate matters.

~~~
dahart
> If you are going to activate a new feature in prod, surely you test it
> first?

Yes, my teams test features before pushing to master regardless of branch
strategy. What I meant is that the prod/master/nightly tests stil run the prod
config as-is. Teams run tests, but features under toggles aren't tested using
the master branch's automation tests until the feature is turned on. Exactly
like how a team branch won't get tested in the nightly run until merged.

The QA dept. is typically running the staging branch, which is whatever got
pushed to master, but hasn't gone live yet. When I turn on a toggle, it's just
like I merged a branch, so QA starts testing the new features at that point.
When we want extra testing, we set the feature toggle so that QA is exposed
and the public is not, then if it passes, the code goes live with the feature
toggle turned off.

> A team can not be responsible for testing only their own development work

When we test feature toggled code, my team runs all the automation tests with
my team's features turned on. Similar to how we'd run tests as if our branch
was merged into master, but without pushing the merge.

What we don't do is speculatively run tests with other teams' feature toggles
turned on. Exactly like how you wouldn't run tests against someone else's
unmerged branch. Their features are tested against ours after one of the teams
turns their own toggle on, once one of the features is made public -- to at
least our teams if not everyone.

> The Microsoftie called it "if-statement" hell

I've heard first hand accounts about their branch hell too. And it's a worse
hell than I've ever seen personally. From about 10 years ago, not today, so I
don't know how different it is, but someone in Research said it took a full
month of merging and conflict resolution for a code merge in any given dept.
to propagate to the rest of the company.

If that's happening, feature toggles definitely won't fix it. There is a
chance it could make things worse.

I'd tend to agree if you strictly feature-flagged all commits as a complete
replacement to branching, it would probably be ugly. Git is useful, and
branches are a nice workflow for most dev.

My criteria is to choose the one that makes sense. Feature toggles are
currently better IMO for long-running feature dev or very large features,
branches are better for medium sized features. Adding, merging, then removing
a feature toggle during a single sprint is more overhead than it's worth.

What we did in games before git was everyone pushed to master at all times (or
whatever they called it in Perforce, or the lovely SourceSafe before that.)
Most people did not wrap their features in toggles. We lost a ton of developer
velocity due to someone checking in a bug that broke the build for everyone
who pulled after that. More often than not people would hurry to try and fix
their bug rather than revert, occasionally checking in further bugs. Company-
wide breakage was a weekly occurrence. Those were dark days, it was
ridiculous. Feature toggles were the only safety mechanism we had, which is
maybe why I see them in such a positive light.

I would not recommend going whole hog with feature toggles and eschewing
branches. But I do recommend trying one or two and feeling out exactly how the
whole process would work for you from start to finish. They are still useful
in a branch environment, especially for features that would cause lots and
lots of branch noise.

------
watt
The advice here given to avoid using "master" branch for development, and
advice to create non-default branch named "develop" (or variations thereof) is
quite harmful.

If you must have a "release" branch or "stable" branch, ok, go for it, but
leave the "master" for developing. Why? Strive to have sane defaults.

Frankly, the idea that somebody must check out some extra special branch after
cloning repo in order to start properly developing, is not sane.

~~~
jph
> Leave the "master" for developing.

IMHO do developing always on topic branches, never on master.

This keeps master available for fully-working software, such as for the most-
recent successful build using continuous integration, or for always-available
deployment, or for external users, etc.

To create topic branches, here are git alias commands that you can customize
as you like for your git workflows:

    
    
        topic-start  = "!f(){ b=$1; git checkout master; git fetch; git rebase; git checkout -b "$b" master; };f"
    
        topic-finish = "!f(){ b=$(git branch-name); git checkout master; git branch -d "$b"; git push origin ":$b"; };f"
    
        branch-name = rev-parse --abbrev-ref HEAD

~~~
watt
What's the point of running CI on a branch that's effectively for tracking
releases only?

We run CI on master branch and fix any build breaks or regressions
immediately. (That's the job of unit tests and integration tests.)

In fact, if your team is smaller, you do release from master branch directly,
just tag the release revisions. Then if you need to hotfix it, check out the
tag, make a branch, cherrypick a fix to the branch, and do point release from
the branch: problem solved.

That's if the client running the (older) release version is large enough to
justify releasing hotfix instead of doing fix to main stream and just asking
to upgrade to latest release.

Yes to topic branches. Yes to "cactus model" of rebasing the topic to master.
No to the idea that you need extra long-lived "develop" branch in parallel to
master.

~~~
jph
> What's the point of running CI on a branch that's effectively for tracking
> releases only?

I'm recommending using master as the _output_ of a successful continuous
integration, and thus always ready for release.

I'm rejecting any git flow that has any developer pushing any code directly to
master, while hoping/guessing that master branch integration will succeed.

Caveat: Bugs will still happen.

Caveat: There are more-advanced release processes such as blue/green,
alpha/beta, canary/throttle, etc.

Caveat: There are more-sophisticated integration techniques such as an
internal private master branch that differs from an external public master
branch. YMMV. Use the right tools for the job.)

~~~
sillysaurus3
_Caveat: There are more-advanced release processes such as blue /green,
alpha/beta, canary/throttle, etc._

What does Facebook do? It's hard to imagine that they slow themselves down
this much. They tend to hide features behind feature flags, but is it known
what their CI process is like?

~~~
hdhzy
Github pushes topic branches to production and if they don't cause troubles
_then_ merges to master. The idea is that _good state_ is defined as _works in
production_ not just _passed CI tests_.

------
activatedgeek
It is good exercise to actually learn this branching model and then use it in
practice. You will soon realize that most projects will suddenly start taking
unnecessary toll on you just because now you want to maintain multiple
branches and it is a huge PITA.

Instead just follow this simple routine - stay as close to the master as
possible. If a temporary diversion is needed, create a new branch (and
maintain both master and the diversion for a while). Delete the diversion once
the job is done.

If you are never able to delete the diversion, it is not your git branching
model that failed, it is you and your code who failed. Diversions may be long
term (and I hope you have the workforce to maintain that branch as well) but
still finite time. How to prepare that diversion is a software engineering
problem and not git's fault.

~~~
rtpg
How does this work if you have multiple ongoing changesets?

I'm often working in 3 different features at once, all needing to be merged
separately in the review process

~~~
gregmac
Merge from master back to your branch.

This is how my team handles merge conflicts: your branch must cleanly merge
for the pull request to be approved (which means you must resolve conflicts in
your branch first). If there are two branches that may conflict in terms of
functionality (but not at a source level) we call that out, and have the
people involved reviewing both. When it comes time to merge, we usually merge
the first one done to master, merge master to the second, then do extra
testing in the second branch before merging it.

Sometimes if we know one branch blocks the other, we simply merge one to the
other, but then still go to master separately. This makes the pull request
review much simpler and keeps the code isolated while not duplicating effort.
This works best when a big bug has a quick and simple but incomplete fix, and
a more risky and complex but complete fix, or when there's multiple aspects to
a new feature. We can decide to ship the first branch earlier if necessary.

------
antoncohen
Do not use Git Flow for a web application deployed on your own infrastructure
(SaaS, microservice, mobile backend, etc.). It will slow down development and
make your software less reliable.

The entire purpose of Git Flow is saving up changes to release later, e.g.,
saving up for a weekly release event. Don't do that! Deploy your changes as
soon as they are ready, if they aren't ready don't merge them into a shared
branch. If you do Continues Delivery you don't need "hotfix" branches because
every changes goes out as soon as it is ready, so you don't need any of the
complexity of Git Flow.

By saving up changes for a release event it means more things are getting
released at once. If there is a problem after deployment it will be harder to
narrow down the cause. Git Flow fosters a harmful development mentality where
developers merge untested changes to the develop branch, then move on, and
expect someone to test and stabilize their changes before release. With trunk-
based development
([https://trunkbaseddevelopment.com/](https://trunkbaseddevelopment.com/)) or
GitHub Flow
([https://guides.github.com/introduction/flow/](https://guides.github.com/introduction/flow/))
developers take ownership of their code, and only merge to master after they
have tested it. With a good deployment pipeline they can own their code all
the way to production.

Git Flow also encourages humans to think about and make up version numbers,
like 15.0.5. This is a pointless waste of brain power, web apps don't need
version numbers. The artifact systems (packages, containers, etc.) may need
something, but it can just be an incrementing number that no on thinks about.

Git Flow wastes so much time, and makes everything it touches so complex, all
to enable the harmful behavior of saving up changes for later, and enabling
the pointless use of version numbers.

Trunk-based development and Continues Delivery is the default way people
develop, it is how you would work if you had a one person company with one
customer. It also is how the biggest web companies in the world work. It
scales from smallest to largest. Just use trunk-based development. Stay away
from Git Flow.

Edit: Fixed spelling of incrementing.

~~~
geezerjay
> Git Flow also encourages humans to think about and make up version numbers,
> like 15.0.5. This is a pointless waste of brain power, web apps don't need
> version numbers.

Version numbers are used to represent specific states of the project in order
to have fixed testable and auditable versions. It's what the user sees when he
needs to check which software version he's using when talking about the
software he's using, and what programmers need to know when they need to work
on bugs/features present in previous versions of the software but not on
others. If your app needs to be debugged and there are peopleother than
yourself using, testing or working on the software, it needs version numbers.
Otherwise, everyone will needlessly waste their time.

Version numbers waste as much brain power as knowing the name of someone you
need to contact on a daily basis. You don't need to make up version numbers
because plenty of people already did that. For instance, Semantic Versioning
is a thing.

[http://semver.org/](http://semver.org/)

~~~
antoncohen
Notice I said "web application deployed on your own infrastructure".

While you said "[versions are] what the user sees when he needs to check which
software version he's using when talking about the software he's using, and
what programmers need to know when they need to work on bugs/features present
in previous versions of the software but not on others."

In good SaaS products users don't see version numbers. What version of Gmail
are you using? What version of GitHub? They don't have versions. There are
also only two versions of your software, what is deployed and what us being
deployed (or multiple "being deployed" if you have multiple canaries).
Engineers can look up build numbers and changes in the CI system or other
internal tracking tools without humans making up version numbers.

Semver is great for libraries and shipping applications, where third parties
need to know about breaking changes so they can adjust their applications or
configuration.

When deploying your own app to your own infrastructure, Semver wastes people's
time. I've worked at a company that switched to Git Flow right before I
started. I've seen so much time wasted by people discussing versions and
branches. Should I merge to develop or a release branch, or is it a hotfix,
should it be 15.1.0 or 15.0.1, or no, someone else claimed 15.0.1 before me,
now I'll rename my branch to hotfix-15.0.2, oh 15.0.3 is done being tested
before my 15.0.2, so they will rename to 15.0.2 and I'll rename to 15.0.3,
oops I forgot to merge their changes into my 15.0.3 so I reverted 15.0.2, now
I need to deploy 15.0.4 that has the changes from 15.0.2 and 15.0.3.

Seriously, no joke, this is what happens what you try to use Git Flow for a
web app.

------
mcv
For a moment I thought: Has someone figured out something better than git-
flow? But no, it's the original git-flow article again.

It's good, but now exactly "news". Every git user should be aware of git-flow,
even if you do have a better way of using git.

~~~
imron
> Every git user should be aware of git-flow

Agree. Every git user should be aware of it and should use it on a project at
least once so they know to avoid it forever after.

~~~
Froyoh
Why avoid it?

~~~
Rafert
Because it's complicated and most people don't need that complexity at all.
For some reason a lot of people happily jumped on the band wagon when this was
released and started writing scripts to make it more bearable.

If you have multiple versions of your codebase that you need to maintain for a
longer time to justify those release branches, gitflow might be for you. IMO
GitLab flow is much more applicable for most people:
[https://about.gitlab.com/2014/09/29/gitlab-
flow/](https://about.gitlab.com/2014/09/29/gitlab-flow/)

------
mkempe
I've used the git-flow approach successfully with a small team working on a
medical product (so, embedded software system) -- every feature branch had to
be reviewed before being merged with `develop`, which was submitted to
nightly, extensive functional tests (initially one-hour long, eventually kept
as a nightly subset of the more than 24-hours complete QA run) before it could
be approved as a new (monthly) release and be merged with `master`. Every new
feature branch was automatically treated to quick continuous integration
tests, and available for manually-triggered full functional tests (on the
target devices).

This approach ensured that we had a full trace of development work, (signed)
code reviews, and software changes -- compatible with FDA audits.

We also automated collection of code coverage data during functional tests, to
inform analysis and revisions of the battery of functional tests.

~~~
hdhzy
Interesting. How did you do signed code reviews?

~~~
mkempe
We used PRs with BitBucket for all code reviews. The reviewer(s) had to
digitally sign their final approval of the review comments+answers and of the
related code changes, if any.

The only way to merge a feature branch into `develop` was via the PR + code
review process.

~~~
hdhzy
Was it something like exporting PR history to a file and then signing
(X.509/PGP)? Thanks for answers, it looks like a nice, lightweight auditable
system.

~~~
mkempe
No, simpler than that; we used the BitBucket web interface to enter the
approval message and click the approved button to allow for merge. These
actions are recorded and visible in the overview page of the PR.

However the BitBucket server's web interface was not approved/validated for
long-term storage and evidence for the audit trail, so the PR owner was
responsible (before triggering the merge) for saving a PDF copy of that PR
page and committing the PDF file into a git-controlled code-review directory.

So it's digitally signed to the extent that your account/identity is recorded
in the approval step and in the collection of PDFs. I did ask about a more
systematic export method but it was not considered important given the PDF-
based approach.

~~~
hdhzy
Pragmatic and simple. Thanks for taking time to describe it!

------
xydinesh
GitLab has a good discussion on Git flow too.
[https://about.gitlab.com/2014/09/29/gitlab-
flow/](https://about.gitlab.com/2014/09/29/gitlab-flow/)

------
kuharich
Prior discussion:
[https://news.ycombinator.com/item?id=1966820](https://news.ycombinator.com/item?id=1966820)

------
stonewhite
This was very much valid before the docker workflows came to happen.

Now maintaining two mainline branches forces you to break "don't build a
container per environment" cardinal rule. Trunk based development should be
the go-to repository strategy for dockerized apps.

~~~
icebraining
What's the purpose of that rule?

~~~
stonewhite
If you properly externalized the configurations, Docker provides bit-by-bit
parity between environments granted you use the same image.

This results in increased confidence to test environments and lessening the
chances of a surprise during production deployments. It is the next logical
step in immutable deployment paradigm[1].

[1]:
[https://martinfowler.com/bliki/ImmutableServer.html](https://martinfowler.com/bliki/ImmutableServer.html)

~~~
icebraining
But why not use the typical solution of having two testing environments, in
this case based on "develop" and "master", with the latter being bit-by-bit
equal to what gets deployed?

~~~
stonewhite
What purpose does it serve but to double QA efforts. If you are testing the
same stuff both in develop and master, why not just test only one and save
some time. Ramming gitflow into a docker workflow efficiently is not really
possible I believe.

------
Froyoh
How is this feasible for projects worked on by multiple development teams?

------
bschwindHN
Oh I guess no one has posted it this month, let's argue about git again.

------
Sujan
(2010)

------
nstj
@dang this is old

~~~
otp124
It's okay if it's old, but it should have a (2010) year tag to inform
potential readers.

