#include "exec-cmd.h"
#include "help.h"
#include "run-command.h"
+#include "alias.h"
#define RUN_SETUP (1<<0)
#define RUN_SETUP_GENTLY (1<<1)
static int use_pager = -1;
-static void list_builtins(unsigned int exclude_option, char sep);
+static void list_builtins(struct string_list *list, unsigned int exclude_option);
+
+static void exclude_helpers_from_list(struct string_list *list)
+{
+ int i = 0;
+
+ while (i < list->nr) {
+ if (strstr(list->items[i].string, "--"))
+ unsorted_string_list_delete_item(list, i, 0);
+ else
+ i++;
+ }
+}
+
+static int match_token(const char *spec, int len, const char *token)
+{
+ int token_len = strlen(token);
+
+ return len == token_len && !strncmp(spec, token, token_len);
+}
+
+static int list_cmds(const char *spec)
+{
+ struct string_list list = STRING_LIST_INIT_DUP;
+ int i;
+
+ while (*spec) {
+ const char *sep = strchrnul(spec, ',');
+ int len = sep - spec;
+
+ if (match_token(spec, len, "builtins"))
+ list_builtins(&list, 0);
+ else if (match_token(spec, len, "main"))
+ list_all_main_cmds(&list);
+ else if (match_token(spec, len, "others"))
+ list_all_other_cmds(&list);
+ else if (match_token(spec, len, "nohelpers"))
+ exclude_helpers_from_list(&list);
+ else if (match_token(spec, len, "alias"))
+ list_aliases(&list);
+ else if (match_token(spec, len, "config"))
+ list_cmds_by_config(&list);
+ else if (len > 5 && !strncmp(spec, "list-", 5)) {
+ struct strbuf sb = STRBUF_INIT;
+
+ strbuf_add(&sb, spec + 5, len - 5);
+ list_cmds_by_category(&list, sb.buf);
+ strbuf_release(&sb);
+ }
+ else
+ die(_("unsupported command listing type '%s'"), spec);
+ spec += len;
+ if (*spec == ',')
+ spec++;
+ }
+ for (i = 0; i < list.nr; i++)
+ puts(list.items[i].string);
+ string_list_clear(&list, 0);
+ return 0;
+}
static void commit_pager_choice(void) {
switch (use_pager) {
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--no-replace-objects")) {
- check_replace_refs = 0;
+ read_replace_refs = 0;
setenv(NO_REPLACE_OBJECTS_ENVIRONMENT, "1", 1);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--shallow-file")) {
(*argv)++;
(*argc)--;
- set_alternate_shallow_file((*argv)[0], 1);
+ set_alternate_shallow_file(the_repository, (*argv)[0], 1);
if (envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "-C")) {
}
(*argv)++;
(*argc)--;
- } else if (!strcmp(cmd, "--list-builtins")) {
- list_builtins(0, '\n');
- exit(0);
- } else if (!strcmp(cmd, "--list-parseopt-builtins")) {
- list_builtins(NO_PARSEOPT, ' ');
- exit(0);
+ } else if (skip_prefix(cmd, "--list-cmds=", &cmd)) {
+ if (!strcmp(cmd, "parseopt")) {
+ struct string_list list = STRING_LIST_INIT_DUP;
+ int i;
+
+ list_builtins(&list, NO_PARSEOPT);
+ for (i = 0; i < list.nr; i++)
+ printf("%s ", list.items[i].string);
+ string_list_clear(&list, 0);
+ exit(0);
+ } else {
+ exit(list_cmds(cmd));
+ }
} else {
fprintf(stderr, _("unknown option: %s\n"), cmd);
usage(git_usage_string);
alias_command = (*argv)[0];
alias_string = alias_lookup(alias_command);
if (alias_string) {
+ if (*argcp > 1 && !strcmp((*argv)[1], "-h"))
+ fprintf_ln(stderr, _("'%s' is aliased to '%s'"),
+ alias_command, alias_string);
if (alias_string[0] == '!') {
struct child_process child = CHILD_PROCESS_INIT;
int nongit_ok;
trace_argv_printf(argv, "trace: built-in: git");
+ validate_cache_entries(&the_index);
status = p->fn(argc, argv, prefix);
+ validate_cache_entries(&the_index);
+
if (status)
return status;
{ "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
{ "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
{ "mktree", cmd_mktree, RUN_SETUP },
+ { "multi-pack-index", cmd_multi_pack_index, RUN_SETUP_GENTLY },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
{ "notes", cmd_notes, RUN_SETUP },
{ "prune-packed", cmd_prune_packed, RUN_SETUP },
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
+ { "range-diff", cmd_range_diff, RUN_SETUP | USE_PAGER },
{ "read-tree", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},
- { "rebase--helper", cmd_rebase__helper, RUN_SETUP | NEED_WORK_TREE },
+ /*
+ * NEEDSWORK: Until the rebase is independent and needs no redirection
+ * to rebase shell script this is kept as is, then should be changed to
+ * RUN_SETUP | NEED_WORK_TREE
+ */
+ { "rebase", cmd_rebase },
+ { "rebase--interactive", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
{ "remote", cmd_remote, RUN_SETUP },
{ "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
{ "show", cmd_show, RUN_SETUP },
{ "show-branch", cmd_show_branch, RUN_SETUP },
+ { "show-index", cmd_show_index },
{ "show-ref", cmd_show_ref, RUN_SETUP },
{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
return !!get_builtin(s);
}
-static void list_builtins(unsigned int exclude_option, char sep)
+static void list_builtins(struct string_list *out, unsigned int exclude_option)
{
int i;
for (i = 0; i < ARRAY_SIZE(commands); i++) {
if (exclude_option &&
(commands[i].option & exclude_option))
continue;
- printf("%s%c", commands[i].cmd, sep);
+ string_list_append(out, commands[i].cmd);
}
}
static int run_argv(int *argcp, const char ***argv)
{
int done_alias = 0;
+ struct string_list cmd_list = STRING_LIST_INIT_NODUP;
+ struct string_list_item *seen;
while (1) {
/*
/* .. then try the external ones */
execv_dashed_external(*argv);
- /* It could be an alias -- this works around the insanity
+ seen = unsorted_string_list_lookup(&cmd_list, *argv[0]);
+ if (seen) {
+ int i;
+ struct strbuf sb = STRBUF_INIT;
+ for (i = 0; i < cmd_list.nr; i++) {
+ struct string_list_item *item = &cmd_list.items[i];
+
+ strbuf_addf(&sb, "\n %s", item->string);
+ if (item == seen)
+ strbuf_addstr(&sb, " <==");
+ else if (i == cmd_list.nr - 1)
+ strbuf_addstr(&sb, " ==>");
+ }
+ die(_("alias loop detected: expansion of '%s' does"
+ " not terminate:%s"), cmd_list.items[0].string, sb.buf);
+ }
+
+ string_list_append(&cmd_list, *argv[0]);
+
+ /*
+ * It could be an alias -- this works around the insanity
* of overriding "git log" with "git show" by having
* alias.log = show
*/
- if (done_alias)
- break;
if (!handle_alias(argcp, argv))
break;
done_alias = 1;
}
+ string_list_clear(&cmd_list, 0);
+
return done_alias;
}