Since I made my adages post last year, I've had a few afterthoughts, so here's a second instalment of things I seem to find myself saying a lot. ( seven more short pontifications )
if you always have to remember to specify the ‘work properly’ option, something is wrong with the design
Yes, I'm always so annoyed by this. I remember the photocopier in the Trinity library had a mode: automatically copy whatever you put in, the same size, on the same size paper. What I couldn't figure out is why that mode wasn't the default!
To be fair, this often happens when originally there was some reason to do it a way other than "work properly", or beginners and experts have opposite expectations for "work properly", and you get stuck with the wrong default. But yes, you should be able to make it better somehow.
Yes. I think git commit -a (another classic example of a "work sensibly" option that you nearly always want to add) is a good example of both your reasons - it made sense when the git UI was intended to be used by porcelains rather than people, and also one could argue that power users are more likely to take advantage of the ability to not commit everything in one go.
(Though, on the other hand, I am enough of a git power user to constantly take advantage of partial committing, and even I still find I nearly always have to remember to add -a - to the point that on the occasions I don't want to commit everything, I still find my fingers have reflexively added the -a and then I wonder what went wrong...)
I have configured a `git ci` alias and occasionally use it incorrectly in exactly the way you describe :-) Typical failure mode is: prepare partial commit, then type `git ci -m ...`, swear, and spend twice as long unpicking the error.
Mmm. In fact I find myself thinking that since git commit -a modifies your index in a way that can wipe out carefully prepared stuff in it, you'd actually quite like it to have the side effect of leaving the prior index state somewhere easily recoverable, in cases where the index was modified.
Perhaps a handy approach would be for it to generate a second commit consisting of exactly what it would have done if you hadn't said -a, and pointed an ephemeral ref at it similar to FETCH_HEAD. Then you could trivially recover from an accidental -a by saying git reset NO_THE_OTHER_ONE, or some such.
I realised reading this that indeed I *never* use "git commit" (except for the special case of "git commit --amend" for tweaking commit messages after "git am" in one particular workflow), because pretty much all the time I use git via stgit...
I thought partial committing was great when I first saw it, a much better way for mortals to work, and only experts could make a change in the file system perfect first time and commit it in one go :)
But yes, git is full of things like that where a "do it right" option is added later and people differ in which one they use most commonly. And also yes, it's what your fingers normally type, not what the unadorned command is...
In fact, what I probably want actually is similar to "git commit -a", but shows the proposed changes without changing the index, and only proceeds if I hit return. I should script that...
Hmm. I git commit without -a all the time - I would certainly find it more annoying to have to turn it off than I do having to turn it on. But then I always do a git diff as the first thing when I intend to commit, and I follow up with git commit -a only if the diff already is exactly what I want to commit, which often is not the case.
Generally I make commits once I know I have completed a logical step in the evolution of the code, which generally means I am some way into the next step or the one after or even the one after that one before I am certain. Sometimes this is because I’m not sure what the steps even will be before I start. With trivial steps it can happen that I know beforehand exactly what the step will be, and then I do it, and then (after checking the diff!) I can just commit it - in which case I use -a. With any slightly larger task, I often find myself not knowing how to narrate the overall change as a series of patches until after completing (some part of) it. And I never make “here’s how far I got” commits - an
( ... )
I think the canonical example of a "work properly" option that you always supply is in the Windows command line cd command, the "/D" option.
You technically don't always need to supply it, because "cd newdir" or even "cd ..\..\path\to\newdir" work. But for some unknown reason, the command line keeps a "cd" for each drive. And so "cd S:\temp" will not change your current directory to S:\temp; it'll just mean that the next time you go "S:", your current directory will be S:\temp.
"cd /D S:\temp", on the other hand, actually changes your current directory.
Why /D isn't the default... I can vaguely picture some trains of thought that could have led to the design, but they're all abysmal and it should never have been let out like that.
I don't know for sure why it's like that, but I'd have to suppose that it's some kind of a consequence of DOS's evolution from CP/M which had drive letters but not subdirectories. I bet it'll turn out something like: there was a big and important class of legacy CP/M programs that needed to be easy to port to DOS in order to make DOS sell, which expected to be able to keep opening A:THIS.DAT and B:THAT.DAT, and so if you wanted to actually take advantage of DOS's directory system to keep all the data for those programs somewhere other than the root of your drive(s) then you needed to be able to set a separate persistent cwd per drive before running the legacy program.
Though I suppose even that only explains the idea of having a persistent per-drive cwd and hence some method for adjusting the directory for drive A without also making that the current drive. It still doesn't explain the bizarre idea that the default behaviour of CD A:\THING ought to be to do that specialist operation...
Back when you’d routinely use multiple floppies to keep all the files you were working on, it was not at all a specialist operation. It was pretty nice to be able to COPY A:*.* C: and have it do what you wanted because each drive had a separate working directory, without having to type so much - a bit like a two-pane file manager, without the file manager. (Remember that DOSKEY.EXE was a late addition; COMMAND.COM by itself had no command history for most of DOS standalone life, so being able to set lots of implicit state at the command line was… vital, almost. And tab completion was an even later addition, not to happen before far into the CMD.EXE era.)
Note that there were several other design aspects. Because DOS itself was single-tasked, there was not a strong separation of process state, and working directories were one of these things: if you invoked a program that changed directories, upon return to the command line, you would still be in that directory - working directories were effectively only per-drive, not (at all) per-
( ... )
Of course, it works the right way in Powershell, where CD takes you directly to any location (including network drives, lists of variables, and the registry).
Yes, I'm always so annoyed by this. I remember the photocopier in the Trinity library had a mode: automatically copy whatever you put in, the same size, on the same size paper. What I couldn't figure out is why that mode wasn't the default!
To be fair, this often happens when originally there was some reason to do it a way other than "work properly", or beginners and experts have opposite expectations for "work properly", and you get stuck with the wrong default. But yes, you should be able to make it better somehow.
Reply
(Though, on the other hand, I am enough of a git power user to constantly take advantage of partial committing, and even I still find I nearly always have to remember to add -a - to the point that on the occasions I don't want to commit everything, I still find my fingers have reflexively added the -a and then I wonder what went wrong...)
Reply
Reply
Perhaps a handy approach would be for it to generate a second commit consisting of exactly what it would have done if you hadn't said -a, and pointed an ephemeral ref at it similar to FETCH_HEAD. Then you could trivially recover from an accidental -a by saying git reset NO_THE_OTHER_ONE, or some such.
Reply
Reply
Reply
But yes, git is full of things like that where a "do it right" option is added later and people differ in which one they use most commonly. And also yes, it's what your fingers normally type, not what the unadorned command is...
In fact, what I probably want actually is similar to "git commit -a", but shows the proposed changes without changing the index, and only proceeds if I hit return. I should script that...
Reply
Hmm. I git commit without -a all the time - I would certainly find it more annoying to have to turn it off than I do having to turn it on. But then I always do a git diff as the first thing when I intend to commit, and I follow up with git commit -a only if the diff already is exactly what I want to commit, which often is not the case.
Generally I make commits once I know I have completed a logical step in the evolution of the code, which generally means I am some way into the next step or the one after or even the one after that one before I am certain. Sometimes this is because I’m not sure what the steps even will be before I start. With trivial steps it can happen that I know beforehand exactly what the step will be, and then I do it, and then (after checking the diff!) I can just commit it - in which case I use -a. With any slightly larger task, I often find myself not knowing how to narrate the overall change as a series of patches until after completing (some part of) it. And I never make “here’s how far I got” commits - an ( ... )
Reply
You technically don't always need to supply it, because "cd newdir" or even "cd ..\..\path\to\newdir" work. But for some unknown reason, the command line keeps a "cd" for each drive. And so "cd S:\temp" will not change your current directory to S:\temp; it'll just mean that the next time you go "S:", your current directory will be S:\temp.
"cd /D S:\temp", on the other hand, actually changes your current directory.
Why /D isn't the default... I can vaguely picture some trains of thought that could have led to the design, but they're all abysmal and it should never have been let out like that.
Reply
I don't know for sure why it's like that, but I'd have to suppose that it's some kind of a consequence of DOS's evolution from CP/M which had drive letters but not subdirectories. I bet it'll turn out something like: there was a big and important class of legacy CP/M programs that needed to be easy to port to DOS in order to make DOS sell, which expected to be able to keep opening A:THIS.DAT and B:THAT.DAT, and so if you wanted to actually take advantage of DOS's directory system to keep all the data for those programs somewhere other than the root of your drive(s) then you needed to be able to set a separate persistent cwd per drive before running the legacy program.
Though I suppose even that only explains the idea of having a persistent per-drive cwd and hence some method for adjusting the directory for drive A without also making that the current drive. It still doesn't explain the bizarre idea that the default behaviour of CD A:\THING ought to be to do that specialist operation...
Reply
Back when you’d routinely use multiple floppies to keep all the files you were working on, it was not at all a specialist operation. It was pretty nice to be able to COPY A:*.* C: and have it do what you wanted because each drive had a separate working directory, without having to type so much - a bit like a two-pane file manager, without the file manager. (Remember that DOSKEY.EXE was a late addition; COMMAND.COM by itself had no command history for most of DOS standalone life, so being able to set lots of implicit state at the command line was… vital, almost. And tab completion was an even later addition, not to happen before far into the CMD.EXE era.)
Note that there were several other design aspects. Because DOS itself was single-tasked, there was not a strong separation of process state, and working directories were one of these things: if you invoked a program that changed directories, upon return to the command line, you would still be in that directory - working directories were effectively only per-drive, not (at all) per- ( ... )
Reply
Reply
Reply
Reply
Leave a comment