3 ms·
> I'm confused what this is? jj is a version control system. It is backend-agnostic. The most common backend is a git one, because git is so popular. This allo
by steveklabnik 1y ago
> I'm confused what this is?
jj is a version control system. It is backend-agnostic. The most common backend is a git one, because git is so popular. This allows you to use jj on a git repository, allowing for individuals to adopt it without forcing their teammates to.
> Is it just a git frontend for people who are confused by git?
I used git since before github existed. I considered myself a git lover before I found jj. I will not be going back to git.
The thing is, jj is both simpler and more powerful than git, at the same time. People who are confused by git may like its simplicity, but I like its power.
> It says it abstracts the backend, but it's not clear how something so git-influenced will have abstractions that work with something like a centralized system like Perforce or Piper that has auto-increment numeric commits.
You already got some replies on this one, so I'll leave that to them :)
> Some of the design decisions are also not great. Working copy as commit means you have no quality control. The whole point of a commit is that... you commit it. So now you need a separate repo or filter to remove the worthless changes from the ones that you actually intend to commit. Bad commits polluting git histories is already a big problem.
This is an understandable misunderstanding. The right way to think of it is "the index is also a commit." A common way of working with jj is to do something like this:
Imagine I am working on adding some feature x to my codebase. I'll first make a change, and give it a description:
jj new -m "working on feature x" trunk
Working copy (@) now at: lqqlysul c6756b49 (empty) working on feature x
Parent commit (@-) : ylnywzlx 8098b38d trunk | (empty) foo
Now I will make a new empty change on top of that:
jj new
Working copy (@) now at: pxrvoron c823d73a (empty) (no description set)
Parent commit (@-) : lqqlysul c6756b49 (empty) working on feature x
Now, @- is the change that I intend to push publicly, but @ is my index. Say I add foo.rs:
touch foo.rs
Now, when I run `jj status`, jj takes a snapshot, and it now lives in @:
jj st
Working copy changes:
A foo.rs
Working copy (@) : pxrvoron ba7ad8c6 (no description set)
Parent commit (@-): lqqlysul c6756b49 (empty) working on feature x
We can see the diff here with `jj diff`:
jj diff
Added regular file foo.rs:
(empty)
So, let's say I'm happy with its contents. I want to stage it into my final commit. I can do this with `jj squash`, which by default takes all the diff of @ and puts it into @-:
jj squash
Working copy (@) now at: pxkqmsww 9f7e1ef2 (empty) (no description set)
Parent commit (@-) : lqqlysul 41dc1531 working on feature x
Now that change is in @- instead of @. we can see that by passing -r (for revision) to `jj diff`:
jj diff -r @-
Added regular file foo.rs:
(empty)
I don't have to move the whole change; I can do the same thing as git add -p by using jj squash -i, and only move the portions of the diff.
What's the advantage here? Well, because the index is just a commit, I can use any tools that I use on commits on the index. There's nothing like `git reset` needing to have `--hard` vs `--soft` vs `--mixed` to deal with index behavior: everything is in a commit, so everything acts consistently.
jj makes it very trivial to carve up commits into exactly what you want. It is far easier and more powerful than using the index for the same purpose.
> The biggest problems with git IMO are it scales poorly and it encourages commit pollution. Presumably jj isn't trying to tackle those problems, which is totally fine. But I am confused about which problems it is tackling. That's why I'm wondering whether it's just a frontend that the author finds more to their liking.
IMHO, commit pollution is more due to the pull request workflow than git itself, though I do think that git doesn't do that much to help you. jj can help with this kind of thing, but also on some level, it can only do so much.
- wredcoll 1y agoI want to appreciate this cool-sounding new tool, but everything you've said sounds exactly the same as using git rebase, what am I missing?
- stouset 1y agoGit rebase is, frankly, a massive pain in the ass. It's worth doing if you care about it. I used a rebase-heavy workflow for a decade and a half. But having to drop everything you're in the middle of to fix an endless list of rebase conflicts sucks. And it sucks even worse when you screw up the conflict resolution halfway through and have to start over from scratch. Rebases also don't play nicely with stacked branches. Branches based off your original changes don't get rewritten to be on top of the rebased change, so now multiple rebases are in your future. It turns out that basically none of the rebase friction most people experience is necessary in practice. Rebases can be automatic, implicit, and conflicts can be fixed at your leisure and in whatever order that you feel is best. jj also has a ton of other powers, but you asked about rebase :)
- 1718627440 1y ago> having to drop everything you're in the middle of to fix an endless list of rebase conflicts sucks You can use git commit --fixup to record what you want to change in an earlier commit. > start over from scratch rerere > Branches based off your original changes don't get rewritten As written elsewhere: git rebase --update-refs. If you want to do it manually git rebase --onto.
- baq 1y ago> You can use git commit --fixup to record what you want to change in an earlier commit. jj just does it correctly by default. > rerere jj just does it correctly by default. > As written elsewhere: git rebase --update-refs. If you want to do it manually git rebase --onto. jj just does it correctly by default. defaults matter.
- 1y ago