Remix.run Logo
diggan 3 days ago

> you can always just “jj new” on top of an existing change then squash it down and get automatic rebase past that point

Never used jj, but isn't that just `git commit --amend`? Lets you add/remove/change changes from the previous commit by basically overwritting it with a new changeset+message.

scottgg 2 days ago | parent | next [-]

You can do it to any change in the repo and everything gets automatically rebased downstream of it - so if you three nicely structured changes you can go change the first one if you need and it just works.

I’m selling it short a bit - it does a lot more! There’s a great Steve Klabnik tutorial [1]. To me the main thing is it makes it very easy to think and work in terms of logical changes.

[1] https://steveklabnik.github.io/jujutsu-tutorial/

diggan 2 days ago | parent [-]

> You can do it to any change in the repo and everything gets automatically rebased downstream of it

So does `git rebase -i $commit^1` and marking the commit with `edit`, any commit afterwards (which I think you mean by "downstream"?) also gets rewritten since you've changed a commit in the middle.

I'm not sure if you're selling it a bit short, or if `jj` just have a target audience that I am not a part of, both are of course ok :)

martinvonz a day ago | parent [-]

Yes, the result is (almost) just regular Git commits, so there isn't anything jj can do that Git cannot do. It's just often a lot easier to do it with jj.

A lot of jj users are former Git power users. If all you do you use is `git clone`, `git commit -A`, `git push`, `git pull`, then there's much less to gain for you from switching.

Since you seem to know how to use interactive rebase, I think you are the target audience.

To clarify what's easier in the scenario mentioned above:

1. You don't need to check out a specific branch to start the interactive rebase from. You simply check out the commit you want to edit and then squash into.

2. You don't have to manually rebase other descendant branches. (I.e. if the commit you're modifying is in multiple branches.)

3. Branches (jj calls them bookmarks) get automatically updated. I know Git now has `--update-refs`, but you never need pass that with jj (maybe Git has a config for it, I haven't checked).

4. If you had a dirty working copy before you decided to fix up this commit, you won't need to manually stash or commit those changes.

5. If editing the commit results in conflicts in some descendant, you don't have to resolve those right away.

Try it and let us know how it goes?

yencabulator a day ago | parent | prev | next [-]

I have yet to see anything in jj that isn't also a git operation, they're just emphasized and exposed differently, and the gg GUI makes some things more intuitive (and also makes screwing up your history accidentally much easier).

martinvonz a day ago | parent [-]

In some sense, every jj command does more than any single git command because they implicitly amend the working-copy commit and rebase any descendants on top.

Another example is `jj rebase -d main`. It may look very similar to `git rebase main`, but it rebases a whole tree. See https://stackoverflow.com/questions/17315285/rebasing-a-tree... if you don't know what I mean.

Another example is `jj squash --from main..my-branch --into my-other-branch some/path`, which removes all the changes to `some/path` that happen in any commits in `main..my-branch` and squashes them into the tip commit of `my-other-branch`.

Does that help? I'm not sure I understood your comment correctly.

yencabulator a day ago | parent [-]

Oh I'm not saying jj commands are 1:1 to git. But it looks very much like a convenience layer on git, which is supported by the fact that it (can?) use(s) git as its storage backend. So people are essentially commenting "that jj thing looks perfectly doable in plain git too".

martinvonz a day ago | parent [-]

Yes, that's correct. It's also correct to say that you don't "need" the Git porcelain commands because it's perfectly doable using Git plumbing :)

trust_bt_verify 2 days ago | parent | prev [-]

Sounds like it may be closer to ‘git commit —fixup HEAD’ but same idea.