char *alias_lookup(const char *alias) { struct config_alias_data data = { alias, NULL }; read_early_config(config_alias_cb, &data); return data.v; }
/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ int check_pager_config(const char *cmd) { struct pager_command_config_data data; data.cmd = cmd; data.want = -1; data.value = NULL; read_early_config(pager_command_config, &data); if (data.value) pager_program = data.value; return data.want; }
const char *git_pager(int stdout_is_tty) { const char *pager; if (!stdout_is_tty) return NULL; pager = getenv("GIT_PAGER"); if (!pager) { if (!pager_program) read_early_config(core_pager_config, NULL); pager = pager_program; } if (!pager) pager = getenv("PAGER"); if (!pager) pager = DEFAULT_PAGER; if (!*pager || !strcmp(pager, "cat")) pager = NULL; return pager; }
const char *help_unknown_cmd(const char *cmd) { int i, n, best_similarity = 0; struct cmdnames main_cmds, other_cmds; struct cmdname_help *common_cmds; memset(&main_cmds, 0, sizeof(main_cmds)); memset(&other_cmds, 0, sizeof(other_cmds)); memset(&aliases, 0, sizeof(aliases)); read_early_config(git_unknown_cmd_config, NULL); load_command_list("git-", &main_cmds, &other_cmds); add_cmd_list(&main_cmds, &aliases); add_cmd_list(&main_cmds, &other_cmds); QSORT(main_cmds.names, main_cmds.cnt, cmdname_compare); uniq(&main_cmds); extract_cmds(&common_cmds, common_mask); /* This abuses cmdname->len for levenshtein distance */ for (i = 0, n = 0; i < main_cmds.cnt; i++) { int cmp = 0; /* avoid compiler stupidity */ const char *candidate = main_cmds.names[i]->name; /* * An exact match means we have the command, but * for some reason exec'ing it gave us ENOENT; probably * it's a bad interpreter in the #! line. */ if (!strcmp(candidate, cmd)) die(_(bad_interpreter_advice), cmd, cmd); /* Does the candidate appear in common_cmds list? */ while (common_cmds[n].name && (cmp = strcmp(common_cmds[n].name, candidate)) < 0) n++; if (common_cmds[n].name && !cmp) { /* Yes, this is one of the common commands */ n++; /* use the entry from common_cmds[] */ if (starts_with(candidate, cmd)) { /* Give prefix match a very good score */ main_cmds.names[i]->len = 0; continue; } } main_cmds.names[i]->len = levenshtein(cmd, candidate, 0, 2, 1, 3) + 1; } FREE_AND_NULL(common_cmds); QSORT(main_cmds.names, main_cmds.cnt, levenshtein_compare); if (!main_cmds.cnt) die(_("Uh oh. Your system reports no Git commands at all.")); /* skip and count prefix matches */ for (n = 0; n < main_cmds.cnt && !main_cmds.names[n]->len; n++) ; /* still counting */ if (main_cmds.cnt <= n) { /* prefix matches with everything? that is too ambiguous */ best_similarity = SIMILARITY_FLOOR + 1; } else { /* count all the most similar ones */ for (best_similarity = main_cmds.names[n++]->len; (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len); n++) ; /* still counting */ } if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) { const char *assumed = main_cmds.names[0]->name; main_cmds.names[0] = NULL; clean_cmdnames(&main_cmds); fprintf_ln(stderr, _("WARNING: You called a Git command named '%s', " "which does not exist."), cmd); if (autocorrect < 0) fprintf_ln(stderr, _("Continuing under the assumption that " "you meant '%s'."), assumed); else { fprintf_ln(stderr, _("Continuing in %0.1f seconds, " "assuming that you meant '%s'."), (float)autocorrect/10.0, assumed); sleep_millisec(autocorrect * 100); } return assumed; } fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd); if (SIMILAR_ENOUGH(best_similarity)) { fprintf_ln(stderr, Q_("\nThe most similar command is", "\nThe most similar commands are", n)); for (i = 0; i < n; i++) fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); } exit(1); }