diff --git a/Documentation/technical/api-builtin.txt b/Documentation/technical/api-builtin.txt index f3c1357b7c..e3d6e7a79a 100644 --- a/Documentation/technical/api-builtin.txt +++ b/Documentation/technical/api-builtin.txt @@ -14,8 +14,8 @@ Git: . Add the external declaration for the function to `builtin.h`. -. Add the command to `commands[]` table in `handle_internal_command()`, - defined in `git.c`. The entry should look like: +. Add the command to the `commands[]` table defined in `git.c`. + The entry should look like: { "foo", cmd_foo, }, + diff --git a/builtin.h b/builtin.h index d4afbfe418..c47c110e0f 100644 --- a/builtin.h +++ b/builtin.h @@ -27,6 +27,8 @@ extern int fmt_merge_msg(struct strbuf *in, struct strbuf *out, extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size); +extern int is_builtin(const char *s); + extern int cmd_add(int argc, const char **argv, const char *prefix); extern int cmd_annotate(int argc, const char **argv, const char *prefix); extern int cmd_apply(int argc, const char **argv, const char *prefix); diff --git a/builtin/help.c b/builtin/help.c index cc17e670ce..1fdefeb686 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -288,6 +288,10 @@ static struct cmdnames main_cmds, other_cmds; static int is_git_command(const char *s) { + if (is_builtin(s)) + return 1; + + load_command_list("git-", &main_cmds, &other_cmds); return is_in_cmdlist(&main_cmds, s) || is_in_cmdlist(&other_cmds, s); } @@ -449,7 +453,6 @@ int cmd_help(int argc, const char **argv, const char *prefix) int nongit; const char *alias; enum help_format parsed_help_format; - load_command_list("git-", &main_cmds, &other_cmds); argc = parse_options(argc, argv, prefix, builtin_help_options, builtin_help_usage, 0); @@ -458,6 +461,7 @@ int cmd_help(int argc, const char **argv, const char *prefix) if (show_all) { git_config(git_help_config, NULL); printf(_("usage: %s%s"), _(git_usage_string), "\n\n"); + load_command_list("git-", &main_cmds, &other_cmds); list_commands(colopts, &main_cmds, &other_cmds); } diff --git a/git.c b/git.c index 3799514ccb..bba4378458 100644 --- a/git.c +++ b/git.c @@ -332,124 +332,136 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) return 0; } -static void handle_internal_command(int argc, const char **argv) +static struct cmd_struct commands[] = { + { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE }, + { "annotate", cmd_annotate, RUN_SETUP }, + { "apply", cmd_apply, RUN_SETUP_GENTLY }, + { "archive", cmd_archive }, + { "bisect--helper", cmd_bisect__helper, RUN_SETUP }, + { "blame", cmd_blame, RUN_SETUP }, + { "branch", cmd_branch, RUN_SETUP }, + { "bundle", cmd_bundle, RUN_SETUP_GENTLY }, + { "cat-file", cmd_cat_file, RUN_SETUP }, + { "check-attr", cmd_check_attr, RUN_SETUP }, + { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE }, + { "check-mailmap", cmd_check_mailmap, RUN_SETUP }, + { "check-ref-format", cmd_check_ref_format }, + { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE }, + { "checkout-index", cmd_checkout_index, + RUN_SETUP | NEED_WORK_TREE}, + { "cherry", cmd_cherry, RUN_SETUP }, + { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, + { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, + { "clone", cmd_clone }, + { "column", cmd_column, RUN_SETUP_GENTLY }, + { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, + { "commit-tree", cmd_commit_tree, RUN_SETUP }, + { "config", cmd_config, RUN_SETUP_GENTLY }, + { "count-objects", cmd_count_objects, RUN_SETUP }, + { "credential", cmd_credential, RUN_SETUP_GENTLY }, + { "describe", cmd_describe, RUN_SETUP }, + { "diff", cmd_diff }, + { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE }, + { "diff-index", cmd_diff_index, RUN_SETUP }, + { "diff-tree", cmd_diff_tree, RUN_SETUP }, + { "fast-export", cmd_fast_export, RUN_SETUP }, + { "fetch", cmd_fetch, RUN_SETUP }, + { "fetch-pack", cmd_fetch_pack, RUN_SETUP }, + { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP }, + { "for-each-ref", cmd_for_each_ref, RUN_SETUP }, + { "format-patch", cmd_format_patch, RUN_SETUP }, + { "fsck", cmd_fsck, RUN_SETUP }, + { "fsck-objects", cmd_fsck, RUN_SETUP }, + { "gc", cmd_gc, RUN_SETUP }, + { "get-tar-commit-id", cmd_get_tar_commit_id }, + { "grep", cmd_grep, RUN_SETUP_GENTLY }, + { "hash-object", cmd_hash_object }, + { "help", cmd_help }, + { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, + { "init", cmd_init_db }, + { "init-db", cmd_init_db }, + { "log", cmd_log, RUN_SETUP }, + { "ls-files", cmd_ls_files, RUN_SETUP }, + { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, + { "ls-tree", cmd_ls_tree, RUN_SETUP }, + { "mailinfo", cmd_mailinfo }, + { "mailsplit", cmd_mailsplit }, + { "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE }, + { "merge-base", cmd_merge_base, RUN_SETUP }, + { "merge-file", cmd_merge_file, RUN_SETUP_GENTLY }, + { "merge-index", cmd_merge_index, RUN_SETUP }, + { "merge-ours", cmd_merge_ours, RUN_SETUP }, + { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, + { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, + { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, + { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, + { "merge-tree", cmd_merge_tree, RUN_SETUP }, + { "mktag", cmd_mktag, RUN_SETUP }, + { "mktree", cmd_mktree, RUN_SETUP }, + { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE }, + { "name-rev", cmd_name_rev, RUN_SETUP }, + { "notes", cmd_notes, RUN_SETUP }, + { "pack-objects", cmd_pack_objects, RUN_SETUP }, + { "pack-redundant", cmd_pack_redundant, RUN_SETUP }, + { "pack-refs", cmd_pack_refs, RUN_SETUP }, + { "patch-id", cmd_patch_id }, + { "pickaxe", cmd_blame, RUN_SETUP }, + { "prune", cmd_prune, RUN_SETUP }, + { "prune-packed", cmd_prune_packed, RUN_SETUP }, + { "push", cmd_push, RUN_SETUP }, + { "read-tree", cmd_read_tree, RUN_SETUP }, + { "receive-pack", cmd_receive_pack }, + { "reflog", cmd_reflog, RUN_SETUP }, + { "remote", cmd_remote, RUN_SETUP }, + { "remote-ext", cmd_remote_ext }, + { "remote-fd", cmd_remote_fd }, + { "repack", cmd_repack, RUN_SETUP }, + { "replace", cmd_replace, RUN_SETUP }, + { "rerere", cmd_rerere, RUN_SETUP }, + { "reset", cmd_reset, RUN_SETUP }, + { "rev-list", cmd_rev_list, RUN_SETUP }, + { "rev-parse", cmd_rev_parse }, + { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, + { "rm", cmd_rm, RUN_SETUP }, + { "send-pack", cmd_send_pack, RUN_SETUP }, + { "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER }, + { "show", cmd_show, RUN_SETUP }, + { "show-branch", cmd_show_branch, RUN_SETUP }, + { "show-ref", cmd_show_ref, RUN_SETUP }, + { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, + { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, + { "stripspace", cmd_stripspace }, + { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, + { "tag", cmd_tag, RUN_SETUP }, + { "unpack-file", cmd_unpack_file, RUN_SETUP }, + { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, + { "update-index", cmd_update_index, RUN_SETUP }, + { "update-ref", cmd_update_ref, RUN_SETUP }, + { "update-server-info", cmd_update_server_info, RUN_SETUP }, + { "upload-archive", cmd_upload_archive }, + { "upload-archive--writer", cmd_upload_archive_writer }, + { "var", cmd_var, RUN_SETUP_GENTLY }, + { "verify-pack", cmd_verify_pack }, + { "verify-tag", cmd_verify_tag, RUN_SETUP }, + { "version", cmd_version }, + { "whatchanged", cmd_whatchanged, RUN_SETUP }, + { "write-tree", cmd_write_tree, RUN_SETUP }, +}; + +int is_builtin(const char *s) +{ + int i; + for (i = 0; i < ARRAY_SIZE(commands); i++) { + struct cmd_struct *p = commands+i; + if (!strcmp(s, p->cmd)) + return 1; + } + return 0; +} + +static void handle_builtin(int argc, const char **argv) { const char *cmd = argv[0]; - static struct cmd_struct commands[] = { - { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE }, - { "annotate", cmd_annotate, RUN_SETUP }, - { "apply", cmd_apply, RUN_SETUP_GENTLY }, - { "archive", cmd_archive }, - { "bisect--helper", cmd_bisect__helper, RUN_SETUP }, - { "blame", cmd_blame, RUN_SETUP }, - { "branch", cmd_branch, RUN_SETUP }, - { "bundle", cmd_bundle, RUN_SETUP_GENTLY }, - { "cat-file", cmd_cat_file, RUN_SETUP }, - { "check-attr", cmd_check_attr, RUN_SETUP }, - { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE }, - { "check-mailmap", cmd_check_mailmap, RUN_SETUP }, - { "check-ref-format", cmd_check_ref_format }, - { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE }, - { "checkout-index", cmd_checkout_index, - RUN_SETUP | NEED_WORK_TREE}, - { "cherry", cmd_cherry, RUN_SETUP }, - { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, - { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, - { "clone", cmd_clone }, - { "column", cmd_column, RUN_SETUP_GENTLY }, - { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, - { "commit-tree", cmd_commit_tree, RUN_SETUP }, - { "config", cmd_config, RUN_SETUP_GENTLY }, - { "count-objects", cmd_count_objects, RUN_SETUP }, - { "credential", cmd_credential, RUN_SETUP_GENTLY }, - { "describe", cmd_describe, RUN_SETUP }, - { "diff", cmd_diff }, - { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE }, - { "diff-index", cmd_diff_index, RUN_SETUP }, - { "diff-tree", cmd_diff_tree, RUN_SETUP }, - { "fast-export", cmd_fast_export, RUN_SETUP }, - { "fetch", cmd_fetch, RUN_SETUP }, - { "fetch-pack", cmd_fetch_pack, RUN_SETUP }, - { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP }, - { "for-each-ref", cmd_for_each_ref, RUN_SETUP }, - { "format-patch", cmd_format_patch, RUN_SETUP }, - { "fsck", cmd_fsck, RUN_SETUP }, - { "fsck-objects", cmd_fsck, RUN_SETUP }, - { "gc", cmd_gc, RUN_SETUP }, - { "get-tar-commit-id", cmd_get_tar_commit_id }, - { "grep", cmd_grep, RUN_SETUP_GENTLY }, - { "hash-object", cmd_hash_object }, - { "help", cmd_help }, - { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY }, - { "init", cmd_init_db }, - { "init-db", cmd_init_db }, - { "log", cmd_log, RUN_SETUP }, - { "ls-files", cmd_ls_files, RUN_SETUP }, - { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, - { "ls-tree", cmd_ls_tree, RUN_SETUP }, - { "mailinfo", cmd_mailinfo }, - { "mailsplit", cmd_mailsplit }, - { "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE }, - { "merge-base", cmd_merge_base, RUN_SETUP }, - { "merge-file", cmd_merge_file, RUN_SETUP_GENTLY }, - { "merge-index", cmd_merge_index, RUN_SETUP }, - { "merge-ours", cmd_merge_ours, RUN_SETUP }, - { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE }, - { "merge-tree", cmd_merge_tree, RUN_SETUP }, - { "mktag", cmd_mktag, RUN_SETUP }, - { "mktree", cmd_mktree, RUN_SETUP }, - { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE }, - { "name-rev", cmd_name_rev, RUN_SETUP }, - { "notes", cmd_notes, RUN_SETUP }, - { "pack-objects", cmd_pack_objects, RUN_SETUP }, - { "pack-redundant", cmd_pack_redundant, RUN_SETUP }, - { "pack-refs", cmd_pack_refs, RUN_SETUP }, - { "patch-id", cmd_patch_id }, - { "pickaxe", cmd_blame, RUN_SETUP }, - { "prune", cmd_prune, RUN_SETUP }, - { "prune-packed", cmd_prune_packed, RUN_SETUP }, - { "push", cmd_push, RUN_SETUP }, - { "read-tree", cmd_read_tree, RUN_SETUP }, - { "receive-pack", cmd_receive_pack }, - { "reflog", cmd_reflog, RUN_SETUP }, - { "remote", cmd_remote, RUN_SETUP }, - { "remote-ext", cmd_remote_ext }, - { "remote-fd", cmd_remote_fd }, - { "repack", cmd_repack, RUN_SETUP }, - { "replace", cmd_replace, RUN_SETUP }, - { "rerere", cmd_rerere, RUN_SETUP }, - { "reset", cmd_reset, RUN_SETUP }, - { "rev-list", cmd_rev_list, RUN_SETUP }, - { "rev-parse", cmd_rev_parse }, - { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, - { "rm", cmd_rm, RUN_SETUP }, - { "send-pack", cmd_send_pack, RUN_SETUP }, - { "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER }, - { "show", cmd_show, RUN_SETUP }, - { "show-branch", cmd_show_branch, RUN_SETUP }, - { "show-ref", cmd_show_ref, RUN_SETUP }, - { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, - { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, - { "stripspace", cmd_stripspace }, - { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, - { "tag", cmd_tag, RUN_SETUP }, - { "unpack-file", cmd_unpack_file, RUN_SETUP }, - { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, - { "update-index", cmd_update_index, RUN_SETUP }, - { "update-ref", cmd_update_ref, RUN_SETUP }, - { "update-server-info", cmd_update_server_info, RUN_SETUP }, - { "upload-archive", cmd_upload_archive }, - { "upload-archive--writer", cmd_upload_archive_writer }, - { "var", cmd_var, RUN_SETUP_GENTLY }, - { "verify-pack", cmd_verify_pack }, - { "verify-tag", cmd_verify_tag, RUN_SETUP }, - { "version", cmd_version }, - { "whatchanged", cmd_whatchanged, RUN_SETUP }, - { "write-tree", cmd_write_tree, RUN_SETUP }, - }; int i; static const char ext[] = STRIP_EXTENSION; @@ -517,8 +529,8 @@ static int run_argv(int *argcp, const char ***argv) int done_alias = 0; while (1) { - /* See if it's an internal command */ - handle_internal_command(*argcp, *argv); + /* See if it's a builtin */ + handle_builtin(*argcp, *argv); /* .. then try the external ones */ execv_dashed_external(*argv); @@ -563,14 +575,14 @@ int main(int argc, char **av) * - cannot execute it externally (since it would just do * the same thing over again) * - * So we just directly call the internal command handler, and - * die if that one cannot handle it. + * So we just directly call the builtin handler, and die if + * that one cannot handle it. */ if (starts_with(cmd, "git-")) { cmd += 4; argv[0] = cmd; - handle_internal_command(argc, argv); - die("cannot handle %s internally", cmd); + handle_builtin(argc, argv); + die("cannot handle %s as a builtin", cmd); } /* Look for flags.. */