Live data from Hacker News

What I've learned from jj

zerowidth.com

101–110 of 140 posts

Re: What I've learned from jj

#101

> If I had s -> t -> u -> v and wanted to reorder them, it’s as easy as jj rebase --revision u --after s, and I’d end up with s -> u -> t -> v, How did t end up after u? I'd expect that to fork into (s -> t) and (s -> u -> v). Either that or maybe (s -> t -> v) and (s -> u).

I'm not sure if you meant "how" or "why". As for "how", it's done by rebasing 'u' onto 's' and then rebasing 't' and 'v' onto the rebased 'u'. As for "why", I think it behaves different from what you expected in two ways. The first is that `--revision` rebased only the specified revisions without theirs descendants (there's also `--source` if you want to include the descendants). The other things it that `--after` is…

> it's done by rebasing 'u' onto 's' and then rebasing 't' and 'v' onto the rebased 'u'.

That sounds like 2 operations, not 1. I think that's why I was confused.

The docs do clarify that there's an extra rebase going on though, so thanks!

Yes, -d sounds like what I expected.

Re: What I've learned from jj

#102
post #83

> You don’t need to explicitly tell jj about what you’ve done in your working copy, it’s already tracked. This removes the need for an “index” or staging area Does this mean that you have to proactively remember and undo any config file changes you made e.g. while fixing an issue in a test environment? Sounds a little risky.

As others have pointed out, gitignore exists and you should try and build your configuration so that most of the time you're changing gitignored files rather than checked in ones. That said, you can do some pretty cool stuff with Jujutsu in this regard. Because changes are always automatically rebased, you can often create the change that will ultimately become your final commit, then create a new change where you edit any config you need to, then a change on top of that that's basically your staging area.

For example, I recently had a set up that looked something like this:

    @ w - the checked out change where I'm editing files
    |
    * x - local config change
    |
    * y (bookmark 1) - CI config change that sets up a temp test env
    |
    * z (bookmark 2) - Start of the changes that will eventually get reviewed and merged
With this set up, I could make changes in an environment that included all of the config changes I needed. Then when I was happy with something and wanted to "save my work", I could run `jj squash --to z`, which would squash everything in change w into change z, rebasing everything else automatically on top of that. Then I could run `jj git push`, and this force-pushed the changes at y and z to their separate branches on GitHub. I had a pull request for the branch at z which other people could then review and where all the tests could run. Meanwhile the branch at y had updated the CI config to remove the usual tests and deploy everything to a temporary environment. So each push automatically updated my test env, and updated the pull request with the "clean" changes (i.e. without my config file fiddling).

If I wanted this sort of setup more long term, I'd find some other way to achieve it without relying on Jujutsu, but for ad-hoc cases like this it's absolutely great.

Re: What I've learned from jj

#103

As entrenched as git is, I feel like its only a matter of time until it's dethroned. The basic workflow is fine. And there are some very powerful features. But then you try find the parent of a given branch and you're left wondering how the f#!@ thats so hard. It's definitely nit picking. It's probably 85-90% of what you want it to be. But there is definitely enough room for improvement to warrent moving beyond it. I…

I think the larger holes in git are its lack of reasonable support for large files and also its inability to keep secrets.

Both relate to the same fundamental problem/feature that a git commit is a hash of its contents, including previous content (via the parent commit, who's hash is part of the input for the child commit hash).

Re: What I've learned from jj

#104
post #27

Earlier quoted context omitted.

Worrying about individual commits is also what makes it possible for you to later use git bisect without going crazy.

How often do you find that command useful? In ~18 years of git use, I have never needed it, but I see it mentioned often as an important reason to handle commits in some certain way. I wonder what accounts for the difference.

Often enough that I am truly shocked to hear someone say they have never needed it.

Re: What I've learned from jj

#105

Earlier quoted context omitted.

How do you trace the origin of breaking changes, especially those arising from integration problems? For fairly busy codebases (>10 commits per day), and a certain subset of regressions, bisect is invaluable in finding the root cause. you can always do it the "hard way", so it's not the only way

I don't really ever find myself having to do that. I guess it's been a long time since I worked in an environment which did not use an "only merge to main after passing CI" workflow, and back then we weren't using git, anyway. There was one git-using startup I worked for which had a merge-recklessly development style, and there was one occasion when I could have used `git bisect` to disprove my coworker's accusation…

> I don't really ever find myself having to do that. I guess it's been a long time since I worked in an environment which did not use an "only merge to main after passing CI" workflow, and back then we weren't using git, anyway.

You _never_ have bugs that slip through the test suite? That is extremely impressive / borderline impossible. Even highly tested gold-standard projects like SQLite see bugs in production.

And once you find a regression that wasn't covered by your test suite, the fastest way to find where it originated is often git bisect.

Re: What I've learned from jj

#106
post #27

Earlier quoted context omitted.

Worrying about individual commits is also what makes it possible for you to later use git bisect without going crazy.

Squash merge gives you the same thing.

Squash merges simply guarantee that git bisect will not be able to pinpoint a breaking change, because that history is gone.

Re: What I've learned from jj

#107

Earlier quoted context omitted.

Squash merge gives you the same thing.

Squash merges simply guarantee that git bisect will not be able to pinpoint a breaking change, because that history is gone .

If you treat a PR as a unit of work, then there is nothing to bisect. If you don't treat it as a unit of work, then people just edit their git history to merge commits just like a squash.

Re: What I've learned from jj

#108
post #42

Earlier quoted context omitted.

How often do you find that command useful? In ~18 years of git use, I have never needed it, but I see it mentioned often as an important reason to handle commits in some certain way. I wonder what accounts for the difference.

It's useful when the codebase is difficult to debug directly. Eg, your users have a bug that maybe appears on specific hardware, which the developers don't have. The users can't be expected to comprehend the code base enough to debug, but bisect is a mechanical process that they are capable of. Having said that, bisect is also an O(log N) method and it's useful where otherwise you might end up spending O(N) time debu…

whats N here?

Re: What I've learned from jj

#109

Earlier quoted context omitted.

Here’s the most relevant (to me) difference: - The real unit of change lives in Git - The real unit of change lives on some forge I want it to live in Git.

They are the same if you use squash merge.

modulo the commit message, which github apparently takes a lot of effort to not surface when needed; the most egregious example is that it's a complete afterthought to fill out right before the 'squash and merge' button becomes green.

Re: What I've learned from jj

#110
post #82

I used jj for a bit. It messed up my code, put everything in staged and what not. I might try it again when it's stable.

It's by design. It's quite stable, too. You were probably confused by assuming it works like git, it really doesn't when you're working on a change. It kinda starts looking like git when changes are committed and pushed to master/main.
Post reply on HN