If you have a config containing something like this:
[alias] l = "log --stat -M ORIG_HEAD.." you can call git l and it will do the same as git log --stat -M ORIG_HEAD.. Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Junio C Hamano <junkio@cox.net>maint
parent
441c823e89
commit
2b11e3170e
111
git.c
111
git.c
|
@ -10,6 +10,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "git-compat-util.h"
|
#include "git-compat-util.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
||||||
|
@ -32,6 +33,113 @@ static void prepend_to_path(const char *dir, int len)
|
||||||
setenv("PATH", path, 1);
|
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;
|
const char git_version_string[] = GIT_VERSION;
|
||||||
|
|
||||||
static void handle_internal_command(int argc, const char **argv, char **envp)
|
static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||||
|
@ -121,6 +229,7 @@ int main(int argc, const char **argv, char **envp)
|
||||||
if (!strncmp(cmd, "git-", 4)) {
|
if (!strncmp(cmd, "git-", 4)) {
|
||||||
cmd += 4;
|
cmd += 4;
|
||||||
argv[0] = cmd;
|
argv[0] = cmd;
|
||||||
|
handle_alias(&argc, &argv);
|
||||||
handle_internal_command(argc, argv, envp);
|
handle_internal_command(argc, argv, envp);
|
||||||
die("cannot handle %s internally", cmd);
|
die("cannot handle %s internally", cmd);
|
||||||
}
|
}
|
||||||
|
@ -178,6 +287,8 @@ int main(int argc, const char **argv, char **envp)
|
||||||
exec_path = git_exec_path();
|
exec_path = git_exec_path();
|
||||||
prepend_to_path(exec_path, strlen(exec_path));
|
prepend_to_path(exec_path, strlen(exec_path));
|
||||||
|
|
||||||
|
handle_alias(&argc, &argv);
|
||||||
|
|
||||||
/* See if it's an internal command */
|
/* See if it's an internal command */
|
||||||
handle_internal_command(argc, argv, envp);
|
handle_internal_command(argc, argv, envp);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue