Jujutsu Megamerges and jj Absorb

82 points by chriskrycho 6 months ago | 63 comments
  • Valodim 6 months ago
    So interestingly, many folks I've talked to had a reaction of "so jj is just a frontend to git, big whoop. There are hundreds of them, my favorite is X". That's an understandable reaction.

    But jj is more than that, and you couldn't implement it as a git wrapper. I think the core innovation is that rebases are so fast they are essentially free, which opens up amazing potential.

    But so far I haven't found a way to really convey the full weight of this without a long explanation, because people are so used to thinking in git, it takes a long time to go beyond "so rebase -i will be faster, then? But it's not slow, is it?"

    It's funny, that git is now in the position that subversion was in almost two decades ago: People were so used to svn and felt productive with it, it was hard to convey why free branches and a distributed data model are a gamechanger, and how much svn limited their thinking. But as a git user you had certainty that you were right, and that your tool is superior.

    Now, people are so used to git, in an eerily similar way. But ask most git users, "how would you move a specific change from your branch to another?" I have yet to receive a confident answer and workflow to this (they do exist ofc), the common reaction I get is that this isn't something they'd ever need anyways.

    I'm curious how this will look in a few years :)

    • williamdclt 6 months ago
      > this isn't something they'd ever need anyways.

      Oh I do that quite often, either because I didn’t realise I was committing on the wrong branch, or I decided to split my work in two branches, or i need some other unmerited change for my current branch…

      It’s usually a rebase —onto or cherry-pick, I’d say I agree it’s not simple.

      jj seems interesting, I’m very comfortable with git but I think its UX is terrible, but everyone use git and it is not an area where I have capacity or willingness to innovate. I’d love to see git being replaced with something better designed though

      • stouset 6 months ago
        Nobody else needs to convert to jj for you to use it, so there’s no real downside to switching.
        • williamdclt 5 months ago
          The downside part is "it is not an area where I have capacity or willingness to innovate". I'd happily follow, I don't care enough to lead the innovation.
          • Macha 6 months ago
            Yeah, this is the real advantage that jj (and sapling) have compared to how many years I'd been hearing about fossil and seeing it as a non-starter to experiment with.
        • bayindirh 6 months ago
          The difference between git and svn is, svn is very fixed in terms of workflow. On the other hand, git allows many different workflows, and allows people to handle their codebases the way they see fit.

          Of course, no tool is truly universal, and git frontends and alternatives leverage different parts of the underlying data structures with different trade-offs.

          I personally never use rebase, and am a merge guy. I don't use a gazillion branches either, not because I'm afraid of them, but my mental model works like that. Some people squash commits, others rebase, etc. Everybody is different in their ways.

          svn to git was a fundamental change and allowed new things to happen. jj on the other hand makes some workflows easier while others take the back seat. So I don't see jj as a git disruptor, but an opinionated alternative tool which uses git data structures as the backend.

          • Certhas 6 months ago
            I agree that the change isn't of comparable magnitude. But JJ changes the user facing conceptual structure of version control. It unifies working directory, stash, index and commit, and replaces them with a single thing. And it shows that all existing git workflows can efficiently be constructed on this much simpler conceptual basis.

            In my mind this demonstrates convincingly that gits conceptual model carries unnecessary incidental complexity. Within a fixed complexity budget jj absolutely does allow new things to happen.

            I also don't really see any workflow examples that truly suffer under jj, so I don't think it's just another trade-off. It's a real substantial improvement. If it wasn't it wouldn't be making headway against gits network effects.

            • bayindirh 6 months ago
              From what I understand, all these different places/things (working directory, stash, index and commit) confuses, and comes across unnecessary to some people. They want a simpler solution, and less mental load during version control phase of their software, that's understandable.

              In my experience software developers come in two flavors. a) Developers who want to understand all the pieces they work with and have the desire to deep-dive into them b) Developers who write and commit code. They think that former part is their job and care about it. They don't care after it leaves their machine (in the sense of "I give box to machine it magically integrates").

              IMHO, jj is very enticing for the latter camp, and that's not a bad thing. Not all of us are passion programmers/developers, and some are don't want to think about beyond their immediate realm. I respect these people. But, again, from my perspective, jj doesn't make sense for me. It's useful alright, but I actively use index, commit and stash very naturally. I might be good at understanding it because Eclipse has a great git integration which makes everything super workable and understandable, and I'd never change a power tool like git to something "push button, magic happens" class of tool.

              jj might be very conductive to more complex workflows by removing some complexities, but unifying my stash, staging area and index is not something I want to be dome to my workflow for example.

              Some trade-offs make great headways into networks because a large part of that network is silently suffering without being aware, and the trade-offs are worth it. See Rust for example. People accept 5x mental load and 10x compile times for memory safety. Same for jj. People accept a much simpler interface because it makes their painful workflows "push button, magic happens" levels of simplicity. Or, the people who like jj work under time pressure and want to remove a time-sink from their workflows, again understandable and respectable.

              Having something like "jj" is not a bad thing. What I'm squarely against is "git is dead, new king is jj. Now move to your new kingdom and worship jj" mentality.

            • stouset 6 months ago
              > I personally never use rebase

              Probably a lot of that is because it is painful. When it becomes a no-op, suddenly a lot of things become easy to do.

              Do you ever want to go back and edit a previous unpublished commit? Yes fixups exist, but that’s a band aid over the fact that editing a previous one is annoying and hard.

              Do you ever want to maintain a linear chain of branches? Branch A needs to be merged before Branch B needs to be merged before Branch C. It’s a massive pain with git, especially if you need to change Branch A. It’s a no-op in jj.

              There are a ton of straightforward and useful workflows in git that are just completely impractical.

              • bayindirh 6 months ago
                No, not because it's painful, I just don't need it.

                > Do you ever want to go back and edit a previous unpublished commit?

                Honestly, no? I plan what I'm going to change, do it, commit it, and if I messed up, I don't hide it, just fix it and write "I messed up X in $HASH. This fixes that".

                > Do you ever want to maintain a linear chain of branches?

                No, I always keep a single thing moving at one time. If the project is big, I use a branch per feature, if it's a smaller branch, there's a development branch. That's all. I have a habit of designing before touching code, so I always move in well planned moves.

                It's not like that because I'm afraid of rebase. It's just how I design/implement software. Yes, it's generally not a group work, but I do what I do, and it works.

                > There are a ton of straightforward and useful workflows in git that are just completely impractical.

                That's fine. I don't claim otherwise. I just don't do to prefer source code / branch acrobatics. I'd love to share a seven year development tree to show how I work, but unfortunately that repo is not meant to be open, at least for now.

                • Izkata 6 months ago
                  > Do you ever want to go back and edit a previous unpublished commit? Yes fixups exist, but that’s a band aid over the fact that editing a previous one is annoying and hard.

                  Also unnecessary, "git rebase -i" has an "edit" command that pauses the rebase at that commit to let you do whatever.

              • dijit 6 months ago
                You’ll find this to be true about many things.

                For example, the solution to almost all problems is oddly kubernetes shaped even though that was not the case 15 years ago. And Google themselves would be the 1st to tell you that kubernetes is not capable of doing all jobs.

                Monocultures are insidiously bad, they poison solutions and reasoning, but they have their upshots too- if you never need to learn a new mental model; us tech workers become more interchangeable and the cost to onboard goes down.

              • setheron 6 months ago
                You've been so welcoming in the jj community. Thank you.

                I don't understand how absorb works in your example. Why would the commit "z" be affiliated with some random documentation changes you come across and fix in the wip commit.

                All that I see is it makes it easier to make small refinements to preciously altered lines ?

                Super excited for jj.... Almost want to find a work opportunity to promote it. Been a refreshing tool I've adopted in 2024 I'm happy about.

                • masklinn 6 months ago
                  > Why would the commit "z" be affiliated with some random documentation changes you come across and fix in the wip commit

                  It's not? z is the root pseudo-commit.

                  > All that I see is it makes it easier to make small refinements to preciously altered lines ?

                  Well yes, the point is to untangle working copies with various unrelated changes (usually fixups) which should really go into older commits.

                • xyzsparetimexyz 6 months ago
                  This does halfway convince me to try it using jujitsu.. However I think the biggest barrier so far is that I understand how to undo mistakes in git but I don't in jujitsu.. if you accidentally run 'jj squash --into x --keep-emptied' when you meant 'jj squash --into n --keep-emptied', how do you undo that?
                  • barakm 6 months ago
                    Literally `jj undo`

                    There's a whole operation log (`jj op log`), as another sequence of actions, and you can undo them. It gets crazier from there, but I've also been enjoying jujutsu lately and I had to RTFM a good couple of times to get comfortable with it.

                    • stouset 6 months ago
                      Also cool: jujutsu remembers every previous state of all your changes. So you make some edits, run `jj status` (or anything), and keep working.

                      Two hours later you realize your experiment is a total failure and you wish you had the half-working changes from earlier. You don’t need to have actively commited anything, it’s all in the obsolte log and you can retrieve it.

                      I want to repeat that last bit. Unlike git, there was no point where you needed to finalize your changes with a commit in order for them to be persisted and archived for later retrieval.

                      • xdfgh1112 6 months ago
                        You can even undo operations that aren't the most recent one.
                        • corytheboyd 6 months ago
                          Huh this comment thread may have convinced me to finally try it. I’m comfortable with git, and fixing mistakes in git, but not being able to trivially reverse any and every transaction is annoying.
                      • stouset 6 months ago
                        To elaborate on the other comments, it is extremely easy to use the op log to undo basically anything.

                        I was live demoing something and performing some manual repo surgery in order to demonstrate some thing that can happen with git but is nicely solved by jj. In doing the surgery I absolutely fucked everything.

                        I had never used the undo feature or the op log before. In less than five minutes—during the live demo—I was able to figure out how to reset things back to a known good state. It was stupidly easy.

                      • bjackman 6 months ago
                        I am slowly inching towards trying out jj. I think the main issue will be if I find some issue in the git compatibility aspect. I do two kinds of work:

                        1. Work on smaller projects with simple histories. Git is perfectly satisfactory.

                        2. Work on huge projects with very complex git histories and weird legacy workflows (primarily Linux kernel).

                        jj is only interesting for part 2, but then it's only useful if it's easy to bridge into the Git world that everyone else uses.

                        But this workflow is exactly the kind of thing that seems handy. There's so much stuff that Git can totally _do_ but could just do a lot _better_.

                        • stouset 6 months ago
                          Just try it!

                          I converted 6mo ago after finally pulling together the motivation to give it a shot. My biggest hesitation was in how long I expected to struggle with it before feeling comfortable, followed closely by skepticism about how good the compatibility story actually is.

                          Both, it turns out, were non issues. It took all of a day to feel perfectly comfortable using it. I spent the rest of the week gradually plugging most of the remaining holes in my workflow. And git compatibility is as advertised. A coworker switched shortly after I did and zero people have noticed or cared.

                          Though at this point I don’t even bother colocating the .git repo alongside .jj. Meaning I haven’t found a need to fall back to git commands in maybe four or five months.

                          • evgpbfhnr 6 months ago
                            > Though at this point I don’t even bother colocating the .git repo alongside .jj. Meaning I haven’t found a need to fall back to git commands in maybe four or five months.

                            That interests me -- is there a native jj protocol for push/fetch? Even if just ssh? Or do you just work in local repos?

                            • steveklabnik 6 months ago
                              Backends can do whatever. The git backend knows how to push to git remotes. If you used a different backend, it would know what those backends expect. There aren’t any of these publicly, but Google has one to work with piper.
                            • masklinn 6 months ago
                              How's the tool compatibility when using gg tho? My repo work tends to be split between git and magit, and while I would very much welcome the ability to get rid of git for a better experience, doing so at the cost of magit is an extremely steep hurdle.
                              • 6 months ago
                            • chriskrycho 6 months ago
                              I actually find jj great for (1). The project I reference working on in this post is in exactly that bucket, and the kinds of things I do with it are not “complicated” but jj is still much, much better than working with Git—not least for the kind of workflow I showed in this post!
                            • evgpbfhnr 6 months ago
                              How does jj handle very large git repos, e.g. this linux clone with a mix&mash of quite a few upstreams with a 6GB big .git dir?

                              (I agree I probably shouldn't focus on that first, and could just try jj first on smaller rpos... But git is already slow enough in there that it's an honest question, I don't need to keep using git there as long as I can keep pulling from stable kernels git trees for regular merges)

                              • Macha 6 months ago
                                It works fine on nixpkgs, which is by some measures larger than the linux git repo.

                                jj git clone/fetch/push are using the corresponding git commands under the hood so they won't improve on git performance but also it doesn't have much overheard of its own.

                                If you're using the -T revset syntax, you can specify a revset that requires looking at every commit, which is slow, but that's equivalent to asking for `git log -n 1000000`

                                • evgpbfhnr 6 months ago
                                  Thanks! My nixpkgs clone is 5.2GB so it's not too far indeed! :)

                                  I think the nixpkgs workflow is much less prone to rebase/merges (some cherry-picks to stable branches I don't do much), but it's a very good data point, thank you. I guess I'll give it a try over christmas break..

                              • dilap 6 months ago
                                Looks amazing -- hopefully some day they'll add git-lfs support and I'll finally be able to try it. :-)
                                • CT4u8798 6 months ago
                                  Goddammit. This gets me every-time. Click these threads expecting Jujitsu only to find source control!
                                  • IshKebab 6 months ago
                                    Does jj do anything about submodules being horribly buggy in Git, or LFS being taped on the side as an afterthought? I guess they can fix the submodule bugs but presumably they can't fix LFS without breaking Git compatibility?
                                    • steveklabnik 6 months ago
                                      Right now Jj basically ignores submodules, they do want to fix it but haven’t yet. So you just use git commands in a colocated repo for now.

                                      Large file stuff is also a “want to do something better but no progress yet” kind of thing.

                                      • IshKebab 6 months ago
                                        I think having both those working would be a serious reason for a lot of people to switch. E.g. just having working submodules and worktrees would do it for me.

                                        Fingers crossed. Glad we're finally getting some viable Git competition with jj, Sapling and Pijul.

                                        • steveklabnik 6 months ago
                                          To be clear, submodules work, you just have to use the git commands to update them. I agree things will be nicer when that’s not necessary though :)
                                          • chriskrycho 6 months ago
                                            It does not implement Git worktrees, but instead implements its own notion of workspaces which frankly I find much nicer (unsurprisingly!). As with most things jj: just as much or more power than Git, but less hassle.

                                            Working with submodules natively (see steveklabnik’s sibling comment for the “non-native” bit) will definitely be a big win.

                                      • sausagefeet 6 months ago
                                        jj might be the future. I certainly hope git is not. My current system is Mercurial with hg-git and evolve, and so far I find this to be fantastic for local development. There are a few rough edges but I just find hg so simple to use and consistent in functionality. I can usually just figure out how to do what I want from the --help screens. In git I often read the man page for a commit and then I just ask ChatGPT how to do it because the man page for each sub command is a novel. I hope that jj will aim for simplicity in the long run but I guess we'll see.
                                        • sa1 6 months ago
                                          There’s also gitbutler for this kind of workflow, a bit more visual.
                                          • steveklabnik 6 months ago
                                            Yes, gitbutler is very cool. Scott is in the jj discord, and they’re jj fans in general. Lots of good cross pollination going on in this space!
                                          • kkfx 6 months ago
                                            It's a bit a joke, but not too much: the next step will be full integration with editor's undo/redo mechanism, which in the end could be seen as a log-based storage. Because that's the trend I've seen on the (little) new ideas from the VCS world.
                                            • chriskrycho 6 months ago
                                              If you enable the watchman integration, then you actually get very close to this: your current change’s evolution log and the repo operation log will have every change which was persisted to disk. There are tradeoffs to that, of course, but it’s a very powerful capability—and notice that it’s something that would be a huge pain to cobble together somehow in GitHub which Just Works in Jujutsu. It falls cleanly out of making the working copy a commit.
                                            • 6 months ago