I’m generally a big fan of Git’s “similar command” tip, but the other
day after forgetting that git isn’t as smart as hg hitting Enter too early, I
noticed something odd:
$ git st
git: 'st' is not a git command. See 'git --help'.
The most similar commands are
status
reset
stage
stash
$ git st 2>&1 | sort
reset
stage
stash
status
The most similar commands are
git: 'st' is not a git command. See 'git --help'.
The out-of-order list is coming from help_unknown_cmd
.
At a high level, it’s calculating edit distance between “st” and the other Git commands, and then listing the closest matches1.
It prioritizes common commands (aka the commands that show up when you run
git help
), which is why status
is first in the list above2.
At a slightly lower level...
- It collects all git builtins, gitconfig aliases, and “git-” $PATH executables into a single sorted list.
- Then collects the common commands into a similar list. These are the commands from command-list.txt that are categorized as init, worktree, info, history, or remote.
- For each command from the list from Step 1, it calculates the edit distance against the input. If the command is a common one and is prefixed by the input, it gets a score of 0.
- Finally it sorts the list by score and prints the closest matches. It won’t print anything if the lowest score is larger than 7. Now go read that email from Johannes.
Autocorrection
I also found some code that deals with autocorrecting invalid commands. Git can either prompt you or just do the right thing on its own. The former is new in Git 2.34. I noticed a pretty terrible bug when I tried it though:
$ ./git config --global help.autocorrect prompt
$ ./git lol
WARNING: You called a Git command named 'lol', which does not exist.
Run 'log' instead? (y/N)^
^ text cursor
There’s no space after the prompt! So I added a space and now I’m a contributor to the Git programming language. BYE
-
It lists the commands with the lowest score. But only as long as that score is below 7. You should read Johannes' totally scientific method of discovering that threshold: https://marc.info/?l=git&m=126082583920712. ↩︎
-
Specifically,
status
is both a common command and prefixed by “st”, so it gets a very good score of zero, whilereset
,stage
, andstash
get not very good scores of four. ↩︎