Hacker News new | ask | show | jobs
by arxanas 1421 days ago
git-branchless author here. By "branchless", I mean literally using detached HEAD as the primary state of development. If you're using tools like Gerrit or Phabricator, you never have to explicitly make a branch to get your code merged. If using GitHub, then branches are unavoidable, but it can be nice to do branchless development as part of rapid prototyping (see https://github.com/arxanas/git-branchless/wiki/Workflow:-div...).

Another term you could use is "anonymous branching". This is not technically accurate in the above workflows, but it captures the essence pretty well in Git, more so than "branchless".

1 comments

But when you call it "anonymous branching" you lay bare that the only advantage is that you don't need to name your work "branch", and meanwhile you have a workflow that's needlessly incompatible with most other git tooling.

In particular, since this is the one I see usually called out as a benefit of branchless:

Stock Git does not have good ways of rebasing a sequence of branches.

A sequence of branches can be rebased by rebasing (or otherwise rewriting) the longest one (the only one you'll need locally) then pushing the individual commits in the current branch to the remote under any relevant branch names. This doesn't take zero time, but with good git UIs it will take less time than remembering `git move`, and it's not especially hard to do with the stock CLI either.

> But when you call it "anonymous branching" you lay bare that the only advantage is that you don't need to name your work branch

Sure, I'm only responding to what you were saying about "There is no such thing; considering one special branch as 'not a branch'". There is such a thing in that there is no branch involved in the detached HEAD state. It's not some kind of Git misunderstanding. I think you might be referring to trunk-based development and always building off of the remote main branch instead of having your own local copy, which is unrelated to being "branchless", for the reasons you stated.

For many people (particularly those on Github!), a branchless workflow won't help, so you're free to not use it. In my opinion, it's a workflow that is better compatible than stock Git with code review tools like Gerrit and Phabricator.

I personally argue that anonymous branching is useful even in some branch-based workflows. Mainly, if Git branches are so lightweight to use, why do we also use the command `git stash`, instead of just always creating a new branch for our temporary work? One benefit of anonymous branching is that it consolidates these workflows in a convenient way. Some people don't stash changes or feel that branching in those cases is heavyweight, so anonymous branching doesn't help them at all.

> then pushing the individual commits in the current branch to the remote under any relevant branch names

If I'm understanding correctly, every time you rebase the longest branch, for each commit in the branch, you would manually run e.g. `git push <commit> origin:my-branch-name`? That seems like it would take a lot of time to me. Is the tacit assumption here that you don't have a lot of commits in your branch, so this doesn't take a lot of time?

> There is such a thing in that there is no branch involved in the detached HEAD state.

But at the very least there's still an existing remote branch, which is the ultimate merge target, for example - perhaps even multiple. Since we're talking about coordination, there's also the actual state at the remote vs. my view of the remote vs. my teammates' views of the remote. But we don't think about this too much, because we can synchronize easily as long as the remote branch has a name. Taking the name off the branch makes it more difficult to do anything with someone else's work other than merge it, e.g. pass a changeset back and forth or hand over a half-complete task.

> why do we also use the command `git stash`, instead of just always creating a new branch for our temporary work?

I have no idea actually, because I don't. I haven't run git stash manually since I learned about autostash, and even before that it wasn't for temporary work but for changes I decided I wanted somewhere else only after writing them. Temporary work mostly does get a branch (usually as a new commit on top of my current local branch).

> If I'm understanding correctly, every time you rebase the longest branch, for each commit in the branch, you would manually run e.g. `git push <commit> origin:my-branch-name`?

Close, except I'd scroll down the list of commits and type `P o RET TAB branch-name` (or something to that effect, it'd be slightly different if I have several remotes). This would take perhaps ~0.5 seconds per branch and not require me to context switch to a terminal.

It does take longer for people using less powerful clients, but virtually all do provide some way to do it even it means a few right-clicks on a menu and clicking some "OK" buttons, and there's value in everyone using analogous operations. And the people using those clients usually can't reliably recover from a large class of "git broke" mistakes, assistance from git-branchless or not, so handing them a CLI and a prayer is out of the question. And even the "long version" is pretty negligible (like, maybe 10 seconds per branch?) compared to everything else you should do to make your changeset approachable for review.

Which Git client do you use, and also, how do you remember all the remote branch names?

> And even the "long version" is pretty negligible (like, maybe 10 seconds per branch?)

I notice that mainly the differences in opinion with regards to workflow is disagreement about "how long is too long" for various operations :)

Magit, and the remote branch names are visible in the log view and easy to enter via tab completion. (We're still talking about stacked PRs right? Median stacked at any given time is probably 2 and p90 is maybe 4? Max I've ever seen is ~10 and that was quite a fucked up situation for plenty of other reasons.)

10 seconds would certainly be too long for me. It is obviously not too long for them, or they'd learn some keyboard shortcuts to get the easy 5 out of the way to begin with. But regardless, it's all pretty much dwarfed by things that need actual brainpower like re-reading my commit messages for grammatical errors / broken links / etc.

I see, thanks for the information. I often stack 10+ commits, so I don't think your workflow would be reasonable for me. (For example, here, I have 11 finished commits and 3 in progress: https://github.com/arxanas/git-branchless/pull/451 — but I don't actually use stacked PRs on Github, particularly if no one is reviewing my code. Most of my stacking is at work with Phabricator anyways, which handles this better.)