Readit News logoReadit News
nateb2022 · 7 months ago
Related:

Jujutsu (jj), a Git compatible VCS (89 points, 112 comments) https://news.ycombinator.com/item?id=41895056

Steve's Jujutsu Tutorial (158 points, 117 comments) https://news.ycombinator.com/item?id=41881204

Jujutsu: A Next Generation Replacement for Git (94 points, 80 comments) https://news.ycombinator.com/item?id=40908985

A better merge workflow with Jujutsu (135 points, 90 comments) https://news.ycombinator.com/item?id=40842762

Jujutsu: A Git-compatible DVCS that is both simple and powerful (673 points, 262 comments) https://news.ycombinator.com/item?id=36952796

password4321 · 7 months ago
Possibly most recently (last week), with many anecdotal recommendations:

2025-02-04 https://news.ycombinator.com/item?id=42934427 (234 points, 122 comments) Jujutsu VCS: Introduction and patterns

throwup238 · 7 months ago
The most recent post is today, just two posts down on the front page as I write this: JJ Cheat Sheet (86 points, 39 comments) https://news.ycombinator.com/item?id=43020180

I assume that’s the inspiration for this link.

relistan · 7 months ago
I just want to say that we all finally are using mostly the same VCS and that is actually an undervalued, beautiful thing. An actual “standard” that is almost universal.

It used to be such a mess with all the VCS systems and having to know all of them to commit on various dependencies from different projects.

I know that jj can be backed by git. But already it doesn’t need to be. Between this and other projects, I don’t have to squint too hard to see a future that looks like the past. I hope I’m wrong.

motorest · 7 months ago
> I just want to say that we all finally are using mostly the same VCS and that is actually an undervalued, beautiful thing. An actual “standard” that is almost universal.

This bears repeating.

To further frame the importance of this, we've started seeing git being used as the deployment tool of some notable mainstream software projects such as nvm. This is only possible if a VCS becomes ubiquitous and a de-facto standard.

MrJohz · 7 months ago
I think that's actually one of the nice things about JJ in comparison to many others (such as hg or Pijul): it uses Git essentially like a protocol or standard by which it communicates with other systems (and as a file-system standard, like using SQLite or something similar).

Essentially, it agrees that Git has become a de-facto standard as a file format and as a protocol, but that doesn't mean it can't have a very different approach to that file format and protocol.

It's similar to how HTTP can support a RESTful approach, or GRPC, or GraphQL or whatever else, and all these different systems can build on the same underlying technology.

globular-toast · 7 months ago
To generalise a bit, this is really an example of the power of having a common language. I find this is generally undervalued. Having a common language at all is more important than having a "perfect" language. People are too eager to disrupt the language. We instead need to embrace it for what it is, learn to work with it, and only change it in small ways.

If you're learning French you don't argue with the language and try to get French people to talk how you want them to talk, you suck it up and do what they do. As with all things it's a trade off: you get to converse with everyone in France, but, yeah, you will have to deal with saying "le parking" etc.

underdeserver · 7 months ago
Git has lots of downsides, lots of power that forces you to work hard for things that should be easy.

jj is better.

If it's backed by git and doesn't break anyone else working on the repo, what's the problem?

pbh101 · 7 months ago
A useful question is ‘how much better?’

For so many reasons, SVN to Git was a no-brainer but still constituted significant migration costs for existing teams and codebases: training, retooling, high-fidelity data transfer (you retained the commit history, right?).

For a tool with such wide adoption, motivating an ecosystem to move where there are many actors with different incentive structures, some of them will look and say ‘30% better isn’t even close to sufficient to spend time and $$$ on this. I would need ~10x better and/or a gain of altogether new capabilities impossible in previous tool to motivate that.’

It’s great that jj can be used independently without needing the whole ecosystem to move today, but once/if that part changes I’d expect it to be a long slog towards re-standardization if ever.

But jj likely already fully anticipated this given its compatibility with the Git wire protocol in the first place and I doubt it would ever give that up given the current landscape.

motorest · 7 months ago
> Git has lots of downsides, lots of power that forces you to work hard for things that should be easy.

Care to point one concrete example?

usrbinbash · 7 months ago
> jj is better

Primarily jj is different. And a lot of the "problems" it solves barely ever come up in git. And when they come up, its usually as "difficult" as "google the solution and enter the commands". And worst case scenario, someone has to manually copy paste some files around.

If this happened every day, I'd agree that we need a different system. But it doesn't.

In short, the situations where jjs advantages can really shine, and the advantages in these situations are simply not common enough / important enough to justify the headache of switching the world over to another VCS.

In an ideal world, "the better" solution wins.

In a pragmatic world of limited resources, "better" on its own is not enough. The differential between the new and the old solution has to be large enough to offset the cost of switching, and the more entrenched the existing solution is, the higher that cost will be.

fragmede · 7 months ago
Mostly everyone using the same standard is amazing. Power tools batteries are the glaring failure. Kubernetes gets a lot of shit for being complicated, which it should, because it is, but I'm glad that enough people use it to manage their fleet of computers that I don't have to learn too many special cases for managing fleets of computers.

XKCD 927.

baq · 7 months ago
git is good (good enough even) but not perfect. I’d love to see pijul receive funding for a small team for a couple years but we’ve got what we’ve got.

jj’s killer feature is git compatibility, obviously. For now it’s table stakes so we can pretend only git exists.

v3ss0n · 7 months ago
This got spammed a lot but does anyone actually use it in the wild? We have This and Sapling (mercurial) for alternative git. Back in 2014 up til 2018 we used mercurial , development workflow is a lot smoother and better in DX wise vs git but soon after bitbucket decided to cut mercurial we have no choice but to use Git since there is literally no opensource or cloud service mercurial `hub` in existence.

What you need for your CVS to be popular is not having a new CVS that do a thing a little bit different and better vs Git but to have a good GitHub alternative. In Git world there we have Gitea - which is very easy to setup and experience is much better than github , and gitlab for bigger orgs. Plus a good IDE support.

Sapling and JJ need something like that - built in or selfhostable.

steinuil · 7 months ago
> but to have a good GitHub alternative.

JJ doesn't currently have a "native" repository format (or rather, it's in development and not ready for general usage), so right now a JJ forge wouldn't look too different from your usual Git forges.

Everybody who's using it right now uses it on Git repos on Git forges. I've been using it for months on my own and at work and I didn't make any changes to the infrastructure outside of my own command line usage.

It would be interesting to see what a JJ-native forge would even look like in the future, but I don't think anybody knows exactly what that would be right now! JJ is in development (but stable enough to work with) and people have only just started using it, so it's still in the phase of discovering what workflows are possible.

> Plus a good IDE support.

Now that's something I would love to see. Git tooling works mostly fine but due to how JJ's git backend works, it always thinks it's in a "detached HEAD" state.

gpm · 7 months ago
> Everybody who's using it right now uses it on Git repos on Git forges.

As I understand it there's also a group of Googlers using it internally at Google with an internal to Google non git backend.

v3ss0n · 7 months ago
i gotta try a bit then.
fragmede · 7 months ago
Given than jj is compatible with git servers, does it matter? If you prefer jj, you can just use it on your laptop to just get shit done, meanwhile using whatever git server you're given.
KingMob · 7 months ago
A year ago, I played around with jj out of curiosity, and within a couple weeks, I was ready to abandon git forever, despite jj still being so new.

I only use git directly when I have to now.

(As others have pointed out, jj uses git as a storage/network layer, so you don't need a new forge to start using it.)

sbaildon · 7 months ago
Mitchell of Hashicorp and Ghostty fame uses jj

https://x.com/mitchellh/status/1845869748841832667

Skinney · 7 months ago
I'm using it for everything now. The beauty of JJ is that everyone else on my team can keep on using git if they want, even if I'm using JJ on the same repo.
MrJohz · 7 months ago
JJ should be compatible with any existing Git server. The project is currently maintained on Github, and I believe all the maintainers use JJ to work on the project itself. At work, I use JJ a lot with repositories hosted on Azure Devops, and that also works well (in some ways, better than Github).

This is using JJ's "Git" backend, which internally stores data as Git refs, and communicates with other servers the same way that Git does. There is a work-in-progress native backend, but this is still being developed and you need to explicitly opt into it if you want to try it out.

jrockway · 7 months ago
I'm using it day to day for my personal projects and at work. The thing that always annoyed me about ... work ... is that I'll be working on like 5 things, with 4 of them being code reviewed at my code reviewer's leisure. So I always end up with a crazy stack of branches, and as "main" changes, the burden of keeping everything up to date becomes painful. jj makes this all very easy! "jj rebase -d main" to clean up one of my topic branches. No interrupt to whatever I'm working on (as git checks out the files to your working copy and you resolve conflicts for each step in "git rebase main"). Conflicts can be removed at your leisure.

Something I always regretted doing with my many-topic-branches-out-for-review approach was making changes that depend on two topic branches. With jj, it's easy, you just "jj new qrs xyz" and now you have a new change on top of those two topic branches. If you add something in this commit that you want in one of your topic branches, "jj squash --onto qrs some/change/to/qrs.go" and now that change is in there.

It works well with Github and a PR per change. You create a PR with "jj bookmark create whatever" and then "jj git push --allow-new" to make "whatever" a remote branch. As you update that commit, "jj git push" adjusts the remote state as necessary. "jj git fetch" automatically adds bookmarks for upstream branches (so you can "jj new coworker/their-change" to test and modify their thing locally).

Finally, it works well when you have persistent changes that you don't want to commit but you do want to keep around. For some reason, we check in dev configs, and each engineer needs to modify them to run stuff locally. I have a commit called 'private: local setup' and that forms the base for each new (local) commit I work on. To do a PR, I squash my changes into a commit based on main instead of that commit. jj will avoid pushing anything with the prefix 'private: ' so I don't have to worry about leaking my keys, even though they are checked in locally. I wouldn't recommend managing secrets like this, but ... I didn't make this decision and jj handles it fine.

Overall, a huge improvement to my workflow. There have been times when I have so much stuff in flight that I just give up for the day until a few PRs get resolved. That never happens anymore. I can kind of work on whatever I want and let the world move at its own speed. Updating my work to account for PR comments or PRs merged before mine now takes seconds and never goes wrong. Truly an amazing tool and I wish I discovered this years ago.

lytigas · 7 months ago
I've read a few small overviews of jj. One thing that's off-putting as a git lover is that while git is truly append-only (except refs), jj seems quite "mutable" by comparison.

Say I'm messing around with the commit that introduced a bug, somewhere deep in the history. With git, it's basically impossible to mess up the repo state. Even if I commit, or commit --amend, my downstream refs still point to the old history. This kind of sucks for making stacked PRs (hello git rebase -i --autosquash --update-refs) but gives me a lot of confidence to mess around in a repo.

With jj, it seems like all I would have to do is forget to "jj new" before some mass find+replace, and now my repo is unfixable. How does jj deal with this scenario?

MrJohz · 7 months ago
As others have pointed out there's `jj undo` and other tools, but they all rely on the fact that JJ is less mutable than it seems.

Internally, JJ is still backed by an append-only tree of commits. You don't normally get to see these commits directly, but they're there. A change (i.e. the thing you see in `jj log`) is always backed by one or more commits. You can see the latest commit in the log directly (the ID on the left is the change ID, the ID on the right is the commit ID), but you can also look back in history for a single change using `jj evolog`, and you can see all commits using `jj op log`.

This ensures that even if you were to exclusively use `jj edit`, never made a new commit, and kept all your work and history in a single change, you could still track the history of your project (or the "evolution", hence the name evolog). It would be kind of impractical, but it would work.

The only caveat here is that, by default, JJ only creates new snapshots/commits from the working directory whenever you run the CLI. So if you made a large change, didn't run any JJ command at all, then made a second large change, JJ would by default see that as a single change to the working directory. To catch these issues, you can use a file watcher to automatically run JJ whenever any file changes, which typically means that JJ makes much more frequent snapshots and therefore you're less likely to lose work (at the cost of having a file watcher running, and also potentially bloating your repository with lots of tiny snapshots).

Note also that the above is all local. When using the git backend, Jujutsu will only sync one commit for each change when pushing to a remote repository, so the people you're collaborating with will not see all these minor edits and changes, they'll only see the finished, edited history that you've built. But locally, all of those intermediate snapshots exist, which is why Jujutsu should never lose your data.

johnisgood · 7 months ago
> you can use a file watcher to automatically run JJ whenever any file changes, which typically means that JJ makes much more frequent snapshots and therefore you're less likely to lose work (at the cost of having a file watcher running, and also potentially bloating your repository with lots of tiny snapshots).

For example? Or should I create my own in C using inotify/kqueue? Is there a library for jj?

baq · 7 months ago
The first time I’ve tried to prepare a set of commits to push out I found out the hard way that merges cannot be undone - and I’m not sure which of the commands were doing a merge.
cornstalks · 7 months ago
> With git, it's basically impossible to mess up the repo state.

I must be a wizard because I’ve lost count of the number of times I’ve messed up my repo’s state.

I jest. Kinda. I know that git’s state might technically not be messed up and someone skilled in the ways of git could get me out of my predicament. But the fact that I’m able to easily dig myself into a hole that I don’t know how to get out of is one of git’s biggest issues, in my opinion.

bboygravity · 7 months ago
Totally.

That hole is very easily dug with git:

use ctrl x ctrl v to move files around commit boom, you've lost history for those files (file tracking only works in theory, not in real life), let's say you don't notice (very easy to not notice)

commit some more, merge

discover your mistake tons of commits back

good luck fixing that, without digging a bigger hole.

And that's one of 100's of examples in which git just is really really not fun or user friendly.

phildenhoff · 7 months ago
If you want to “checkout” some previous commit, jj has your back in three ways

- first, that commit that’s been merged to main is marked as immutable and, unless you add a flag to say “I know this is immutable and I want to mutate it anyway”, you can’t mutate it

- second, as part of your regular workflow, you haven’t actually checked out that historical commit. You created a new, empty commit when you “checked it out” using “jj new old_commit”

- third, you can use jj undo. Or, you can use “jj obs log” to see how a change has evolved over time (read: undo your mass find+replace by reverting to a previous state)

arxanas · 7 months ago
jj is pretty much just safer than Git in terms of the core architecture.

There's several things Git can't undo, such as if you delete a ref (in particular, for commits not observed by `HEAD`), or if you want to determine a global ordering between events from different reflogs: https://github.com/arxanas/git-branchless/wiki/Architecture#...

In contrast, jj snapshots the entire repo after each operation (including the assignment of refs to commits), so the above issues are naturally handled as part of the design. You can check the historical repo states with the operation log: https://jj-vcs.github.io/jj/latest/operation-log/ (That being said, there may be bugs in jj itself.)

ninjamuffin99 · 7 months ago
“jj op log” shows you the operation history, which you can then “jj op restore” and point to where you want to restore to :) (disclaimer: im still jj newbie, but this has gotten me out of the snafus ive put myself into while learning g)
OccamsMirror · 7 months ago
Can I ask what your motivation was for trying jj?

I'm always keen to explore new things but I don't have many complaints about git. I'm wondering what this solves that made it attractive for you.

swiftcoder · 7 months ago
> With git, it's basically impossible to mess up the repo state

I'd like to introduce you to a couple of my former colleagues...

cube2222 · 7 months ago
As other commenters have mentioned, there's `jj undo`, but you can also configure a set of immutable commits (by default it's the main branch and heads of untracked branches) and jj will stop you from changing those unintentionally (there's a flag you have to explicitly set if you want to force it).
jjfanboy · 7 months ago
Er, well, never type `jj edit` and this will never be an issue?

I exclusively move in a jj repo with `jj new` and `jj squash` or `jj squash --to <rev>` as appropriate. I've been using it 8+ hours daily for months and have never, ever even thought of having this issue.

porridgeraisin · 7 months ago
I find it quite funny that this is exactly the kind of the thing "just don't use ... 8+hours daily ... Never had issues ..." that people who remain with git say.

And now people are saying it for jj.

Endless cycle it seems, with every new tool.

ozornin · 7 months ago
I have colleagues who are big fans of it. I gave it a try, but I really don't get what is the problem it is trying to solve. Like, what is it that I will be able to do that I couldn't do with git, and why bother learning it at all
Skinney · 7 months ago
I find JJ to be what you get when you take a step back, evaluate everything that works in Git and try to find a design that accomplishes all those things with the fewest amount of concepts possible. Like a Git 2.0, if you will.

You can do most of the same things, but it's easier to understand it intuitively so you don't need to google or give up on the more advanced usages. And the things you do everyday you can do with fewer steps.

Couple that with colocated repos, meaning I can use JJ while everyone keeps on using Git, there wasn't really anything holding me back.

motorest · 7 months ago
> You can do most of the same things, but it's easier to understand it intuitively so you don't need to google or give up on the more advanced usages. And the things you do everyday you can do with fewer steps.

Care to point out any concrete example?

Nullabillity · 7 months ago
Ultimately, jj is trying to make the "branches are a mutable series of patches" workflow easier.

The problem is that that workflow is still ultimately harmful nonsense[0] that is based on a misunderstanding of version control.

[0]: https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md

exceptione · 7 months ago
Rebase is not harmful, but thanks for your link. There are quite some people that do not understand rebase, and this link helps to get a grasp of how people can be confused.

- in section 2.2, they think that in a feature branch only the latest commit counts. You should not just be interested in how the tip of your feature branch compares to the latest main, but also into the logical sequence of steps your feat branch builds up a feature. In a rebase model, every step of your feature can be compared to main.

- in section 2.2, they conveniently omit what happens if you keep merging main into your feat branch. Your feat branch will show all useless commits telling you that "at this time, my feature diffed such and such from how main looked at at that time". "Oh, and here again a useless diff" "Oh and here again." "By the way, have a nice ball of diffs again". I don't fucking care. Why don't you just commit some info about the local weather at that time too or that your back was hurting on Wednesday 23th?

- "Rebase encourages siloed development". That claim is just ridiculous. If you don't want people to take ownership of a feature, by all means, forego branches. If someone wants to work on my feature, then we just agree that the public feat branch is to be considered public history. When the work finishes, someone can take ownership, (possibly clean up the mess with rebasing) and get it into mainline by rebasing on top of main.

motorest · 7 months ago
> The problem is that that workflow is still ultimately harmful nonsense[0] that is based on a misunderstanding of version control.

The problem with that article is that it's utter nonsense and completely misses the whole point of rebase.

No one cares if under the hood a rebase is technically a merge that forgets where it came from. I mean, isn't that the whole point of a rebase?

The whole point of a rebase is to move your local branch onto the tip of another branch while preserving the local history. The goal is to simplify the repository history by eliminating irrelevant noise. That's not a problem, it's a solution. Is this too hard to understand? How can they possibly miss the extra forks and joins in their commit graph? Do they not see that? Do they spend any time looking at commit graphs?

It's ok if Fossil's devs want to force their opinionated take on VCS onto Fossil's users, but this does not mean they are right or have a point. In this case they are not only missing the whole point but also taking a completely wrong approach to mitigate it. The fact that they felt compelled to put up a page trying to present their case (and failing) is already telling.

If there is criticism to throw at Git, rebases clearly ain't it.

hhjinks · 7 months ago
The author of that article clearly doesn't understand rebasing. They state that "the golden rule of rebasing" in the "Git rebase documentation" (actually just an Atlassian git tutorial) says that you should "never rebase on a public branch", when the tutorial they reference unambiguously states you shouldn't rebase a public branch onto your own local changes. Rebasing on public branches is the raison d'être of rebasing. The entire article seems like cope, the author deciding to bash rebase because they don't understand it.
martinvonz · 7 months ago
Have you tried asking your colleagues? What did they say?
ozornin · 7 months ago
I considered it, but it would inevitably involve talking to people, and it is a little too far for me
baq · 7 months ago
If you ever did stacked prs and then had to rebase them all on top of each other, this is why.

Otherwise I also find it not really an improvement and a downgrade in terms of other tooling (editor etc.)

ks6g10 · 7 months ago
I do this regularly with magit, but mby I am missing something?

I.e. the typical Gerrit workflow

benrutter · 7 months ago
> Have you ever wanted to store your version controlled repositories inside a Dropbox folder? Or continuously backup repositories to S3? No? Well, now you can!

This made me chuckle. In all seriousness, does jj afford anything new by connecting to filesystems more directly?

The main issue with git I've heard of is for projects, like video games for instance, that bundle text based code with a huge amount of non-text assets (audio, images etc).

I don't understand what causes gitissues here, is it storage? Or is it more attempting to map differences between non-text assets. Curious about whether jj's filesystem usage help here.

steveklabnik · 7 months ago
That claim has nothing to do with integrating with file systems. Issues with Dropbox and git are fairly well known https://stackoverflow.com/questions/19305033/why-is-putting-...

Jj interacts with files in a way that ensures this can’t happen.

Jj is the same as git with regards to large non-text assets. But that’s just because it’s still young, it will gain good support eventually.

(And yeah it’s about storage and also about diffs. How would you fix a merge conflict in a PNG?)

SoftTalker · 7 months ago
benrutter · 7 months ago
5 star logo right there!
geenat · 7 months ago
Auto-commit of large files and no way to un-bloat your repo is a showstopper for me no matter how good the DX might be.

Large file handling needs to be sane in any new VCS, IMHO, as this is a main failing of git (..without the extra legwork of git-lfs).

Edit: https://github.com/jj-vcs/jj/issues/80 Could maybe bring jj up to parity with git here

necauqua · 7 months ago
There's an anti-footgun heuristic that asks "are you sure", basically, if the file about to be tracked is >=1mb, saved a lot of asses a lot of times.

But also, if it is such a showstopper, you can disable auto-amend of _new_ files with snapshot.auto-track=none() config (or even something funky like src/*) - and recently jj status finally started showing untracked files too, it's very usable