jj is great and while it was an adjustment at first, I've never looked back. I feel like when you're working with other people, things never get reviewed and merged as quickly as you'd like. With jj, it's pretty low-cost to have a bunch of PRs open at once, and you can do something like `jj new <pr1> <pr2> <pr3>` to build stuff that requires all 3. This lets me do things like... not do a big refactoring in the same PR as adding a feature. I can have them both self-contained, but still start on the next step before they're all merged. It's easy to add changes on top, switching between the individual PRs as comments come up, etc.
I always liked doing things like this. At Google where we used a custom fork of Perforce, I told myself "NEVER DO STACKED CLs HAVE YOU NOT LEARNED YOUR LESSON YET?" If one CL depended on another... don't do it. With git... I told myself the same thing, as I sat in endless interactive rebases and merge conflict commits ("git rebase abort" might have been my most-used command). With jj, it's not a problem. There are merge conflicts. You can resolve them with the peace of mind as a separate commit to track your resolution. `jj new -d 'resolve merge conflict` -A @` to add a new commit after the conflicted one. Hack on your resolution until you're happy. jj squash --into @-. Merge conflict resolved.
It is truly a beautiful model. Really a big mental health saver. It just makes it so easy to work with other people.
I'm having trouble understanding the value of this and most other supposed advantages of jj I'm seeing.
I'm trying to pinpoint if it's because 1) my workflow doesn't need jj's fancy stuff, 2) I've gotten so used to `git`'s "flaws" that I don't notice them, or 3) the git porcelain I use (magit) does a good enough job at managing the flaws.
If you need to build on something that requires changes from 3 open PRs, can't you just start a new branch from main, merge all 3 PRs into it, and get to work? As changes are applied to the open PRs, you can rebase. Obviously that might cause some merge conflicts here and there, but as long as the PRs aren't super overlapping, they should still be manageable. If there's a ton of overlap between 3 open PRs, that to me sounds like a problem in the workflow/plan, which must be dealt with regardless of the VCS or porcelain.
For me, it wasn't so much that jj enabled things I couldn't do before, though there are some things. What it enabled was me doing the things I was doing, but in a more easy way. This also leads you to do things that you can do, but sometimes avoid because it's a lot of work.
I guess that makes sense but also reinforces the confusion I have on whether jj is just another git "porcelain" (aka UI), or a replacement for git altogether.
If it aims to mainly improve the UX (do the same things you were doing before but easier), then it's irrelevant to those of us who have been lucky to find and learn sensible UXs.
If it aims to be a git replacement, I'm a little curious why the developers would decide to re-implement something from scratch only to end up with an "alternative" that is mostly compatible and doesn't radically change the internal model or add new features.
I last used GitHub Desktop years ago and had a terrible time. The git CLI is powerful but not very intuitive. It really wasn't until I learned magit that things "clicked" for me.
I know that many git UXs are pretty bad. But the way git works internally seems pretty great to me. Too often, criticism of git conflates the two.
When I mentor new devs, I explain to them how I use git. Sometimes I show them the workflow in magit, which makes it easier to visualize things. But mostly I just show them how their intended actions map onto the relevant CLI commands and I tell them to figure out how those map onto their porcelain of choice. I've developed this intuition thanks to magit, but I don't think magit is necessary. This approach seems preferable to me than onboarding new devs onto a new tool that is not the industry standard.
> This strikes me a lot like the C vs. safer programming language debate all over again.
I don't see how. Safer programming language address a clear problem in C, with trade-offs (sometimes arguably the trade-offs may not be worth it, and in my experience that's what the debate tends to be about). If jj is a replacement for git it should be clear what problem within git it aims at addressing. If the problem is in the UX, then to me and many others it's not worth the trouble.
Fundamentally, jj is its own VCS. It's just that it has pluggable backends. So when you use it with the git backend, it functions as a nicer git UI, but it's also not just that, because you can use it without git entirely. (though the major alternative backend is not open source, so while people do, unless you work at Google (or the startup I'm at...) you may personally not be able to.)
> then it's irrelevant to those of us who have been lucky to find and learn sensible UXs.
I was never someone who was upset at git's UX. I never found the 'hg is so much nicer' thing compelling. But then, I found that jj is just so much nicer to use, for me, that I haven't used git itself in years at this point. But it's also true that if you like using git, and want to keep using it, that's fine! The wonderful thing about the interop here is that I can use jj, and you can use git, and we're all good.
> I'm a little curious why the developers would decide to re-implement something from scratch only to end up with an "alternative" that is mostly compatible
Realistically, with git's dominance, compatibility is the only way that you get people to actually try out your thing. I know I wouldn't have given it a shot unless I could use it with a git repo.
> or add new features
I mean, there's two things here: one of which is, jj does have new features. I described the ability for a jj repo to exist in a conflicted state upthread, for example. jj undo is a godsend. But at the same time, at the end of the day, when you're trying to manipulate a graph of changes, there's always some way to end up in the same end state with git, because, well, you're trying to interoperate. So you can sort of handwave away a lot of features with a kind of "well I can do that in git via <totally different means>", and sure, that's true in a sense, but tools affect the way you work. I'm much more effective with jj's model of the world than I was with git's, even though I didn't actively feel that pain until I tried jj.
> It really wasn't until I learned magit
Ah, you use magit! So yeah, like, jj is like magit in the sense that it lets you interact with a git repository in a different way than the standard tool. And that's useful. I never would have used magit because I don't use emacs. (and there are some folks trying to do "magit but for jj"...)
> But the way git works internally seems pretty great to me. Too often, criticism of git conflates the two.
I agree, in general. I do think that there are still good criticisms to be made, but a lot of it is uninformed. Just how things go.
> Ah, you use magit! So yeah, like, jj is like magit in the sense that it lets you interact with a git repository in a different way than the standard tool. And that's useful. I never would have used magit because I don't use emacs.
I also use magit and I was confused by the "advantages" that jj has over git. The nice thing about magit is that it doesn't hide git. What it does add is easier typing of the flags (using transient), completions of arguments like branch names (using Emacs), DWIM behavior depending on cursor position and region selection (especially for commit hashes). Also it has nice presentation of the information which acts like hubs for all the above.
I guest jj makes sense if you're using the cli directly. But with magit, every operation is only a few keystrokes. It is to git, what vim is to editing. And I could probably cobble something close with tig or lazygit if I switched from emacs.
I have read the HN articles and seen the grumbling from coworkers, but I haven't felt it myself. I am not really a one-shotter, though. I kind of think about how I would refactor / write something myself and walk Claude through that, and nitpick it at each step... and the recent changes haven't really bothered me there. Likely due to being new at it.
Sometimes Claude can be a little weird. I was asking it about some settings in Grafana. It gave me an answer that didn't work. I told it that. "Yeah, I didn't really check, I just guessed." Then I said, "please check" and it said "you should read the discussion forums and issue tracker". I said "YOU should read the discussion forms and issue tracker". It consumed 35k tokens and then told me the thing I wanted was a checkbox. It was! I am not sure this saved me time, Claude. I am not experienced enough to say that this is a deal breaker. While this is burned into my mind as an amusing anecdote, it doesn't ruin the service for me.
My coworkers have noticed a degradation and feel vindicated by some of the posts here that I link. A lot of them are using Cursor more now. I have not tried it yet because I kind of like the Claude flow and /effort max + "are you sure?" yield good results. For now. I'm always happy to switch if something is clearly better.
How exactly do you use Claude Code, in the browser? Claude Code? The Desktop App (which has a "Code" tab) or some other way? I feel like people who have issues with Claude / Anthropic are not conveying where they are struggling. I see people say they tried "Claude" and didn't like it, but the secret sauce is Claude Code. Claude Code is what most people enjoy using, even if we all wish they would open up the harness, because there's so many more improvements that could go into it.
I do use the browser version on occasion. I have no strong feelings one way or the other there. I like it better than Google search in many cases, but probably just search more often.
ITAR feels a lot like Bernstein v. US all over again. Until very recently, everyone who can do anything that would be covered by ITAR was a giant corporation that likes the moat that regulations create, so it's unthinkable to challenge it. But that is changing, just like cryptography was in the early 90s.
RTL-SDR-grade fleet doing passive radar (using radio/TV OTA broadcasts) isn't actually that new; but pretty much any detailed reports have caught self-censoring after TLA visitors came by.
Sometimes I wonder if we just do these wars so that companies can raise prices and when the war ends, not lower them. Do we ever see "oil prices are down 3.5%, we are lowering our prices by 3.5%"? Never. "But the free market will force someone to do this to gain marketshare." But Amazon is the only Amazon, so I doubt that will happen.
> Do we ever see "oil prices are down 3.5%, we are lowering our prices by 3.5%"? Never.
Companies lower prices all the time. It's the competitive market at work. They just don't tend to say why, because nobody cares about the reason, so it's not necessary.
There’s an argument to be made that Amazon has so much of the online buying market that’s it’s not competitive and can likely get away with increasing price. And I tend to agree with that
Walmart.com is a major competitor to Amazon, including for third-party vendors. So are brands choosing to sell direct. Lots of people regularly compare prices like that. And tons of people use Google Shopping for price comparison.
Amazon is in an extremely competitive market. They can raise prices for fulfillment because everybody has to because everybody's fuel prices are going up.
I disagree. There are many other sites to buy anything you find on Amazon. If they raise prices and don't drop them, but other online retailers either don't increase or lower after they do, Amazon loses.
People Google things they're going to buy. Or at the very least they go to other places they're familiar with like Walmart (for the US).
It's worth pointing out that plenty of pilots take off and land safely at uncontrolled airports. ATC is a throughput optimization; the finite amount of airspace can have more aircraft movements if the movements are centrally coordinated. It feels like we are nearing the breaking point of this optimization, however, and it's probably worth looking for something better (or saying no to scheduling more flights).
The FAA already does issue temporary ground stops for IFR flights when ATC capacity is saturated. This acts as a limit on airlines scheduling more flights, although the feedback loops are long and not always effective. The FAA NextGen system should improve this somewhat.
I think the choice of breed has meaning. The border collie is the smartest breed of dog, and its origin is in herding sheep. Calling your coworkers sheep isn't particularly nice. Calling yourself the smartest breed of dog isn't particularly humble. That's why the person you're replying to objects.
Ridiculous. We should be calling people out for being performatively offended. It reduces the impact and gravitas of situations where real offense is given that should be considered.
I have herded cats, sorted sheep, and wrangled cattle all throughout my career. I can come up with more that are quite accurate to the situation.
And I've been the cat, sheep, and cattle likely more than I have been on the other side.
It's simply part of working with groups of humans. We become dumb in groups and lend ourselves towards herd behavior. It often requires someone tending to us to break us of the habit.
That's probably reading too much into the metaphor. I think it's apropos because regardless of whether the others are smart or not, we all have blind sides, and in order to get things done that need to be done you have to apply pressure in the right way to overcome a certain amount of group inertia. Those things still fit with the metaphor without necessarily being disrespectful.
I still don't understand why people don't cheat in FPSes by looking at the video stream and having a USB mouse that emits the right mouse movements. (The simplest thing is to just click when someone's head is under your crosshair, in games with hitscan weapons.)
The problem with these bots is that they are indiscriminate which makes them vulnerable to active detection methods. They can also introduce an amount of latency that begins to defeat the purpose for sufficiently skilled players. 100ms is an eternity when you are playing with shotguns in close quarters.
I always liked doing things like this. At Google where we used a custom fork of Perforce, I told myself "NEVER DO STACKED CLs HAVE YOU NOT LEARNED YOUR LESSON YET?" If one CL depended on another... don't do it. With git... I told myself the same thing, as I sat in endless interactive rebases and merge conflict commits ("git rebase abort" might have been my most-used command). With jj, it's not a problem. There are merge conflicts. You can resolve them with the peace of mind as a separate commit to track your resolution. `jj new -d 'resolve merge conflict` -A @` to add a new commit after the conflicted one. Hack on your resolution until you're happy. jj squash --into @-. Merge conflict resolved.
It is truly a beautiful model. Really a big mental health saver. It just makes it so easy to work with other people.
reply