Re: [PATCH v4 2/7] git: allow alias-shadowing deprecated builtins

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 11, 2025 at 07:31:04PM +0200, Kristoffer Haugsbakk wrote:

> But it turns out there is a regression in my code with the recursion
> detection.  Compare:
> 
>     $ ./git -c alias.one=two -c alias.two=two one -h
>     'one' is aliased to 'two'
>     'two' is aliased to 'two'
>     fatal: recursive alias: two

Your example there is a little funny; "two" is recursive to itself, even
without "one". We detect that case in handle_alias(), and we would still
detect:

  git -c alias.whatchanged=whatchanged whatchanged -h

in the same spot. I assume what you meant was:

  $ ./git -c alias.one=two -c alias.two=one one -h
  'one' is aliased to 'two'
  'two' is aliased to 'one'
  fatal: alias loop detected: expansion of 'one' does not terminate:
    one <==
    two ==>

which is handled in the caller. And indeed...

>     $ ./git -c alias.whatchanged=pack-redundant -c alias.pack-redundant=whatchanged whatchanged -h
>     'whatchanged' is aliased to 'pack-redundant'
>     'pack-redundant' is aliased to 'whatchanged'
>     'whatchanged' is aliased to 'pack-redundant'
>     'pack-redundant' is aliased to 'whatchanged'
>     'whatchanged' is aliased to 'pack-redundant'
>     'pack-redundant' is aliased to 'whatchanged'
>     'whatchanged' is aliased to 'pack-redundant'
>     'pack-redundant' is aliased to 'whatchanged'
>     [forever]

...that cannot work with where we've placed the new conditional, because
it continues the loop before hitting the alias check. If we move that to
the top, like the patch below, it works.

It is a little funny to do it up front even when we're going to directly
run a builtin, but I don't think it harms much. OTOH I find the whole
placement a little odd in the first place. We are speculatively adding
to the cmd list before even finding out if we have an alias. It kind of
feels like this should be part of handle_alias() in the first place.
We'd need to pass in the cmd_list variable for it to add to and check.

-Peff

---
diff --git a/git.c b/git.c
index ca66e24639..17c566a802 100644
--- a/git.c
+++ b/git.c
@@ -814,6 +814,24 @@ static int run_argv(struct strvec *args)
 	struct string_list_item *seen;
 
 	while (1) {
+		seen = unsorted_string_list_lookup(&cmd_list, args->v[0]);
+		if (seen) {
+			struct strbuf sb = STRBUF_INIT;
+			for (size_t i = 0; i < cmd_list.nr; i++) {
+				struct string_list_item *item = &cmd_list.items[i];
+
+				strbuf_addf(&sb, "\n  %s", item->string);
+				if (item == seen)
+					strbuf_addstr(&sb, " <==");
+				else if (i == cmd_list.nr - 1)
+					strbuf_addstr(&sb, " ==>");
+			}
+			die(_("alias loop detected: expansion of '%s' does"
+			      " not terminate:%s"), cmd_list.items[0].string, sb.buf);
+		}
+
+		string_list_append(&cmd_list, args->v[0]);
+
 		/*
 		 * Allow deprecated commands to be overridden by aliases. This
 		 * creates a seamless path forward for people who want to keep
@@ -874,24 +892,6 @@ static int run_argv(struct strvec *args)
 		/* .. then try the external ones */
 		execv_dashed_external(args->v);
 
-		seen = unsorted_string_list_lookup(&cmd_list, args->v[0]);
-		if (seen) {
-			struct strbuf sb = STRBUF_INIT;
-			for (size_t i = 0; i < cmd_list.nr; i++) {
-				struct string_list_item *item = &cmd_list.items[i];
-
-				strbuf_addf(&sb, "\n  %s", item->string);
-				if (item == seen)
-					strbuf_addstr(&sb, " <==");
-				else if (i == cmd_list.nr - 1)
-					strbuf_addstr(&sb, " ==>");
-			}
-			die(_("alias loop detected: expansion of '%s' does"
-			      " not terminate:%s"), cmd_list.items[0].string, sb.buf);
-		}
-
-		string_list_append(&cmd_list, args->v[0]);
-
 		/*
 		 * It could be an alias -- this works around the insanity
 		 * of overriding "git log" with "git show" by having






[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux