The last paragraph might be the most important one:
> There's one other reason you should be interested in giving jj a try: it has a git compatible backend, and so you can use jj on your own, without requiring anyone else you're working with to convert too. This means that there's no real downside to giving it a shot; if it's not for you, you're not giving up all of the history you wrote with it, and can go right back to git with no issues.
We all need to give ourselves a push and finally make the next step in version control. Github, Google, Microsoft, Meta (did I forget anyone relevant? Probably) should just join forces and finally make it happen, which should not be a problem with a new system that is backend compatible to Git. Sure, Github may lose some appeal to their brand name, but hey, this is actually for making the world a better place.
I'm giving jj a try but one aspect of it I dislike is edits to files are automatically committed, so you need to defensively create empty new commits for your changes. As in, want to browse the repo from a commit 2 weeks ago? Well if you just checkout that commit and then edit a file, you've automatically changed that commit in your repo and rebased everything after it on top of your new changes. So instead you create a new branch off of the old commit and add an empty commit to that branch so any file changes don't end up rewriting the past 2 weeks of history. git is much nicer in that I can do whatever I want to the files and it won't change the repo until _I tell it to_.
> so you need to defensively create empty new commits for your changes.
I thought that for a long while too, and was equally pissed. Then I happened upon `jj evolog`. Turns out jj had a better solution than staging all along - I just didn't realise it existed.
The move from using jj as an alternate porcelain to git to using it efficiently took me more months than I care to admit. I suspect being familiar with git cli is actually a handicap in learning jj. New users without pre-conceptions will have a much easier time of it.
And oddly, I also suspect they will also end up knowing more about the underlying git storage engine than git users. It turns out it's capable of being used far more effectively than git uses it.
Doubly oddly, I blame Linus's familiarity with CVS and SVN for that. He (correctly) bemoaned how unsuited to the job of distributed source code management they were and invented a storage engine that has proved to be remarkably good at the job. But he carried across many the concepts in their CLIs to gits porcelain. Jj (with a lot of help from hg), finally broke free of that legacy.
You can turn that off (I do). In your config file:
[snapshot]
auto-track = "none()"
Auto-tracking could be a great default in certain projects, and a terrible one in others. jj doesn't require it at all and is still awesome without it.
Bonus tips:
# show help by default, as the subcommands do
[ui]
default-command = "-h"
# more readable log (also affects jjui)
[templates]
log = 'builtin_log_oneline'
Has anyone found a good code review workflow with `jj`? My problem is that GitHub doesn't remember the content of the last reviewed SHA, so every time I push a new change from jj, reviewers lose the delta from their last reviewed commit.
To work around this I stopped moving revs (squash/rebase) after review starts, which creates awkward local graphs if I have to merge from main for merge conflicts. Graphite works but it's $$$, and phabricator/reviewable/gerritt all have significant onboarding hurdles.
I would like more uniformity in the way jjui handles commands when you are viewing changes vs when you are viewing files within a single change.
Often I just make my changes and leave it there without `new`, as I am not sure which file should go in a single commit. I just leave it there and I interactively commit later.
For me to use `new` more, I would like the ability to also simply be able to get a tree view of all changes, which contains file which contains file changes, so I could can have marks that span multiple changes and then either `split` or `commit` or `squash` the change, idk if there is a good word for it. Right now I can only mark within a single change, and I lose it once I navigate up.
yeah, i know almost nothing about jj because i only use it via jjui. Why would I waste brain power learning about and remembering new incantations when I can just browse around with arrow keys and mouse and then use like 9 hotkeys to do everything that I could possibly need?
1) Are there any benefits in replacing a personal private project git repo with jj? I usually just commit straight to master in order to just not to lose the changes and be able to roll back.
2) Are there any pros in doing so in a project with many large binary files (3d models, images)?
Is there a concise introduction / overview of jj? I've read 8 pages of this link and the author is still in preambles and considerations... Not my favourite style of article!
Does JJ really prefer for me to think backwards? It wants me to start with the new and describe command, but with git I first make the changes and name the changeset at the end of the workflow.
I also often end up with in a dirty repo state with multiple changes belonging to separate features or abstractions. I usually just pick the changes I want to group into a commit and clean up the state.
Since it's git compatible, it feels like it must work to add files and keep files uncommitted, but just by reading this tutorial I'm unsure.
JJ doesnt prefer you to do anything. I regularly just create description-free commits, do whatever, then name them later (or squash, split, absorb the changes into other commits). It is exceptionally flexible and forgiving. Even moreso if you use jjui, the best TUI ive ever used.
> Does JJ really prefer for me to think backwards?
No, you run `jj new` when you’re done with your work just like you’d run `git commit`. You can even just run `jj commit` which is a shorthand for `jj describe && jj new`.
If you want to have a workflow similar to Git with index, check out the Squash Workflow: basically, you would edit your files in a disposable commit having the same purpose of Git’s index.
I tend to approach jj commits as local PRs. Decide what it is I'm working on, make a new, empty commit on top of that :
jj new -m 'do thing'
jj new
As I work on the "local PR", I `jj squash` my working changes into the named commit. By keeping my working commit description-free, I avoid accidentally pushing it (and potentially broken code) to origin.
> Does JJ really prefer for me to think backwards?
Perhaps it’s the other way around. I have a standard agentic instruction to summarize prompt instructions using jj describe. After it makes changes I can see both the file changes made and a log description of what prompted those changes. When done it’s just jj new and its ready for the next set of prompts.
I tried jj for a few months. It was fun to learn a new thing, but I haven't had a single case of "wow, this would have been a pain with git". Then I went back to git (it's been 6 months now) and I haven't had a single case of "this is so painful, I wish something better existed".
So it felt like the XKCD on "standards": I now have one versioning system, if I learn jj I will have two. What for?
Don't get me wrong: it's nice that jj exists and some people seem to love it. But I don't see a need for myself. Just like people seem to love Meson, but the consequence for me is that instead of dealing with CMake and Autotools, I now have to deal with CMake, Autotools and Meson.
EDIT: no need to downvote me: I tried jj and it is nice. I am just saying that from my point of view, it is not worth switching for me. I am not saying that you should not switch, though you probably should not try to force me to switch, that's all.
its almost impossible for me to tell if this better or worst than git
i read few things about jj, and my conclusion
1. its different
2. very few user would really care about this difference
i think git is good (not good enough, good just good, or really good)
and unlike shells, i cant think of a reason to have mass migration to it
people use zsh because apple choose it, and pwsh because microsoft settled on it,
on linux i am sure we can do better than bash, but it good enough and nothing justified replacing it (that being said, all 3 OSes should have settled non nushell)
in summary, if we couldnt replace bash on linux, i dont think anyone can replace git, git as an scm tool if far better than bash as a shell
we may have not been able to replace bash yet, but the popularity of alternative shells that are not bash compatible is growing. besides nushell there are fish, elvish, murex, oils (also includes a bash compatible mode to help with the transition) and probably some others that i missed. i see more and more tooling support for some of these, which shows that usage of these shells is growing.
JJ might be good (this article couldn't convey why in the "What is jj and why should I care?" page) but it's not 10x better than git, so it will likely die. Sorry, nothing personal, Mercurial/hg was a little bit better than git and died too. Network effects.
What has a change is ast-based version control.
You adding a feature to a function that uses a struct I renamed shouldn't be a conflict. Those actions don't confliuct with each other, unless you treat code as text - rather than a representation of the logic.
Ending merge conflicts might make a new version control 10x better than git, and therefore actually replace it.
Many folks aren’t aware that there is also an open-source, cross-platform desktop GUI application for Jujutsu called GG: https://github.com/gulbanana/gg
I mention it because while the jj command line interface is excellent, there are certain tasks that I find easier to perform with a graphical user interface. For example, I often want to quickly tap on various revisions and see their diffs. GG makes that kind of repository browsing — and certain squash operations — much more efficient for me.
94 comments
[ 3.1 ms ] story [ 82.0 ms ] thread> There's one other reason you should be interested in giving jj a try: it has a git compatible backend, and so you can use jj on your own, without requiring anyone else you're working with to convert too. This means that there's no real downside to giving it a shot; if it's not for you, you're not giving up all of the history you wrote with it, and can go right back to git with no issues.
I thought that for a long while too, and was equally pissed. Then I happened upon `jj evolog`. Turns out jj had a better solution than staging all along - I just didn't realise it existed.
The move from using jj as an alternate porcelain to git to using it efficiently took me more months than I care to admit. I suspect being familiar with git cli is actually a handicap in learning jj. New users without pre-conceptions will have a much easier time of it.
And oddly, I also suspect they will also end up knowing more about the underlying git storage engine than git users. It turns out it's capable of being used far more effectively than git uses it.
Doubly oddly, I blame Linus's familiarity with CVS and SVN for that. He (correctly) bemoaned how unsuited to the job of distributed source code management they were and invented a storage engine that has proved to be remarkably good at the job. But he carried across many the concepts in their CLIs to gits porcelain. Jj (with a lot of help from hg), finally broke free of that legacy.
Bonus tips:
To work around this I stopped moving revs (squash/rebase) after review starts, which creates awkward local graphs if I have to merge from main for merge conflicts. Graphite works but it's $$$, and phabricator/reviewable/gerritt all have significant onboarding hurdles.
I would like more uniformity in the way jjui handles commands when you are viewing changes vs when you are viewing files within a single change.
Often I just make my changes and leave it there without `new`, as I am not sure which file should go in a single commit. I just leave it there and I interactively commit later.
For me to use `new` more, I would like the ability to also simply be able to get a tree view of all changes, which contains file which contains file changes, so I could can have marks that span multiple changes and then either `split` or `commit` or `squash` the change, idk if there is a good word for it. Right now I can only mark within a single change, and I lose it once I navigate up.
I also often end up with in a dirty repo state with multiple changes belonging to separate features or abstractions. I usually just pick the changes I want to group into a commit and clean up the state.
Since it's git compatible, it feels like it must work to add files and keep files uncommitted, but just by reading this tutorial I'm unsure.
No, you run `jj new` when you’re done with your work just like you’d run `git commit`. You can even just run `jj commit` which is a shorthand for `jj describe && jj new`.
https://arialdomartini.github.io/pre-emptive-commit-comments
If you want to have a workflow similar to Git with index, check out the Squash Workflow: basically, you would edit your files in a disposable commit having the same purpose of Git’s index.
Perhaps it’s the other way around. I have a standard agentic instruction to summarize prompt instructions using jj describe. After it makes changes I can see both the file changes made and a log description of what prompted those changes. When done it’s just jj new and its ready for the next set of prompts.
So it felt like the XKCD on "standards": I now have one versioning system, if I learn jj I will have two. What for?
Don't get me wrong: it's nice that jj exists and some people seem to love it. But I don't see a need for myself. Just like people seem to love Meson, but the consequence for me is that instead of dealing with CMake and Autotools, I now have to deal with CMake, Autotools and Meson.
EDIT: no need to downvote me: I tried jj and it is nice. I am just saying that from my point of view, it is not worth switching for me. I am not saying that you should not switch, though you probably should not try to force me to switch, that's all.
people use zsh because apple choose it, and pwsh because microsoft settled on it, on linux i am sure we can do better than bash, but it good enough and nothing justified replacing it (that being said, all 3 OSes should have settled non nushell)
in summary, if we couldnt replace bash on linux, i dont think anyone can replace git, git as an scm tool if far better than bash as a shell
Also might be relevant for claude, since it wants to put its settings into the repo itself as `.claude/`:
For some more common files, I use global gitignore file asWhat has a change is ast-based version control.
You adding a feature to a function that uses a struct I renamed shouldn't be a conflict. Those actions don't confliuct with each other, unless you treat code as text - rather than a representation of the logic.
Ending merge conflicts might make a new version control 10x better than git, and therefore actually replace it.
I mention it because while the jj command line interface is excellent, there are certain tasks that I find easier to perform with a graphical user interface. For example, I often want to quickly tap on various revisions and see their diffs. GG makes that kind of repository browsing — and certain squash operations — much more efficient for me.
If you’re interested in more information about GG, my co-host and I talked about it in a recent episode of the Abstractions podcast at about the 8:17 mark: https://shows.arrowloop.com/@abstractions/episodes/052-they-...