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

[PATCH] Support for configurable git command aliases (v2)

From
Petr Baudis <pasky@suse.cz>
Date
Jun 4, 2006, 21:19 UTC
Message-ID
<20060604211931.10117.82695.stgit@machine.or.cz>

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).

The second version does all the work in handle_aliases() which was inspired by Johannes Schindelin's patch.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---
 Documentation/config.txt |    5 ++++
 Documentation/git.txt    |    3 ++
 git.c                    |   60 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index c861c6c..aaaa33d 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -91,6 +91,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 bc463c9..50850fb 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"
 
@@ -88,13 +89,65 @@ 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;
+}
+
+void handle_alias(int *argc, const char ***argv)
+{
+	/* XXX: We do a redundant git directory detection. */
+	int nongit = 0;
+	const char *subdir;
+
+	if (!isatty(1))
+		return;
+
+	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);
+}
+
+
 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
@@ -121,6 +174,7 @@ int main(int argc, const char **argv, ch
 	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);
 	}
@@ -178,7 +232,7 @@ int main(int argc, const char **argv, ch
 	exec_path = git_exec_path();
 	prepend_to_path(exec_path, strlen(exec_path));
 
-	/* See if it's an internal command */
+	handle_alias(&argc, &argv);
 	handle_internal_command(argc, argv, envp);
 
 	/* .. then try the external ones */
Next: Petr Baudis
Message 1 of 12 in “Support for configurable git command aliases (v2)”
  1. Support for configurable git command aliases (v2)Petr Baudis, Jun 4, 2006
  2. Petr BaudisJun 4, 2006
  3. Martin MaresJun 4, 2006
  4. Petr BaudisJun 4, 2006
  5. Junio C HamanoJun 4, 2006
  6. Linus TorvaldsJun 4, 2006
  7. "git --less cmd" to page anywhereJunio C Hamano, Jun 6, 2006
  8. Linus TorvaldsJun 7, 2006
  9. Petr BaudisJun 7, 2006
  10. Linus TorvaldsJun 7, 2006
  11. Martin LanghoffJun 7, 2006
  12. Linus TorvaldsJun 7, 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.