Re: git switch/restore, still experimental?
flat view
From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2021-05-05 11:47:39
On Tue, May 04 2021, Elijah Newren wrote:
On Tue, May 4, 2021 at 3:36 AM Gábor Farkas [off-list ref] wrote:quoted
hi, the "git switch" and "git restore" commands were released two years ago, but the manpage still says "THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.". i'd love to use them, but this warning gives me pause, perhaps i should wait until it stops being experimental, i worry that it might change in behavior unexpectedly and cause problems for me. considering that they were released two years ago, could the experimental-warning be removed now? thanks, gaborThis probably makes sense. The author of switch and restore isn't involved in the git project anymore. He decided to work on other things, which was and is a big loss for us. I think others (myself included) didn't know all the things that might have been in Duy's head that he wanted to verify were working well before marking this as good, but these two commands have generally been very well received and it has been a few years. Personally, I'm not aware of anything that we'd need or want to change with these commands.
I am. I think it's quite confusing that "git switch" doesn't switch to a new "doesnotexist" branch on something like: git switch doesnotexist But requires: git switch -c doesnotexist I mean, I see why. You don't want a typo of "master" as "maaster" to create a new "maaster" branch, so really that's out. But it really should be: # -n or -N for --new / --new --force (the latter just in case of a # race, and just for consistency) git switch -n doesnotexist The design choice of squatting on "-c" for "create" as opposed to "copy" as implemented in 52d59cc6452 (branch: add a --copy (-c) option to go with --move (-m), 2017-06-18) has the knock-on effect that we can't mirror the "git branch" UI. I.e. to make "switch" be "branch with checkout" for these common cases. I.e.: # copies a branch and config from old->new (or -C for --force) git branch -c old new # just creates a "new" starting at "old", but no copying! git switch -c new old And: # Moves a branch (or -M for --force) git branch -m old new That last one we can't have either because "switch" squats on "-m" for "--merge", which I daresay is a much more obscure use-case not deserving of a short option than "rename and switch to". In summary, I think it should be changed to act like this: |---------------------------+------------------------+---------------------------| | What | Now | New | |---------------------------+------------------------+---------------------------| | Switch | git switch existing | git switch existing | | Error | git switch nonexisting | <no change (errors)> | | Switch with --merge | git switch -m branch | git switch --merge branch | | Create | git switch -c new | git switch -n new | | Create from existing | N/A | git switch -c new [<old>] | | Move & switch to existing | N/A | git switch -m new [<old>] | |---------------------------+------------------------+---------------------------| One thing that sucks about my proposal is that it would be squatting on "-n" for "new" as opposed to "--dry-run". It would be nice if switch/checkout learned a --dry-run mode, I don't like e.g. "fetch" having a "-n" that isn't "--dry-run", but can't think of a better option in the switch case. In its current state I find "git switch" to be unusable. That sounds like dramatic hyperbole, but I'm serious. As much as I applaud the effort to move git's UI forward in this particular case it's doomed to be only skin-deep because of that unfortunate initial design choice of sort-of acting like "git branch with checkout", but squatting on "-c/-C/-m". I.e. to me the ideal end state would be to deprecate (or at least warn/discourage) the "git branch -m" case where it does its own checkout (but for nothing else), and to make "git switch" a "branch with checkout" with the same -c/-C/-m/-M semantics, just also with a -n/-N for "create first". So at the end of the day you still have to use "git branch" for these common (at least for me) operations of copy/move, *and* maintain a mental model that "-c" means "xyz" here, but "abc" there. The "switch" command also solves the very real problem (and I believe this was the main motivation) of not knowing beforehand if "checkout" will interpret your "foo" as a file, a branch or whatever. I find it easier to solve that (I'm aware that it's not a 100% solution) by consistently using "--" to escape path names, rather than needing to mentally model the difference in "-c/-C/-m" behavior.