# Branchless Git


Git is a (in)famously
[polarizing](https://matt-rickard.com/the-terrible-ux-of-git/) tool, and there
are as many distinct Git workflows as there are developers that use Git.
However, since Git has the most mindshare of any extant VCS tool, it's worth
finding ways to make it more comfortable to use.

One Git usage pattern that I think is underused is the "branchless" workflow.
The idea here is pretty intuitive if you've used
[trunk-based development](https://trunkbaseddevelopment.com/): there's just one
"main" branch that everything gets merged into. No feature branches, no release
branches, no hotfix branches.

The "branchless" workflow is, in a nutshell: You work in a stack of atomic
commits which are all eventually intended to be merged into a single trunk
branch. Each commit can become a pull request, and each pull request consists of
a single commit.

When you're working on a commit, incremental changes are amended into the
commit, instead of being added as a new commit. Commits can be "stacked" in your
local copy, and you jump between them to make changes. Commits can also be
reordered or moved to change the dependency relationship between commits.

I've been using a "branchless" workflow in a Mercurial environment for a few
years, and wasn't aware until recently that it was possible to do the same thing
in Git. My favorite tool so far that implements "branchless git" is, fittingly,
[git-branchless](https://github.com/arxanas/git-branchless). Since a picture
speaks a thousand words, here's a screencast of git-branchless in action:

[![asciicast](https://asciinema.org/a/3UVPMf0IpJaGdP6Kd6Zum4cq8.svg)](https://asciinema.org/a/3UVPMf0IpJaGdP6Kd6Zum4cq8)

In my opinion, the key features of git-branchless are:

-   Navigation commands for moving between commits (e.g. `next`, `prev`,
    interactive `checkout`).
-   The ability to view the local graph of commits (`smartlog`).
-   The ability to automatically rebase commits following an amend (`restack`).

What are the benefits of the branchless workflow?

-   It makes it feasible to use a
    [stacked diff](https://jg.gg/2018/09/29/stacked-diffs-versus-pull-requests/)
    workflow on top of Git.
-   It's more manageable to maintain a set of dependent commits, swap between
    them, and have "child" commits automatically get updated with the changes of
    their parents.
-   Commits can be more easily reordered. e.g. You can move a commit within your
    local tree of commits, and all its children will move with it.

What are the downsides of the branchless workflow?

-   It's amend-heavy, which git doesn't handle very well by default. Under the
    hood, amending a commit in Git actually creates a new commit with updated
    contents, which means you lose the history of the old commit unless you have
    an external system that can track it.
-   You're swimming upstream (no pun intended) against common git patterns.
    Github doesn't support this workflow well, for example, since you need to
    have _a_ branch to open a pull request.
-   The ecosystem is still pretty new. The tools aren't rock-solid yet, and it's
    too soon to know if they'll have staying power.

I would not recommend using git "branchlessly" unless you have an external
helper tool -- the built-in commit, amend, and rebase commands just aren't
suited to it. However, there is a growing ecosystem of commands that support
this workflow. Aside from
[git-branchless](https://github.com/arxanas/git-branchless), there's:

-   [epage/git-stack: Stacked branch management for Git](https://github.com/epage/git-stack)
-   [Stacked Git](https://stacked-git.github.io/)
-   [ezyang/ghstack: Submit stacked diffs to GitHub on the command line](https://github.com/ezyang/ghstack)
-   And
    [more](https://github.com/epage/git-stack/blob/main/docs/comparison.md)...

I ended up sticking with git-branchless, since it works quite well with
[Gerrit](https://www.gerritcodereview.com/) (the Git review tool that I use at
work). I've made a
[few contributions](https://github.com/arxanas/git-branchless/commits?author=bcongdon)
to git-branchless, so at this point I'm biased (😄), but it's one of the better
new tools that I've picked up recently. Highly recommended!

[^1]: By this, I mean "all commits must pass tests and build successfully".

