| 642 | "able to execute it. Maybe git-%s is broken?"); |
| 643 | |
| 644 | char *help_unknown_cmd(const char *cmd) |
| 645 | { |
| 646 | struct help_unknown_cmd_config cfg = { 0 }; |
| 647 | int i, n, best_similarity = 0; |
| 648 | struct cmdnames main_cmds = { 0 }; |
| 649 | struct cmdnames other_cmds = { 0 }; |
| 650 | struct cmdname_help *common_cmds; |
| 651 | |
| 652 | read_early_config(the_repository, git_unknown_cmd_config, &cfg); |
| 653 | |
| 654 | /* |
| 655 | * Disable autocorrection prompt in a non-interactive session |
| 656 | */ |
| 657 | if ((cfg.autocorrect == AUTOCORRECT_PROMPT) && (!isatty(0) || !isatty(2))) |
| 658 | cfg.autocorrect = AUTOCORRECT_NEVER; |
| 659 | |
| 660 | if (cfg.autocorrect == AUTOCORRECT_NEVER) { |
| 661 | fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd); |
| 662 | exit(1); |
| 663 | } |
| 664 | |
| 665 | load_command_list("git-", &main_cmds, &other_cmds); |
| 666 | |
| 667 | add_cmd_list(&main_cmds, &cfg.aliases); |
| 668 | add_cmd_list(&main_cmds, &other_cmds); |
| 669 | QSORT(main_cmds.names, main_cmds.cnt, cmdname_compare); |
| 670 | uniq(&main_cmds); |
| 671 | |
| 672 | extract_cmds(&common_cmds, common_mask); |
| 673 | |
| 674 | /* This abuses cmdname->len for levenshtein distance */ |
| 675 | for (i = 0, n = 0; i < main_cmds.cnt; i++) { |
| 676 | int cmp = 0; /* avoid compiler stupidity */ |
| 677 | const char *candidate = main_cmds.names[i]->name; |
| 678 | |
| 679 | /* |
| 680 | * An exact match means we have the command, but |
| 681 | * for some reason exec'ing it gave us ENOENT; probably |
| 682 | * it's a bad interpreter in the #! line. |
| 683 | */ |
| 684 | if (!strcmp(candidate, cmd)) |
| 685 | die(_(bad_interpreter_advice), cmd, cmd); |
| 686 | |
| 687 | /* Does the candidate appear in common_cmds list? */ |
| 688 | while (common_cmds[n].name && |
| 689 | (cmp = strcmp(common_cmds[n].name, candidate)) < 0) |
| 690 | n++; |
| 691 | if (common_cmds[n].name && !cmp) { |
| 692 | /* Yes, this is one of the common commands */ |
| 693 | n++; /* use the entry from common_cmds[] */ |
| 694 | if (starts_with(candidate, cmd)) { |
| 695 | /* Give prefix match a very good score */ |
| 696 | main_cmds.names[i]->len = 0; |
| 697 | continue; |
| 698 | } |
| 699 | } |
| 700 | |
| 701 | main_cmds.names[i]->len = |
no test coverage detected