Remix.run Logo
bilekas 2 days ago

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.

jFriedensreich 2 days ago | parent | next [-]

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.

codethief 2 days ago | parent [-]

> If using a tool doesn't speak to you, git is adding more support for stacking every day. The new --update-refs option lets you update a stack with fewer rebases; however, parts of the stacking process are still tedious (i.e. opening PRs on GitHub or any other provider).

This doesn't seem to be entirely up-to-date: http://github.github.com/gh-stack

dzaima 2 days ago | parent | prev | next [-]

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.

jychang 2 days ago | parent | prev [-]

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.

bilekas 2 days ago | parent [-]

> 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.

dwattttt 2 days ago | parent | next [-]

I've often found myself needing to work on two features at once, esp. where one has a dependency on the other. Maybe that branch is the real goal, and the other branch is an independent chunk of work that the feature needs.

Both get iterated on, because it's hard to know everything about a feature before it's done; maybe you find bugs that need fixing, or you realise you were missing something.

Rebasing the dependent branch onto the tip of the other branch gets you there, but as a workflow it's not pleasant, especially if you're not the only person working on the features... It's a recipe for conflicts, and worse that rebased branch conflicting with another person's view of it.

JonGretarB 2 days ago | parent | prev | next [-]

Another example is that there is this simple monorepo that holds both the latest _BlaJS_ frontend and the backend API.

You are working on stuff in the backend, but it sure would be nice to see it in the frontend so you jury rig something in the frontend to display your work as well as some console.log() commands. Then you forget to revert changes to the frontend before pushing the branch.

In jj you would start with these as separate branches. Then you work on a merge of these. Then you use the absorb command to auto-move the code you are working on to the correct branch or you squash the changed files to the branch. Then you can push the backend branch to server and PR it. Then you throw away the frontend branch or just leave it there so you can use it in a future feature.

A real case from my work. I had to work on an old Python project that used Poetry and some other stuff that was just not working correctly on my computer. I did not want to toucj the CD/CI pipeline by switching fully to uv. But I created a special uv branch that moved my local setup to uv. Then went back up the tree to main and created a feature branch from there. Merged them together and worked out from that branch moving all the real changes to the feature branch. Now whenever I enter that project I have this uv branch that I can merge in with all the feature branches to work on them.

pythonaut_16 2 days ago | parent | prev [-]

Imagine you have 3 branches: local-dev-tuneup, bugfix-a, feature-b

Remember in JJ you're always "in a commit", so the equivalent of the git working tree (i.e. unstaged changes in git) is just a new commit, often with no description set yet. (Because in JJ a commit also doesn't need a description/commit message immediately).

So in a mega-merge you can have a working tree that pulls from local-dev-tuneup, bugfix-a, and feature-b, and you can then squash or split changes out of it onto any of those source branches. Like you can avoid serializing those branches before you're ready to.

I've definitely faced the scenario in Git where I have a unmerged changes that I want to use while continuing work on a feature branch. I end up creating a PR for the branch of the first smaller features (e.g. local-dev-tuneup->master), then a second PR pointing at the first (feature-a -> local-dev-tuneup). It works but it's all a bit cumbersome, even more so if feature-a ends up needing to land before local-dev-tuneup. JJ has better tools for handling this.

Or potentially a team member has critical changes with a PR open and you want to start building on top of their changes now. Manageable in Git but you're locked in on a branch of their branch. Now add a second set of critical changes. Can be done in git but you'll be jumping through hoops to make it happen.

Of course you might say that all indicates a workflow/process problem, but my experience is this situations are common enough but not frequent.

(I haven't actually used megamerges myself yet but the article has me ready to try them out!)