summaryrefslogtreecommitdiff
path: root/help.c
diff options
context:
space:
mode:
Diffstat (limited to 'help.c')
-rw-r--r--help.c192
1 files changed, 67 insertions, 125 deletions
diff --git a/help.c b/help.c
index ff05fd22df..3c3bdec213 100644
--- a/help.c
+++ b/help.c
@@ -34,7 +34,7 @@ static struct category_description main_categories[] = {
{ CAT_foreignscminterface, N_("Interacting with Others") },
{ CAT_plumbingmanipulators, N_("Low-level Commands / Manipulators") },
{ CAT_plumbinginterrogators, N_("Low-level Commands / Interrogators") },
- { CAT_synchingrepositories, N_("Low-level Commands / Synching Repositories") },
+ { CAT_synchingrepositories, N_("Low-level Commands / Syncing Repositories") },
{ CAT_purehelpers, N_("Low-level Commands / Internal Helpers") },
{ 0, NULL }
};
@@ -85,7 +85,8 @@ static void print_command_list(const struct cmdname_help *cmds,
if (cmds[i].category & mask) {
size_t len = strlen(cmds[i].name);
printf(" %s ", cmds[i].name);
- mput_char(' ', longest > len ? longest - len : 1);
+ if (longest > len)
+ mput_char(' ', longest - len);
puts(_(cmds[i].help));
}
}
@@ -262,6 +263,8 @@ void load_command_list(const char *prefix,
const char *env_path = getenv("PATH");
const char *exec_path = git_exec_path();
+ load_builtin_commands(prefix, main_cmds);
+
if (exec_path) {
list_commands_in_dir(main_cmds, exec_path, prefix);
QSORT(main_cmds->names, main_cmds->cnt, cmdname_compare);
@@ -374,14 +377,7 @@ void list_cmds_by_config(struct string_list *list)
{
const char *cmd_list;
- /*
- * There's no actual repository setup at this point (and even
- * if there is, we don't really care; only global config
- * matters). If we accidentally set up a repository, it's ok
- * too since the caller (git --list-cmds=) should exit shortly
- * anyway.
- */
- if (git_config_get_string_const("completion.commands", &cmd_list))
+ if (git_config_get_string_tmp("completion.commands", &cmd_list))
return;
string_list_sort(list);
@@ -392,8 +388,8 @@ void list_cmds_by_config(struct string_list *list)
const char *p = strchrnul(cmd_list, ' ');
strbuf_add(&sb, cmd_list, p - cmd_list);
- if (*cmd_list == '-')
- string_list_remove(list, cmd_list + 1, 0);
+ if (sb.buf[0] == '-')
+ string_list_remove(list, sb.buf + 1, 0);
else
string_list_insert(list, sb.buf);
strbuf_release(&sb);
@@ -403,101 +399,16 @@ void list_cmds_by_config(struct string_list *list)
}
}
-void list_common_guides_help(void)
+void list_guides_help(void)
{
struct category_description catdesc[] = {
- { CAT_guide, N_("The common Git guides are:") },
+ { CAT_guide, N_("The Git concept guides are:") },
{ 0, NULL }
};
print_cmd_by_category(catdesc, NULL);
putchar('\n');
}
-struct slot_expansion {
- const char *prefix;
- const char *placeholder;
- void (*fn)(struct string_list *list, const char *prefix);
- int found;
-};
-
-void list_config_help(int for_human)
-{
- struct slot_expansion slot_expansions[] = {
- { "advice", "*", list_config_advices },
- { "color.branch", "<slot>", list_config_color_branch_slots },
- { "color.decorate", "<slot>", list_config_color_decorate_slots },
- { "color.diff", "<slot>", list_config_color_diff_slots },
- { "color.grep", "<slot>", list_config_color_grep_slots },
- { "color.interactive", "<slot>", list_config_color_interactive_slots },
- { "color.remote", "<slot>", list_config_color_sideband_slots },
- { "color.status", "<slot>", list_config_color_status_slots },
- { "fsck", "<msg-id>", list_config_fsck_msg_ids },
- { "receive.fsck", "<msg-id>", list_config_fsck_msg_ids },
- { NULL, NULL, NULL }
- };
- const char **p;
- struct slot_expansion *e;
- struct string_list keys = STRING_LIST_INIT_DUP;
- int i;
-
- for (p = config_name_list; *p; p++) {
- const char *var = *p;
- struct strbuf sb = STRBUF_INIT;
-
- for (e = slot_expansions; e->prefix; e++) {
-
- strbuf_reset(&sb);
- strbuf_addf(&sb, "%s.%s", e->prefix, e->placeholder);
- if (!strcasecmp(var, sb.buf)) {
- e->fn(&keys, e->prefix);
- e->found++;
- break;
- }
- }
- strbuf_release(&sb);
- if (!e->prefix)
- string_list_append(&keys, var);
- }
-
- for (e = slot_expansions; e->prefix; e++)
- if (!e->found)
- BUG("slot_expansion %s.%s is not used",
- e->prefix, e->placeholder);
-
- string_list_sort(&keys);
- for (i = 0; i < keys.nr; i++) {
- const char *var = keys.items[i].string;
- const char *wildcard, *tag, *cut;
-
- if (for_human) {
- puts(var);
- continue;
- }
-
- wildcard = strchr(var, '*');
- tag = strchr(var, '<');
-
- if (!wildcard && !tag) {
- puts(var);
- continue;
- }
-
- if (wildcard && !tag)
- cut = wildcard;
- else if (!wildcard && tag)
- cut = tag;
- else
- cut = wildcard < tag ? wildcard : tag;
-
- /*
- * We may produce duplicates, but that's up to
- * git-completion.bash to handle
- */
- printf("%.*s\n", (int)(cut - var), var);
- }
- string_list_clear(&keys, 0);
-}
-
static int get_alias(const char *var, const char *value, void *data)
{
struct string_list *list = data;
@@ -561,12 +472,26 @@ int is_in_cmdlist(struct cmdnames *c, const char *s)
static int autocorrect;
static struct cmdnames aliases;
+#define AUTOCORRECT_NEVER (-2)
+#define AUTOCORRECT_IMMEDIATELY (-1)
+
static int git_unknown_cmd_config(const char *var, const char *value, void *cb)
{
const char *p;
- if (!strcmp(var, "help.autocorrect"))
- autocorrect = git_config_int(var,value);
+ if (!strcmp(var, "help.autocorrect")) {
+ if (!value)
+ return config_error_nonbool(var);
+ if (!strcmp(value, "never")) {
+ autocorrect = AUTOCORRECT_NEVER;
+ } else if (!strcmp(value, "immediate")) {
+ autocorrect = AUTOCORRECT_IMMEDIATELY;
+ } else {
+ int v = git_config_int(var, value);
+ autocorrect = (v < 0)
+ ? AUTOCORRECT_IMMEDIATELY : v;
+ }
+ }
/* Also use aliases for command lookup */
if (skip_prefix(var, "alias.", &p))
add_cmdname(&aliases, p, strlen(p));
@@ -614,6 +539,11 @@ const char *help_unknown_cmd(const char *cmd)
read_early_config(git_unknown_cmd_config, NULL);
+ if (autocorrect == AUTOCORRECT_NEVER) {
+ fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
+ exit(1);
+ }
+
load_command_list("git-", &main_cmds, &other_cmds);
add_cmd_list(&main_cmds, &aliases);
@@ -683,7 +613,7 @@ const char *help_unknown_cmd(const char *cmd)
_("WARNING: You called a Git command named '%s', "
"which does not exist."),
cmd);
- if (autocorrect < 0)
+ if (autocorrect == AUTOCORRECT_IMMEDIATELY)
fprintf_ln(stderr,
_("Continuing under the assumption that "
"you meant '%s'."),
@@ -713,8 +643,33 @@ const char *help_unknown_cmd(const char *cmd)
exit(1);
}
+void get_version_info(struct strbuf *buf, int show_build_options)
+{
+ /*
+ * The format of this string should be kept stable for compatibility
+ * with external projects that rely on the output of "git version".
+ *
+ * Always show the version, even if other options are given.
+ */
+ strbuf_addf(buf, "git version %s\n", git_version_string);
+
+ if (show_build_options) {
+ strbuf_addf(buf, "cpu: %s\n", GIT_HOST_CPU);
+ if (git_built_from_commit_string[0])
+ strbuf_addf(buf, "built from commit: %s\n",
+ git_built_from_commit_string);
+ else
+ strbuf_addstr(buf, "no commit associated with this build\n");
+ strbuf_addf(buf, "sizeof-long: %d\n", (int)sizeof(long));
+ strbuf_addf(buf, "sizeof-size_t: %d\n", (int)sizeof(size_t));
+ strbuf_addf(buf, "shell-path: %s\n", SHELL_PATH);
+ /* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */
+ }
+}
+
int cmd_version(int argc, const char **argv, const char *prefix)
{
+ struct strbuf buf = STRBUF_INIT;
int build_options = 0;
const char * const usage[] = {
N_("git version [<options>]"),
@@ -728,25 +683,11 @@ int cmd_version(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix, options, usage, 0);
- /*
- * The format of this string should be kept stable for compatibility
- * with external projects that rely on the output of "git version".
- *
- * Always show the version, even if other options are given.
- */
- printf("git version %s\n", git_version_string);
+ get_version_info(&buf, build_options);
+ printf("%s", buf.buf);
+
+ strbuf_release(&buf);
- if (build_options) {
- printf("cpu: %s\n", GIT_HOST_CPU);
- if (git_built_from_commit_string[0])
- printf("built from commit: %s\n",
- git_built_from_commit_string);
- else
- printf("no commit associated with this build\n");
- printf("sizeof-long: %d\n", (int)sizeof(long));
- printf("sizeof-size_t: %d\n", (int)sizeof(size_t));
- /* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */
- }
return 0;
}
@@ -760,19 +701,19 @@ static int append_similar_ref(const char *refname, const struct object_id *oid,
{
struct similar_ref_cb *cb = (struct similar_ref_cb *)(cb_data);
char *branch = strrchr(refname, '/') + 1;
- const char *remote;
/* A remote branch of the same name is deemed similar */
- if (skip_prefix(refname, "refs/remotes/", &remote) &&
+ if (starts_with(refname, "refs/remotes/") &&
!strcmp(branch, cb->base_ref))
- string_list_append(cb->similar_refs, remote);
+ string_list_append_nodup(cb->similar_refs,
+ shorten_unambiguous_ref(refname, 1));
return 0;
}
static struct string_list guess_refs(const char *ref)
{
struct similar_ref_cb ref_cb;
- struct string_list similar_refs = STRING_LIST_INIT_NODUP;
+ struct string_list similar_refs = STRING_LIST_INIT_DUP;
ref_cb.base_ref = ref;
ref_cb.similar_refs = &similar_refs;
@@ -780,7 +721,8 @@ static struct string_list guess_refs(const char *ref)
return similar_refs;
}
-void help_unknown_ref(const char *ref, const char *cmd, const char *error)
+NORETURN void help_unknown_ref(const char *ref, const char *cmd,
+ const char *error)
{
int i;
struct string_list suggested_refs = guess_refs(ref);