Merge branch 'jc/checkdiff'
[gitweb.git] / git.c
diff --git a/git.c b/git.c
index 0cb86884d738a8314f164c82e4cc619a9998f3db..22ac5226def5c2dd4e699533255b84e18f630bfa 100644 (file)
--- a/git.c
+++ b/git.c
@@ -6,6 +6,9 @@
 const char git_usage_string[] =
        "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
 
+const char git_more_info_string[] =
+       "See 'git help COMMAND' for more information on a specific command.";
+
 static int handle_options(const char*** argv, int* argc, int* envchanged)
 {
        int handled = 0;
@@ -87,19 +90,6 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
        return handled;
 }
 
-static const char *alias_command;
-static char *alias_string;
-
-static int git_alias_config(const char *var, const char *value)
-{
-       if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) {
-               if (!value)
-                       return config_error_nonbool(var);
-               alias_string = xstrdup(value);
-       }
-       return 0;
-}
-
 static int split_cmdline(char *cmdline, const char ***argv)
 {
        int src, dst, count = 0, size = 16;
@@ -155,15 +145,18 @@ static int split_cmdline(char *cmdline, const char ***argv)
 
 static int handle_alias(int *argcp, const char ***argv)
 {
-       int nongit = 0, envchanged = 0, ret = 0, saved_errno = errno;
+       int envchanged = 0, ret = 0, saved_errno = errno;
        const char *subdir;
        int count, option_count;
        const char** new_argv;
+       const char *alias_command;
+       char *alias_string;
+       int unused_nongit;
 
-       subdir = setup_git_directory_gently(&nongit);
+       subdir = setup_git_directory_gently(&unused_nongit);
 
        alias_command = (*argv)[0];
-       git_config(git_alias_config);
+       alias_string = alias_lookup(alias_command);
        if (alias_string) {
                if (alias_string[0] == '!') {
                        if (*argcp > 1) {
@@ -289,12 +282,14 @@ static void handle_internal_command(int argc, const char **argv)
                { "branch", cmd_branch, RUN_SETUP },
                { "bundle", cmd_bundle },
                { "cat-file", cmd_cat_file, RUN_SETUP },
+               { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
                { "checkout-index", cmd_checkout_index,
                        RUN_SETUP | NEED_WORK_TREE},
                { "check-ref-format", cmd_check_ref_format },
-               { "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
+               { "check-attr", cmd_check_attr, RUN_SETUP },
                { "cherry", cmd_cherry, RUN_SETUP },
                { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+               { "clone", cmd_clone },
                { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
                { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
                { "commit-tree", cmd_commit_tree, RUN_SETUP },
@@ -302,7 +297,7 @@ static void handle_internal_command(int argc, const char **argv)
                { "count-objects", cmd_count_objects, RUN_SETUP },
                { "describe", cmd_describe, RUN_SETUP },
                { "diff", cmd_diff },
-               { "diff-files", cmd_diff_files },
+               { "diff-files", cmd_diff_files, RUN_SETUP },
                { "diff-index", cmd_diff_index, RUN_SETUP },
                { "diff-tree", cmd_diff_tree, RUN_SETUP },
                { "fast-export", cmd_fast_export, RUN_SETUP },
@@ -332,6 +327,8 @@ static void handle_internal_command(int argc, const char **argv)
                { "merge-base", cmd_merge_base, RUN_SETUP },
                { "merge-file", cmd_merge_file },
                { "merge-ours", cmd_merge_ours, RUN_SETUP },
+               { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
+               { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
                { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
                { "name-rev", cmd_name_rev, RUN_SETUP },
                { "pack-objects", cmd_pack_objects, RUN_SETUP },
@@ -342,6 +339,7 @@ static void handle_internal_command(int argc, const char **argv)
                { "push", cmd_push, RUN_SETUP },
                { "read-tree", cmd_read_tree, RUN_SETUP },
                { "reflog", cmd_reflog, RUN_SETUP },
+               { "remote", cmd_remote, RUN_SETUP },
                { "repo-config", cmd_config },
                { "rerere", cmd_rerere, RUN_SETUP },
                { "reset", cmd_reset, RUN_SETUP },
@@ -350,10 +348,10 @@ static void handle_internal_command(int argc, const char **argv)
                { "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 | USE_PAGER },
+               { "shortlog", cmd_shortlog, USE_PAGER },
                { "show-branch", cmd_show_branch, RUN_SETUP },
                { "show", cmd_show, RUN_SETUP | USE_PAGER },
-               { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
+               { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE | USE_PAGER },
                { "stripspace", cmd_stripspace },
                { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
                { "tag", cmd_tag, RUN_SETUP },
@@ -386,6 +384,36 @@ static void handle_internal_command(int argc, const char **argv)
        }
 }
 
+static void execv_dashed_external(const char **argv)
+{
+       struct strbuf cmd;
+       const char *tmp;
+
+       strbuf_init(&cmd, 0);
+       strbuf_addf(&cmd, "git-%s", argv[0]);
+
+       /*
+        * argv[0] must be the git command, but the argv array
+        * belongs to the caller, and may be reused in
+        * subsequent loop iterations. Save argv[0] and
+        * restore it on error.
+        */
+       tmp = argv[0];
+       argv[0] = cmd.buf;
+
+       trace_argv_printf(argv, "trace: exec:");
+
+       /* execvp() can only ever return if it fails */
+       execvp(cmd.buf, (char **)argv);
+
+       trace_printf("trace: exec failed: %s\n", strerror(errno));
+
+       argv[0] = tmp;
+
+       strbuf_release(&cmd);
+}
+
+
 int main(int argc, const char **argv)
 {
        const char *cmd = argv[0] ? argv[0] : "git-help";
@@ -432,6 +460,7 @@ int main(int argc, const char **argv)
                /* The user didn't specify a command; give them help */
                printf("usage: %s\n\n", git_usage_string);
                list_common_cmds_help();
+               printf("\n%s\n", git_more_info_string);
                exit(1);
        }
        cmd = argv[0];
@@ -449,7 +478,7 @@ int main(int argc, const char **argv)
                handle_internal_command(argc, argv);
 
                /* .. then try the external ones */
-               execv_git_cmd(argv);
+               execv_dashed_external(argv);
 
                /* It could be an alias -- this works around the insanity
                 * of overriding "git log" with "git show" by having