Remix.run Logo
saghm 2 days ago

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

nightski 2 days ago | parent [-]

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.

sswatson 2 days ago | parent | next [-]

I find this kind of advice to be a more scathing indictment of an interface than a critic could ever muster: asking users to forego available functionality so that some sense of order can be imposed.

tom_alexander 2 days ago | parent [-]

< glances around at all the people telling me to never use `jj edit` >

dwattttt a day ago | parent | next [-]

That goes in the same bucket as rebase. Until you know what it does, you'll be fine avoiding it.

Since people are sharing their experiences and my recent one is relevant to edit, I'll go:

Working on a feature recently, I ended up making 3 changes ("commits") on top of each other and hopping between them via jj edit.

The first change wasn't feature specific, it was extending the base project in preparation.

The second change just added a doc describing all the changes needed for the feature.

The third change removed the doc as parts were implemented, bit by bit.

As I progressed on the third change & found stuff I'd missed at the start of this process, I jumped back to edit the first change (maybe I had a bug in that base project extension) and the second change (oh hey, I found something else that needed to be done for the feature).

It sounds crazy compared to a git workflow, but at the end of the process I have 3 changes, all tested & working. If I was doing this with git, I'd have to rebase/squash to get the final changes into a neat clear history.

smackmybishop a day ago | parent | prev | next [-]

I suggested that since you seemed really concerned about editing the commit that you just told it to edit. Use 'edit' all you want if your goal is to edit commits, otherwise 'new' does what it seems like you're expecting...

baq 2 days ago | parent | prev [-]

edit is useful and there are good reasons to use it, 'never use edit' is like 'never use goto' i.e. false - but if you're just starting out, jj new/jj squash is the way to go indeed.

(my particular favorite reasons to use jj edit are git-native tools which expect to work with uncommitted files e.g. autoformatters, linters, etc. which have been scripted in CI/dev workflows such that they cannot accept a list of files as params)

saghm a day ago | parent | prev | next [-]

"Just don't accidentally do things wrong" is also the way to avoid null pointer errors, type mismatches in dynamically typed languages, UB in C/C++. It works, until it doesn't, and in practice that happens pretty quickly. Personally, I like things that have proper safety checks.

nightski a day ago | parent [-]

Except it's not an unrecoverable error. If you do it all it does is add that file to the working index. No commits are made and no harm is done. So no, I do not feel it's the same as a null pointer exception or type mismatch.

saghm a day ago | parent [-]

> If you do it all it does is add that file to the working index.

No, that's not at all what it's doing!

    git init
    touch foo.txt
    git commit -m 'empty foo.txt'
    echo something >> foo.txt
    git diff --stat # Shows one line added to foo.txt
    git checkout foo.xt
    git diff --stat # empty output; no changes!
It removes changes that are not yet checked in. You can only get them back by going into the reflog (which is pretty much identical to the situation described with `jj edit` at the beginning of this thread; `jj op log` will let you get them back fine).

edit: Actually, I was wrong; the changes will NOT be in the reflog because they were never checked in. It's fully destructive; you've lost the changes and don't have any way of getting them back through git. This is strictly worse than anything possible with `jj edit`, and even when making this point I didn't realize how bad it was, and clearly neither did anyone defending it.

The fact that there have already been two instances of defending git's behavior without even understanding what it's doing with this command is exactly my point. It's not your fault; the command is unintuitive, and that's my entire point. How many times should it take for people to try to explain what's happening incorrectly before we accept this?

20 hours ago | parent [-]
[deleted]
hollowcelery 2 days ago | parent | prev | next [-]

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.

saghm a day ago | parent [-]

It's a useful thing to be able to do! It just fundamentally shouldn't be under one command. To its credit, git did add `switch` (with `-c` for creating a new branch and `-d` for specifying detached HEAD), but after two decades I can't imagine they'll ever get rid of checkout entirely because it was so fundamental for so long, and as long as its there, it's a loaded footgun with the safety off.

tom_alexander 2 days ago | parent | prev [-]

If you don't run checkout on file paths, how do you undo changes to specific files that you haven't committed yet? Like you've edited but not committed <foo>, <bar>, and <baz>. You realize your edits to <bar> are a mistake. I'd just run `git checkout <bar>` to revert those changes, what do you do?

It is also really useful when you realize you want <bar> to be the version from a commit two weeks ago. I guess you could always switch to the branch 2 weeks ago, copy the file to /tmp/, switch back, and copy the file into place, but `git checkout c23a99b -- <bar>` is so quick and easy. Or does this example not fall under the "dont run checkout on a path" since it is taking a treeish first before the path?