5 ms·
It's not "wildly" different behavior based on the thing it's pointing to. In all 3 cases, the command is pointed at a commit and the behavior is the same. Onc
by nightski 6mo ago
It's not "wildly" different behavior based on the thing it's pointing to. In all 3 cases, the command is pointed at a commit and the behavior is the same. Once you know that branches/HEAD are just named pointers to commits, then it becomes obvious you are always just working on commits and branches/ids/HEAD etc are just ways of referencing them.
- saghm 6mo ago> In all 3 cases, the command is pointed at a commit and the behavior is the same echo "something" >> foo.txt git checkout foo.txt What's the name of the branch this is pointed at? If I have to run another git command to find out, then it's not "pointed" at it.
- webstrand 6mo agoIf you don't provide it a <tree-ish> it reads from the index (staged files). So you're right its not really pointed anywhere, since the index isn't a ref.
- saghm 6mo agoThat'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 6mo agoI 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 6mo agoI 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 6mo ago< glances around at all the people telling me to never use `jj edit` >
- baq 6mo agoedit 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)
- dwattttt 6mo agoThat 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 6mo ago
- MrJohz 6mo agoBut 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 "detached head" mode, and making a commit will just create a new commit somewhere that by default is hidden into I learn what a reflog is. And the kicker is: these two states look completely identical - I can have exactly the same files in my repository, and exactly the same parent commit checked out, but the hidden mode changes how git will respond to my commands. In fairness, none of this is so difficult that you can't eventually figure it out and learn it. But it's not intuitive. This is the sort of weirdness that junior developers stumble over regularly where they accidentally do the wrong kind of checkout, make a bunch of changes, and then suddenly seem to have lost all their work. This is one of the ways that I think the JJ model is so much clearer. You always checkout a commit. Any argument you pass to `jj new` will get resolved to a commit and that commit will be checked out. The disadvantage is that you need to manually bump the branch pointer, but the advantage is that you don't necessarily need branch pointers unless you want to share a particular branch with other people, or give it a certain name. Creating new commits on anonymous branches is perfectly normal and you'll never struggle to find commits by accidentally checking out the wrong thing.
- fragmede 6mo ago> 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 with git, but I know what I'm doing in that case. For someone new to version control, committing to an unnamed branch doesn't seem like a desired operation no matter which system you're using. What's wrong with requiring branches to be named?
- steveklabnik 6mo ago