git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] Support for configurable git command aliases

From
Petr Baudis <pasky@ucw.cz>
Date
May 28, 2006, 21:59 UTC
Message-ID
<20060528215945.GD10488@pasky.or.cz>
In-Reply-To
<200605271252.k4RCqZhR003192@laptop11.inf.utfsm.cl>

Dear diary, on Sat, May 27, 2006 at 02:52:35PM CEST, I got a letter where Horst von Brand <vonbrand@inf.utfsm.cl> said that...

Show 12 quoted lines
> > So they would do "alias cvs git" in a desperate attempt to save themselves 
> > from CVS, and then add
> > 
> > 	[alias "co"]
> > 		cmd = commit -a
> 
> I don't like this syntax. What other stuff (beside "cmd") would be under
> "[alias "co"]? Why not simply:
> 
>         [alias]
> 		co = commit -a
> 		publish = push public.site.com:/pub/scm/my-public-repo
Nice, I like this.

Well, the following isn't exactly the nicest code I have ever written... But it seems to work. ;-)

---

This patch adds support for configurable aliases for git commands - "alias.WHATEVER = which ever" will kick in when you do "git WHATEVER" and substitute WHATEVER with "which ever" (splitted to arguments at whitespaces).

Signed-off-by: Petr Baudis <pasky@suse.cz>
---
 Documentation/config.txt |    5 ++++
 Documentation/git.txt    |    3 +++
 git.c                    |   52 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index d1a4bec..ce616e3 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -83,6 +83,11 @@ core.warnAmbiguousRefs::
 	If true, git will warn you if the ref name you passed it is ambiguous
 	and might match multiple refs in the .git/refs/ tree. True by default.
 
+alias.*::
+	Command aliases for the gitlink:git[1] command wrapper - e.g.
+	after defining "alias.last = cat-file commit HEAD", the invocation
+	"git last" is equivalent to "git cat-file commit HEAD".
+
 apply.whitespace::
 	Tells `git-apply` how to handle whitespaces, in the same way
 	as the '--whitespace' option. See gitlink:git-apply[1].
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 24ca55d..e474bdf 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -21,6 +21,9 @@ link:everyday.html[Everyday Git] for a u
 "man git-commandname" for documentation of each command.  CVS users may
 also want to read link:cvs-migration.html[CVS migration].
 
+The COMMAND is either a name of a Git command (see below) or an alias
+as defined in the configuration file (see gitlink:git-repo-config[1]).
+
 OPTIONS
 -------
 --version::
diff --git a/git.c b/git.c
index 10ea934..0d9cd0e 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" /* setup_git_directory_gently() */
 
 #include "builtin.h"
 
@@ -87,13 +88,27 @@ static void handle_internal_command(int 
 	}
 }
 
+static const char *cmd;
+static char *cmdalias;
+
+int git_alias_config(const char *var, const char *value)
+{
+	if (strncmp(var, "alias.", 6))
+		return 0;
+	var += /* strlen("alias.") */ 6;
+	if (!strcmp(var, cmd))
+		cmdalias = strdup(value);
+	return 0;
+}
+
 int main(int argc, const char **argv, char **envp)
 {
-	const char *cmd = argv[0];
-	char *slash = strrchr(cmd, '/');
+	char *slash = strrchr(argv[0], '/');
 	char git_command[PATH_MAX + 1];
 	const char *exec_path = NULL;
 
+	cmd = argv[0];
+
 	/*
 	 * Take the basename of argv[0] as the command
 	 * name, and the dirname as the default exec_path
@@ -165,6 +180,39 @@ int main(int argc, const char **argv, ch
 	}
 	argv[0] = cmd;
 
+	/* Is this an alias? */
+	{
+		/* XXX: We do a redundant git directory detection. */
+		int nongit = 0;
+		const char *subdir = setup_git_directory_gently(&nongit);
+
+		if (!nongit) {
+			git_config(git_alias_config);
+			if (cmdalias) {
+				/* More than the worst case: */
+				const char **argv2 = malloc((strlen(cmdalias) + argc) * sizeof(char*));
+				int argc2 = 0, i = 1;
+
+				while (cmdalias && *cmdalias) {
+					argv2[argc2++] = strsep(&cmdalias, " \t");
+					if (cmdalias)
+						while (*cmdalias == ' ' || *cmdalias == '\t')
+							cmdalias++;
+				}
+				while (i < argc) {
+					argv2[argc2++] = argv[i++];
+				}
+				argv2[argc2] = NULL;
+				argv = argv2;
+				argc = argc2;
+			}
+		}
+
+		/* Go back so that the commands start with clean table */
+		if (subdir)
+			chdir(subdir);
+	}
+
 	/*
 	 * We search for git commands in the following order:
 	 *  - git_exec_path()
-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
Previous: Horst von BrandNext: Jakub Narebski
Message 12 of 19 in “Re: Trial git RPM's..”
  1. Horst von BrandJul 11, 2005
  2. Horst von BrandSep 16, 2005
  3. Horst von BrandSep 29, 2005
  4. Linus TorvaldsSep 30, 2005
  5. Junio C HamanoSep 30, 2005
  6. Linus TorvaldsSep 30, 2005
  7. Linus TorvaldsOct 1, 2005
  8. Horst von BrandOct 1, 2005
  9. Linus TorvaldsOct 3, 2005
  10. Horst von BrandNov 1, 2005
  11. Horst von BrandMay 27, 2006
  12. Support for configurable git command aliasesPetr Baudis, May 28, 2006
  13. Jakub NarebskiMay 28, 2006
  14. Jeff KingMay 29, 2006
  15. Junio C HamanoMay 29, 2006
  16. Petr BaudisMay 29, 2006
  17. Horst H. von BrandDec 2, 2006
  18. Sam VilainDec 2, 2006
  19. Linus TorvaldsDec 2, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.