[PATCH] git: handle aliases defined in $GIT_DIR/config
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..
This also works with hard links.
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
For me, short cuts have to be easy to type, so they never
include digits, and they are never case sensitive, so I do not
need any fancy config stuff...
git.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/git.c b/git.c
index bc463c9..846062f 100644
--- a/git.c
+++ b/git.c
@@ -10,6 +10,7 @@ #include <limits.h>
#include <stdarg.h>
#include "git-compat-util.h"
#include "exec_cmd.h"
+#include "cache.h"
#include "builtin.h"
@@ -32,6 +33,60 @@ static void prepend_to_path(const char *
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;
+}
+
+#define MAX_ALIAS_ARGS 32
+
+static int handle_alias(int *argcp, const char **argv, char **envp)
+{
+ int i, i2, j = 0;
+ char *new_argv[MAX_ALIAS_ARGS];
+
+ alias_command = argv[0];
+ git_config(git_alias_config);
+ if (!alias_string)
+ return 0;
+
+ /* split alias_string */
+ new_argv[j++] = alias_string;
+ for (i = i2 = 0; alias_string[i]; i++, i2++) {
+ if (isspace(alias_string[i])) {
+ alias_string[i2] = 0;
+ while (alias_string[++i] && isspace(alias_string[i]));
+ new_argv[j++] = alias_string + i;
+ i2 = i;
+ if (j >= MAX_ALIAS_ARGS)
+ die("too many args in alias %s",
+ alias_command);
+ } else {
+ if (alias_string[i] == '\\')
+ i++;
+ if (i != i2)
+ alias_string[i2] = alias_string[i];
+ }
+ }
+
+ if (j < 1)
+ die("empty alias: %s", alias_command);
+
+ /* insert after command name */
+ if (j > 1)
+ memmove(argv + j, argv + 1, (*argcp - 1) * sizeof(char*));
+ memcpy(argv, new_argv, j * sizeof(char*));
+ *argcp += j - 1;
+
+ return 1;
+}
+
const char git_version_string[] = GIT_VERSION;
static void handle_internal_command(int argc, const char **argv, char **envp)
@@ -121,6 +176,7 @@ int main(int argc, const char **argv, ch
if (!strncmp(cmd, "git-", 4)) {
cmd += 4;
argv[0] = cmd;
+ handle_alias(&argc, argv, envp);
handle_internal_command(argc, argv, envp);
die("cannot handle %s internally", cmd);
}
@@ -178,6 +234,8 @@ int main(int argc, const char **argv, ch
exec_path = git_exec_path();
prepend_to_path(exec_path, strlen(exec_path));
+ handle_alias(&argc, argv, envp);
+
/* See if it's an internal command */
handle_internal_command(argc, argv, envp);
--
1.3.3.ga182-dirty