{"thread":{"id":"4416","subject":"[PATCH] Support for configurable git command aliases (v3)","startedAt":"2006-06-07T00:16:38Z","lastAt":"2006-06-07T00:29:18Z","messageCount":3,"participants":["Petr Baudis","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"21361","messageId":"20060607001638.5175.77792.stgit@machine.or.cz","threadId":"4416","inReplyTo":null,"subject":"[PATCH] Support for configurable git command aliases (v3)","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-07T00:16:38Z","receivedAt":"2006-06-07T00:16:38Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"This patch adds support for configurable aliases for git commands -\n\"alias.WHATEVER = which ever\" will kick in when you do \"git WHATEVER\"\nand substitute WHATEVER with \"which ever\" (splitted to arguments at\nwhitespaces).\n\nThe second version does all the work in handle_aliases() which was\ninspired by Johannes Schindelin's patch.\n\nThe third version does not expand aliases when called as 'git-something'\nor when the $GIT_NO_ALIASES environment variable is set; that is now\ndone in git-sh-setup.sh. The documentation has been slightly expanded.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/config.txt |   12 +++++++++\n Documentation/git.txt    |    3 ++\n git-sh-setup.sh          |    2 +\n git.c                    |   64 ++++++++++++++++++++++++++++++++++++++++++++--\n 4 files changed, 78 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex c861c6c..071ff4e 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -91,6 +91,18 @@ core.warnAmbiguousRefs::\n \tIf true, git will warn you if the ref name you passed it is ambiguous\n \tand might match multiple refs in the .git/refs/ tree. True by default.\n \n+alias.*::\n+\tCommand aliases for the gitlink:git[1] command wrapper - e.g.\n+\tafter defining \"alias.last = cat-file commit HEAD\", the invocation\n+\t\"git last\" is equivalent to \"git cat-file commit HEAD\". You can\n+\toverride even existing command names with aliases (you can use that\n+\tto define some default set of parameters for some command). However,\n+\tthere is only a single level of alias expansion - the alias definition\n+\tis not searched for aliases anymore. Alias checking is disabled when\n+\tthe \"$GIT_NO_ALIASES\" environment variable is set - you should\n+\tdefinitely do that if you call commands by the 'git' wrapper in your\n+\tscripts.\n+\n apply.whitespace::\n \tTells `git-apply` how to handle whitespaces, in the same way\n \tas the '--whitespace' option. See gitlink:git-apply[1].\ndiff --git a/Documentation/git.txt b/Documentation/git.txt\nindex 24ca55d..e474bdf 100644\n--- a/Documentation/git.txt\n+++ b/Documentation/git.txt\n@@ -21,6 +21,9 @@ link:everyday.html[Everyday Git] for a u\n \"man git-commandname\" for documentation of each command.  CVS users may\n also want to read link:cvs-migration.html[CVS migration].\n \n+The COMMAND is either a name of a Git command (see below) or an alias\n+as defined in the configuration file (see gitlink:git-repo-config[1]).\n+\n OPTIONS\n -------\n --version::\ndiff --git a/git-sh-setup.sh b/git-sh-setup.sh\nindex d15747f..c56ae8c 100755\n--- a/git-sh-setup.sh\n+++ b/git-sh-setup.sh\n@@ -49,3 +49,5 @@ then\n else\n \tGIT_DIR=$(git-rev-parse --git-dir) || exit\n fi\n+\n+export GIT_NO_ALIASES=1\ndiff --git a/git.c b/git.c\nindex bc463c9..b85dafa 100644\n--- a/git.c\n+++ b/git.c\n@@ -10,6 +10,7 @@ #include <limits.h>\n #include <stdarg.h>\n #include \"git-compat-util.h\"\n #include \"exec_cmd.h\"\n+#include \"cache.h\" /* setup_git_directory_gently() */\n \n #include \"builtin.h\"\n \n@@ -88,13 +89,66 @@ static void handle_internal_command(int \n \t}\n }\n \n+static const char *cmd;\n+static char *cmdalias;\n+\n+int git_alias_config(const char *var, const char *value)\n+{\n+\tif (strncmp(var, \"alias.\", 6))\n+\t\treturn 0;\n+\tvar += /* strlen(\"alias.\") */ 6;\n+\tif (!strcmp(var, cmd))\n+\t\tcmdalias = strdup(value);\n+\treturn 0;\n+}\n+\n+void handle_alias(int *argc, const char ***argv)\n+{\n+\t/* XXX: We do a redundant git directory detection. */\n+\tint nongit = 0;\n+\tconst char *subdir;\n+\tchar *env = getenv(\"GIT_NO_ALIASES\");\n+\n+\tif (!env || !*env)\n+\t\treturn;\n+\n+\tsubdir = setup_git_directory_gently(&nongit);\n+\tif (!nongit) {\n+\t\tgit_config(git_alias_config);\n+\t\tif (cmdalias) {\n+\t\t\t/* More than the worst case: */\n+\t\t\tconst char **argv2 = malloc((strlen(cmdalias) + *argc) * sizeof(char*));\n+\t\t\tint argc2 = 0, i = 1;\n+\n+\t\t\twhile (cmdalias && *cmdalias) {\n+\t\t\t\targv2[argc2++] = strsep(&cmdalias, \" \\t\");\n+\t\t\t\tif (cmdalias)\n+\t\t\t\t\twhile (*cmdalias == ' ' || *cmdalias == '\\t')\n+\t\t\t\t\t\tcmdalias++;\n+\t\t\t}\n+\t\t\twhile (i < *argc) {\n+\t\t\t\targv2[argc2++] = (*argv)[i++];\n+\t\t\t}\n+\t\t\targv2[argc2] = NULL;\n+\t\t\t*argv = argv2;\n+\t\t\t*argc = argc2;\n+\t\t}\n+\t}\n+\n+\t/* Go back so that the commands start with clean table */\n+\tif (subdir)\n+\t\tchdir(subdir);\n+}\n+\n+\n int main(int argc, const char **argv, char **envp)\n {\n-\tconst char *cmd = argv[0];\n-\tchar *slash = strrchr(cmd, '/');\n+\tchar *slash = strrchr(argv[0], '/');\n \tchar git_command[PATH_MAX + 1];\n \tconst char *exec_path = NULL;\n \n+\tcmd = argv[0];\n+\n \t/*\n \t * Take the basename of argv[0] as the command\n \t * name, and the dirname as the default exec_path\n@@ -117,6 +171,10 @@ int main(int argc, const char **argv, ch\n \t *\n \t * So we just directly call the internal command handler, and\n \t * die if that one cannot handle it.\n+\t *\n+\t * We also do not evaluate aliases in this case since git-log\n+\t * should never expand to something unpredictable (that is\n+\t * important e.g. for scripts).\n \t */\n \tif (!strncmp(cmd, \"git-\", 4)) {\n \t\tcmd += 4;\n@@ -178,7 +236,7 @@ int main(int argc, const char **argv, ch\n \texec_path = git_exec_path();\n \tprepend_to_path(exec_path, strlen(exec_path));\n \n-\t/* See if it's an internal command */\n+\thandle_alias(&argc, &argv);\n \thandle_internal_command(argc, argv, envp);\n \n \t/* .. then try the external ones */\n"},{"id":"21362","messageId":"20060607002550.GB2609@pasky.or.cz","threadId":"4416","inReplyTo":"20060607001638.5175.77792.stgit@machine.or.cz","subject":"Re: [PATCH] Support for configurable git command aliases (v3)","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-06-07T00:25:50Z","receivedAt":"2006-06-07T00:25:50Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, Jun 07, 2006 at 02:16:38AM CEST, I got a letter\nwhere Petr Baudis <pasky@suse.cz> said that...\n> This patch adds support for configurable aliases for git commands -\n> \"alias.WHATEVER = which ever\" will kick in when you do \"git WHATEVER\"\n> and substitute WHATEVER with \"which ever\" (splitted to arguments at\n> whitespaces).\n> \n> The second version does all the work in handle_aliases() which was\n> inspired by Johannes Schindelin's patch.\n> \n> The third version does not expand aliases when called as 'git-something'\n> or when the $GIT_NO_ALIASES environment variable is set; that is now\n> done in git-sh-setup.sh. The documentation has been slightly expanded.\n> \n> Signed-off-by: Petr Baudis <pasky@suse.cz>\n\nSo, I chose the approach suggested by Linus, but I do not have a strong\npreference and if Junio still wants, we can rather just disallow aliases\nwith the same name as builtins - I just think that it *might* be\npractical to add some default options to the commands without relearning\nyour typing habits.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nA person is just about as big as the things that make them angry.\n"},{"id":"21363","messageId":"7vk67tn6zl.fsf@assigned-by-dhcp.cox.net","threadId":"4416","inReplyTo":"20060607001638.5175.77792.stgit@machine.or.cz","subject":"Re: [PATCH] Support for configurable git command aliases (v3)","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-06-07T00:29:18Z","receivedAt":"2006-06-07T00:29:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I've already swallowed Johannes's patch that also takes good\nparts from your patch (most importantly, the part to call\nsetup_git_directory_gently() so that things can work from a\nsubdirectory and still find the config) in \"next\", and I am\nhoping to push it out by end of (my) tomorrow.  So I'd\nappreciate any improvements (including docs perhaps) on top of\nthat instead.\n"}]}