I don't get JJ. Every time it's posted people gush about how JJ enables some super complicated workflow that I can't wrap my head around. I have a simple feature branch/rebase workflow in git that has served me well for decades so I guess I don't understand why I would want to complicate things with (in this case) an "octopus merge/megamerge". Wouldn't that make it more difficult to reason about the repository/history?

I don't get git. Every time it's posted people gush about how git enables some super complicated workflow that I can't wrap my head around. I have a simple edit/undo workflow in my editor that has served me well for decades so I guess I don't understand...

There is a limit to how far one needs to abstract personally.

I don't layer my utensils for example, because a spoon is fit for purpose and reliable.

But if I needed to eat multiple different bowls at once maybe I would need to.

For my personal use case, git is fit for purpose and reliable, even for complex refactoring. I don't find myself in any circumstances where I think, gosh, if only I could have many layers of this going on at once.

If you think about it, git is really just a big undo/redo button and a big "merge 2 branches" button, plus some more fancy stuff on top of those primitives.

You haven’t helped anyone with this.

If you wrangle a lot of in flight changes that are not yet merged into your teams primary git repo, it's very helpful. I have some 10-30 changes in various states at any time. Sometimes they have dependencies on each other sometimes they don't. Placing them all into one branch can work but it's a lot less ergonomic in many ways. jj makes my life simpler because it accommodates my workflow in a way git doesn't.

Honestly, if you don't find it appealing you don't need to use it. I think a lot of folks don't find vim appealing and stick to vscode and that's okay too.

Every time I hear about this megamerge and stacked pr nonsense, it just smells to me. Like, why does your engineering organization have a culture where this sort of nonsense is required in the first place? Anytime I see articles like this gushing about how great tool XYZ is for stack merging and things like that, all I hear is "you don't have a culture where you can get someone looking at and mainlining your PR on the same day"

The jj lovers can go build their massive beautiful branches off in a corner, I'll be over here building an SDLC that doesn't require that.

Old man yells at cloud moment is over

Not all software is developed by one software organization.

Programs to manage “stacks of patches” go back decades. That might be hundreds that have accumulated over years which are all rebased on the upstream repository. The upstream repository might be someone you barely know, or someone you haven’t managed to get a response from. But you have your changes in your fork and you need to maintain it yourself until upstream accepts it (if they ever call back).

I’m pretty sure that the Git For Windows project is managed as patches on top of Git. And I’ve seen the maintainer post patches to the Git mailing list saying something like, okay we’ve been using this for months now and I think it’s time that it is incorporated in Git.[1]

I’ve seen patches posted to the Git mailing list where they talk about how this new thing (like a command) was originally developed by someone on GitHub (say) but now someone on GitLab (say) took it over and wants to upstream it. Maybe years after it was started.

Almost all changes to the Git project need to incubate for a week in an integration branch called `next` before it is merged to `master`.[1] Beyond slow testing for Git project itself, this means that downstream projects can use `next` in their automated testing to catch regressions before they hit `master`.

† 1: Which is kind of a like a “megamerge”

I'd really like to hear your argument about when single large PR is better than stacked PRs from both PR author and reviewers' perspectives

It depends. We have pretty good review culture (usually same day rarely more than 24H), but some changes may need multiple rounds of review or might be have flaky tests that uncovers after a few hours. Also some work is experimental and not ready for pushing out for review. Sometimes I create a very large number of commits as part of a migration DND I can't get them all reviewed in parallel. It can be a lot of things. Maybe it happens more with monorepos.

All fair points, indeed I face each of the challenges you listed periodically myself. But it's never been often enough to feel like I need to seek out an entirely different toolchain and approach to manage them.

Why would you like git and not jj is beyond me, this must be something like two electric charges being the same and repelling themselves. It’s the same underlying data structure with a bit different axioms (conflicts allowed to be committed vs not; working tree is a commit vs isn’t).

Turns out these two differences combined with tracking change identity over multiple snapshots (git shas) allow for ergonomic workflows which were possible in git, just very cumbersome. The workflows that git makes easy jj also keeps easy. You can stop yelling at clouds and sleep soundly knowing that there is a tool to reach for when you need it and you’ll know when you need it.

> you don't have a culture where

Yeah, and? Not everyone is in control of the culture of the organization they work in. I suspect most people are not. Is everyone on HN CEOs and CTOs?

I think the unspoken part is that the mess of commits is being produced by agents not people.

That’s why it’s always the same confusing hype when it’s discussed, because it’s AI/LLM hype effectively

Depending on people workflow/mindset we often face stacked branches, lots of fixup commits, and over the years new git commands and tricks emerged to deal with that but not in cohesive way I guess. JJ seems (I only tried it a short while long ago) to address just that.

Even with that workflow jj can help a lot. Haven't you ever been annoyed by situations like, while working on a few features at once, having unrelated changes from different feature branches piling up in the stash? Or wanting to switch to another branch mid-rebase without losing your place? jj's working-copy-as-commit model and its first-class treatment of conflicts address those pain points.

No? You work on something and finish it. At most I have 2-3 feature branches open. If none are in review, I have commits in them with current work. Maybe I use the stash 2-3 times a year when I am heavily experimenting with different implementations.

I love Jujutsu because it makes my work simpler, whatever kind of branching/merging structure I use. It just has a better model for me than git.

The thing is, JJ makes mega merges easy... Which opens paths to simple but powerful workflows that match reality better. Having multiple converging changes, or even separated bits of history for $reasons becomes ready without rebar and serializing PRs.

And better conflict resolution means it often becomes viable to just have mega merge add next release

I stick to basic workflows most of the time, and it's still much better.

I concur, seems that lately we’ve collectively forget about the KISS principle.

Sounds like a SVN user complaining about git

> I don't get JJ. Every time it's posted people gush about how JJ enables some super complicated workflow that I can't wrap my head around.

This. Things like stacks and mega-merges are huge red flags, and seeing enthusiastic people praising how a tool is more convenient to do things that raise huge red flags is perplexing.

Let's entertain the idea of mega-merges, and assume a tool fixes all tool-related issues. What's the plan to review the changes? Because what makes mega merges hard is not the conflicts but ensuring the change makes sense.

I use jj but not mega merges. But as I understand it you're not going to push the merge itself for review. It allows you to work locally on multiple branches at once. But when ready you push the individual branch, pre merge, for review.

What's the red flag about a stack?

Trying out jj is super low-risk--since it uses git as a backend, you can test it out and bail back to git without any drawbacks other than a detached head state.

And I hope you do. It is so much better than git in every way. It enables working with stacks and the aforementioned megamerges so easily, allowing me to continue working forward while smaller units of work are reviewed/merged.

When I first tried to use jj, I wasn't entirely committed and switched between jj and git. Finally I hit a breaking point being fed up with stacks/merges and tried jj _for real_.

I recommend to give it a serious try for a few solid days and use it exclusively to really understand it. You won't go back.

The jj Discord is a very helpful place. Thanks to everyone there. Great article Isaac!

I tried out with a tiny project. It is the muscle memory built up with Git that kicks in and wish that JJ does it. I went through all the raw mistakes and doing things the hard way with Git, that, my mind plays trick trying to use JJ with the Git mindset. For now, I have mapped all of my Git aliases to JJ equivalent. But I would like to learn it the right way and do it the JJ way. This is going to take time, I’ll go slow.

I really recommend just ripping off the band-aid and using jj "as intended". It took me only a day or two to adapt, and a week to feel like I am now a jj native. It's really a tiny cost to pay, and way less than the overhead of maintaining a bidirectional mental mapping between jj and git.

> Trying out jj is super low-risk--since it uses git as a backend, you can test it out and bail back to git without any drawbacks other than a detached head state.

Btw, the risk of trying out other modern version control systems is nearly as low: most of them are compatible with git and you can convert back and forth. That definitely includes mercurial etc.

> That definitely includes mercurial etc.

People tried mercurial. They went back to git.

Some did, sure. I made a more limited claim: you can convert back and forth between mercurial and git.

As others have said before, I used Magit in emacs and thay already feels like a superpower compared to git alone.

I’ve been loving it for personal projects. But for work, some of our homebrew tooling relies heavily on hashes. So any operation that causes snapshotting to occur tends to lead to breakage that utterly confounds Claude. I tried giving it rules and instructions to make sure to sync git up to the correct commit for the current snapshot, but as soon as the signal for that is too week in the context it blows a gasket trying to figure out what has gone wrong.

I think I'm missing some major selling point of jj, to me it's just git with a different flow that might be more suitable for a rare few cases where heavy parallel work is happening, and even then git is fine if people know what they're doing, the idea of no staging areas doesn't appeal to me, mutable commits seems actively negative to me personally.

I understand if people are enjoying it great, but the amount of praise and 'this is revolutionary' comments I see makes me really feel I'm missing a beat.

You have to look at it from the workflow side not compare the tool on your current git workflow. Check out https://www.stacking.dev for a description of stacked commits, which is more the everyday workflow on jj than the octopus in this article.

Don't necessarily need heavy parallel work, or even anything parallel, to make use of jj; it's very nice for even just manipulating one local sequence of commits (splitting commits up, reordering them, moving files/hunks/lines between them or into/out of the working copy, without needing to checkout anything).

Won't get you much if you don't like to mutate commits in general, of course; at that point it's just a different committing workflow, which some may like and some dislike. (I for one am so extremely-happy with the history-rewriting capabilities that I've written some scripts for reinventing back a staging area as a commit, and am fine to struggle along with all the things I don't like about jj's auto-tracking)

As a fun note, git 2.54 released yesterday, adding `git history reword` and `git history split` in the style of jj (except less powerful because of git limitations) because a git dev discovered jj.

Did you read the article?

> Basically, in the megamerge workflow you are rarely working directly off the tips of your branches. Instead, you create an octopus merge commit (hereafter referred to as “the megamerge”) as the child of every working branch you care about. This means bugfixes, feature branches, branches you’re waiting on PRs for, other peoples’ branches you need your code to work with, local environment setup branches, even private commits that may not be or belong in any branch. Everything you care about goes in the megamerge. It’s important to remember that you don’t push the megamerge, only the branches it composes.

> You are always working on the combined sum of all of your work. This means that if your working copy compiles and runs without issue, you know that your work will all interact without issue.

You don't even push the megamerge to the origin. Or perhaps you don't even need to push it. You can just... work off it.

> You don't even push the megamerge to the origin.

But why would I do that with git anyway ? My local branch is what I'm working of, if I'm not ready to push, why would I ? I can as you say just work off it..

And when I'm ready to push, I prep my commit, because I'm expecting it to be immutable and pulled by others 'as-is'. Again, I must be missing something. I think the tool is just not for me, yet at least.

Some fantastic tricks in this article. Will definitely improve my Megamerge game. Thanks!

Though, I'd be remiss not to mention that this (and any other) jj workflow would be much easier with jjui. It's the best TUI around, not just for jj

I proposed incorporating some of this article into it. https://github.com/idursun/jjui/discussions/644

Sometimes I have several pull requests to review and none of them have any meaningful overlap (e.g. they touch code in different places, no apparent risk of overlap). So I've started making integration branches to test all of them in one go. But then I sometimes find things to improve upon. Then I might make a few commits on top of that. And then later I have to manually move them to the correct branch. I might also remove them from the integration branch, but git-rebase(1) is likely to just drop them as already-applied.

My mind was a little blown when I read about the megamerge strategy in Steve Klabnik's tutorial.[1]

Yes, Jujutsu's approach of autorebasing changes is very nice. Now all I have to do is to try it myself.

† 1: https://steveklabnik.github.io/jujutsu-tutorial/advanced/sim...

Semi off-topic, but does anyone know of good resources for jj that don't assume git knowledge? Steve's and others are high quality, but often things are explained in terms of git equivalents or describe workflows that I struggle to fully understand the purpose of, as someone who knows only the barest basics of git necessary to work on personal projects.

If none exist, I think there's a great opportunity there, for anyone with the knowledge and motivation to make some absolute beginner guides. Already jj is infinitely more user-friendly, and as the tool matures, it isn't far fetched to think a new generation of programmers could go straight to jj without knowing their way around git first.

I'm not immediately aware. There's a certain amount of git-ness embedded in it with it being a DAG, having commits, and being compatible with git remotes. And, since the industry still runs on git, most people will need to learn it somewhat, anyway.

Honestly, until JJ is 1.0, I wouldn't recommend it for beginners. There's significant changes happening to the interface still.

I've been using it in relatively the same way for a while now. The only meaningful changes were native support for `tug` and `absorb`, neither of which significantly changed my workflow.

Makes me happy to see the influx of jj posts as of late. Great tool. Roughly this workflow is how I convinced a few friends to finally loosen their death grip on git and try something new.

I enjoyed this article a lot, gave me some new ideas for my Jujutsu TUI, Majjit:

https://github.com/anthrofract/majjit

Been trying to get into jj lately, but I rely a lot on VS Code's git gutter to review changes as I code. Doesn't look like jj has an equivalent in VS Code. Anyone got tool recommendations?

You should be able to use the normal git gutter as long as your repository is colocated.

I just use the VS Code git integration with the jj colocated git repo. HEAD is @- and the changes in @ are considered working copy changes. It works for all I was using the VS Code integration for.

Same experience here

There are a number of jj plugins for vsc. VisualJJ and Jujutsu Kaizen are probably the two most popular

https://www.visualjj.com/

https://github.com/keanemind/jjk

> jjk

what's next, "oh! my gitess"? "chainsvn man"?

jjk or jjview

I have a PR up for jjk that does the full change as a review changes, and there's another user's PR that allows diffs over arbitrary ranges (i.e. when working out whether the commits that make up a PR are good as a whole rather than individually)

visualjj, it’s fantastic

[deleted]

Great writeup! I've been using `jj parallelize` [1] a lot (and wrote about it here [2]) to fan out a sequence of commits to set up a megamerge, but your stack alias sounds super useful to create them on the fly, rather than at the very end of a work stream. Thanks for the tips!

[1] https://docs.jj-vcs.dev/latest/cli-reference/#jj-parallelize [2] https://blog.chay.dev/parallelized-commits

You are not actually working in parallel. You are making the cost of stopping one thing near zero. In git, pausing A for B costs a rebase. In jj, you edit B, the stack reflows, you keep going. That is the whole thing. Context switches get cheap so you take them.

I do not understand the appeal of the workflow of working on separate things in parallel, then splitting it off into branches/commits. imo, isn't it better to fully focus on one thing at a time, even if it is "simple"?

I imagine if I follow this workflow, I might accidentally split it off in a way that branch A is dependent on some code changes in branch B, and/or vice versa. Or I might accidentally split it off in a way that makes it uncompilable (or introduce a subtle bug) in one commit/branch because I accidentally forgot there was a dependency on some code that was split off somewhere else. Of course, the CI/CD pipeline/reviewers/self-testing can catch this, but this all seems to introduce a lot of extra work when I could have just been working on things one at a time.

I'm open to changing my mind, I'm sure there are lots of benefits to this approach, since it is popular. What am I missing here?

From practical experience from using jj daily and having (disposable) mega merges:

When I have discrete, separate units of work, but some may not merge soon (or ever), being able to use mega merges is so amazing.

For example, I have some branch that has an experimental mock-data-pipeline thingy. I have yet to devote the time to convince my colleagues to merge it. But I use it.

Meanwhile, I could be working on two distinct things that can merge separately, but I would like to use Thing A while also testing Thing B, but ALSO have my experimental things merged in.

Simply run `jj new A B C`. Now I have it all.

Because jj's conflict resolution is fundamentally better, and rebases are painless, this workflow is natural and simple to use as a tool

It does seem to introduce a lot of complexity for its own sake. This kind of workflow only survives on the absorb command and like you said it doesn't really cover all the interplay of changes when separated. It's a more independent version of stacked diffs, with worse conceptual complexity.

> I do not understand the appeal of the workflow of working on separate things in parallel, then splitting it off into branches/commits.

Your repo is small and/or your CI is fast. You’ll understand in a big repo or when CI has to run overnight to get you results.

Sometimes you want to work on something and as a prerequisite that needs X. Then you realise once X is in place you can actually build a number of useful things against X. And so forth. There’s no good way to merge sequentially, other then a multi merge

I don't think I really understand the way jujutsu is doing this, but if it's what I think, one example would be that you realize while working that some changeset is getting too big and makes sense to split it. So B would depend on A and be on top eventually, but you don't know the final form of B until you've finished with both. I've always just done this with rebasing and fixups, but I could see it being easier if you could skip that intermediate step.

>I do not understand the appeal of the workflow of working on separate things in parallel, then splitting it off into branches/commits. imo, isn't it better to fully focus on one thing at a time, even if it is "simple"?

because agents are slow.

I use SOTA model (latest opus/chatgpt) to first flesh out all the work. since a lot of agent harness use some black magic, i use this workflow

1. Collect all issues 2. Make a folder 3. Write each issue as a file with complete implementation plan to rectify the issue

After this, i change from SOTA to Mini model

Loop through each issue or run agents in parallel to implement 1 issue at a time.

I usually need to do 3 iteration runs to implement full functionality.

"because AI" isn't really a good answer since JJ was not created for AI, and most people who use JJ aren't just AI bots.

I’ve found megamerge really helpful in cases where I’m working on a change that touches multiple subsystems. As an example, imagine a feature where a backend change supports a web change and a mobile change. I want all three changes in place locally for testing and development, but if I put them in the same PR, it becomes too hard to review—maybe mobile people don’t want to vouch for the web changes.

You’re right that I have to make sure that the backend changes don’t depend on the mobile changes, but I might have to be mindful of this anyway if the backend needs to stay compatible with old mobile app versions. Megamerge doesn’t seem to make it any harder.

This can be especially useful in a monorepo where you may need to pull changes in from multiple other branches and projects and build on top of them

I had a big feature I was working on. jj made it easy to split it into 21 small commits so I could give reviewers smaller things to review while I continued to work. It wasn't perfect and maybe git can do it all by itself but it's not my experience.

In other words, I effectively was working on one thing, but at a quicker easier pace.

I've been doing this in git for years. Interactive rebasing isn't that scary. At work we have a very big stacked PR culture on github using native git

As a jujutsu user, I don't disagree. I can see the appeal of doing a megamerge, but routinely working on the megamerged version and then moving the commits to the appropriate branch would be the exception, not the norm.

I gather one scenario is: You do a megamerge and run all your tests to make sure new stuff in one branch isn't breaking new stuff in another branch. If it does fail, you do your debug and make your fix and then squash the fix to the appropriate branch.

If your CI pipeline takes hours and it has good reasons to you start to do things like this.

I wouldn't do it this exact way either but the benefit is "having any local throwaway integration branch" vs. having none at all. You don't need to do it this exact way to have one.

>The absorb command will do a lot of this for you by identifying which downstream mutable commit each line or hunk of your current commit belong in and automatically squashing them down for you. This feels like magic every time I use it (and not the evil black box black magic kind of magic where nothing can be understood), and it’s one of the core pieces of Jujutsu’s functionality that make the megamerge workflow so seamless.

IUUC This is already implemented for git as an extension. https://github.com/tummychow/git-absorb

I think this is such a basic thing that should be part of any DVCS implementation.

Something really magical about “Distributed Version Control System” sharing an acronym with “Disney Vacation Club Services”.

Great article, Isaac!

If anyone is JJ-curious, I also can't recommend the Discord[1] enough. The community is very helpful and welcoming.

[1]: https://discord.com/invite/dkmfj3aGQN

I reluctantly stopped using mercurial 10 or so years ago, and reading this brings a little tear to my eye. Mercurial was just about where jj seems to be now. It had revsets. It had just gotten the concept of mutable and immutable commits. It had absorb. It had bookmarks. It never had an "index". The commands had human readable options like I see in this post. It could work with git repositories. Man I miss it.

I'm hesitant to pick jj up in case it ends up losing to git like mercurial did. But it's very tempting.

It can't really lose to git, because underlying it is git

One of the golden rules of git is: Don't rewrite public history (for example by rebasing and force-pushing already published commits). The article hints at immutable and mutable commits (https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-an...) but I am unsure about how fundamental this protection is. I don't want to ruin my co-worker's day by accidentally rewriting public history.

Don't rewrite shared public history

It's ok to force-push a branch that only you have worked on (and even in the case of others working on the same branch it can be fine as long as you communicate with them)

There's a configurable setting for which changes are marked as immutable. The default works perfectly for my workflow (pull-only from upstream, rewrite and push freely to my fork). other workflows may presumably need to tweak it

https://www.jj-vcs.dev/latest/config/#set-of-immutable-commi...

Jujutsu is immutable for public changes by default.

You can force changes with a ‘—ignore-inmutable’ flag.

If this works like I think it does, it might be the missing piece I've been waiting for, for actually trying jj. Thanks!

Awesome! Tbh other than GitButler idk where I'd even start if I had to recreate this with vanilla Git

Can this technique help with fixing a bug on master then having to merge it easily to older release-branches , without resorting to cherry-picking (and losing all history)?

"Evil" merged are only evil if your tooling skips over merge commits as "unimportant" which is a common tactic to try and prune some of the crazy trees you get when hundreds of people are making merge commits into a repo which then creates its own commits for automation reasons...

I found octopus megamerge hard to collaborate - my colleagues don't use JJ so they may introduce changes that would cause conflitcts to my megamerge. When you have a conflict on a change that has more than 2 parents, the conflict resolution becomes unmanageable very quickly. No merge tool can handle more than 3-way merge, so you have to do that manually.

Eventually I settled on a tree-like megamerge that's more practical: merge 2 branches at a time and merge the merged branch with the next branch. This way I only need to handle 2-way conflicts at a time which is more manageable.

Also you have to be very careful to decide the order when you (and your colleagues) are going to land the branches, or if you expect any new features other people are working on that's going to conflict with your branches. When using megamerger workflow, most of the problems come from coordinating with other colleagues.

Fwiw I've not had this experience, I use megamerges in teams of 8+ devs without much issue

I was skeptical at first but when I dragged and dropped a bookmark in `gg` then a light went on in my head. Also the fact that jujutsu does everything in "detached mode" locally means that you can't mess up your remote git repo (unless you force push all yolo from git itself, but you're never expected to do that).

How does the megamerge handle the case where two included branches overlap in changes and a new commit is made that applies to the overlap?

This is something you have to generally handle manually since absorb won't squash hunks with ambiguous targets, but I typically stack these branches and accept the dependency. I have had instances where this has backfired a little bit re: ordering but thankfully with JJ and the very patient little man in my computer named Codex it's easy to reorder them and end up with the same diff

The mega merge wouldn't handle that based on the way the article shows. You COULD have a revset that includes stacked changes, though. That does work and is what I currently do.

Could you please elaborate on how you do this?

I love this stuff as a hobbyist, but professionally I can't help but think this is all obsolete in the age of agent-driven development. I wish jj was around a decade ago.

I disagree. Easily reviewing and combining multiple streams of parallel work is more valuable than ever.

With jj worktrees, you can even have agents working on each of those sub-megamerge branches in parallel.

I've been playing around with agent-native source annotation to specifically address the massively parallel work problem. Check it out here: https://github.com/draxl-org/draxl

You don’t need jj for this anymore. The whole premise of optimizing human workflows around source control is becoming obsolete.

When LLMs are driving development, source control stops being an active cognitive concern and becomes a passive implementation detail. The unit of work is no longer “branches” or “commits,” it’s intent. You describe what you want, the model generates, refactors, and reconciles changes across parallel streams automatically.

Parallel workstreams used to require careful coordination: rebasing, merging, conflict resolution, mental bookkeeping of state. That overhead existed because humans were the bottleneck. Once an LLM is managing the codebase, it can reason over the entire state space continuously and resolve those conflicts as part of generation, not as a separate step.

In that world, tools like jj are optimizing a layer that’s already being abstracted away. It’s similar to how no one optimizes around assembly anymore. It still exists, it still matters at a lower level, but it’s no longer where productivity is gained.

> The unit of work is no longer “branches” or “commits,”

It better be, now and going forward for people who use LLMs..because they will need it when LLM messes up and have to figure out, manually, how to resolve.

You ll need all the help (not to mention luck) you need then..

There are a lot of assumptions baked into your assessment. We are not at the point where manual workflows are obsolete. Maybe it is for folks who work on web apps, but it's certainly not the case for many others. AI Agents are constantly making mistakes and need oversight. Things have gotten dramatically better, but not enough for me to trust it to not create a terrible mess.

A lot of words to say "LLMs are good for this, trust me bro!"

You're bashing the old way, but you do not provide any concrete evidence for any of your points.

> The unit of work is no longer “branches” or “commits,” it’s intent.

Insert <astronaut meme "always has been">.

Branching is always about "I want to try to implement this thing, but I also want to quickly go back to the main task/canonical version". Committing is about I want to store this version in time with a description of the changes I made since the last commit. So both are an expression and a record of intent.

> Parallel workstreams used to require careful coordination: rebasing, merging, conflict resolution, mental bookkeeping of state.

Your choice of words is making me believe that you have a poor understanding of version control and only see it as storage of code.

Commits are notes that annotates changes, when you want to share your work, you share the changes since the last version everyone knows about alongside the notes that (should) explain those changes. But just like you take time to organize and edit your working notes for a final piece, rebasing is how you edit commits to have a cleaner history. Merging is when you want to keep the history of two branches.

Conflict resolution is a nice signal that the intent of a section of code may differ (eg. one wants blue, the other wants red). Having no conflict is not a guarantee that the code works (one reduces the size of the container, while the other increase the flow of the pipe, both wanted to speed up filling the container). So you have to inspect the code and run test afterwards.

Discard the above if you just don't care about the code that you're writing.

I've found agents like Claude are absolute ass at fixing any halfway complex merge conflict. I won't trust them to do it.

Actually it’s more relevant than ever since agents trivially parallelize work, but it still needs to be validated together. You can work on individual branches in worktrees and have the ‘megamerge’ in yet another.

I have been using Claude for 95% of the mechanical coding for months, and jj has proven to be more relevant than not for me. Because it is a better VCS tool than git, it allows to work with the firehose of commits much more seamlessly.

this is great stuff. I've been ad hoc building a version of this workflow, and it is quite fantastic.

I'm still not as smooth at figuring out conflicts on mega-rebase.

It's interesting to see the strange workflows that come from jujutsu users, as someone who works on git workflows.

There's some counterproductive stuff in there from my perspective but at its core you're keeping up a throwaway integration branch, which is helpful practice if you'll ever care about an integration. It's annoying with git because the interface for updating your throwaway integration branch is very clunky and easy to get wrong.

Finally

Look man life gets busy and I'm horrible at accepting "good enough" lol

love to see it, been looking forward to this.

I saw Jujutsu on HN a few days ago and gave it a try. I picked a bunch of it up in just a couple hours and a couple days later I've completely switched to it for all my projects, it's not even close. Git is dead to me.

I just wish Jujutsu supported git tags rather than only supporting bookmarks as branches. And I also wish that Jujutsu supported preserving commit dates during rebases.

One of my absolute favorite things about Jujutsu is how easy it is to manipulate the commit graph remotely without having to manually checkout each commit first. I've been working on some pull requests to their built-in diff editor lately trying to improve the user experience enough that most conflicts will be fixable without having to use a text editor.

Also, the lack of a special staging area means you also never have to fucking stash your changes before you can do practically anything. Your changes always have a place, you can always go somewhere else and you can always come back.

> git tags

There are commands for manipulating tags (jj tag set, jj tag delete), and recently [1] support for fetching / pushing

[1]: https://github.com/jj-vcs/jj/pull/9279

Oh? That's incredibly recent. Thank you for letting me know. As it turns out, I just built jj from source earlier today, so ironically I should already have tags. I'll give it a try.

Re: commit dates, fundamentally those always change when rebasing because you're rewriting the commit object, but we don't touch the author date unless you explicitly reset it with metaedit

Same here, picked it up a week ago and haven’t touched git again.

Probably my favourite thing that has really changed my workflow is being able to write empty commits in advance then just switch between them. It helps me remember what I’m doing and whats next whenever I get distracted or take a break.

Great post. Thanks for sharing.

Thanks!

[dead]

[dead]