
My unorthodox, branchless Git workflow - corenting_
https://drewdevault.com/2020/04/05/My-weird-branchless-git-workflow.html
======
raziel2p
> I’ll just apply them to master, rebase them behind my WIP work, and then use
> git push origin HEAD~5:refs/heads/master to send them upstream, or something
> to that effect.

if you're going through the trouble of carefully rebasing to change the order
of commits, _and_ remembering exactly how many commits behind HEAD you should
push, _and_ remembering what state the remote is in (what is master is
actually pointing at HEAD~4?)... why not just go through the comparatively
minor trouble of using branches?

also it's not like working on branches excludes the possibility of sometimes
committing directly to master. that's what I do for most of my personal
projects: small cleanup and fixes happen on master, larger things happen in a
branch on a PR until I'm happy with it. ~30% of the time I'm actually not
happy with how it turns out, and then I'd rather just close the PR and delete
the branch than carefully revert work in progress.

~~~
jdhzzz
With you 100%. And yes, I will sue.

~~~
newswasboring
What will you sue?

~~~
grayed-down
For peace?

------
nicksantamaria

        No time spent creating new branches for new features.
        No time spent switching between branches to address feedback.
    

I'm sorry but these are non-issues with git. The approach you've outlined
makes collaboration on features impossible. Cherry-picking and rebasing does
not scale for either teams, or lots of parallel workstreams.

~~~
drchopchop
_git checkout -b new_feature_branch_ is an onerous workflow?

~~~
Cthulhu_
Switching branches does get a bit annoying if you happen to work in multiple
branches simultaneously and have to switch halfway through a task, or there's
a lot of differences; however, that is also a matter of organization.

It's happened to me though; one scenario is that you created a couple of merge
requests for the same repo over the course of a day, and the next day feedback
from code review or testing comes in. You end up having to switch to various
branches to fix the reviews.

But that's really not that big of a deal. The context switch is worse than the
git checkout call.

~~~
malingo
Git checkout understands "hyphen expansion" for your previous branch (a la `cd
-` to switch to your previous working directory), so switching between two
branches is as easy as `git checkout -` or even `git co -` if you have an
alias.

~~~
iainmerrick
But you’ll also have to rebuild. If your build system is bad, that could be
slow. If your build system is really bad, you might need a clean build.

All build systems (that people actually use) are really bad.

------
hprotagonist
Seems like all the time you'd ostensibly save on not branching you instead
spend doing very careful munging later and crafting very careful commits with
git add -p and rebase and other equally time consuming tools.

I don't see the value-add at all.

~~~
derefr
> you instead spend doing very careful munging later and crafting very careful
> commits with git add -p and rebase

I mean, I already do this, because I like to be able to understand my commits
as standalone historical artifacts. IMHO commits exist to be read (by your
future self trying to figure out WTF you were on about most of all!) as much
as they exist to change the state of the codebase.

Given that I'm already doing this, it wouldn't be any _more_ work to use a
workflow like this, I guess? (I still use branches. And have multiple git
worktrees checked out at once from the same repo.)

------
btreecat
I was with you till this part

>When I’m ready to present some or all of my changes to upstream, I grab git
rebase and reorganize all of these into their respective features, bugfixes,
and so on, forming a series of carefully organized, self-contained patchsets.

That seems like a lot of extra work to "not use" branches.

I do less work than that and don't use branches. I just tag the releases.

Whenever I want a certain commit to triger CI/CD for build/testing and preprod
deploy, I just tag a git commit as "release-[most recent git commit 8char
fingerprint]" using a little script and some cli aliasing.

Then push. Release is built, and I can keep pushing to master unfinished
features. But because the working version is tagged, Ops can always rebuild,
redeploy, or roll back to known good commits.

------
dahart
This workflow doesn’t seem weird or unorthodox to me, it just seems like a
solo contributor workflow. There aren’t as many reasons to use branches when
you aren’t working with other people in those branches. It seems fine to skip
some of the overhead when you’re by yourself. The implicit suggestion that
everyone else is _always_ using branches does seem a bit strange, if that’s
the implication. I use branches when I need them, but I don’t always use them,
and usually on small teams we adopt a policy of checking self-contained
single-commit features into master, and using branches for multi-person,
multi-commit, and multi-day features.

    
    
        No time spent creating new branches for new features.
        No time spent switching between branches to address feedback.
        All of my features are guaranteed to be mutually applicable to master, saving me time addressing conflicts.
        Any conflicts with upstream are addressed in all of my workstreams at once, without switching between branches or allowing any branch to get stale.
    

To be honest all 4 of these are unconvincing. Creating branches and switching
branches is a non-problem, these operations are faster than committing.

To the third and fourths points - that all “streams” resolve at the same time,
that’s an okay point, but isn’t normally a problem in practice with branches.
If you’re working on multiple branches than conflict with an incoming commit,
it means you’ve touched the same code in multiple branches, and also someone
else has too. It tends to indicate bad planning or bad communication or both.
And it just doesn’t happen very often.

Here are a few reasons to use branching anyway when you’re alone:

\- To do an experiment multiple ways on the same code.

\- To avoid use of git stash. Branching is safer and adds no extra difficulty.
Stash doesn’t have as good of a safety net (it’s in the manual).

\- To write & test your feature without your other in-progress features
getting in the way.

------
ninjapenguin54
This is a very eclectic workflow that _might_ work if you have very good
mental organization. For most people this sounds a recipe for disaster. A good
way to lose work and get confused about the scope of individual features.

I tend to think of git as tool to aid organization and not an opportunity to
flex my prowess at mental gymnastics. Crazy, I know.

------
rhplus
Local testing would become meaningless as “features” are not being tested in
isolation. It’ll lead to the classic “but the tests work on my machine”
because half the changed code isn’t in the published changeset.

~~~
ginko
Yeah, this sounds like hell to bisect.

------
Hnrobert42
I used git as a solo dev for years. I always used branches, but there wasn’t
much reason. Now working with a team, branches are useful.

------
rahimiali
Here's better rationale for this kind of approach: it requires a lot less
rebasing and merging:

1) If you branch a lot, keeping up with upstream changes can be tedious: you
have to rebase each branch separately just to keep up. With this method, to
keep up, you rebase just once, on your one branch.

2) If you branch a lot, merging each branch can cascade into a bunch of
rebasing. As you build your feature, you might clean up unrelated code. Your
"implement feature" commits could be interspersed with "fix unrelated code"
commits. If you're creating a branch for each cleanup commit, as you submit
them for review earlier than your feature, you have to rebase all your
branches one by one. With this method, you rebase just once.

------
dilap
People are quick to dismiss this, but I think it's a fish-in-water kind of
thing, where they are so used to the normal git flow, they can't see any way
that it might be non-ideal.

I am excited about the promise of patch-based VCs. In theory they are clearly
a better, more flexible model, that is a closer match to how we actually think
of changes.

As an example, the branch-free model of this post just falls out naturally,
w/o the need to rebase at the end.

However, we're still missing a great implementation to make this promise a
practical reality (perhaps the upcoming version of Pijul will be that
implementation?).

~~~
smcameron
You might take a look at stgit.
[http://www.procode.org/stgit/](http://www.procode.org/stgit/)

------
daveguy
I much prefer separate local branches and rebase against master to start the
daily workflow. If you are regularly keeping your feature branch on the up to
date with master head there is little conflict day to day. When there is a
conflict it's because you have to make a decision between two features or
collaborator updates and your feature. As long as you haven't pushed your
local branch you can rebase it all you want.

Way way more organized to use branches.

------
Hamuko
Is this the cutting off your nose to spite the face workflow? It seems like a
lot of faff to avoid the trivial task of creating a branch.

------
mixedmath
I think the success of such a workflow says a lot of positive things both
about drewdevault and git.

With respect to git, this is yet another successful workflow conducted through
git. While git may have its flaws, one cannot deny that many different
workflows are enabled by it.

And with respect to this particular workflow, I think it says that drewdevault
makes largely self-contained commits with good commit messages and that
constantly work. I have been on projects using branched development with
people who sometimes make commits that break things, but that then fix them in
other commits, with a does-it-really-matter-before-it's-merged-anyway
attitude. And I have been on projects where the default commit message is
absolutely lousy. (And I am currently involved in a project where both of
these are true).

But to be able to successfully rebase and reorder and cherrypick commits says
a lot to me about highly disciplined organization. I would expect many
workflows to be enabled by such habits.

~~~
leejo
> I think the success of such a workflow says a lot of positive things both
> about drewdevault and git.

There's a massive flaw in this approach if the repo is not private
(collaboration is mentioned in the post in terms of "review some incoming
patches") in that you can't push works in progress to the remote as you are
doing it all in master. If you _did_ push those then when you tidy it up you
will cause problems for other collaborators.

If you can't push WIP out then you have the only copy, and you're losing some
of the distributed advantages of git: distributed backups of your WIP changes
being one of those.

> But to be able to successfully rebase and reorder and cherrypick commits
> says a lot to me about highly disciplined organization.

Yeah, rebases and cherry-picks are great features. Just use branches as the
starting point.

------
smcameron
I do something kind of similar using stgit[1]. I do everything on a single
branch creating patches with stgit. stgit lets you easily change the order of
commits (a lot like quilt[2], but more robust because it's using git
underneath). When features are ready, I just cherry pick them over to master
and push upstream.

[1][http://www.procode.org/stgit/](http://www.procode.org/stgit/)
[2][https://en.wikipedia.org/wiki/Quilt_(software)](https://en.wikipedia.org/wiki/Quilt_\(software\))

------
RichardCA
He understands the power of rebasing, but he doesn't address how you use that
power and also coordinate your work with other people.

He seems to be implying that it's OK to rebase against master and/or force
push the remote ref, as long as the only person you are pleasing is yourself.

I mean, a lot of people progress in their Git knowledge until they reach the
point where they want to minimize the clutter of merge commits. That's almost
a cliche.

But how you do that when you are working with others, some of whom may have
advanced Git knowledge while others are complete novices, that's what the real
world looks like.

------
salomon812
When I go rock climbing, I don’t use ropes. It saves me time of having to set
anchors.

The git advice works for either experts or small projects. If you’re an
expert, choose your own workflow. I find in large projects with many users,
branches help to recover quickly from mistakes and help define testing
history. My primary concern is for novices to go at it without branches
because they’re hard to deeply understand without experience and they see
experts managing without.

Learn how to use rock climbing equipment before you rely on it. Experts, do
whatever works best for you!

------
pjc50
Isn't it incredibly annoying to edit a git change that isn't at the branch
(HEAD) tip?

Our workplace uses gerrit, and while it sort of supports this workflow I
personally use a lot of short-lived branches, one for each gerrit review,
simply in order to get at them easily to make changes.

~~~
kragniz
It's a lot easier with git commit --fixup:

[https://blog.sebastian-daschner.com/entries/git-commit-
fixup...](https://blog.sebastian-daschner.com/entries/git-commit-fixup-
autosquash)

------
bryanlarsen
A long time ago I used to use Stacked Git (1) for a similar but different
workflow.

1: [http://www.procode.org/stgit/](http://www.procode.org/stgit/)

I miss the days when you were expected to use a porcelain on top of raw git.

~~~
hprotagonist
It may not be _expected_ now, but i'll always take the opportunity to plug
magit, which is by far the nicest porcelain i've ever used.

------
flyingcasual
This is an interesting article. I do find it pleasant to use git without
branches. It allows you to invent a different type of agility and
resourcefulness with git operations. I would not recommend this to new users
or teams.

------
remmargorp64
So essentially, he is using Git as a logging and versioning tool, instead of
using it as a collaborative tool.

------
waynecochran
Sounds like me using RCS in the 1980's.

------
clarkmoreno
nope.

~~~
dang
" _Please don 't post shallow dismissals, especially of other people's work. A
good critical comment teaches us something._"

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

------
stephc_int13
If I read correctly, this is trunk-based development.

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

And this is also my experience, I absolutely hate spending time to merge
things and resolve the conflicts and bugs.

I think this should be the default behavior for small/medium teams.

Branching should only be used when trunk-based dev is no longer possible.

I really liked this article from the Our Machinery guys, who created the
Bitsquid engine.

[https://ourmachinery.com/post/moving-away-from-git-
flow/](https://ourmachinery.com/post/moving-away-from-git-flow/)

This other article is also interesting:
[https://medium.com/@mattia.battiston/why-i-love-trunk-
based-...](https://medium.com/@mattia.battiston/why-i-love-trunk-based-
development-641fcf0b94a0)

~~~
mikewhy
Branches are still very much a thing in trunk-based development.

