after defining `alias.last = cat-file commit HEAD`, the invocation
`git last` is equivalent to `git cat-file commit HEAD`. To avoid
confusion and troubles with script usage, aliases that
- hide existing Git commands are ignored. Arguments are split by
+ hide existing Git commands are ignored except for deprecated
+ commands. Arguments are split by
spaces, the usual shell quoting and escaping are supported.
A quote pair or a backslash can be used to quote them.
+
exit(128);
}
+static int is_deprecated_command(const char *cmd)
+{
+ struct cmd_struct *builtin = get_builtin(cmd);
+ return builtin && (builtin->option & DEPRECATED);
+}
+
static int run_argv(struct strvec *args)
{
int done_alias = 0;
struct string_list expanded_aliases = STRING_LIST_INIT_DUP;
while (1) {
+ /*
+ * Allow deprecated commands to be overridden by aliases. This
+ * creates a seamless path forward for people who want to keep
+ * using the name after it is gone, but want to skip the
+ * deprecation complaint in the meantime.
+ */
+ if (is_deprecated_command(args->v[0]) &&
+ handle_alias(args, &expanded_aliases)) {
+ done_alias = 1;
+ continue;
+ }
/*
* If we tried alias and futzed with our environment,
* it no longer is safe to invoke builtins directly in
test_grep "^fatal: alias loop detected: expansion of" output
'
+test_expect_success 'looping aliases - deprecated builtins' '
+ test_config alias.whatchanged pack-redundant &&
+ test_config alias.pack-redundant whatchanged &&
+ cat >expect <<-EOF &&
+ ${SQ}whatchanged${SQ} is aliased to ${SQ}pack-redundant${SQ}
+ ${SQ}pack-redundant${SQ} is aliased to ${SQ}whatchanged${SQ}
+ fatal: alias loop detected: expansion of ${SQ}whatchanged${SQ} does not terminate:
+ whatchanged <==
+ pack-redundant ==>
+ EOF
+ test_must_fail git whatchanged -h 2>actual &&
+ test_cmp expect actual
+'
+
# This test is disabled until external loops are fixed, because would block
# the test suite for a full minute.
#
test_cmp expect actual
'
+can_alias_deprecated_builtin () {
+ cmd="$1" &&
+ # some git(1) commands will fail for `-h` (the case for
+ # git-status as of 2025-09-07)
+ test_might_fail git status -h >expect &&
+ test_file_not_empty expect &&
+ test_might_fail git -c alias."$cmd"=status "$cmd" -h >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'can alias-shadow deprecated builtins' '
+ for cmd in $(git --list-cmds=deprecated)
+ do
+ can_alias_deprecated_builtin "$cmd" || return 1
+ done
+'
+
+test_expect_success 'can alias-shadow via two deprecated builtins' '
+ # some git(1) commands will fail... (see above)
+ test_might_fail git status -h >expect &&
+ test_file_not_empty expect &&
+ test_might_fail git -c alias.whatchanged=pack-redundant \
+ -c alias.pack-redundant=status whatchanged -h >actual &&
+ test_cmp expect actual
+'
+
test_done