gcr 2 days ago

I use jj for all my projects on github! It's really useful for my sort of workflow: chains of commits with easily-editable history. If you make a change back in time, you edit the previous commit (which puts you in a state similar to git's detached head), and any edits you make there are automatically carried forward (rebased) onto descendants. It feels way more natural, especially for newer users.

The killer feature that I love the most is a small one, but it's that commit messages can be made ahead of time rather than after-the-fact. So I can sit down at my desk, say

    jj new -m "Work on XYZ feature"
then edit my code in the editor. When I'm finished, I move on to the next commit:

    jj new -m "Working on UVW feature"
No more "oh no I accidentally started touching code and forgot to commit my work, so now I have to manually split two git commits;" it's a small way that the tooling encourages you to be intentional about your engineering philosophy.
  • miki123211 2 days ago

    > It feels way more natural, especially for newer users.

    I have thought about this recently, and it feels like jj would be a lot easier to teach to new users than git.

    For one, jj lets you work on things directly without having to worry about an index, while still giving you all the advantages of one if you're advanced enough to need that.

    THe commands also feel a lot easier to explain than in git. For example, you use `edit` to change what commit you're working on, `restore` to copy a file from a commit to your working directory (and abandon your changes to it), and `abandon` to drop a commit completely. Meanwhile, git has `checkout`, `restore`, `switch`, `reset` and `reset --hard`, which all do various parts of one or more of these.

    • 3eb7988a1663 2 days ago

      Reading the jj changelog is fun where you see them deprecate functions, acknowledging that they perform identical purposes. Beautiful to see this simplification that benefits all users going forward.

      The one that stood out in my mind:

        `jj checkout` and `jj merge` are both deprecated; use `jj new` instead to replace both of these commands in all instances.
      
        Rationale: jj checkout and jj merge both implement identical functionality, which is a subset of jj new. checkout creates a new working copy commit on top of a single specified revision, i.e. with one parent. merge creates a new working copy commit on top of at least two specified revisions, i.e. with two or more parents.
      
        The only difference between these commands and jj new, which also creates a new working copy commit, is that new can create a working copy commit on top of any arbitrary number of revisions, so it can handle both the previous cases at once. The only actual difference between these three commands is the command syntax and their name. These names were chosen to be familiar to users of other version control systems, but we instead encourage all users to adopt jj new instead; it is more general and easier to remember than both of these.
    • Certhas 2 days ago

      I feel like one of the reasons I see the problems with git more than many commenters on here is precisely because I often teach beginners who do not have a CS background.

  • frizlab 2 days ago

    This might be the single most compelling reason I’ve ever read to try jj. I won’t, but thanks for this particular feedback.

    • DJiK 8 hours ago

      I've yet to try jj, but in git, my flow is to start a new feature with a WIP commit and then to `--amend` it with every change. I usually have a running TODO list in the commit message body that I check off along the way.

  • fragmede 2 days ago

    I use git add -p to deal with that particular issue, but it's great that other people are making and finding tools that work for them.

    • ibejoeb 2 days ago

      Same. I love the power and flexibility. But, then again, I sometimes found myself spending a nontrivial amount of time planning my git maneuvers. That was a bit taxing. Either it took away from the focus on the objective, or it was enough of a chore that it I felt a little worn, especially during intense working sessions. I don't get that as much with jj.

  • ghfhghg 2 days ago

    Sounds kind of like perforce

    • gcr a day ago

      jj was inspired by a bunch of internal Google tooling around their VCS, which was originally built on top of Perforce, so I'm not surprised the history shows through a little.

  • adastra22 2 days ago

    You can edit your commit message ahead of time in git too.

    • crabmusket 2 days ago

      What's your workflow like to do this?

      • Superfud 2 days ago

        Initial empty commit with just a message you can create with "git commit --allow-empty -m'Early commit message"

        Then when you have the changes lined up you --amend that same commit.

      • xorcist 2 days ago

        There's nothing to it, it's just "git commit".

        You then add your changes and "git commit --amend".

        (These could be aliases. Mine are "ci" and "ca" respectively.)

        • adastra22 2 days ago

          You can do that. But I mean there is literally a spot in the .git directory for the work-in-progress commit message. When you later do git commit -a or whatever, it pulls up the message.

          • stavros 2 days ago

            Is there any way you can be specific enough for people to reproduce this?

      • adastra22 2 days ago

        I don’t do it, because I don’t find it valuable. I’m kinda confused at why patent poster wants to do this. Just pointing out that git supports it too.

dang 2 days ago

Recent and related:

I'm daily driving Jujutsu, and maybe you should too - https://news.ycombinator.com/item?id=42380306 - Dec 2024 (47 comments)

Others:

Git and Jujutsu: In Miniature - https://news.ycombinator.com/item?id=42111597 - Nov 2024 (72 comments)

Jujutsu (jj), a Git compatible VCS - https://news.ycombinator.com/item?id=41895056 - Oct 2024 (110 comments)

Steve's Jujutsu Tutorial - https://news.ycombinator.com/item?id=41881204 - Oct 2024 (116 comments)

Jujutsu Strategies - https://news.ycombinator.com/item?id=41468750 - Sept 2024 (1 comment)

Jujutsu: A Next Generation Replacement for Git - https://news.ycombinator.com/item?id=40908985 - July 2024 (80 comments)

Lazyjj: TUI for Jujutsu/Jj - https://news.ycombinator.com/item?id=40859315 - July 2024 (1 comment)

A better merge workflow with Jujutsu - https://news.ycombinator.com/item?id=40842762 - July 2024 (90 comments)

GG, a GUI for Jujutsu - https://news.ycombinator.com/item?id=39713896 - March 2024 (2 comments)

jj init – getting serious about replacing Git with Jujutsu - https://news.ycombinator.com/item?id=39232456 - Feb 2024 (110 comments)

Jujutsu: A Git-compatible DVCS that is both simple and powerful - https://news.ycombinator.com/item?id=36952796 - Aug 2023 (261 comments)

Jujutsu: A Git-compatible DVCS that is both simple and powerful - https://news.ycombinator.com/item?id=36371138 - June 2023 (1 comment)

Jujutsu – A Git-compatible DVCS that is both simple and powerful - https://news.ycombinator.com/item?id=30398662 - Feb 2022 (228 comments)

sam_goody 2 days ago

What front ends work with jujutsu? Do I have to start doing all on the command line, or can I use existing clients such as Fork?

Kudos for the article. I have been seeing jj here and there, but this is the first that made me want to try it.

  • nulld3v 2 days ago

    AFAIK there is no polished standalone frontend for jj yet. https://github.com/gulbanana/gg comes closest but I ran into some quirks when using it on git compatible/colocated repos.

    Someone has made a VSCode plugin but it's closed source and I believe it will be paid at some point? https://www.visualjj.com/

    If you are willing to use a TUI, jj-fzf (https://github.com/tim-janik/jj-fzf) has been wonderful and development is extremely active too.

    I exclusively use git through the GUI, but the jj CLI improves so much over the git CLI that I'm willing to live with the CLI for now.

    Still hoping that the GUIs become more polished though, and also for Inteliij IDEA integration.

  • lawn 2 days ago

    I've been itching to use jj for real but the lack of a dedicated Neovim plugin killed my enthusiasm a bit.

    Yes, regular git plugins sort-of mostly works, but it's different enough to introduce a lot of painful edges when you do.

setheron 2 days ago

The jj community on discord has been great also. It took a while for it to sync in but when I use git now it feels "wrong"

thibran 2 days ago

How do the rebased commits work when working with others together on a branch?

  • mpalmer 2 days ago

    It's no different from how rebasing works in any shared git project; rebased commits are re-created with different SHAs.

    • crabmusket 2 days ago

      Right but that doesn't address the collaboration issue: who gets to decide where the branch points to?

      • nulld3v 2 days ago

        The person who last pushed.

        jj force pushes by default, but unlike git, the force push defaults to the "safe" variant (similar to git's --force-with-lease). So you won't accidently overwrite someone else's changes with your force push.

      • gcr a day ago

        In jj, pulled commits are immutable by default. Commits that you author are mutable until you push them.

        If I'm on a project with change AAA -> BBB, suppose my friend authors CCC and I author DDD.

        So my history looks like:

            AAA  ---->  BBB  ---->  DDD
            (immutable) (immutable) (mutable)
        
        And my friend's has:

            AAA  ---->  BBB  ---->  CCC
            (immutable) (immutable) (mutable)
        
        But then my friend pushes their change first. So when I pull, I'll have:

            AAA -> BBB -> CCC (immutable)
                    \
                     '-> DDD (mutable)
        
        Just like git, I then rebase my commit by saying `jj next` (mnemonic: "move this commit to its next descendant") to get

            AAA -> BBB -> CCC (immutable) -> DDD (mutable)
forrestthewoods 2 days ago

I’m quite happy with Sapling at work. I still haven’t figured out what Jujutsu does better. I think nothing substantial? Not that Sapling can be easily used in the public sphere. But at a conceptual level I’m not sure there’s anything in JJ I’m missing.

  • sunshowers 2 days ago

    Sapling is great. I worked on it for many years at Facebook and I think we did a pretty good job building a workflow that most developers preferred to Git.

    To the extent that Jujutsu is similar to any other systems, it is most similar to Sapling — both have a Mercurial heritage (Sapling is derived from hg, while Jujutsu is a new codebase with an hg-inspired UX). However, Jujutsu introduces a number of fantastic improvements over Sapling, such as first-class merge conflicts and automatic working copy snapshots. See my testimonial, the top one on this page:

    https://jj-vcs.github.io/jj/latest/testimonials/#what-the-us...

    I no longer do VCS development, but I'm a very happy full-time jj user. I've also helped onboard a number of people onto it.

    (Personally, I'm just happy that after the dark era of Git's branch-first UX being dominant, the anonymous heads/commit-first UX pioneered by Mercurial is making a resurgence. The vast majority of developers prefer a commit-first UX, and it is so much easier to explain things like stacked commits if you don't have to introduce git rebase -i.)

    • forrestthewoods 2 days ago

      > automatic working copy snapshots

      One of my favorite things about Sapling is that all commits are automagically backed up to the cloud. The D in DVCS is not important for roughly every project ever. So I’m not sure how to feel about “every state is a commit”.

      • sunshowers 2 days ago

        I'm not sure why you think the two are incompatible? Commit Cloud is pretty great but makes more sense in a corporate environment. You don't have to upload every automatic commit that gets made locally, though you could choose to if the capacity requirements work out.

        The automatic snapshots provide a great degree of UX coherence — definitely more than Sapling currently does. (When I last chatted with the Sapling folks, they were quite interested in porting some Jujutsu features over to it.)

        • forrestthewoods 2 days ago

          Uploading everything everytime someone runs jj status seems potentially burdensome. Uploading on every commit is maybe also burdensome but at least it’s also nice and explicit? I dunno maybe it’s fine! Or maybe some heuristic would make it fine enough. I don’t really get the “working copy commit” concept. It hasn’t clicked yet.

          > The automatic snapshots provide a great degree of UX coherence — definitely more than Sapling currently does.

          Don’t think I understand what this means.

          • sunshowers 2 days ago

            Try jj out on an open source Git repo -- I think it will both be very easy to pick up, since you're used to Sapling, and quickly make sense.

            You know how sl amend and sl fold/squash are two different commands, right? Well, jj amend is actually an alias for jj squash. And that's just the beginning.

            Regarding uploading, yeah, you'll likely have to have some heuristics, but Mononoke is generally built for very high throughput. The heuristics might just be around local debouncing and aggressive expiry of uncommitted snapshots in the cloud. But in general, it's worth thinking about the local moment-to-moment UX independently of commit cloud considerations.

  • bsder 2 days ago

    Sapling is Mercurial with some advancements. Mercurial is ridiculously better than git, but lost the network effects battle due to Github. So, JJ probably doesn't give you anything amazing.

    JJ is useful for those of us who understand the shittiness of Git but have to work in a world that got locked into path dependent network effects by VC money.

    • CharlieDigital 2 days ago

      From the blog:

          > When I left Google three years ago I recall they were trying to figure out what to do about either making Git scale, or adopting Mercurial, or what.
      
      It's interesting because I used Mercurial (hg) for close to a decade after coming from Subversion.

      Rarely had to consult the docs for weird edge cases and generally operation felt natural and seamless. It was easy to onboard new devs of all experience levels.

      I switched to git 5 years back and I still feel lost sometimes and inadvertently end up in detached head state once in a while. Git feels really "unnatural" or "unintuitive" to me in some way that Mercurial never did (I can't put my finger on why because I never gave Mercurial much thought).

      • sunshowers 2 days ago

        You're like most developers! The core problem is that Git's workflow treats branches as the source of truth for what's in the repo, while Mercurial and its progeny (Jujutsu and Sapling) treat individual commits as the source of truth. The latter is vastly simpler, and also (as Jujutsu shows) more powerful.

        While working on a stack of changes, you should be able to check out an earlier commit, amend it, and have its descendants be automatically rebased. Of course you should be able to -- this is a natural and straightforward way to think about working on changes, and builds on prior knowledge about how to work with individual commits and how to rebase them onto a newer upstream. Now compare this to git rebase -i.

    • fragmede 2 days ago

      Mercurial was slow, right when it mattered, and didn't have the Linux kernel using it. GitHub's VC funding helped, for sure, but that had more to do with the rise of GitHub over Gitlab, SourceForge, Google Code, and BitBucket than the success of git itself. Getting people to switch RCSes has a bootstrapping problem that the Linux kernel solved for git. Firefox was on Mercurial/hg, as was CPython, but neither of those have the same ecosystem of developers.

      if you take the time to learn it, the underlying data model for git makes sense, leading to the tools making sense, for those that put in the time investment to understand the underlying data model. This meant that there was a bunch of git expertise floating around IRC and mailing lists. Git tooling also wasn't super opinionated, letting pre-git workflows be run on git with little modification (which is also its problem, but does drive adoption). Sure, a recommended workflow has emerged, but that came later. By the time GitHub started in 2008, that was three years after its invention and use on the Linux kernel and git already had the mindshare and intertia. Without VC funding, GitLab or BitBucket or even Google Code might be the dominant platform, but it really was git's speed and fast branching, and proven scalability from managing Linux kernel development that led to git's rise as the preferred solution. (Its inability to handle monorepos like Google/Meta wasn't an issue for that time.)

      Mercurial's lack of speed and inflexibility are what hurt adoption. VC money pouring in might have saved it, by somehow addressing those two issues, but unfortunately we'll never know. Mercurial's workflow is pretty central though so I doubt its community would have supported changes to the central workflow. Moving from Subversion to a DVCS (aka mercurial/hg or git) required learning a new tool and being forced to change workflow on top of that made the decision to go with git easier since a git expert could make a company-specific cheat sheet that didn't also require learning and adapting to a new way of working at the same time.

      Most of the world was on SVN by the time git came around, and Git-svn was a pretty popular adapter. You could use git and its fast local branching before the company turned to git. I really can't stress the fast local branching enough as a reason for git winning. SVN server-side branches took forever to be created (even with the underlying data not actually being copied) and I remember even just running "hg" and no arguments being slow.

      VC funding helped GitHub, but git still would have won out because hg didn't have a dev community to rival the Linux Kernel. Maybe Wikipedia/Wikimedia, but that's a much smaller codebase.

      • sunshowers 2 days ago

        > I remember even just running "hg" and no arguments being slow.

        This was definitely a really big complaint. Python's just slow to start up, and last I checked Python 3 makes things even worse here.

        Startup time really made me believe that the optimal language to write CLI tools is Rust.

        • pimeys 2 days ago

          That and the great libraries Rust have for CLI apps. Really good stuff, and you can get productive quickly.

    • samatman 2 days ago

      Git succeeded to large degree because of GitHub, yes. But that isn't how it happened at all. They built an amazing product that people loved, there was nothing even vaguely like it before, and it earned its adoption through providing a superior product than the competition, by leaps and bounds.

      It ended on a bitter note when Microsoft bought them, sure. But let's not rewrite history, GitHub was not dumped on the market by deep-pocketed VCs. GitHub was self-funded from 2007 to 2012, at which point it was wildly popular and used a big cash injection to get to where it is now. By the time that happened it had the #1 position in commits per month and was about to become #1 in repos hosted also.

      • layer8 2 days ago

        Git and Mercurial both were initially released in the same month (April 2005), and DVCSs had existed for some time before [0]. Linus even considered Monotone, which is also based on SHA-1 hashes, as a replacement for Bitkeeper before starting his own Git. Most people who worked with both Mercurial and Git consider Mercurial’s UI to be superior. It was mostly the draw of Linus and then GitHub that made Git “win”.

        [0] https://en.wikipedia.org/wiki/Distributed_version_control#Hi...

        • riwsky 2 days ago

          You aren’t contradicting your parent; neither Linus nor GitHub were VC money dumps.

ziml77 2 days ago

This is the first summary of Jujutsu that has made me truly want to give it a try. I had it on my radar as something to check out but never felt motivated to because it seemed like I was going to have to put a lot of effort into changing my workflow from the one with the default Git porcelain. Based on this post, it sounds very logical and I'm looking forward to trying it on a project at work.

akdor1154 2 days ago

Great article. How do people deal with the lack of branches, esp in a full time setting where it's common to have a few independent features on the go?

  • fprotthetarball 2 days ago

    There are still branches, but they aren't named by default. You give them names with "bookmarks", which you can push to remote git repositories as branches.

    This lets you work on things without having to worry about giving it a name. This turns out to be pretty helpful when you're experimenting — just "jj new <revision>" and start editing. If it turns out to be something you want to share, "jj bookmark create <name>" and then you can push it. (You can also push without giving it a name, in which case you'll get a git branch with a name based off of the change id.)

    Change IDs stay constant with each change, so you use those as a type of branch name when switching between the features you're working on.

    • J_tt 2 days ago

      Adding onto this, there’s also an experimental feature to move a bookmark as you create new revisions (similar to how a git branch behaves)

      • pkulak 2 days ago

        Oh, that would be nice. I get the reasoning not to, but it would be nice to have the option.

    • stavros 2 days ago

      What changes the change ID? What constitutes a change? Is a change made up of many commits, or the other way around?

      • Superfud 2 days ago

        A change ID is stable over time as you tweak the message of the change or the files edited by the change. Each of these changes become a new immutable git commit under the hood.

        The fact that change ID is stable is very convenient for humans - means you have something explicit to hold on to as everything else may change over time.

  • sunshowers 2 days ago

    So, with VCS in general you don't really need to have branches to be able to track multiple independent changes. (With Git you do, but that's an artifact of Git's model, not an inherent property of source control.)

    What you do need is a good way to visualize what work you have in flight. With Jujutsu that's as simple as typing in `jj` on the command line.

    At Facebook it was common for even junior devs to have 5-6 changes in flight with nary a branch in sight, and experienced devs like myself routinely had dozens.