X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=git.c;h=88544724532b61e408cb6bb01caa11b626c7f74c;hb=2b11e3170e919866c7f5554dd4089289a1bb6726;hp=01b7e28b8c459c677a340f195a969a67a6d21792;hpb=e5de2c5e308a23b8f1531bbac2f100af7ab0767b;p=git.git diff --git a/git.c b/git.c index 01b7e28b..88544724 100644 --- a/git.c +++ b/git.c @@ -10,6 +10,7 @@ #include #include "git-compat-util.h" #include "exec_cmd.h" +#include "cache.h" #include "builtin.h" @@ -32,6 +33,113 @@ static void prepend_to_path(const char *dir, int len) setenv("PATH", path, 1); } +static const char *alias_command; +static char *alias_string = NULL; + +static int git_alias_config(const char *var, const char *value) +{ + if (!strncmp(var, "alias.", 6) && !strcmp(var + 6, alias_command)) { + alias_string = strdup(value); + } + return 0; +} + +static int split_cmdline(char *cmdline, const char ***argv) +{ + int src, dst, count = 0, size = 16; + char quoted = 0; + + *argv = malloc(sizeof(char*) * size); + + /* split alias_string */ + (*argv)[count++] = cmdline; + for (src = dst = 0; cmdline[src];) { + char c = cmdline[src]; + if (!quoted && isspace(c)) { + cmdline[dst++] = 0; + while (cmdline[++src] + && isspace(cmdline[src])) + ; /* skip */ + if (count >= size) { + size += 16; + *argv = realloc(*argv, sizeof(char*) * size); + } + (*argv)[count++] = cmdline + dst; + } else if(!quoted && (c == '\'' || c == '"')) { + quoted = c; + src++; + } else if (c == quoted) { + quoted = 0; + src++; + } else { + if (c == '\\' && quoted != '\'') { + src++; + c = cmdline[src]; + if (!c) { + free(*argv); + *argv = NULL; + return error("cmdline ends with \\"); + } + } + cmdline[dst++] = c; + src++; + } + } + + cmdline[dst] = 0; + + if (quoted) { + free(*argv); + *argv = NULL; + return error("unclosed quote"); + } + + return count; +} + +static int handle_alias(int *argcp, const char ***argv) +{ + int nongit = 0, ret = 0; + const char *subdir; + + subdir = setup_git_directory_gently(&nongit); + if (!nongit) { + int count; + const char** new_argv; + + alias_command = (*argv)[0]; + git_config(git_alias_config); + if (alias_string) { + + count = split_cmdline(alias_string, &new_argv); + + if (count < 1) + die("empty alias for %s", alias_command); + + if (!strcmp(alias_command, new_argv[0])) + die("recursive alias: %s", alias_command); + + /* insert after command name */ + if (*argcp > 1) { + new_argv = realloc(new_argv, sizeof(char*) * + (count + *argcp - 1)); + memcpy(new_argv + count, *argv, sizeof(char*) * + (*argcp - 1)); + } + + *argv = new_argv; + *argcp += count - 1; + + ret = 1; + } + } + + if (subdir) + chdir(subdir); + + return ret; +} + const char git_version_string[] = GIT_VERSION; static void handle_internal_command(int argc, const char **argv, char **envp) @@ -46,6 +154,31 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "log", cmd_log }, { "whatchanged", cmd_whatchanged }, { "show", cmd_show }, + { "push", cmd_push }, + { "format-patch", cmd_format_patch }, + { "count-objects", cmd_count_objects }, + { "diff", cmd_diff }, + { "grep", cmd_grep }, + { "rm", cmd_rm }, + { "add", cmd_add }, + { "rev-list", cmd_rev_list }, + { "init-db", cmd_init_db }, + { "tar-tree", cmd_tar_tree }, + { "upload-tar", cmd_upload_tar }, + { "check-ref-format", cmd_check_ref_format }, + { "ls-files", cmd_ls_files }, + { "ls-tree", cmd_ls_tree }, + { "tar-tree", cmd_tar_tree }, + { "read-tree", cmd_read_tree }, + { "commit-tree", cmd_commit_tree }, + { "apply", cmd_apply }, + { "show-branch", cmd_show_branch }, + { "diff-files", cmd_diff_files }, + { "diff-index", cmd_diff_index }, + { "diff-stages", cmd_diff_stages }, + { "diff-tree", cmd_diff_tree }, + { "cat-file", cmd_cat_file }, + { "rev-parse", cmd_rev_parse } }; int i; @@ -96,6 +229,7 @@ int main(int argc, const char **argv, char **envp) if (!strncmp(cmd, "git-", 4)) { cmd += 4; argv[0] = cmd; + handle_alias(&argc, &argv); handle_internal_command(argc, argv, envp); die("cannot handle %s internally", cmd); } @@ -153,6 +287,8 @@ int main(int argc, const char **argv, char **envp) exec_path = git_exec_path(); prepend_to_path(exec_path, strlen(exec_path)); + handle_alias(&argc, &argv); + /* See if it's an internal command */ handle_internal_command(argc, argv, envp);