For anyone who's debating whether or not jj is worth learning, I just want to highlight something. Whenever it comes up on Hacker News, there are generally two camps of people: those who haven't given it a shot yet and those who evangelize it.
You will be hard-pressed to find someone who stuck with it for a week and decided to go back to git. You will not find a lot of people who say they switched but just stayed out of inertia. Of course both of these do happen—nothing is perfect—but they are by far the exception. From my own personal anecadata, I have seen a 100% conversion rate from everyone who gave it a serious try.
I encourage you to let today be the day that you decide to try it out. It is far less effort to make the switch than you probably think it is: I was productive the same day I switched and within a week I had no remaining situations where I needed to fall back to git commands. You will quickly be more productive and you will find yourself amazed at how you ever got by without it.
> For anyone who's debating whether or not jj is worth learning
I don't have any productivity issues with git, like... at all. It's not like I spend an hour running git commands every day.
I can totally imagine that some people spend their day manipulating repos with git, and jj is better for them. But that's not my case, and git is already everywhere.
To me it sounds like telling me: "You HAVE TO move to bim, the better vim. It's very similar to vim, but different enough that you have to learn new stuff. But you will be infinitely more productive: when you start bim, you're already in edit mode, so you don't have to type i! And the auto-complete in Julia is objectively a lot better in bim!".
Sure, but typing "i" a few times more is really not a concern for me, and I don't use Julia. But if it's better for you, please enjoy bim!
For a lot of people, making small and tightly-focused branches that are easy to review and merge is very important.
This is where jj excels. Especially if you find yourself often doing large chunks of work between convenient checkpoints, but you still want to create commits as if this work was all done in tiny and discrete chunks. It's also very helpful if you're the kind of developer who makes lots of unrelated changes in a single coding session, and wants all those changes to be in parallel branches that can be reviewed and merged independently. I greatly prefer working with (and being) the kind of developer that puts out a large number of very tiny and easy to review PRs, eve. jj makes doing that a breeze.
There are lots of people for whom these things aren't important. I will be slightly judgmental and say I don't really enjoy working with them. They tend to write very large PRs that are difficult and time-consuming to review. And it's a frequent source of frustration for everyone when 95% of the work is uncontroversial but a merge is being held up because of legitimate concerns with an unrelated 5%. This is even worse when there's later work that builds upon it that can't happen until a merge (or that needs to be constantly rebased as the PR is improved).
This is not to say if you do this you’re a bad developer. There are plenty of great developers who don’t care about these things and still do great work. This is also not to say you can’t follow my preferred approach with git. I did it with git for a decade and a half.
>I don't have any productivity issues with git, like... at all. It's not like I spend an hour running git commands every day.
Agreed. Having used SCCS, CVS, Subversion, VSS, Perforce, Clearcase, Accurev (the weirdest of the lot), Mercurial and Git, I'll move when the market decides what has critical mass and my job needs it.
jj feels a bit like learning a Dvorak keyboard and then being in an office of qwerty. Jobs want git, my colleagues know git, I'll be asked a question about... git. Using git has been the lowest version control churn in my brain for a decade, which is nice.
I use like five commands total in Git and the rest is driven through my IDE which handles everything else. People who tell me Git is hard or recommend alternate tools are living in a different world.
It's totally possible to have no issues with Git, e.g. if you are only using it for small or slow moving repos.
There definitely are lots of big issues with Git though. I dunno how many jj solves but it doesn't seem unreasonable to suggest people move to a better system.
Actually I find this tutorial to make a really good point in introducing it Jujutsu [1] without implying that "if you don't know it you don't know the Truth/haven't seen the light/are a peasant".
The author starts by saying that they actually have no issue with the git CLI, which is exactly my case.
I started trying jujutsu and until now, I can describe the feeling as an ergonomic keyboard: I am fine with any keyboard, really, it's not that some keyboards are "hard to use". Nobody would (should?) say "with a cheap keyboard, you can't type fast enough to be efficient, but with this ergonomic keyboard, you will be faster". But one may find that an ergonomic keyboard is more comfortable for them, or that it sounds a bit better or feel a bit better.
There is no real need to change keyboard if you like yours. It doesn't mean that it's impossible to find another keyboard that would be more pleasant to use.
JJ may be that (for me, but again I'm just starting): it seems equivalent to git CLI (as in, it's not a heavy GUI or a VScode plugin: it's really a CLI) and it feels like it may be more ergonomic.
> You HAVE TO move to bim, the better vim. It's very similar to vim, but different enough that you have to learn new stuff
Wit the added bonus that "bim" won't remain popular enough to sustain its development for long, so "bim" users have to switch to the fork "bbim" in 2 years, that won't remain popular enough to sustain its development for long...
How do you know? Maybe jj would be a productivity improvement for you. Maybe it wouldn't. There's only one way to find out and it seems like a pretty painless thing to try. If this is your attitude toward new things do you still pump water out of a well when you're thirsty?
It's certainly a solid improvement in the space of VCS UI, but beware that jj has some current limitations which might prohibit switching, especially for the git power users.
Lack of gitattributes support precludes git-crypt and git-lfs usage or anything that needs filters; line ending settings will get ignored, making Windows interop a little less smooth; etc.
Also note that auxillary tooling, such as git-annex and git-bug, becomes second class, i.e. no oplog integration and they might mess up your log with internal-use commits and heads.
I use gitattributes quite a lot (lfs, various diff engines, and export-ignore). Thanks for the heads-up, jj looked very interesting but I'm not going to give up gitattrivutes.
Oh thanks for the heads up! I use jj but it would be a disaster if I committed something using it and git-crypt didn't work, and the secrets were all plaintext.
"You will be hard-pressed to find someone who stuck with it for a week and decided to go back to git. "
Reporting in. Doesn't mean I will not end up with jj eventually, but so far I always went back to git after a while.
For me it is the staging area and the workflow it allows. Most people hate it and love jj because it does away with it. That is just not me. I don't see the staging area as a hack that was necessary to overcome some superfluous technical limitations but as a workflow tool.
Could I change my ways? Sure. jj just did not provide enough benefit for me so far to do it, but we will see. I am still open to give jj another try some day.
The staging area is a hack in that it is its own unique concept that doesn't work with any of the rest of git's tooling without needing special, inconsistent flags for commands to target it (git stash, git reset, etc.).
I use a staging area with jj! I would surmise most jj users do too. It's just a real, honest-to-god commit in the repo instead of a special snowflake.
# do some work
…
# prepare a new, empty commit if you don't already have one
jj new --no-edit --insert-before @
# move changes into it; repeat ad nauseam
jj squash --interactive
Since it's just a commit, all your tools work with it out of the box. And you don't need to stash changes when you jump around between branches.
I found it hard to stick to due to pre-existing workflows too. I find I'm often switching between branches in git, and our CI depends on pushing to specific branches - I constantly found myself a bit lost with jj about which underlying branch I was on and where that would get pushed to. I did Steve's tutorial and came out of that really liking the concepts, but still unable to map it all in my head when it came to pushing my work to a remote.
On the other hand, tools like jj seem great for people who spend a lot of time refining and perfecting every commit so that their repo history is pristine. I’m not one of those people. My git hygiene is atrocious. I have git halitosis. But functionally, it’s fine. Everything is in the git history and is recoverable. That’s about all I care about.
Also, I don’t have the capacity to juggle a lot in my mind. If someone does, then sure, jj may facilitate that. But I don’t need such facilitation.
I used jj for several months, then eventually went back to git.
The biggest killer was performance. jj operations took several seconds for me, whereas git is instantaneous no matter how big the project. Maybe this is fixed now.
But also honestly I felt like there was a bit more mental burden to using jj. When I switched back to git, it was like a weight off my shoulders. Maybe that's just due to the decade of constant use though.
> You will be hard-pressed to find someone who stuck with it for a week and decided to go back to git.
I’ve tried jj on three occasions and I always get confused by something and just bounce. It hasn’t clicked for me.
I’ve only tried it solo hobby projects. For which git is perfectly tolerable.
I have many many many complaints about git. But jj doesn’t move the needle for me.
Reading this post I am extremely annoyed. Almost every single section is “but more on that later”. It’s still far more complicated than it needs to be.
I also really really really hate the jj log rendering. The colors are a sea of barf. Bolding the leading character that represent uniqueness is stupid and adds noise. The username being second is dumb, I almost never care about that. And the bright neon green (empty)(no description set) is such bad spew. Kinda nit picky, but blech.
Jujutsu suffers the same thing Git suffers. Every god damn blog post that tries to explain how simple it is just my eyes gloss over and think “this is too complex for me to care”.
> I also really really really hate the jj log rendering. The colors are a sea of barf. Bolding the leading character that represent uniqueness is stupid and adds noise. The username being second is dumb, I almost never care about that. And the bright neon green (empty)(no description set) is such bad spew. Kinda nit picky, but blech.
Must be a preference thing. Showing me the unique characters is awesome. Git sucks after getting used to it.
I tried it and didn't switch. The funny thing is I immediately recognised that it was forcing me to use git in basically the same way I use it anyway. I have more than 15 years experience with git at this point. I never had to do the "delete repo and reclone" thing after the first year. In other words, I actually understand git, so I don't really need Jujutsu.
I also already use very good tooling for git, namely Magit. IMO Magit is a much better git frontend than Jujutsu. It guides you down the right path but doesn't take away any of the power of git at all. It's quite remarkable.
Maybe I should recommend jj to some of my colleagues, though. Trouble is I'm already on the hook for helping them with git, but I don't have the experience with jj.
> In other words, I actually understand git, so I don't really need Jujutsu.
This is kind of a poor take. By all means use what you prefer! But understanding git and knowing the "right" way to use it doesn't make jj obsolete.
I am (or was) a git expert. I’ve used it since pre-GitHub. I’ve written a git implementation. I know (or knew) the interface inside and out. I haven’t deleted and re-cloned a repo in as long as I can remember.
jj is still leagues better. Things I want to do and know how to do in git are dramatically faster and easier. They require less mental overhead. They’re less error prone. And I get superpowers with workflows that are super useful but wildly impractical in git.
This isn’t even really opinion at this point. Any task you can give me in git, I can with almost near certainty give you a shorter and more elegant alternative with jj that is an intuitive and obvious interaction with its core primitives.
A month ago our company split off a division. They needed to take a specific repo and sanitize out all of the parts that aren’t relevant to the new company, going back to the beginning of its commit history. You can do this with git. It wouldn’t be fun. I’d have to spend a lot of time reading the filter-branch manpage, and people have written countless wrappers of varying quality that try and make it a bit more ergonomic.
It took me like ten minutes to come up with:
declare -rA paths=(
…
)
# for every commit that touched a file
# we want to excise
for id in "$(
jj log \
--revisions '..' \
--no-graph \
--template 'change_id ++ "\n"' \
"${paths[@]}"
)"; do
# restore those paths’ contents from the
# the empty root commit; this happens
# entirely in-memory without having to check
# out each revision into the working copy to
# do file operations so it is FAST
jj restore \
--from 'root()' \
--to "${id}" \
"${paths[@]}"
done
# remove any commits that are now empty
# (except for the implicit root commit)
jj abandon \
--revisions 'empty() ~ root()'
Three dumb, simple commands that I already use every day: list some commits, copy file contents from one commit into another, and remove some commits from the tree.
Not only was this more or less obvious to do, but it was exceedingly fast to perform on a pretty highly-trafficked repo due to not having to thrash around in the working directory with checkouts.
> Magit is a much better git frontend than Jujutsu. It guides you down the right path but doesn't take away any of the power of git at all.
jj is more powerful than git. It’s not simply a dumbed-down alternative. By having a more carefully chosen set of primitives that compose better, you gain a lot of abilities that are technically possible with git but never used in practice due to the complexity. The above is IMO a fantastic example of how and why.
And you can still do all the normal git things too.
The relevant question is, why would a stranger take time out of their life to evangelize an open source VCS tool?
What other tools do people do that for? Not many. I see the most similar language and behaviour with regards to uv, which similarly revolutionized/simplified python tooling.
Likewise mise, which makes it similarly frictionless to install and manage tooling and their versions across projects and system-wide.
The evangelizing for these things comes because these tools start to heal the trauma that came from immense friction. We want others to be similarly liberated.
For those who say "I don't feel friction/trauma with git, legacy Python tooling etc", I can only say that you're living in Plato's cave/the matrix/in a cult/with Stockholm syndrome and just don't know what you're missing out on.
Reason I like git is because I use like 2% of its features. I don't fall for propaganda that I need to use bisect and co. 99% of git commands I call are aliased to 3 characters, so it's dense terminology doesn't bother me.
I relish the day I get to use bisect. It's like, finally I get to use all this version data I've been collecting.
I don't understand why anyone would say you have to use it. It does a very specific thing, namely finding the source of a regression between two commits. If you need it you'll know.
I used bisect once in my life but it was extremely helpful. Without it I'd spend weeks trying to find regression. With bisect I found and fixed it in under 1 hour.
It's a command that is needed rarely but there's no replacement for it in some situations.
Counter point: I adopted it internally at Google (there's a backend for Piper, Google's monorepo Perforce thingy). I don't do my day-to-day work in the monorepo but I still jump in there once or twice a week. I adopted JJ because the existing frontend (Mercurial-based) is slow while JJ is fast.
It's nice, I really like it! I'll probably switch to it as my main VCS eventually. But it doesn't feel that important to me. Even though my main work involves quite a lot of annoying rebases which is where JJ really seems to shine.
I dunno I guess it's just that a) I've really mastered git and have a deeply-rooted workflow in it and b) despite my project involving annoying rebases, version control still isn't very high on the list of problems I have.
So yeah I'm basically bullish on JJ as a technology but I think movement from Git is inevitably gonna be slow and steady.
I'm not entirely sure that "after using it I really like it and I'll switch eventually" is that much of a counterpoint :)
What really kept you from staying with it? It does seem like if your workflow involves a lot of nasty rebases you'd reap dividends from something like jj. I was also someone who'd mastered git (hell, I've written a git implementation) so I get having its patterns deeply ingrained.
Curious, I was under the impression that Google was all a monorepo, but your phrasing suggests that there are others. As my company is pushing for a monorepo, I'd love to know what causes someone at big G to not be in the monorepo. Thanks for any insights you can help me with!
Is this one of the repos that uses Gerrit? Does JJ play well with Gerrit?
IIRC Gerrit was super picky about amending commits and I was worried JJ's laissez faire attitude about creating git commits on demand wouldn't jive well.
There is a 3rd group (probably mostly gamedevs) who think it seems like a great idea and really want to try it, but are blocked waiting for git-lfs support.
Every time jujutsu pops back up on HN I check to see if they've added it yet. Not yet! But they are slowly getting there:
You can consider your perfect conversion rate now broken; I tried jujutsu on a personal project and found it to be a hassle without any upsides.
I believe your perception is flawed because the people who just try it and throw it away don't tend to talk about it because it's not popular enough to warrant even a twitter comment. This is the first time I got the impulse to share this but only because you claimed a rather silly 100% conversion rate.
I'm sure if I did the proper time investment I would enjoy jj. I've heard basically only good things about it in casual conversation. So far, my experience has been that I tried it, immediately got really annoyed that it automatically adds every untracked file that's not gitignored to the current commit, and was advised that I might want to stay with git if that's a problem.
That said, I struggle a bit with learning version control systems (that aren't git, like, I never really wrapped my head around svn or darcs or anything until they invented git). Seems like everybody just wants to write about the cool new commands they can run now instead of conveying how the data model works, or what mental model it wants to encourage. I had the same issue trying to get into pijul a while back, couldn't understand how to conceptualize the current state of a branch if I couldn't point at a commit in a tree and say "that's the branch, right there".
Mental model: “everything is a commit”. Commits are commits. Stashes are commits. The working tree is a commit. The index doesn’t exist, because it’s unnecessary.
The data model is technically of revisions, which are stable across operations like rebases (which change the underlying git commit).
How to conceptualize a branch: as a bookmark of a specific commit.
I use colocated mode, so Git tools see a detached HEAD but otherwise continue to work. I don't normally use the IDE for creating commits or moving around the repo, but I'll still use it for conflict resolution and for exploring history.
I used it for a little over a week, and switched back. This was a while ago, but the main reason was my neovim setup and flow never felt as good. Maybe jj has a good neovim plugin and diff mechanism now, though?
How fast I can deliver value is almost never gated by my VCS, so why should I try? In total I maybe lose a few minutes a month to VCS impedance mismatch, and I am merging on average ~4-5 PRs a day.
For sure git is hard to learn for beginners and there could be an alternative which is easier to pick up (maybe jj) but for those who know how git works internally and are proficient with it I don’t see it being worth the switch.
> How fast I can deliver value is almost never gated by my VCS
Oh, the number of times I do
git commit --fixup ...searches `git log` and pastes`... && \
git rebase -i --autosquash ...that same commit^...
I waste several half minutes several times per day in periods!
Another time-consuming thing is context-switching from a feature branch with staged/unstaged changes. If you're good with worktrees, you can largely avoid this, but the way I work with worktrees, I instantiate them as subdirectories to my repo's parent, which clutters my directories unless I make space for this as I clone the repository, which I haven't got used to.
I deliberately avoid too complicated git workflow aliases because I hate being stuck without them.
I am definitely in the camp of "I'd switch to jj the moment I give myself time to try it."
In the meantime, running git commands does sometimes take more time than it needs to.
Most of the projects I do for money are on Github and Gitlab.
I got my hands on things like YT videos explaining, official docs, cheatsheets.
About 4 hours exploring, trying to use with some side projects.
I did the same decades ago from CVS/SVN to git (even tried Hg). At that time it was obvious the "revolution" + "evolution" effect. Also git provided some transition tools that were easier to use from my pov.
Now it's just "evolution".
I see the added power to work with different "branches" simultaneously, move commits in different order in a way that is easier to have some better management logic, etc.
This is basically compelling if you work on different facets on big monorepos.
But I want to work on one thing a time nowadays, do something reliable, instead several features simultaneously, even with AI assistance, so the gains are not that huge, yet.
Like you I ended up using git commands again naturally. Stopping using svn commands eons ago felt amazing.
I have noticed this trend too. I don't know if I'm simply too smooth-brained for `jj` or what, but I forced myself to use it for a month to give it a fair shake and simply couldn't grok it. I gave up and went back to rawdogging git. So there are at least some of us out there.
I used it for several days and went back to git; it doesn't really provide that much for someone already proficient with git, and you need to know the underlying mechanism well for when something goes wrong anyway (just like with any other abstraction).
yes, I haven’t managed for a week, but I tried to Jujutsu and gave up. It is too complicated for no visible gain. Plus, there is no infrastructure supporting it (in the end, you store the stuff in the crippled git repositories). `git commit --amend` and `git rebase --update-refs` together with few scripts (e.g., https://git.sr.ht/~mcepl/git-fixup) does the same, and I am still with true git.
I tried it a year or two ago and went back to git. I didn't dislike JJ, it just didn't cover all the things I needed to do my usual workflow at the time, and being the only dev on my team using it was a bit tricky
I've been meaning to give it another shot, and probably will after this article
i've never considered testing out any of the new version control systems i see from time to time for the simple reason that i already know git, everybody else already knows git, git already completely handles everything i could conceivably want it to do (and a bunch more stuff that i will never touch), and perhaps biggest of all, i can't tell my manager that i want our whole team to migrate our code into (new thing) which everybody will have to learn for no reason.
serious question as somebody who has never even looked into what jujutsu offers - unless you're a solo dev with some free time, what exactly is the selling point here?
edit: i didnt realise that its just a layer on top of git so that basically answers my question, fair
1) actually gave it a fair shake - and are now evangelize it, and
2) people who simply didn't give it a fair shake due to
a) time restraints and
b) just not having an open enough mind to genuinely try it out
And then those who haven't tried it but
1) have never heard of it, and
2) are unwilling to try it because they are stuck in their ways (I view these people as being in Plato's Cave, or the matrix, or a cult - even though us evangelizers obviously sound like we're in a cult). They're in an even sadder position than those who tried it half-heartedly.
All such sorts of people are on display in this thread. I hope us zealots have been able to convince (hopefully via education) at least a few to try it out.
Fwiw. It took me 4 or 5 attempts of various lengths (2 to 10 days) before I actually sticked with it. I've hit unimplemented deal breakers and was generally uncomfortable a lot. Now I like it more than git, but I don't think the difference is large and stacking commits is a bit of a pass time for me. I do it more now because it's easier but I would just do less of it with git and no one would care much.
> I was productive the same day I switched and within a week I had no remaining situations where I needed to fall back to git commands.
When it's our first time, the tissue damage caused by the training can weight a lot to the point we could not even be able to sit properly in front of the desk during the first couple of weeks.
I started doing jujitsu a few months ago. The title of the article and this top comment had me bewildered until I remembered what jujitsu was in this space LOL
I feel pretty dense, because I still struggle to get my head around automatically adding changes to a revision. Sometimes, I'll make a change locally to a file that I'll use during the development process that I have no intention of committing. With regular git, I never stage that file so there's no danger of accidentally pushing my change to the remote repo, but it seems with jj I'll need to somehow unstage that change or something to prevent this. Perhaps it's just habit, but I feel more comfortable explicitly saying what I want to commit rather that defaulting to everything. Or have I totally misunderstood jj?
In jj you tend to use `jj split` to break changes apart. The selected bits become the first revision, the remaining bits become the second revision.
I tend to do a bunch of work then split into small, bite-sized revisions. Often I split something out to a parallel revision (e.g., a separate branch) if it’s an independent thread of work like a bugfix elsewhere or a documentation fix. This is an obvious one-liner in jj but a bunch of annoying branch-switching and stashing in git.
You can also use a `git add`-style workflow. Create a new revision with `jj new`. Do it again. Make your changes, then `jj squash -i/--interactive` to select the bits you want to include. Keep making changes and squashing into the previous commit you’re building up until you’re happy. Conceptually just think of @ (the current revision) and @- (the previous revision) as the working copy and the staged copy, respectively.
I usually work, then do `jj split` to review changes I want to make commits to. This generally makes the workflow look like `git add -p`.
A decent mental model is that the top-most commit isn't generally going to get pushed up anywhere. It's like your working copy but also you get stashing "for free" (change back to main to make a new commit? All the WIP stuff stays on that branch instead of being carried over to main!)
jj's auto staging isn't always desirable. I feel jj docs and evangelists should make clearer that it's easy to turn off by default, by adding this to ~/.jjconfig:
No that is correct, and also a habit I am trying to break. The reasonable argument is that we should stop running code with untracked state. Either the changes are important and should be committed or not. Otherwise you are recording code versions that never truly existed during development.
Where this gets extra sticky for me is tooling which refuses to distinguish repo wide config vs a local only version. VSCode being a huge offender where there is only a ‘launch.json’ and no ‘launch.local.json’ suitable for per host customization (eg maybe I am already running something on port 8888, so I need to map it to 9000, that does not mean a quirk of my environment should be committed).
If you want this workflow, you can treat jj's `@` (nominally equivalent to git's HEAD) as the git index, then at commit time, manually squash changes to `@-` just like you would with `git add --patch`.
When I've asked about using a jj stage, that's the workflow people pointed me to, as described in this tutorial [0]. I've not tried it, nor jujutsu, but I felt it worth pointing at a concrete example to allay or stoke fears of people on the fence.
The main things that drives me crazy about jj is that all changes are always staged implicitly. This is what SVN did back in the day, and git was a huge improvement by staging changes explicitly.
I almost always have more changes in my repository that those which I want to include in the next commit. With git, I just add the changes I want. With jj (and svn), there’s not obvious way around it—you have to manually copy-paste changes outside of the repository before committing.
> The main things that drives me crazy about jj is that all changes are always staged implicitly.
That's one way to look at it, but I would encourage you to think about it a bit differently.
JJ does not have a concept of "staging", it only has changes and commits. Yes, it automatically snapshots the workspace commit, but I wouldn't use the workspace commit as your staging area. If you want to do explicit staging use the parent commit (@-) as your staging area. You can move changes from the workspace commit (@) to the staging area (@-) explicitly, just like in Git. And you can "commit" (Git terminology) your staging area by starting a new staging area.
The difference here really is "only" that the workspace, the index, and committed changes are modeled with the same concept. And that is very powerful. Admittedly you have to make an informed decision on how to map your workflows onto the model, but that is what comes with the powerful flexibility that it gives you.
I'm torn on this - I don't know if there's a simple solution.
Having to stage things every time was always a real pain for me (coming from Mercurial).
Having it autocommit is what I need well over 90% of the time. But then there are always those pesky files that for various dumb reasons I'm not allowed to put in .gitignore.
I could disable autoadding files, but life will be worse that way.
> I could disable autoadding files, but life will be worse that way.
```
[snapshot]
auto-track = 'none()'
```
This is what I do, and I don't think it is worse. I prefer not having all my ignored files auto-tracked when I accidentally go back to a commit without them in the .gitignore
Some other solutions (which aren't simple at all):
- Remove specific files from auto-track
- Have a private commit with changes to the .gitignore and work on top of a merge commit
- Like last one, have a private commit with the files you don't want to push (+ merge)
I have it setup where any commit with a description that starts with "IGNORE:" is private.
snippet from my config:
```
[git]
private-commits = '''
description(regex:"(?x)
# (?x) enables the x flag (verbose mode) allowing comments and ignores whitespace
# see: https://docs.rs/regex/latest/regex/#grouping-and-flags
# Ignores commits starting with:
# (case-insensitive) PRIV: or PRIVATE:, or IGNORE:
^(?i:PRIV(ATE)?):
| ^IGNORE:
")
I think the workflow in JJ is a bit different in this case, you can try to have a base commit `jj new -m 'base'`, then create an anonymous commit on top `jj new`, then make some changes in the anonymous commit and when you are ready to send out a PR/MR you squash `jj squash` or split `jj split` and squash what you need in the base commit.
`jj commit -i` (or a lot of commands `-i`) and maybe `snapshot.auto-track="none()"` in the config, to a certain extent is what I use. I used to do the same with mercurial. In practice, I also use `absorb` a lot, that leaves unrelated files and chunks alone.
I’ve been trying unsuccessfully to convert my team to jujutsu. I feel like what would be great is a page that really shows some common but complicated operations in git and how much easier they are in jujutsu. Something like the elevator pitch here but expanded on without the depth of Steve’s tutorial.
Maybe what I need to do is do a demo so people can see and ask questions.
> I feel like what would be great is a page that really shows some common but complicated operations in git and how much easier they are in jujutsu.
What I find isn't that common git operations are easier in jujutsu. They're not; sometimes they're slightly harder, due to the impedance mismatch with the git backend.
Rather, what git makes easier are operations that are next to impossible — or at least highly inconvenient — in git, and which therefore next to no-one does. That makes it harder to explain, because you're telling them there's this great new workflow that does stuff that... they don't think they need (they have workarounds), and the notion of which triggers their ick reflex if they're good at programming.
I do understand that point, but to me it sounds like "you should use jj because it's a lot better at solving problems you don't have".
If there are really common use-cases where git is annoying and jj is great, it shouldn't be that hard to explain, should it? If you can say "remember how in the last few days you struggled with this? Jujutsu solves it", then I'm happy to try.
If your argument starts with "imagine you are in a team that looks like X (but your team does not), with a project that looks like Y (but your project does not), and now imagine that you need to do this thing that you have never done before...", then maybe I actually don't need jj?
I don't especially like git. I stuck with mercurial for a long time.
But that was ten years ago. Now git is kind of hard-wired in my brain. By and large, it works well enough.
It's not really clear to me that Jujutsu offers a significant enough of a benefit to spend the time re-wiring my brain, never mind dealing with the initial setup (e.g. the unreadable colours, setting up some scripts/aliases for things I like).
Yeah I find abstraction layers suck a bit. Same with miso and uv (for python). They don't "just work TM" and now I have 2 problems. By just work I couldn't install miso onto a fresh Ubuntu without 404 errors and uv kept bitching about my pyproject file instead of just working or trying to fix it.
Some of these tools do just work. E.g. nvm seems to just work and is much nicer than raw node installs.
I think that comparison is unclear and unfair. The core is that instead of:
jj rebase -r @ -B abc
the recommended Git alternative is:
git rebase -i abcd1234
# move the last line to the desired position
This is a process I use heavily, and one of the rare cases where I prefer the Git way: less cognitive load (I don't need to memorise options b/s/r/d/A/B for `jj rebase`) and the interactive editing of the history feels simpler (especially if I move several commits).
I've used jj for a few weeks, but switched back to git. I'm fluent enough with Git so I never struggle any more. jj mostly felt nice, but the added value was not enough to replace years of expertise.
This article convinces me that what he wants to do is easier in jj, I just don't understand why he wants to do it.
My quick summary is that in one case he's try to avoid "extra" commits and in another case he's trying to re-order some commits. In my usual work flow, both of those problems would be handled by the git-rebase-squash I do after the feature works.
Thanks. This is a really good one. It outlines an operation that would resonate well with most developers and clearly demonstrates how much simpler, easier, and faster this is in jujutsu vs git. I think most devs just wouldn't even bother to do it in git, they'd leave the test out of order and call it a day.
I think you'll probably like the next part I'm going to add to this post, then! I'm sure it'll get posted separately, but it'll also appear at the bottom of the page linked here when it's up (hopefully soon, as in the next few days).
I've been using jj for two weeks now and it's kinda exciting, because for the first time I'm comfortable with using version control just via the command line.
With Git I always had to use a GUI (preferably Git Graph in VSCode) and launch all operations by right clicking items, but jj was simple and consistent enough that I could just start using it after reading Steve Klabniks tutorial.
The thing I'm running into right now is that I should really learn the revset language, so that I don't have to constantly copy paste ids from jj log
I'm in a very similar situation: been using git for a long time, but anything more complicated always via some kind of UI (often intellij).
Been using jj without significant issues for about a month and been super happy to be comfortable using the cli and slowly ramping up to more complicated operations.
The documentation still assumes a lot of inherent knowledge which sometimes makes it a little difficult. I love seeing blog posts like these and hopefully some more in depth resources will appear over time. Steve's guide is good, but there are still gaps for me :).
Next I want to learn some more revset language and become a bit more fluent with rebase operations. I love the more simplified cli, conflict resolution and op log!
I had the same copy paste problem, now I use jjui (https://github.com/idursun/jjui). The daily operations become even smoother, it looks like I’m flying over the log.
I've been using jj for a few weeks, and recently made an auto-commit-message script for it[1]. Just today I started working in an old git repo and thought that I should port the script to git. It turns out that jj made the script trivial because of immutable commits, and mt script would need to automatically do that with git: I use a rebase/amend/clean history workflow at work, so I would need the script to determine when to commit or when to amend. It's obviously possible, but I don't want to expend the effort - I just re-cloned it with jj.
It's amazing how quickly I forgot about the commit vs. amend papercut.
Is it just a git frontend for people who are confused by git?
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.
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.
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.
> Working copy as commit means you have no quality control
The working copy doesn't get automatically pushed to GitHub or anything crazy like this seems to be implying. You review/curate your commit when you give it a description.
> 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.
Its Piper backend honestly works better than the Git backend. Which isn't a knock on the Git backend, but the impedance mismatch is worse there.
> 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.
Sorry, but saying this implies you haven't tried it. :-)
Jujutsu commits aren't equivalent to Git commits. They're implemented with a mixture of Git commits and the Git working tree, yes (if you use the Git backend!), but when you see 'commit', you should read 'named diff'.
Jujutsu also has a notion of immutable commits, by default meaning (roughly) commits which have been pushed upstream.
You can and should rewrite the un-pushed commits to clean up history prior to pushing changes upstream. jj makes that much MUCH easier than rebases and history edits could ever be with git. Most of my nontrivial jj work involves at least three or four commits at some point, everything from experiments to documentation branches, which with git I would have needed to awkwardly fit into stash or inconvenient throwaway branches.
Thanks, can you link me to their perforce backend code? I don't see the string "perforce" or "p4" anywhere in the code and it's not coming up on search.
> You can and should rewrite the un-pushed commits to clean up history prior to pushing changes upstream.
My concern isn't just about pushing upstream. What I'm saying is that the typical change to a file shouldn't be committed to my local repo until I indicate that it's ready. The FAQ suggests this isn't possible and that you should work around it by using a separate branch and then merge into your target branch, which is a pretty ugly workflow.
Their GitHub branches are a mess of auto-generated strings, which suggests to me that this problem isn't just an abstract concern but is a form of technical debt that the jj devs are currently piling up.
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.
I’ve had a lot of success using https://graphite.dev/. Been pretty easy to pick up and slots right into our usual GitHub workflow. I end up using the vscode extension to manage it. Anyone have opinions how jujutsu compares?
It’s both. Their CLI has a lot of overlap with what you’d use jj for (rebasing, amending, etc), but does basically everything worse other than “creating stacked PRs”. Slower; refuses to work from a detached HEAD; gets confused more easily by changes on the remote.
You will be hard-pressed to find someone who stuck with it for a week and decided to go back to git. You will not find a lot of people who say they switched but just stayed out of inertia. Of course both of these do happen—nothing is perfect—but they are by far the exception. From my own personal anecadata, I have seen a 100% conversion rate from everyone who gave it a serious try.
I encourage you to let today be the day that you decide to try it out. It is far less effort to make the switch than you probably think it is: I was productive the same day I switched and within a week I had no remaining situations where I needed to fall back to git commands. You will quickly be more productive and you will find yourself amazed at how you ever got by without it.
I don't have any productivity issues with git, like... at all. It's not like I spend an hour running git commands every day.
I can totally imagine that some people spend their day manipulating repos with git, and jj is better for them. But that's not my case, and git is already everywhere.
To me it sounds like telling me: "You HAVE TO move to bim, the better vim. It's very similar to vim, but different enough that you have to learn new stuff. But you will be infinitely more productive: when you start bim, you're already in edit mode, so you don't have to type i! And the auto-complete in Julia is objectively a lot better in bim!".
Sure, but typing "i" a few times more is really not a concern for me, and I don't use Julia. But if it's better for you, please enjoy bim!
This is where jj excels. Especially if you find yourself often doing large chunks of work between convenient checkpoints, but you still want to create commits as if this work was all done in tiny and discrete chunks. It's also very helpful if you're the kind of developer who makes lots of unrelated changes in a single coding session, and wants all those changes to be in parallel branches that can be reviewed and merged independently. I greatly prefer working with (and being) the kind of developer that puts out a large number of very tiny and easy to review PRs, eve. jj makes doing that a breeze.
There are lots of people for whom these things aren't important. I will be slightly judgmental and say I don't really enjoy working with them. They tend to write very large PRs that are difficult and time-consuming to review. And it's a frequent source of frustration for everyone when 95% of the work is uncontroversial but a merge is being held up because of legitimate concerns with an unrelated 5%. This is even worse when there's later work that builds upon it that can't happen until a merge (or that needs to be constantly rebased as the PR is improved).
This is not to say if you do this you’re a bad developer. There are plenty of great developers who don’t care about these things and still do great work. This is also not to say you can’t follow my preferred approach with git. I did it with git for a decade and a half.
Agreed. Having used SCCS, CVS, Subversion, VSS, Perforce, Clearcase, Accurev (the weirdest of the lot), Mercurial and Git, I'll move when the market decides what has critical mass and my job needs it.
jj feels a bit like learning a Dvorak keyboard and then being in an office of qwerty. Jobs want git, my colleagues know git, I'll be asked a question about... git. Using git has been the lowest version control churn in my brain for a decade, which is nice.
There definitely are lots of big issues with Git though. I dunno how many jj solves but it doesn't seem unreasonable to suggest people move to a better system.
bat just is more useful even if you didn't have issues with cat
The author starts by saying that they actually have no issue with the git CLI, which is exactly my case.
I started trying jujutsu and until now, I can describe the feeling as an ergonomic keyboard: I am fine with any keyboard, really, it's not that some keyboards are "hard to use". Nobody would (should?) say "with a cheap keyboard, you can't type fast enough to be efficient, but with this ergonomic keyboard, you will be faster". But one may find that an ergonomic keyboard is more comfortable for them, or that it sounds a bit better or feel a bit better.
There is no real need to change keyboard if you like yours. It doesn't mean that it's impossible to find another keyboard that would be more pleasant to use.
JJ may be that (for me, but again I'm just starting): it seems equivalent to git CLI (as in, it's not a heavy GUI or a VScode plugin: it's really a CLI) and it feels like it may be more ergonomic.
And at the very least, it's fun to try.
[1]: https://steveklabnik.github.io/jujutsu-tutorial/
Wit the added bonus that "bim" won't remain popular enough to sustain its development for long, so "bim" users have to switch to the fork "bbim" in 2 years, that won't remain popular enough to sustain its development for long...
Lack of gitattributes support precludes git-crypt and git-lfs usage or anything that needs filters; line ending settings will get ignored, making Windows interop a little less smooth; etc.
Also note that auxillary tooling, such as git-annex and git-bug, becomes second class, i.e. no oplog integration and they might mess up your log with internal-use commits and heads.
This one got fixed just a few days ago! https://github.com/jj-vcs/jj/pull/6728
Arguably a good thing - git's autocrlf setting causes way more issues than it solves. I highly recommend setting it to "input" (basically bans CRLF).
I hit this - I develop in Windows.
I still prefer jj and won't go back to pure git :-)
Reporting in. Doesn't mean I will not end up with jj eventually, but so far I always went back to git after a while.
For me it is the staging area and the workflow it allows. Most people hate it and love jj because it does away with it. That is just not me. I don't see the staging area as a hack that was necessary to overcome some superfluous technical limitations but as a workflow tool.
Could I change my ways? Sure. jj just did not provide enough benefit for me so far to do it, but we will see. I am still open to give jj another try some day.
I use a staging area with jj! I would surmise most jj users do too. It's just a real, honest-to-god commit in the repo instead of a special snowflake.
Since it's just a commit, all your tools work with it out of the box. And you don't need to stash changes when you jump around between branches.On the other hand, tools like jj seem great for people who spend a lot of time refining and perfecting every commit so that their repo history is pristine. I’m not one of those people. My git hygiene is atrocious. I have git halitosis. But functionally, it’s fine. Everything is in the git history and is recoverable. That’s about all I care about.
Also, I don’t have the capacity to juggle a lot in my mind. If someone does, then sure, jj may facilitate that. But I don’t need such facilitation.
The biggest killer was performance. jj operations took several seconds for me, whereas git is instantaneous no matter how big the project. Maybe this is fixed now.
But also honestly I felt like there was a bit more mental burden to using jj. When I switched back to git, it was like a weight off my shoulders. Maybe that's just due to the decade of constant use though.
I’ve tried jj on three occasions and I always get confused by something and just bounce. It hasn’t clicked for me.
I’ve only tried it solo hobby projects. For which git is perfectly tolerable.
I have many many many complaints about git. But jj doesn’t move the needle for me.
Reading this post I am extremely annoyed. Almost every single section is “but more on that later”. It’s still far more complicated than it needs to be.
I also really really really hate the jj log rendering. The colors are a sea of barf. Bolding the leading character that represent uniqueness is stupid and adds noise. The username being second is dumb, I almost never care about that. And the bright neon green (empty)(no description set) is such bad spew. Kinda nit picky, but blech.
Jujutsu suffers the same thing Git suffers. Every god damn blog post that tries to explain how simple it is just my eyes gloss over and think “this is too complex for me to care”.
Must be a preference thing. Showing me the unique characters is awesome. Git sucks after getting used to it.
You can fully change/customise it. Sounds like you just don't like the default.
I also already use very good tooling for git, namely Magit. IMO Magit is a much better git frontend than Jujutsu. It guides you down the right path but doesn't take away any of the power of git at all. It's quite remarkable.
Maybe I should recommend jj to some of my colleagues, though. Trouble is I'm already on the hook for helping them with git, but I don't have the experience with jj.
This is kind of a poor take. By all means use what you prefer! But understanding git and knowing the "right" way to use it doesn't make jj obsolete.
I am (or was) a git expert. I’ve used it since pre-GitHub. I’ve written a git implementation. I know (or knew) the interface inside and out. I haven’t deleted and re-cloned a repo in as long as I can remember.
jj is still leagues better. Things I want to do and know how to do in git are dramatically faster and easier. They require less mental overhead. They’re less error prone. And I get superpowers with workflows that are super useful but wildly impractical in git.
This isn’t even really opinion at this point. Any task you can give me in git, I can with almost near certainty give you a shorter and more elegant alternative with jj that is an intuitive and obvious interaction with its core primitives.
A month ago our company split off a division. They needed to take a specific repo and sanitize out all of the parts that aren’t relevant to the new company, going back to the beginning of its commit history. You can do this with git. It wouldn’t be fun. I’d have to spend a lot of time reading the filter-branch manpage, and people have written countless wrappers of varying quality that try and make it a bit more ergonomic.
It took me like ten minutes to come up with:
Three dumb, simple commands that I already use every day: list some commits, copy file contents from one commit into another, and remove some commits from the tree.Not only was this more or less obvious to do, but it was exceedingly fast to perform on a pretty highly-trafficked repo due to not having to thrash around in the working directory with checkouts.
> Magit is a much better git frontend than Jujutsu. It guides you down the right path but doesn't take away any of the power of git at all.
jj is more powerful than git. It’s not simply a dumbed-down alternative. By having a more carefully chosen set of primitives that compose better, you gain a lot of abilities that are technically possible with git but never used in practice due to the complexity. The above is IMO a fantastic example of how and why.
And you can still do all the normal git things too.
This sounds exactly like something a person evangelizing it would say.
What other tools do people do that for? Not many. I see the most similar language and behaviour with regards to uv, which similarly revolutionized/simplified python tooling.
Likewise mise, which makes it similarly frictionless to install and manage tooling and their versions across projects and system-wide.
The evangelizing for these things comes because these tools start to heal the trauma that came from immense friction. We want others to be similarly liberated.
For those who say "I don't feel friction/trauma with git, legacy Python tooling etc", I can only say that you're living in Plato's cave/the matrix/in a cult/with Stockholm syndrome and just don't know what you're missing out on.
I don't understand why anyone would say you have to use it. It does a very specific thing, namely finding the source of a regression between two commits. If you need it you'll know.
It's a command that is needed rarely but there's no replacement for it in some situations.
It's nice, I really like it! I'll probably switch to it as my main VCS eventually. But it doesn't feel that important to me. Even though my main work involves quite a lot of annoying rebases which is where JJ really seems to shine.
I dunno I guess it's just that a) I've really mastered git and have a deeply-rooted workflow in it and b) despite my project involving annoying rebases, version control still isn't very high on the list of problems I have.
So yeah I'm basically bullish on JJ as a technology but I think movement from Git is inevitably gonna be slow and steady.
What really kept you from staying with it? It does seem like if your workflow involves a lot of nasty rebases you'd reap dividends from something like jj. I was also someone who'd mastered git (hell, I've written a git implementation) so I get having its patterns deeply ingrained.
Is this one of the repos that uses Gerrit? Does JJ play well with Gerrit?
IIRC Gerrit was super picky about amending commits and I was worried JJ's laissez faire attitude about creating git commits on demand wouldn't jive well.
Every time jujutsu pops back up on HN I check to see if they've added it yet. Not yet! But they are slowly getting there:
https://github.com/jj-vcs/jj/issues/80
Is it that I have to fall back to git for its changes? Or that I just shouldn’t use jj if I’m in a repo with lfs files?
I believe your perception is flawed because the people who just try it and throw it away don't tend to talk about it because it's not popular enough to warrant even a twitter comment. This is the first time I got the impulse to share this but only because you claimed a rather silly 100% conversion rate.
I used it for a week and switched back to `git`. Most of its hallmark features are not something I use that often.
That said, I struggle a bit with learning version control systems (that aren't git, like, I never really wrapped my head around svn or darcs or anything until they invented git). Seems like everybody just wants to write about the cool new commands they can run now instead of conveying how the data model works, or what mental model it wants to encourage. I had the same issue trying to get into pijul a while back, couldn't understand how to conceptualize the current state of a branch if I couldn't point at a commit in a tree and say "that's the branch, right there".
The data model is technically of revisions, which are stable across operations like rebases (which change the underlying git commit).
How to conceptualize a branch: as a bookmark of a specific commit.
Now that I switched to jj (colocated with a get repo, very useful), I went back to using the CLI again for jj and I don't miss the graphical tools.
For sure git is hard to learn for beginners and there could be an alternative which is easier to pick up (maybe jj) but for those who know how git works internally and are proficient with it I don’t see it being worth the switch.
Oh, the number of times I do
I waste several half minutes several times per day in periods!Another time-consuming thing is context-switching from a feature branch with staged/unstaged changes. If you're good with worktrees, you can largely avoid this, but the way I work with worktrees, I instantiate them as subdirectories to my repo's parent, which clutters my directories unless I make space for this as I clone the repository, which I haven't got used to.
I deliberately avoid too complicated git workflow aliases because I hate being stuck without them.
I am definitely in the camp of "I'd switch to jj the moment I give myself time to try it."
In the meantime, running git commands does sometimes take more time than it needs to.
Most of the projects I do for money are on Github and Gitlab.
I got my hands on things like YT videos explaining, official docs, cheatsheets.
About 4 hours exploring, trying to use with some side projects.
I did the same decades ago from CVS/SVN to git (even tried Hg). At that time it was obvious the "revolution" + "evolution" effect. Also git provided some transition tools that were easier to use from my pov.
Now it's just "evolution".
I see the added power to work with different "branches" simultaneously, move commits in different order in a way that is easier to have some better management logic, etc.
This is basically compelling if you work on different facets on big monorepos.
But I want to work on one thing a time nowadays, do something reliable, instead several features simultaneously, even with AI assistance, so the gains are not that huge, yet.
Like you I ended up using git commands again naturally. Stopping using svn commands eons ago felt amazing.
Cognitive dissonance is a thing.
1) use a git hook to generate Gerrit IDs for new commit. AFAIK, JJ doesn't support these.
2) we also use submodules, which must be handled using git commands.
So if I decide to use JJ, I'll have to use a mix of JJ and git..
This landed in a jj release a few months back. I assume it’s live in gerrit now too.
And there's nothing crippled about thr git repos.
Try jjui for a great TUI experience on top of jj.
I've used it and I like it but I couldn't find a good plugin for Neovim so I reverted back to my old more well-supported workflow.
I've been meaning to give it another shot, and probably will after this article
Deleted Comment
serious question as somebody who has never even looked into what jujutsu offers - unless you're a solo dev with some free time, what exactly is the selling point here?
edit: i didnt realise that its just a layer on top of git so that basically answers my question, fair
do you know about git rerere?
if yes - try jj.
Those who have tried it and
1) actually gave it a fair shake - and are now evangelize it, and
2) people who simply didn't give it a fair shake due to a) time restraints and b) just not having an open enough mind to genuinely try it out
And then those who haven't tried it but
1) have never heard of it, and
2) are unwilling to try it because they are stuck in their ways (I view these people as being in Plato's Cave, or the matrix, or a cult - even though us evangelizers obviously sound like we're in a cult). They're in an even sadder position than those who tried it half-heartedly.
All such sorts of people are on display in this thread. I hope us zealots have been able to convince (hopefully via education) at least a few to try it out.
And also to try jjui, which is incredible.
https://github.com/idursun/jjui
When it's our first time, the tissue damage caused by the training can weight a lot to the point we could not even be able to sit properly in front of the desk during the first couple of weeks.
As it is, I go with whatever our clients require of us, and that isn't jj.
Dead Comment
I tend to do a bunch of work then split into small, bite-sized revisions. Often I split something out to a parallel revision (e.g., a separate branch) if it’s an independent thread of work like a bugfix elsewhere or a documentation fix. This is an obvious one-liner in jj but a bunch of annoying branch-switching and stashing in git.
You can also use a `git add`-style workflow. Create a new revision with `jj new`. Do it again. Make your changes, then `jj squash -i/--interactive` to select the bits you want to include. Keep making changes and squashing into the previous commit you’re building up until you’re happy. Conceptually just think of @ (the current revision) and @- (the previous revision) as the working copy and the staged copy, respectively.
A decent mental model is that the top-most commit isn't generally going to get pushed up anywhere. It's like your working copy but also you get stashing "for free" (change back to main to make a new commit? All the WIP stuff stays on that branch instead of being carried over to main!)
Where this gets extra sticky for me is tooling which refuses to distinguish repo wide config vs a local only version. VSCode being a huge offender where there is only a ‘launch.json’ and no ‘launch.local.json’ suitable for per host customization (eg maybe I am already running something on port 8888, so I need to map it to 9000, that does not mean a quirk of my environment should be committed).
[0] https://steveklabnik.github.io/jujutsu-tutorial/real-world-w...
Dead Comment
I almost always have more changes in my repository that those which I want to include in the next commit. With git, I just add the changes I want. With jj (and svn), there’s not obvious way around it—you have to manually copy-paste changes outside of the repository before committing.
That's one way to look at it, but I would encourage you to think about it a bit differently.
JJ does not have a concept of "staging", it only has changes and commits. Yes, it automatically snapshots the workspace commit, but I wouldn't use the workspace commit as your staging area. If you want to do explicit staging use the parent commit (@-) as your staging area. You can move changes from the workspace commit (@) to the staging area (@-) explicitly, just like in Git. And you can "commit" (Git terminology) your staging area by starting a new staging area.
The difference here really is "only" that the workspace, the index, and committed changes are modeled with the same concept. And that is very powerful. Admittedly you have to make an informed decision on how to map your workflows onto the model, but that is what comes with the powerful flexibility that it gives you.
Having to stage things every time was always a real pain for me (coming from Mercurial).
Having it autocommit is what I need well over 90% of the time. But then there are always those pesky files that for various dumb reasons I'm not allowed to put in .gitignore.
I could disable autoadding files, but life will be worse that way.
Damned if you do, damned if you don't.
``` [snapshot] auto-track = 'none()' ```
This is what I do, and I don't think it is worse. I prefer not having all my ignored files auto-tracked when I accidentally go back to a commit without them in the .gitignore
Some other solutions (which aren't simple at all): - Remove specific files from auto-track - Have a private commit with changes to the .gitignore and work on top of a merge commit - Like last one, have a private commit with the files you don't want to push (+ merge)
I have it setup where any commit with a description that starts with "IGNORE:" is private.
snippet from my config: ``` [git] private-commits = ''' description(regex:"(?x) # (?x) enables the x flag (verbose mode) allowing comments and ignores whitespace # see: https://docs.rs/regex/latest/regex/#grouping-and-flags
''' ```Maybe what I need to do is do a demo so people can see and ask questions.
What I find isn't that common git operations are easier in jujutsu. They're not; sometimes they're slightly harder, due to the impedance mismatch with the git backend.
Rather, what git makes easier are operations that are next to impossible — or at least highly inconvenient — in git, and which therefore next to no-one does. That makes it harder to explain, because you're telling them there's this great new workflow that does stuff that... they don't think they need (they have workarounds), and the notion of which triggers their ick reflex if they're good at programming.
If there are really common use-cases where git is annoying and jj is great, it shouldn't be that hard to explain, should it? If you can say "remember how in the last few days you struggled with this? Jujutsu solves it", then I'm happy to try.
If your argument starts with "imagine you are in a team that looks like X (but your team does not), with a project that looks like Y (but your project does not), and now imagine that you need to do this thing that you have never done before...", then maybe I actually don't need jj?
But that was ten years ago. Now git is kind of hard-wired in my brain. By and large, it works well enough.
It's not really clear to me that Jujutsu offers a significant enough of a benefit to spend the time re-wiring my brain, never mind dealing with the initial setup (e.g. the unreadable colours, setting up some scripts/aliases for things I like).
Some of these tools do just work. E.g. nvm seems to just work and is much nicer than raw node installs.
be wary of the stockholm syndrome. I too love git, but it is a very cumbersome tool for some workflows.
https://lottia.net/notes/0013-git-jujutsu-miniature.html
I've used jj for a few weeks, but switched back to git. I'm fluent enough with Git so I never struggle any more. jj mostly felt nice, but the added value was not enough to replace years of expertise.
My quick summary is that in one case he's try to avoid "extra" commits and in another case he's trying to re-order some commits. In my usual work flow, both of those problems would be handled by the git-rebase-squash I do after the feature works.
https://v5.chriskrycho.com/essays/jj-init/https://v5.chriskrycho.com/journal/jujutsu-megamerges-and-jj...https://ofcr.se/jujutsu-merge-workflow
The thing I'm running into right now is that I should really learn the revset language, so that I don't have to constantly copy paste ids from jj log
Been using jj without significant issues for about a month and been super happy to be comfortable using the cli and slowly ramping up to more complicated operations.
The documentation still assumes a lot of inherent knowledge which sometimes makes it a little difficult. I love seeing blog posts like these and hopefully some more in depth resources will appear over time. Steve's guide is good, but there are still gaps for me :).
Next I want to learn some more revset language and become a bit more fluent with rebase operations. I love the more simplified cli, conflict resolution and op log!
It's amazing how quickly I forgot about the commit vs. amend papercut.
[1]: https://codeberg.org/jcdickinson/nix/src/branch/main/home/co...
Is it just a git frontend for people who are confused by git?
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.
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.
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.
The working copy doesn't get automatically pushed to GitHub or anything crazy like this seems to be implying. You review/curate your commit when you give it a description.
Its Piper backend honestly works better than the Git backend. Which isn't a knock on the Git backend, but the impedance mismatch is worse there.
> 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.
Sorry, but saying this implies you haven't tried it. :-)
Jujutsu commits aren't equivalent to Git commits. They're implemented with a mixture of Git commits and the Git working tree, yes (if you use the Git backend!), but when you see 'commit', you should read 'named diff'.
Jujutsu also has a notion of immutable commits, by default meaning (roughly) commits which have been pushed upstream.
You can and should rewrite the un-pushed commits to clean up history prior to pushing changes upstream. jj makes that much MUCH easier than rebases and history edits could ever be with git. Most of my nontrivial jj work involves at least three or four commits at some point, everything from experiments to documentation branches, which with git I would have needed to awkwardly fit into stash or inconvenient throwaway branches.
This makes sense to me as a longtime Mercurial user. In short, by default, when you push a commit, it becomes public and therefore immutable [1].
Other awesome Mercurial features that appear in JJ are revsets [2], filesets [3] and templates [4]. Looking forward to giving JJ a try.
[1]: https://wiki.mercurial-scm.org/ChangesetEvolution
[2]: https://jj-vcs.github.io/jj/latest/revsets/
[3]: https://jj-vcs.github.io/jj/latest/filesets/
[4]: https://jj-vcs.github.io/jj/latest/templates/
> You can and should rewrite the un-pushed commits to clean up history prior to pushing changes upstream.
My concern isn't just about pushing upstream. What I'm saying is that the typical change to a file shouldn't be committed to my local repo until I indicate that it's ready. The FAQ suggests this isn't possible and that you should work around it by using a separate branch and then merge into your target branch, which is a pretty ugly workflow.
Their GitHub branches are a mess of auto-generated strings, which suggests to me that this problem isn't just an abstract concern but is a form of technical debt that the jj devs are currently piling up.
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:
Now I will make a new empty change on top of that: Now, @- is the change that I intend to push publicly, but @ is my index. Say I add foo.rs: Now, when I run `jj status`, jj takes a snapshot, and it now lives in @: We can see the diff here with `jj diff`: 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 @-: Now that change is in @- instead of @. we can see that by passing -r (for revision) to `jj diff`: 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.