alias: show the call history when an alias is looping
Just printing the command that the user entered is not particularly helpful when trying to find the alias that causes the loop. Print the history of substituted commands to help the user find the offending alias. Mark the entrypoint of the loop with "<==" and the last command (which looped back to the entrypoint) with "==>". Signed-off-by: Tim Schumacher <timschumi@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tim Schumacher committed
Sep 16, 2018 at 09:50 UTC
82f71d9a5a9df718553bf257ad8610e2ef1e1179
1 file changed
+15
-2
git.c
+15
-2
@@ -675,6 +675,7 @@ static int run_argv(int *argcp, const char ***argv)
675
{
676
int done_alias = 0;
677
struct string_list cmd_list = STRING_LIST_INIT_NODUP;
678
+ struct string_list_item *seen;
679
680
while (1) {
681
/*
@@ -692,9 +693,21 @@ static int run_argv(int *argcp, const char ***argv)
693
/* .. then try the external ones */
694
execv_dashed_external(*argv);
695
695
- if (unsorted_string_list_has_string(&cmd_list, *argv[0])) {
696
+ seen = unsorted_string_list_lookup(&cmd_list, *argv[0]);
697
+ if (seen) {
698
+ int i;
699
+ struct strbuf sb = STRBUF_INIT;
700
+ for (i = 0; i < cmd_list.nr; i++) {
701
+ struct string_list_item *item = &cmd_list.items[i];
702
+
703
+ strbuf_addf(&sb, "\n %s", item->string);
704
+ if (item == seen)
705
+ strbuf_addstr(&sb, " <==");
706
+ else if (i == cmd_list.nr - 1)
707
+ strbuf_addstr(&sb, " ==>");
708
+ }
709
die(_("alias loop detected: expansion of '%s' does"
697
- " not terminate"), cmd_list.items[0].string);
710
+ " not terminate:%s"), cmd_list.items[0].string, sb.buf);
711
}
712
713
string_list_append(&cmd_list, *argv[0]);