28 comments

  • y1n013 hours ago
    I don&#x27;t get why people like jujutsu. I tried it for a while but I work with a quite a few people in the same repo and I need easy named branches that keep up with commits. For all the many problems in git, branches are dead easy. That was the big innovation over svn at the time.<p>Last time I tried jj, branches were an extremely laborious process to keep up to date. I don&#x27;t see how people that aren&#x27;t working alone can work with that. I have numerous branches in flight at any given time, and my colleagues do as well. The idea of manually keeping them pointed at the right commit is just nuts.<p>Maybe they&#x27;ve fixed that astonishing choice since then, and I&#x27;d give things another go if they did. But branches and worktrees are how I operate.<p>Regarding the article, I have no idea what is going on as I&#x27;m red-green color deficient.
    • BeetleB6 hours ago
      I think much of the problem with this thread is people trying to convince one way is superior&#x2F;inferior.<p>There are just multiple different ways of working. Some ways fit some people&#x27;s mental models better.<p>You&#x27;re not going to get a definitive &quot;jujutsu is better than git&quot; or vice versa. You should accept that some people have no problems with what you&#x27;ve described using jujutsu, and likewise jujutsu users should understand that not everyone can handle jj as well as they can.<p>Imagine a different thread where jj users take your exact scenario, and complain about solving the problem with git. You wouldn&#x27;t understand their pain, because it&#x27;s not painful for you. This thread is the same, just with jj and git reversed.<p>Personally, I don&#x27;t see the pain you have. Back when I used git a lot, if I left a branch for a few weeks, I&#x27;d forget the name of the branch and would have to list all the branches (and set an alias to sort by and list the last commit dates of each) to discover the appropriate branch name. It&#x27;s really not all that different from looking at all (recent) heads. Once you get used to this, you stop naming branches - other than to share with others. And when you do share with them, you cannot push (newer) changes because only bookmarked nodes and their parents can be pushed - so just prior to pushing, you advance the bookmark. With the shells I use, it&#x27;s a few keystrokes before autocomplete&#x2F;fzf produces the command for me - no mental effort at all.<p>You definitely wouldn&#x27;t advance the bookmark with each commit. Only when you need to push.<p>And oh man, it&#x27;s <i>so</i> nice not to have to manage all the branches. With git, I&#x27;d routinely go and delete old branches to declutter. With jj, there&#x27;s simply no need to. The same with stashes. It&#x27;s really nice not having to do that labor, and simultaneously not dealing with long lists.<p>If this doesn&#x27;t appeal to you - that&#x27;s fine. You&#x27;re not deficient. But understand, nor are those for whom your workflow sucks.
      • jaredklewis6 hours ago
        It’s only natural to want to defend one’s preferences with these things. Because unlike with some other preferences, such as what IDE, operating system, or terminal emulator you use, version control systems must be shared.<p>If it is like you say and different people are just inherently more or less suited to different paradigms, then not everyone can be happy.
        • BeetleB5 hours ago
          &gt; version control systems must be shared.<p>This whole thread is about working with git coworkers while using jujutsu, and it was in that context that I wrote my comment: Namely that most who prefer jujutsu happily work with their colleagues who use git in precisely the scenario the OP mentions and don&#x27;t see why the OP finds it painful. The OP and others should accept that reality.<p>&gt; If it is like you say and different people are just inherently more or less suited to different paradigms, then not everyone can be happy.<p>If you force everyone to use git, of course not everyone will be happy.<p>If you force everyone to use jj, of course not everyone will be happy.<p>Thankfully, the whole point is git and jj users can interoperate without needing to care what the other is using. So yes, not only <i>can</i> everyone be happy, but everyone <i>is</i> happy! This isn&#x27;t a hypothetical - it&#x27;s a reality. It&#x27;s the reason so many use jujutsu at work.
    • arccy37 minutes ago
      i too work with worktrees (jj workspaces) and prs (requires branches). it&#x27;s easier if you give up choosing the name of your branch, and instead rely on finding things by description or your workspace name.<p>for prs, I usually start with a single commit, so `jj git push -c` will auto create a named branch based on the change id. And i have template like the following to push to the same branch if i decided to stack commits rather than rewrite:<p><pre><code> branch-push = [&quot;util&quot;, &quot;exec&quot;, &quot;--&quot;, &quot;sh&quot;, &quot;-c&quot;, &quot;&quot;&quot; name=&quot;$(jj log --no-graph --no-pager --color=never -r &#x27;fork_point(@ | trunk())+ &amp; fork_point(@ | trunk())..@&#x27; -T &#x27;&quot;push-&quot; ++ change_id.short()&#x27;)&quot; jj bookmark set -r @- &quot;${name}&quot; jj git push -b &quot;${name}&quot; &quot;&quot;&quot;] </code></pre> you could probably write a similar alias that used your workspace name as the branch name to push to.<p>and descriptions are slightly nicer than branch names, since they can be longer.
    • jolux13 hours ago
      I assume you mean <i>named</i> branches (bookmarks in jj)? Because anonymous branches in jj are trivial: you just `jj new &lt;parent_change_id&gt;` and you have a new branch.<p>Bookmarks aren’t that bad either IMO, especially with the recent addition of `jj bookmark advance`. Curious if you can say more about the particular difficulties you found keeping them up to date?
      • y1n010 hours ago
        I think I said named branches, but that is definitely what I mean. I find it strange that people want to work on anonymous branches, but to each their own. I don&#x27;t so that has no appeal to me.<p>I often work on something and then switch away to something else. it might be a week before i get back to it, and the <i>name</i> of the branch is a clue as to what the heck I was doing.<p>Other people often need to check out a branch I&#x27;m working on to help. How does anonymous branching help anyone except a solo developer?
        • justinpombrio9 hours ago
          &gt; it might be a week before i get back to it, and the name of the branch is a clue as to what the heck I was doing.<p>Ah, this is what the description (what git would call the commit message) is for. You can set the description even before you&#x27;ve made any changes.
          • em-bee8 hours ago
            that doesn&#x27;t make sense because when i am working on a feature, i create a branch, name the branch after the feature and then each commit has a description of what is in that commit. the feature has multiple commits, and while i carefully work out what goes in each commit i don&#x27;t squash them.<p>so with jj i could use a bookmark, ok, but having to manually update that bookmark feels wrong.
            • igor476 hours ago
              When I&#x27;m working in git, I always start work by creating a new branch with a name. Sometimes the branch becomes something different as I work and then I might rename it or more often just keep a stale name around. But in git commit descriptions come later.<p>In jj, it&#x27;s the opposite. I start with a change, and I often describe it right away. Branches (bookmarks) come at the end.<p>You could, in jj, tag a new empty change with a bookmark as soon as you create it. You don&#x27;t have to advance the bookmark -- that the first change in a sequence of changes is tagged with a bookmark is probably as much information as you need?
        • jolux9 hours ago
          &gt; I think I said named branches, but that is definitely what I mean<p>I think I misread you, because you were talking about git vs svn in a way that made it sound like jj was a step backward from git as regards branching, and I got confused.<p>&gt; I often work on something and then switch away to something else. it might be a week before i get back to it, and the name of the branch is a clue as to what the heck I was doing.<p>Right, but you can still name your branches with bookmarks, you’re just not required to. Personally, I tend to use commit descriptions more than bookmarks to keep track of what I’m working on, but this is a personal choice.<p>&gt; Other people often need to check out a branch I&#x27;m working on to help. How does anonymous branching help anyone except a solo developer?<p>It’s just nicer as a local workflow, to me at least? I can create throwaway branches without having to come up with a name for them. I end up creating many, many more branches than I did in git as a result, which helps me keep my work better organized and my changes more focused when I submit them for others to review (which at least on GitHub, requires a bookmark of course). This is ultimately psychological because obviously I could just make up a name for the git branch, right? But it makes a big difference for me!
      • nine_k12 hours ago
        Imagine that you use jj, while everyone else who works on the repo along with you uses regular git.<p>Is it easy?
        • Balinares7 minutes ago
          Yeah, trivial. Only difference my teammates see is that my commits are much tidier and scoped in a way that&#x27;s easy to review and think about.
        • Macha9 hours ago
          The biggest issue is my git knowledge is atrophying while my coworkers still know me as “the git wrangler” (mostly because most devs have never actually learned git, so any knowledge looks 10x more than theirs). So when a coworker comes to me with a problem like their local main now has 2000 commits that they’ve (or rather Claude Code has…) somehow accidentally re-signed locally and then the 20 commits that actually contain their work, I’m thinking this would be easy to fix with jj rebase but the best advice I can give them for git is to reset their local main to origin&#x2F;main, create a new branch and then cherry pick their 20 commits to their new branch. Since that’s too time consuming they just checked out the repo again and copied their working copy over, which is the level of avoiding actually using git that the git CLI routinely inspires.<p>Some later googling revealed `git rebase --onto origin&#x2F;main theirbranch main` was probably what they needed. Which I’m sure would have come to me quicker if I hadn’t dropped the git cli for jj 2+ years ago.
          • igor476 hours ago
            Are you me? I do feel like I&#x27;m starting to forget git as a result of my happy jj use. Thankfully some repos use git submodules, which keeps me at least a little connected
        • jolux12 hours ago
          Yes, that describes me at both jobs I’ve had since learning jj. Hence why I asked for specifics: I’m genuinely curious what other people struggle with, partially because I’d like to help them if I can, and partially because it gives me a better understanding of common pitfalls which helps when teaching other people.
        • stouset11 hours ago
          Yes, that is the case for almost every repo I’ve ever used jj for. It is a complete non-issue. There is virtually zero friction.
        • rtpg11 hours ago
          yeah nobody &quot;has to know&quot;, especially if everyone else is also rebasing etc constantly.
        • tiltowait10 hours ago
          I do this all the time at my job, without issue. I think it&#x27;s honestly easier than using plain git.
        • jgtrosh12 hours ago
          I believe this is the most common scenario, yes. If you&#x27;re used to actively pushing and pulling from the same branche as your colleagues, you need to learn how to manipulate diverging changes and conflicting bookmarks, but other than that all the jj magic is limited to your local activity.
        • LoganDark12 hours ago
          I use jj all the time for pull requests, in fact I don&#x27;t use regular git at all anymore, and it&#x27;s perfectly easy. Not only can I easily keep all my pull requests properly synced to their base branches, but I can easily and very quickly address review comments, keeping the commit stack clean without having to manually squash or amend or anything of that sort. Honestly it&#x27;s a lot easier and more efficient than git for me because of how much naturally follows rather than requiring explicit imperative fixups.
    • stouset11 hours ago
      I’ll be honest, as a long-time jj user, I actually haven’t the foggiest what you’re talking about with branches being laborious to keep up to date. Can you elaborate?
      • y1n010 hours ago
        I make a commit and the branch doesn&#x27;t follow it. Bookmark, whatever. That is never a behavior I would want. What purpose does it serve?
        • stouset7 hours ago
          Of all the things I was imagining it might be, this was down at the bottom.<p>Personally I’m a huge fan of this approach. If you aren’t, it’s literally just a one-liner (that is trivially made into an alias) to advance a branch name to the most recent revision. And now there’s a feature to do auto-advancing if you want it.<p>Why is it this way? Because jj is designed around revisions being constantly mutated.<p>In git, when I make a commit, I am typically signaling that that a chunk of work is complete. Not always, but usually. In most jj workflows, revisions are mutated constantly during development. A revision being made on the tip of a branch is rarely a signal that that unit of work is finished. It’s even incredibly common to have <i>multiple</i> revisions in a row that are works in progress. Hell, the article we’re all commenting on discusses just such a workflow. If I make five revisions on top of some branch, there is no reason to assume that any of them are ready to be shared, much less all of them.<p>Because of that difference, it makes sense to have an explicit act to move a branch name forward.
        • paradox4609 hours ago
          They added auto advance bookmarks a while ago. You configure which revset bookmarks you want to advance or not, and then it just keeps them at the &quot;head&quot; of a branch
          • cpeterso8 hours ago
            Having to list all the bookmarks you would list to auto-advance in your jj config.toml is a hassle and easy to forget.
            • em-bee8 hours ago
              ideally this should be done automatically when you create the bookmark, maybe with a commandline option: <i>jj bookmark create -a&#x2F;--auto-advance ...</i>
    • kaladin-jasnah9 hours ago
      I like jujutsu simply because (despite my annoyances, which might be because I started using it 2 weeks ago) it&#x27;s still faster than git.<p>I dislike this as well. I find it easier to keep track of branches with bookmarks, but my workflow still makes things cumbersome. I am usually working with the &quot;megamerge&quot; branches, and I usually want to add commits to my current branch instead of squashing my edits. However, adding commits means I have to add my commit, move my bookmark up to the branch tip (jj tug?), and then rebase the megamerge branch, versus doing nothing for squashing. I also find that when I mess up, I don&#x27;t really love using `jj op log` to fix it. I want to not be in an environment where it&#x27;s this easy to destroy history (I feel like git was on the other end of it).
      • oscillonoscope6 hours ago
        If I need to move a &#x27;branch bookmark&#x27; around a lot, I usually just tie it to an empty commit and then rebase changes before the bookmark.
    • kccqzy10 hours ago
      You don’t need easy named branches. Naming branches is a chore: since you already spend time writing commit messages, branch names are just a summarization of your commit messages but with more character restrictions.<p>That’s why I always use jj’s automatic commit identifiers. They are short and I don’t waste brain cycles naming things that are ephemeral. When I push, I let jj automatically creates, updates, and deletes remote git branches (`jj git push -c` for creation, plain `jj git push` for updates, `jj git push --deleted` for deletions). I do not ever have to think about branch names and it is great!
      • dzaima9 hours ago
        But you probably <i>haven&#x27;t</i> spent time writing commit messages before a branch is finished. Or, if you have, you&#x27;ve quite potentially just wasted time writing something that will be rewritten anyway as things change; replacing a chore with a much bigger chore.<p>Restricted and summarized is good - easier to find&#x2F;remember, less fluff in a list. And easier to recognize a short identifier from a list of the 2-3 most recent branches, than scanning through 50 commits, when trying to remember where some work last was, and which is the proper end-point instead of some failed attempt or unrelated change.<p>Unnamed branches are quite neat - I certainly have a lot more of such than named ones in jj - but as such named branches are, if anything, <i>more</i> important as a result, for separating sequences of changes striving towards a goal, from the sea of smaller experiments.
        • kccqzy9 hours ago
          &gt; But you probably haven&#x27;t spent time writing commit messages before a branch is finished.<p>Wrong. With jj, I use `jj describe` before I start work. It is like writing out a plan for what I want to do.<p>&gt; Or, if you have, you&#x27;ve quite potentially just wasted time writing something that will be rewritten anyway as things change.<p>Rewriting it is not wasted time. It is an opportunity to look at what I have written in the plan and check whether I have really executed them, and then rephrase things to be more easily understandable.<p>&gt; Restricted and summarized is good - easier to find&#x2F;remember, less fluff in a list.<p>The first line of a commit message is already a summary of the work done. And you can use actual English instead of trying to awkwardly avoid spaces in your words.
          • dzaima8 hours ago
            &gt; It is like writing out a plan for what I want to do.<p>I usually don&#x27;t have a plan for the end; certainly not what any specific commit would be; sure, I could make one (and either make my future self have to do extra work to figure out what commits with lies in their descriptions actually do, or continuously update the commit message marking what actually exists), but as I said that&#x27;s basically a waste of time. (if you like comparing with past thoughts, sure, but that&#x27;s definitely not a necessity for a workflow to be reasonable)<p>&quot;is&#x2F;isn&#x27;t an ancestor of the bookmark&quot; is also just a pretty damn good short-hand for denoting a separation between what&#x27;s been considered the best attempt at the goal, vs things with known problems or just unrelated to the task.<p>At the core, this if all of course just a question of workflow; if you go into a thing with a plan, meaningful outlook of a non-vague destination, and without expecting continuous switching back&amp;forth between a dozen other things over the time span the branch is alive, caring less about branches or branch names can perhaps work.<p>&gt; The first line of a commit message is already a summary of the work done.<p>But you can&#x27;t (sanely) use it to reference the branch in a revset, can&#x27;t find it anywhere other than the full log (that&#x27;s interleaved and mixed with a bunch of other things that you won&#x27;t ever need to search for), and actual English just gets in the way for finding it, remembering it, and identifying it in a list.<p>This alone means that, even if I found interest in massively-ahead-of-time-describing commits, having a sane branch reference is still simply just necessary.
      • y1n09 hours ago
        Yeah, I don&#x27;t get it. I&#x27;m sure it&#x27;s because we work differently and that&#x27;s fine.<p>But when I&#x27;m picking up something someone on the team has left behind because they got pulled on to something else, or are sick, or 5 million other reasons, having a branch, with a ticket in the name, explaining what the purpose of the branch is, why it exists, what it&#x27;s current state is, that all matters. I can&#x27;t help but think that everyone that likes JJ isn&#x27;t really doing collaboration.
        • Macha9 hours ago
          When its MR time I use jj push -c and I’ve set my config to auto generate a branch name from the commit message by extracting the ticket ID from the commit message since we have a standard format into something like PROJ-1234-nzytopmn . Since the company I work at enforces squash merge since many coworkers would otherwise have 20 merge, fixup, lint or ci fix commits per MR, auto advancing isn’t relevant. Addressing comments is just squash into that change and repush. We don’t really do long lived branches so the ticket number is enough to find the branch and the commit message explains the change if I need to hand over work.
        • kccqzy9 hours ago
          I collaborate a whole lot. In fact for solo development I use git because jj is overkill for it. Also by default jj prevents you from overwriting commits that exists on the main branch on the remote, but this is what I often do on solo projects.<p>&gt; having a branch, with a ticket in the name, explaining what the purpose of the branch is, why it exists, what it&#x27;s current state is, that all matters<p>In my view, all the above information exists not in the branch name, but either in the ticket, or in the commit message. The branch name is purely a superfluous thing that does not convey any information. Many of my colleagues already use a tool to automatically name their branches from the first line of their commit messages, and jj just makes this awkward process straightforward.
      • rixed4 hours ago
        <p><pre><code> branch names are just a summarization of your commit messages </code></pre> What kind of dev workflow leads to this surprising opinion?
      • cpeterso8 hours ago
        I name my branches for the overall task. The description of the branch’s head commit in jj status doesn’t tell the whole story.
      • krackers3 hours ago
        &gt;You don’t need easy named branches.<p>You can&#x27;t possibly see a use-case for long-lived branches? Say what you will of git, at least it exposes enough knobs that it can mostly accomodate every workflow (possibly with a heavy porcelain layer to hide the plumbing). JJ seems to swing too far in the other direction, great for a &quot;live on head&quot; mentality but less ideal for other setups.<p>(The fact that all edits are automatically recorded is my personal peeve with JJ. I&#x27;m ok with lack of staging area like in Mercurial, but mercurial doesn&#x27;t try to automatically amend the commit with my pending changes. Sure I can pretend that &quot;@&quot; is my staging commit then squash as needed, but then I also need to remember that checking out a commit is &quot;jj new&quot; which feels like absurd mental gymnastics to me.)
    • rmwaite10 hours ago
      I remember being the big innovation over svn being merging. There were others things, obviously, but the distributed model + easy merges is what I remember.
      • kccqzy9 hours ago
        If the big innovation over svn is merging for git, then the big innovation here is conflicts. I hate the fact that git requires you to stop everything and fix the merge conflict when you merge. I especially hate the fact that when rebasing in git sometimes it requires you to solve conflicts one by one. The big innovation here is jj does not require you to resolve merge conflicts in a timely manner; it simply records the fact that there are conflicts in the file and you go about your ways. You don&#x27;t ever have to abort like `git rebase --abort` or `git merge --abort`.
      • y1n010 hours ago
        Yes, that&#x27;s true, merging. Which is what made branching a reasonable thing to do.
    • sakompella7 hours ago
      i had this exact friction trying to use jj this weekend. can&#x27;t fathom for the life of me why i have to run another command that updates the branch to the next commit.
    • LoganDark12 hours ago
      I don&#x27;t try to reimplement the git workflow on top of Jujutsu. I like it because I can let go of a bunch of annoying noise that I needed in Git. I like it because rebases don&#x27;t have to be synchronous and modal. I like it because I can easily edit history, rearrange the commit graph, change commit descriptions, duplicate, and so much more, and even remotely (without having to checkout first). There&#x27;s so much to love that I never could&#x27;ve even dreamed of under Git.<p>I like Jujutsu so much that I&#x27;ve been working on massive refactors to my tooling in order to support it (example: <a href="https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;get-shit-done" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;get-shit-done</a>)
      • y1n09 hours ago
        That&#x27;s great that it has things you like. I don&#x27;t do rebasing, except on MRs where I&#x27;ve come to prefer squashing the branch being committed.<p>But I don&#x27;t rewrite history. It&#x27;s history. While I can understand people have reasons to do it, the reasons have never resonated with me. I&#x27;d rather spend my time getting new work done and not polishing work I&#x27;ve already done.
        • LoganDark4 hours ago
          Using jj is easier when your whole team uses jj. When the rest of your team uses Git, it&#x27;s understandable that the pains of keeping up with Git-isms (e.g. constantly updating branches) start to become quite inconvenient. Though once you get used to jj they&#x27;re not much of an inconvenience at all, they are still extra steps compared to raw Git. So if jj doesn&#x27;t have any other inherent value to you it makes sense not to make the jump.<p>To me, jj has inherent value because I do a lot of things raw Git makes difficult or impossible. For example, <a href="https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;fabric-template" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;fabric-template</a> supports every point release of Minecraft since 1.14, and mods like <a href="https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;debrand" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;LoganDark&#x2F;debrand</a> derive from it. I often rewrite the history of the template with configuration improvements and then rebase the histories of each mod on top of it.<p>This keeps my project setup consistent throughout versions, and consistent between mods, and allows all my mods, across all supported versions, to benefit trivially from all improvements I make to my global template. This workflow is either not possible with git or would require slow, ugly and fragile scripts.
        • RobotCaleb9 hours ago
          I&#x27;m excited for your delayed comment. I&#x27;m sure going to take note that you delayed it and come back later to read it because I&#x27;m super interested in what it is that you&#x27;ve delayed. You know, you can just write the comment instead of holding your place in line
          • jwiz8 hours ago
            The delay is on HN side, when people reply too quickly.
            • RobotCaleb7 hours ago
              Oooh, my apologies, then! I misunderstood
    • throawayonthe11 hours ago
      tbh i never actually learned git, but peope working on the same repos with git seem to be ahme ones struggling with named branches... i just do jj rebase and it just works idk
    • NamlchakKhandro9 hours ago
      Feel the same way about JJ.<p>It feels like Apple vs Linux. Apple being different ... just because (it gives them an artificial moat)
  • winterqt13 hours ago
    &gt; `absorb` assigns the changes based on whichever previous commit most recently touched those files, which sometimes doesn&#x27;t actually correspond to which commit should own these particular changes.<p>I’m pretty sure `jj absorb` (and its predecessors, `git-absorb` [0] and `hg absorb`) are smarter than this, instead looking at the actual diffs.<p>[0]: <a href="https:&#x2F;&#x2F;github.com&#x2F;tummychow&#x2F;git-absorb" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;tummychow&#x2F;git-absorb</a>
    • ikesau12 hours ago
      Ah yeah, you&#x27;re right, that&#x27;s a misrepresentation on my part - it&#x27;s based on lines, not the file:<p>&gt; [absorb] splits changes in the source revision and moves each change to the closest mutable ancestor where the corresponding lines were modified last. If the destination revision cannot be determined unambiguously, the change will be left in the source revision.<p>I use absorb fairly often, fwiw. It&#x27;s great for when I want to make a patch to a commit that will easily absorb into its right place. And I also, sometimes, prefer the more intentional approach where I decide exactly where each hunk will go.
    • oefrha8 hours ago
      Yeah it’s smarter than that, but as a daily user of git absorb it still gets things wrong fairly often though—like a couple times a week often for me. Plus the changes it can’t absorb automatically (e.g. a lone doc change it can’t find peers for).
    • jolux12 hours ago
      Also `sl absorb`.
  • vaylian27 minutes ago
    &gt; This allows reviewers to step through your pull request in small bites, with each set of changes scoped to a single aspect of the feature.<p>Is that a frequent way of reviewing? On GitHub you get shown all changes together in the review tab. You can select individual commits for closer inspection, but where is the benefit?
    • Balinares17 minutes ago
      A series of piecemeal self-contained changes is much easier to wrap your brain around comprehensively enough to detect logic issues.<p>I started doing exactly this and it&#x27;s been invaluable.
  • stouset11 hours ago
    This seems like a lot more effort than the (to me) more natural jj workflow of maintaining the idealized series of commits plus a working commit on top. As you make tweaks and fixes you just squash the relevant parts into the already-clean history.<p>Basically, if you don’t get into that sort of situation with commits containing parts they shouldn’t in the first place, you don’t need to do any extra work to clean them up. The tip of your branch should be the only “messy” part.
    • 3eb7988a166311 hours ago
      That is a lot of discipline up front. I am sure there are problems which are nicely bucketed, but I usually have to go with the flow and make changes as I see them. I want to keep working with the code, not babysitting version control as I focus on getting the initial version to work.
      • stouset8 hours ago
        It’s really not.<p>I start a new branch and begin work. When I’m ready to start organizing that work into a consistent narrative (or when bits are “finished”), I split it out into independent commits. As I keep making fixes and tweaks, I continue squashing bits from my working commit into the parent commits they belong on.<p>I don’t bother making any independent commits until pieces of what I’m working on are becoming fully-formed. Until then, my working commit just has everything.
      • surajrmal9 hours ago
        I think it comes down to your ability to plan and understand how the work can be broken down before you try solving it. I often know what every commit will look like before I ever touch the code. I do sometimes learn things and change my mind as I make changes but it doesn&#x27;t often change my commit structure. I tend to work on a codebase I have 8+ years experience in though. I&#x27;m sure it doesn&#x27;t work in a variety of situations though.
  • drdrey11 hours ago
    I have finally embraced squashing PRs and realized I wasted my youth trying to write Good Commits.
    • vermilingua8 hours ago
      These Good Commits are for the review’s benefit, not necessarily trunk history.
  • gertburger3 hours ago
    I&#x27;d like to give jj another go but I found the &quot;all files must be tracked&#x2F;committed&quot; approach to really break my workflow. I have a lot of temporary uncommitted files, which are not ignored or excluded. Some may eventually be committed but most won&#x27;t. Being then forced to commit these (but only some due to file size) just gets in the way and impedes things like cross branch debugging<p>A checkout is a working space after all, why can&#x27;t it be (temporarily) dirty whilst you work?
    • JimDabell22 minutes ago
      When you are ready to record a change, split your current working changeset and pick the things you want to commit. It’s equivalent to staging then committing with Git.
    • silon4243 minutes ago
      Same here, auto-adding is a non-starter for me. Thankfully there&#x27;s an option to not do it, not sure how well it works, but I&#x27;ll have it enabled for the future when I try jj again.
    • arccy34 minutes ago
      auto add is nice for universal undo for changes made outside your editor...<p>instead of adding changes to a new commit, i split&#x2F;squash them into the previous one so the current commit remains dirty
    • maleldil1 hour ago
      Why not add them to gitignore? If you don&#x27;t want to change the project&#x27;s ignore, there&#x27;s also a repository local ignore file, .git&#x2F;info&#x2F;exclude, which jj will respect.<p>&gt; why can&#x27;t it be (temporarily) dirty whilst you work?<p>Because that would go completely against how jj changes work.
    • a10c2 hours ago
      [flagged]
  • nozzlegear12 hours ago
    As a git rebase enjoyer, I&#x27;ve completely switched over to jujutsu. The whole experience is more ergonomic in my opinion, and the default workflow which I use (using `jj new` to create a new change that clearly delineates work on a different &quot;thing&quot; before I start working on it) fits my mental model much better than the traditional write-then-commit workflow we all grew up with.
  • a10c2 hours ago
    This is roughly how I’ve found myself using jj naturally. I find it hard to “tell the story” of a change ahead of time, because the design often only becomes clear after some exploration. It’s much easier to land at an implementation I’m happy with, then work backwards and shape the commits into the story I wish I’d taken.
  • nextaccountic11 hours ago
    &gt; Latter commits overwrite work that was done in earlier commits and the story breaks.<p>&gt; Some people prefer this, as it helps git bisect work better. Debuggability versus reviewer convenience is the tradeoff, I guess.<p>Ideally we would have a VCS that made ergonomic to store both history-as-it-happened for some purposes, and the cleaned up, squashed and rebased history for other purposes, ensuring they match
    • Izkata2 hours ago
      Force --no-ff merges in git. That&#x27;s pretty much what you want.
    • bschwindHN10 hours ago
      Just squash all the PR commits into one when it gets merged to main or whatever your main branch is.<p>You can revisit the original PR to see the individual commits if you really want.
    • gmueckl7 hours ago
      I think that version control has reached a point where the next major evolutionary steps will be based on making history totally shared and immutable with history edits themselves being non-destructive versioned operations that can be browsed as higher order history.
    • paradox4609 hours ago
      Jj could do that; it stores an evolog of each change, but currently that&#x27;s kept local
  • regularfry1 hour ago
    So I&#x27;d have an <i>immediate</i> problem with the target sequence of commits here. The thing about just getting a &quot;define types&quot; commit is that it shows me <i>nothing</i> about why those types were chosen. I need to flit backwards and forwards in history to see how they hook into the later code. I lose the history of &quot;this type was enough to get us to point A, we needed this other thing to get to point B&quot;. But flitting back and forth is exactly what we&#x27;re trying to avoid here. It feels like we&#x27;re trying to optimise to One True Clean History, when that can&#x27;t possibly exist because no two people&#x27;s idea of &quot;clean&quot; actually matches.<p>Just give me the PR, don&#x27;t sweat the individual patches. But maybe also work on not committing your first idea as finished work.
  • EFLKumo11 hours ago
    This remind me of [jj megamerge](<a href="https:&#x2F;&#x2F;isaaccorbrey.com&#x2F;notes&#x2F;jujutsu-megamerges-for-fun-and-profit" rel="nofollow">https:&#x2F;&#x2F;isaaccorbrey.com&#x2F;notes&#x2F;jujutsu-megamerges-for-fun-an...</a>). jj allows concentrating on developing while leaving things for vcs alone, as well as solving vcs things (conflicts) at very beginning (megamerge). Really good.
  • singiamtel11 hours ago
    The only thing that stops me from switching to jujutsu is that lazygit already paves through all these paper cuts pretty well, and I&#x27;d miss their custom patches feature.<p>I see there&#x27;s a similar project for JJ, but it doesn&#x27;t seem nearly as polished <a href="https:&#x2F;&#x2F;github.com&#x2F;Cretezy&#x2F;lazyjj" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;Cretezy&#x2F;lazyjj</a>
    • nchmy11 hours ago
      Jjui is the best tui for jj
      • sswatson11 hours ago
        What does jjui have on lazyjj? Sincere question; I tried it, and I want to get it, and so far I don’t.
  • nvgrw9 hours ago
    I like how jj allows me to essentially use the same workflow in my personal projects (jj on git) as with my work stuff (jj on piper). That alone is really neat!
  • jadar10 hours ago
    I tend to just commit whenever I see fit, then at the end I do a `git reset —soft` and write the history that makes sense before pushing.
    • ninkendo10 hours ago
      I always tell people I use a “git reset” based workflow. I rarely “checkout” branches, I just stay on main, reset hard when switching topics, reset soft when squashing, and I only name my branches on the remote end via “git push origin HEAD:some-branch”.<p>`git branch` is basically my bookmark tool. I commit for a while, then when I want to remember where I am for later, `git branch wip&#x2F;topic-a-finally-compiles` or whatever. I can reset hard to it when I want to revert back, or any other topic I need. If I forget to name a branch for a commit, the reflog is right there. Nothing’s lost.<p>And yeah, a soft reset is basically the ideal way to just say “pretend all my changes weren’t committed yet, starting from $ref” and then I make my single commit for my PR. Easy peasy.
      • 789-ha9 hours ago
        I can’t tell if this is satire. The fact that we have to memorize soft and hard resets was a thing I and everyone else just have to do. But that goes away if you only have commits, so no staging area vs staged changes vs changes on disk, it’s just all a commit and we have a myriad of tools that already know how to deal with commits. Honestly, your workflow as described sounds incredibly compatible with jujutsu, I’d really recommend giving it a shot &#x2F; another go
      • skydhash7 hours ago
        I follow something similar, especially with the PR process and squash-merge on remote. I do the first ticket push using explicit ref, then just continue on the next one, while I wait for the review process. When the first PR is merged, I rebase on top of the remote branch and do the same for the second PR.<p>I do switch branch for long experiments and touch up on existing PR.<p>It would be great if a PR was about distributing patches and not having those automatically generated from a branch.
  • xyzsparetimexyz12 hours ago
    With jj I mostly just `jj split -B @`. Nice interactive ui for picking the changes I want into a commit. So many times better than &#x27;git add -p&#x27;
  • oncallthrow1 hour ago
    `git rebase -i` and `fixup`
  • BobbyTables210 hours ago
    I don’t understand. Are there people that try to use git without ever invoking “git rebase -i” ?
    • NamlchakKhandro9 hours ago
      Yes. almost the majority of git users do this. i would say that as an expert commenter, 99.9% of people outside of California do this.
    • BeetleB6 hours ago
      I&#x27;ve done both the rebase and the merge flows in different jobs.<p>I just don&#x27;t see the fuss about rebase. Merging just works fine.<p>Edit: OK, I realized later that I&#x27;m not really responding to the usual git rebase -i use case.<p>Have you heard people say that because of magit they started using more &quot;advanced&quot; git workflows, and how they emphasize having a better UI makes a difference?<p>It&#x27;s the same idea with jujutsu. I&#x27;m much more likely to use git&#x27;s power via jujutsu than directly with git. It&#x27;s because jujutsu lets you do it all with a much simpler interface - fewer commands, and fewer concepts. And knowing that &quot;jj undo&quot; has your back.<p>As a sibling commenter said: Likely 99% of git users don&#x27;t do &quot;git rebase -i&quot;. But the percentage who do similar with jujutsu is high - perhaps over half[1] of jujutsu users do the equivalent of &quot;git rebase -i&quot; <i>all</i> the time. Many of them didn&#x27;t when they used git.<p>The interface matters.<p>[1] If you told me 80%, it wouldn&#x27;t surprise me in the least.
    • christophilus10 hours ago
      I don&#x27;t rebase. I just merge and resolve the conflicts. Nowadays, I just have an agent do that for me, and move on with my life.
  • everybodyknows9 hours ago
    &gt; A downside to this technique is that there&#x27;s no guarantee that every commit will compile, which might be a dealbreaker.<p>To some of us, that&#x27;s an essential structural criterion. Passing unit-level self-tests may be as well.
  • mcookly13 hours ago
    I&#x27;m not an expert in Magit by any means, but I bet there&#x27;s a way to accomplish this in only a few keystrokes.
  • diath13 hours ago
    So... git rebase -i?
    • idoubtit12 hours ago
      No, more like:<p><pre><code> git rebase -i # squash all the commits (e.g. in vim with ctrl-v) git reset HEAD^ git add -p # interactively pickup the RED hunks git ci -m RED </code></pre> The main difference to jj is that the RED commit is created later with git.
      • nine_k11 hours ago
        But isn&#x27;t the flow nearly identical with jj, because the key part, the moving of hunks, is interactive (aka manual) anyway?
    • nomel13 hours ago
      Definitely not. Switch to a previous commit, make edits, changes propagate into the future commits (including into a git repo if you wish [1])<p>Jj is not git and is not a git tool, it just (thankfully) uses git as a backend, so you can still carry on with the rest of the world.<p>[1] <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=47765759">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=47765759</a>
      • ahepp12 hours ago
        &gt; Switch to a previous commit, make edits, changes propagate into the future commits<p>In what way is that different from using `git rebase -i` to edit a commit?
        • stouset11 hours ago
          You can literally jump into a commit and edit its contents directly, and everything is auto-rebased on top.<p>There are no modal “sorry rebase failed, best of luck” gotchas. There are no “oops I put the wrong thing in the wrong part of the rebase and now I have to abort and start all over” gotchas.<p>It’s rebase, but without all the extra work, mental overhead, failure cases, and effort.
          • matheusmoreira10 hours ago
            How does it just auto-rebase everything without failing though? If you edit something later commits depend on, then you get merge conflicts. Are you implying that jj just automatically handles all this?
            • steveklabnik9 hours ago
              jj allows your commits to stay in a conflicted state until you choose to resolve them. I wrote about this a month ago: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=47767292">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=47767292</a>
              • matheusmoreira8 hours ago
                I see. It doesn&#x27;t deal with the conflict, it just proceeds regardless. I&#x27;m curious about how it works internally. Does it do something like commit the conflict and soft reset later?
                • stouset7 hours ago
                  The conflict markers are a first-class citizen in the repo. jj tells you when a commit has a conflict, and you can go edit it at your leisure. It also does prevent you from doing some things with branches in a conflicted state, like pushing them.<p>You might not think this is that big a deal, but this also means you don’t have to resolve the entire thing in one go. Plenty of times with complicated rebases in git, I’ve not been 100% certain about the path towards resolving it. But jumping around to view various commits when you’re in the rebase-conflict state is painful. In jj you can just switch to an earlier commit, tweak it there, jump to a later commit, see how it looks, etc. It removes 98% of the pain.<p>It also dovetails nicely with other aspects of jj. Since rebases happen automatically and constantly, they are usually <i>tiny</i>. If there’s a conflict, it’s caught right when you do the thing and not four hours later when that part is no longer fresh in mind. And the op log lets you restore and undo <i>actions</i> atomically, which makes undoing a fuck-up a no-op.
                  • bentcorner7 hours ago
                    I&#x27;ve come to the opinion that conflicts should be committed and merge fixes should be in another commit afterwards. Arguably even if the merge fix is trivial.
                    • stouset6 hours ago
                      That’s almost definitionally what a merge <i>is</i>.<p>A merge conflict means that some automated tool couldn’t figure it out. But all a merge is is a commit with two parents and an accompanying diff that shows the process of combining them. A merge conflict isn’t really in any way special. It just means whatever algorithm was used couldn’t do it unambiguously without human help.
    • 902913 hours ago
      I&#x27;d recommend reading the post, it&#x27;s not that long
      • raincole12 hours ago
        As someone who doesn&#x27;t know jj and read this article, it does sound like `git rebase -i` to me. I&#x27;m sure that if I actually spent time learning jj I&#x27;d know the difference though.
    • ai_slop_hater13 hours ago
      git rebase -i kinda sucks once you tried jj.
  • fragmede12 hours ago
    The elephant in the room is that I haven&#x27;t had to do something complicated and manual in git by hand in a long while. I&#x27;m using AI to generate code, and further, having it commit to git and pushing and pulling and managing branches and merging for me. So for people new to software development, they can also just ask AI to deal with git, which papers over the harder parts of its UX.
    • hu39 hours ago
      This. I feel jj is some years too late.<p>It tries to solve a human problem in an LLM era.<p>LLMs are destined to overcome humans in code merging and change versioning (already did for me).<p>There&#x27;s little point to introducing yet another layer of indirection when LLMs just cut to the chase.
      • nemo16186 hours ago
        Good git hygiene is also less important post-LLMs, as the LLM can make sense of even a messy history.
      • surajrmal8 hours ago
        A lot of humans don&#x27;t currently trust agents to touch VCS today. I also find that my agent tends to be much better about dealing with jj than it is with git.
        • hu36 hours ago
          Culture change is hard.<p>A lot of humans still don&#x27;t use git too.<p>Many do only when they are forced.<p>And it&#x27;s much easier for a professional to be forced to use LLMs than jj when it comes to versioning assist (not even comparable in mindshare but the obvious needs to be said sometimes).<p>So unfortunately I&#x27;m afraid jj is not going to achieve critical mass before 99.99% of merges are done by AI which don&#x27;t need jj.
  • einpoklum12 hours ago
    &gt; For large features, I find this workflow far easier than having to maintain strict git rigour for the lifecycle of the feature&#x27;s development.<p>I don&#x27;t know about all that. All sorts of ex-post-facto automated cut-up-and-splice commits sounds to me like a recipe for an every larger mess. I say maintain git rigor, always. Now, you could say &quot;You only say that because you know git rather than jujutsu&quot; or &quot;if you use git absorb more you&#x27;ll get it&quot;, and theoretically you might be right, but... meh, I kind of doubt it.
    • einpoklum2 hours ago
      s&#x2F;every larger mess&#x2F;even larger mess&#x2F;<p>sorry about that.
  • mi_lk13 hours ago
    So: Squash everything together then pick each component out by squash -i to an empty commit.<p>Seems straightforward, wouldn’t call it special
    • nomel13 hours ago
      I think jj will never gain momentum because people only have a git mental model at this point, so won&#x27;t be able to effectively reason about jj.
      • incognito12413 hours ago
        I spoke about this before, but jj has the Blub Paradox problem, from the pg&#x27;s essay Beating the Averages (<a href="https:&#x2F;&#x2F;paulgraham.com&#x2F;avg.html" rel="nofollow">https:&#x2F;&#x2F;paulgraham.com&#x2F;avg.html</a>).<p>Yes, you can do most commit manipulations with git just like with jj. But, users of jj know they&#x27;re &quot;looking down the power continuum&quot; (to reuse pg&#x27;s terminology) when they look at git, whereas git users cannot fathom what&#x27;s exactly the deal with jj. Unfortunately, the only way to <i>get it</i> is to spend a week with it, with an open mind. It&#x27;s close to impossible to describe it except &quot;it&#x27;s really neat&quot; and &quot;wow it removes all git&#x27;s friction I didn&#x27;t know existed&quot;.<p>And, apparently, there&#x27;s a pattern of having to try at least two times before it becomes intuitive!
        • hooper10 hours ago
          It&#x27;s interesting that even clear advantages like `jj undo` are hard to communicate because of this.
        • bsder9 hours ago
          &gt; I spoke about this before, but jj has the Blub Paradox problem<p>It&#x27;s not relevant. Don&#x27;t try to convert git users--you don&#x27;t need to. They&#x27;re <i>fine</i> doing what they do, and the git backend store is acceptable. People who understand how broken git is will gravitate to jj with the lightest of prodding--give them a light poke and then don&#x27;t harass them further.<p>The main difference is that I can teach jj (like I could teach hg) to <i>normal</i> people. And, because jj is based on the git store, they can operate in a Github world.<p>So, just teach jj to people who haven&#x27;t yet broken their brain with git. Running on the git backend already gains most of the network effect, so don&#x27;t proselytize the git people.
        • ruszki11 hours ago
          The problem with this mindset, that there is zero reason to move away from Git. I can do effortlessly everything with it. There is no incentive. I never said &quot;it would be so good that I would be able to X&quot;... and I didn&#x27;t find a solution for it quickly. As under this post is obvious as much as under other previous posts, you can do the same things effortlessly with Git. The effort is not that I need to use 2 commands less, but to separate the code (in this specific case), which takes about a 100-1000x more time than typing those 2 extra commands, or really the need to think what kind of commands need to be used in any VCS.<p>The same problem with vi for example. Which I learned, deeply and for a long time. Maybe I will be break even in a decade or two. And for example, I can code faster than anybody who I know and use vi all the time (or some vi keyset in Emacs or something), not because I type faster, but because I don&#x27;t need to rewrite my code that many times than them.<p>The same with jj. I&#x27;m happy that it clicks better than Git for some. But I know Git from inside and out. Git was never the bottleneck for me. And really any VCS in the past. If I learn jj, then I don&#x27;t expect that the effort pays off in a decade or less in the best case. My work&#x27;s result would be the exact same thing, just with different commands, commands which takes almost no time compared to my other tasks.
        • skydhash12 hours ago
          &gt; Unfortunately, the only way to get it is to spend a week with it, with an open mind<p>We do get it. But have you ever thought that git inflexible nature and full control is what some people people like?<p>Having three different state for your work (working tree, staging, and committed) is nice for reviewing code. Picking lines and chunk give me an additional mental state to think about the design of the code.<p>And once upon a time, I preferred history log like the one in the article. But this days (mostly inspired by mailing list development style) I wants the commit in my main log to be either features or bug fixes. Everything else is “wip”, which I will squash. It makes it easier when rewriting history, cherry picking, or just browsing the log.
          • jolux12 hours ago
            There’s nothing stopping you from using separate changes to emulate the staging area if you want.
            • entrope12 hours ago
              That is, in essence, the &quot;squash workflow&quot;: <a href="https:&#x2F;&#x2F;steveklabnik.github.io&#x2F;jujutsu-tutorial&#x2F;real-world-workflows&#x2F;the-squash-workflow.html" rel="nofollow">https:&#x2F;&#x2F;steveklabnik.github.io&#x2F;jujutsu-tutorial&#x2F;real-world-w...</a><p>The big differences are that the jj approach gives you a commit message for the staging change, and lets you jump to some other commit without extra steps.
            • skydhash12 hours ago
              I can, but I don’t need to.<p>jj has nothing I need, so it would be changes for the sake of changes. I’m not saying it’s bad, but people do need to realize that their struggles are theirs, not the whole world.
              • sswatson8 hours ago
                Not trying to tell you how to live your life, obviously, but I think “changes for the sake of changes” overstates it. For example, `jj undo` is a pure ergonomics win.<p>It’s been said a million times but it is really true that jujutsu’s appeal is something you feel (or don’t) after giving it a proper go. It doesn’t survive compression into the feature list.<p>Actually I think that property is a much bigger obstacle to adoption than what it does or doesn’t offer to the rare true git wizard.
                • skydhash7 hours ago
                  I use magit on a daily basis. And I do use tig occasionally (I don&#x27;t like lazygit). Most of my magit workflows only requires a handful of keys (most are only two keys). If you&#x27;ve not tried Magit before, it&#x27;s like vim for a git repo. tig is more barebones, but I could quickly configure it to be able to do most of the magit tricks I need.<p>Git cli is tedious. But like all cli operations the goal is always to script your workflow or alias the most used commands in something shorter. I&#x27;m sure that jj may have an easier learning curve. But some people do know how git works and like the level of control over commits.
              • jolux11 hours ago
                Totally fair :) personally I used to be a git wizard and I am relieved at how much about it I’ve been able to forget since learning jj, but I understand not everyone has the same experience.
      • Macha9 hours ago
        Having been often called by coworkers to assist them with their git problems, I can assure you they don’t have a git mental model.
  • dundunUp9 hours ago
    [flagged]
  • codemog13 hours ago
    [flagged]
    • aggregator-ios12 hours ago
      This is my take on it too. And I built BetterGit (<a href="https:&#x2F;&#x2F;www.satishmaha.com&#x2F;BetterGit&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.satishmaha.com&#x2F;BetterGit&#x2F;</a>) before agent capabilities became widespread. A lot of things in Git and existing GUIs are just cumbersome, and my app makes it better to handle the most common tasks and makes them easier. It&#x27;s really meant for newcomers to Git.<p>BUT! You can simply ask an agent to commit every meaningful block of work. Or just ask any agent to create a JIRA ticket and start work on that named branch. Or ask it to create work trees and create a PR. Life has gotten much easier without having to fight the command line or confusing GUI UX.
    • pkulak13 hours ago
      JJ is a whole different way to think about source control. The fact that you don’t need to run an agent just to use it is a nice bonus.
    • nvader13 hours ago
      You can also have you agent use jj with this skill<p><a href="https:&#x2F;&#x2F;github.com&#x2F;danverbraganza&#x2F;jujutsu-skill" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;danverbraganza&#x2F;jujutsu-skill</a>
      • pkulak7 hours ago
        Wow, that&#x27;s really nice. I&#x27;m absolutely stealing that. Thanks!
    • IdiocyInAction6 hours ago
      I am a really heavy Claude Code user but source control is <i>still</i> one area where I have regular bad experiences just using Claude.
  • jonathanyc13 hours ago
    I have been walking some newer programmers through Git recently, so this topic is fresh on my mind. The commands in the blog post do not look friendlier or even different.