Live data from Hacker News

jj – the CLI for Jujutsu

steveklabnik.github.io

371–380 of 517 posts

Re: jj – the CLI for Jujutsu

#371

Earlier quoted context omitted.

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…

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 thos…

> 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.

Re: jj – the CLI for Jujutsu

#372
post #352

Earlier quoted context omitted.

But branches are not just named pointers to a commit. If they were, then checking out the pointer would be the same as checking out the commit itself. But I can check out a commit and I can check out a branch and depending on which I've done, I'm in two different states. Either I'm in branch state, where making a commit bumps the branch pointer and means the commit will be visible in the default log output, or I'm in…

> these two states look completely identical No they don't. As you noted, one state is "detached head" and any competently set up shell PS1 will tell you that, or that you're on a branch by displaying the name of the branch vs the commit. > Creating new commits on anonymous branches is perfectly normal Sorry, that that's an example of more intuitive behavior on jj's partc, you've lost me. I've done that intentionally…

> any competently set up shell PS1 will tell you that

I certainly hope your shell is not running `git` commands automatically for you. If so, that is a RCE vulnerability since you could extract a tarball/zip that you don't expect to be a git repository but it contains a `.git` folder with a `fsmonitor` configured to execute a malicious script: https://github.com/califio/publications/blob/main/MADBugs/vi...

Re: jj – the CLI for Jujutsu

#373
post #352

Earlier quoted context omitted.

But branches are not just named pointers to a commit. If they were, then checking out the pointer would be the same as checking out the commit itself. But I can check out a commit and I can check out a branch and depending on which I've done, I'm in two different states. Either I'm in branch state, where making a commit bumps the branch pointer and means the commit will be visible in the default log output, or I'm in…

> these two states look completely identical No they don't. As you noted, one state is "detached head" and any competently set up shell PS1 will tell you that, or that you're on a branch by displaying the name of the branch vs the commit. > Creating new commits on anonymous branches is perfectly normal Sorry, that that's an example of more intuitive behavior on jj's partc, you've lost me. I've done that intentionally…

They look identical to people who don't know what to look for, and who don't realise that these two states are different, which is the key thing. You can also distinguish them by running `git status`, but that's kind of the point: there's some magic state living in .git/ that changes how a bunch of commands you run work, and you need to understand how that state works in order to correctly use git. Why not just remove that state entirely, and make all checkouts behave identically to each other, the only difference being which files are present in the filesystem, and what the parent commit was?

What's wrong with unnamed branches? I mean, in git the main issue is that they're not surfaced very clearly (although they exist). But if you can design an interface where unnamed branches are the default, where they're always visible, and where you can clearly see what they're doing, what's wrong with avoiding naming your branches until you really need to?

I think this is the key thing that makes jj so exciting to me: it's consistently a simpler mental model. You don't need to understand the different states a checkout can be in, because there aren't any - a checkout is a checkout is a checkout. You don't need to have a separate concept of a branch, because branches are just chains of commits, and the default jj log commands is very good at showing chains of commits.

Re: jj – the CLI for Jujutsu

#374
post #294

Earlier quoted context omitted.

That's my overall point: the argument itself (with respect to the current state of the repo) is what determines the behavior. I don't think this is anywhere close to as intuitive as commands that only ever accept one "type" of argument (and erroring if it's different).

I stand corrected by this one scenario, but I’ve been using git for over a decade and never found that useful. Just don’t use checkout on a file path, there is no need.

Interesting - I use git checkout constantly, whenever I have a file in another branch or commit that I want to drag into this one wholesale.

Re: jj – the CLI for Jujutsu

#375

Earlier quoted context omitted.

If you constantly switch between the two, you're going to have a hard time, but you can take a git repo, try jj for a while, and if you decide to go back, you don't lose anything.

Right, but that’s different from working in a team environment where everyone else continues using git.

You're confusing mixing git and jj in your local copy of the repo vs what it looks like to other people. You can use jj locally, and it interoperates perfectly with any git remote, and no one has to know you're even using it. From the point of view of other people, it doesn't matter.

Re: jj – the CLI for Jujutsu

#376

Earlier quoted context omitted.

I did check that page, as far as I can tell you still need to run Cargo which I don't want to do because I don't care about Rust. I'm not complaining for the sake of complaining, I'm saying if they want to play in the Big Boy leagues, they need to do things right.

You do need Cargo to build from source. If you're on Arch, gentoo, or openSUSE, you can use the package. It is true that Debian has not packaged jj yet. It'll get there, and it's fine if you'd rather wait until things are more mature.

It's available in Debian sid, although a few versions behind: https://packages.debian.org/search?searchon=names&suite=all&...

Re: jj – the CLI for Jujutsu

#377

One of the things that makes jj worth trying out is simply the fact that it is different than git, and having exposure to more than one way of doing things is a good thing. Even if you don't adopt it (and I didn't), it's easy to think that "this way is the only way", and seeing how systems other than your own preferred one manage workflows and issues is very useful for perspective. That doesn't mean you should try ev…

being a good engineer is also understanding when something is a waste of time because the gain is insignificant 99% of the time

Re: jj – the CLI for Jujutsu

#378

Earlier quoted context omitted.

A couple things off the top of my head: - You aren't forced to resolve rebase/merge conflicts immediately. You can switch branches halfway through resolving conflicts and then come back later and pick up where you left off. You can also just ignore the conflicts and continue editing files on the conflicted branch and then resolve the conflicts later. - Manipulating commits is super easy (especially with jjui). I reor…

All of these features sound like the recipe for a confusing nightmare! "You can switch branches halfway through resolving conflicts and then come back later and pick up where you left off. You can also just ignore the conflicts and continue editing files on the conflicted branch and then resolve the conflicts later." "Similar to stashes, but each "stash" is just a normal branch that can have multiple commits. If I wa…

Remember when you used SVN or whatever before git, and you loved git because of how easy it is to make branches?

With branches, jj is to git what git was to SVN. It's an order of magnitude less friction to do branching in jj than git.

Not long ago, I pulled from main and rebased my branch onto it - merge conflicts. But I wanted to work on some other feature at the moment. Why should I have to fix this merge conflict to work on a feature on a totally different branch? With jj, I don't. I just switch to the other branch (that has no conflict), and code my new feature. Whenever I need to work on the conflicted branch, I'll go there and fix the conflict.

Once I started using jj, I realized how silly it was for git to have separate concepts for stash and index. And it's annoying that stash/index is not version controlled in git. Or is it? I have no idea.

In jj, a stash is simply yet another unnamed branch. Do whatever you want there. Add more commits. Then apply it to any branch(es) that you would like to. Or not.

Why does git need a separate concept of a stash? And wouldn't you like a version controlled stash in git?

Have you ever made a ton of changes, done a "git add", accidentally deleted some of the changes in one file, done a "git add", and thought "Oh crap!" I suppose that information can be recovered from the reflog. But wouldn't you wish "git add" was version controlled in the same way everything else is?

That's the appeal of jj. You get a better stash. You get a better index. And all with fewer concepts. You just need to understand what a branch (or graph) is, and you get all of it. Why give it a name like "stash" or "index"?

Why does git insist on giving branches names? Once you get used to unnamed branches, the git way just doesn't make sense. In jj you'll still give names wherever you need to.

Re: jj – the CLI for Jujutsu

#379

Does JJ really prefer for me to think backwards? It wants me to start with the new and describe command, but with git I first make the changes and name the changeset at the end of the workflow. I also often end up with in a dirty repo state with multiple changes belonging to separate features or abstractions. I usually just pick the changes I want to group into a commit and clean up the state. Since it's git compatib…

Not necessarily, I often make changes on unrelated commits. You can always use jj split to extract the change and put it somewhere else.

Re: jj – the CLI for Jujutsu

#380
post #127

Earlier quoted context omitted.

But this is not true. They are interoperable but far from seamless. Those features mainly support migration use cases or things like git deployment from an repo managed in jj. Operations git does are not in jj’s log. You have to constantly import them. The project recommends a single primary interface.

It's been over a year since I last used git manually in the CLI, and I've exclusively worked with git remotes. The only time I had any friction was on a team where stale code-gen output was checked into the repo and for whatever reason no one was willing to either add it to the `.gitignore` or commit (pun intended) to keeping it up to date, meaning that I had to manually remove the changes from when I compiled before…

For what it's worth, you can have your own local gitignore by adding patterns to .git/info/exclude. It's quite useful in this exact situation.
Post reply on HN