- Every time I see one of these nifty git tricks or workarounds I find myself wondering, “why not just use jj?”
You get a nicer, significantly simpler interface. You don’t need any tricks. You don’t have to google how to work yourself out of a bad state, ever. And you get near-perfect git compatibility (ie you can use jj on a shared git repo, doing all the same things, and your teammates won’t know the difference).
I’ve wondered if there is a psychological thing here: someone who spent time memorizing all the git nonsense may have some pride in that (which is earned, certainly), that introduces some mental friction in walking away???
by dimitrieh
2 subcomments
- Jujutsu comes in handy here for the same usecase:
https://github.com/jj-vcs/jj
https://www.stavros.io/posts/switch-to-jujutsu-already-a-tut...
Also found https://github.com/gitbutlerapp/gitbutler
by nopurpose
5 subcomments
- That particular case can be solved much easier by rebasing outer-most branch with `--update-refs` flag.
- Even for 'normal' rebases of a multi-commit series (without named feature branches), I habitually use the --onto form. It is simply easier to conceptualise what is happening if one is explicit about the 3 references.
As such, using it for the situation described in the piece then becomes a trivial matter, especially if one also habitually runs a graph viewer - I generally have one or more instances of gitk running all the time.
- I think ‘git rebase —-update-refs’ is the better way to go for this scenario
- I've settled on a workflow that reverses the situation. I simply commit all my work to the main branch and cherry pick commits into temporary feature branches only when submitting PRs.
This way I only need to worry about maintaining a single consistent lineage of commits. I've been using this workflow for about a year now and find it to be much easier than juggling and rebasing feature branches.
In case anyone's interested, I made a tool that automates this workflow. The worfklow and tool are described here: https://github.com/bjvanderweij/dflock/
- GitButler handles all of this pretty automatically, if you don't want to deal with the Git gymnastics needed here.
https://blog.gitbutler.com/stacked-branches-with-gitbutler
by the_gipsy
1 subcomments
- I usually just `git rebase origin/main -i` after the base branch has been merged there, and this means I need to explicitly drop the merged commits, but I can inspect what's happening.
by perspectivezoom
0 subcomment
- I'm a heavy user of git-spice: https://abhinav.github.io/git-spice (created by a former coworker) and can't really go back to a time without it. While still not nearly as good as Facebook's Phabricator, it's probably the best workflow for small, focused stacked PRs you can achieve in a Github / Gitlab based repository.
- I feel that stacked PR in git should be common knowledge, however many of the documentations are scattered. I found stacked.dev but feels that its not exploring pure-git workflow that well. thats why I tried to collect all of those docs into a single website that's dedicated into that singular workflow. would love to get any feedback:
https://stacked-pr.github.io
(disclaimer: partly supported by AI, but most of the writing structure were made by hand)
by happytoexplain
2 subcomments
- Even if `--update-refs` didn't exist, my experience is that git can identify duplicate commits produced by rebase, and knows to skip them when rebasing the same commits to the same place again. Am I imagining that?
- What I would really like is a Git equivalent to Mercurial's "fold" operation. I usually make a bunch of commits as I work, just as checkpoints, which I then want to turn into a single final commit when it's done, which could be quite some time later, e.g. "started on thing", "broke it", "broke it more", "Add thing to improve foo of bar".
Mercurial's "histedit" command offers two operations to combine the commits: "fold" and "roll", where "fold" brings the earlier commit into the later commit and "roll" does the reverse. The "fold" operation does exactly what I want in this case: It brings all the changes into the final commit from when I actually finished it, using the commit date of that commit.
Git's "rebase -i" command offers "squash" and "fixup" and "fixup -c" and "fixup -C", but they all do the same thing as "roll", i.e. they keep the earliest commit's date, the date when I started working on the thing and not the date when I finished working on it. (So I then cut and paste the correct date and update the commit afterwards. This may not be the best way to do it.)
- This made good sense, though by the time I got to bits saying "that last step is critical. Without it, your next sync will break" and "Don't forget!" I was laughing out loud. I love git :-)
by andrebianchessi
0 subcomment
- Stacked commits is awesome, but it sucks that with git you need all these workarounds, and that the servers (GitHub etc) are not designed with that workflow in mind.
I left Google a few months back to work on another project. I missed the internal version control so much that I dropped that other project and am now focused http://twigg.vc
It's very similar to what's used at Meta and Google. Atomic commits, linear history, auto rebase, code review compatible with stacked commits.
by nrhrjrjrjtntbt
1 subcomments
- Fun stuff, but I'll stick to trunk based dev, small PRs... thanks!
by dspillett
1 subcomments
- For the example given, would merging branch 2 into branch 1 then branch 1 into main achieve the same effect?
Perhaps not an option if you need to release the work in branch 1 before the work in branch 2 is ready/reviewed/etc.
- I’ve been meaning to write this article for a long time @flexdinesh . Thanks for taking the time to share this technique for managing stacked diffs using vanilla git rebase!
- I believe the author would love stg: https://stacked-git.github.io/guides/tutorial/#patches
by politelemon
2 subcomments
- This marker branch step feels like a workaround to a missing capability. It's something I can easily see one forgetting especially if they haven't been doing stacked diff workflows regularly.
by hahahacorn
0 subcomment
- I consider myself a shmedium experienced dev who likes to learn their tools and read source.
This seems like a house of cards whose juice isn’t worth the squeeze. But I would love to split up my PRs into smaller pieces.
I just would hate to waste time with an incomprehensibly goofed git history because I forgot a command.
- We use graphite at work to automate this workflow. The whole point is avoid this toil.
- Ah, I've been doing this for ages but apparently this practice has a name
- Is there any reason besides merge commits ending up in history to not do this with merges instead? ie merge main into feature-1, then feature-1 into feature-2.
Sounds like using --update-refs would let you do all that in a single operation, but you still need to force-push and don't maintain an explicit merge/conflict resolution history, both of which could be considered sub-optimal for collaborative scenarios.
by mytailorisrich
2 subcomments
- Instead of "stacked diffs", isn't the more "continuous integration" solution to split a big feature into small chunks that actually get merged?
Having to rebase again and again is a symptom that a dev branch is living for too long.
- Eh I just use `git rebase -i` and delete the commits I don't want. Much easier to think about.
But the real problem with this workflow is that neither Github nor Gitlab support it at all. Not even Forgejo does. Which blows my mind because is such an obvious way to work.
As far as I know only Tangled actually supports it, but unfortunately Tangled is tangled up in its own weird federation ideas. There's no way to privately host it at all.