My unorthodox, branchless Git workflow
drewdevault.com
drewdevault.com
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.
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.He may think that he is rebasing later anyway, but sorting all those commits into "need for my feature" vs. "don't need for my feature", followed by the rebasing within the feature certainly takes much longer than the split second of creating a branch and keeping those features separate from the beginning.
It's great if it works for him, but he's certainly not saving time.
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.
All build systems (that people actually use) are really bad.
Sure, but its not like the different changes just don’t exist if you use only master, branches are a way of managing them separately and only merging when you are ready, if you don’t use branches, you have to have some other way to manage this. If you don’t, and its not a problem, then you could also just not work on three branches at once.
I don't see the value-add at all.
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.)
>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.
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.
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.
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.
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?).
Way way more organized to use branches.
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.
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.
Eh. I can use an iPad as a cutting board, but I'm not going to put that down as one of the iPad's achievements.
[1]http://www.procode.org/stgit/ [2]https://en.wikipedia.org/wiki/Quilt_(software)
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.
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!
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.
https://blog.sebastian-daschner.com/entries/git-commit-fixup...
1: http://www.procode.org/stgit/
I miss the days when you were expected to use a porcelain on top of raw git.
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/
This other article is also interesting: https://medium.com/@mattia.battiston/why-i-love-trunk-based-...