Bug: Hierarchical Aliases no longer work in 2.54.0
18 messages between Apr 23, 2026 and May 19, 2026, from Grossfeld, Michael, Jeff King, René Scharfe, Michael Grossfeld, Jonatan Holmgren, Kristoffer Haugsbakk, Junio C Hamano.
Plain Markdown or JSON for tools and agents.
Grossfeld, MichaelApr 23, 2026, 18:19 UTC on loreHello all! Seeing this issue on 2.54.0 and it didn't look like anyone had reported it yet.
> What did you do before the bug happened? (Steps to reproduce your issue)
Attempting to use the hierarchical alias "pull.sub", which was working in 2.53.0, is no longer working in 2.54.0. It returns the following error: "git: 'pull.sub' is not a git command. See 'git --help'."
> What did you expect to happen? (Expected behavior)
The git alias should have firsted pulled, then updated submodules recursively.
> What happened instead? (Actual behavior)
It reports the following error: "git: 'pull.sub' is not a git command. See 'git --help'."
> What's different between what you expected and what actually happened?
git 2.53.0 to git 2.54.0.
> Anything else you want to add:
The alias was defined in my gitconfig as in 2.53.0, and remains this way:
[alias "pull"]
sub = "!f() { git pull origin --recurse-submodules=no --ff-only; echo Updating Submodules...; git submodule update --recursive --jobs=16 --progress; }; f"It was written via this command:
git config --global alias.pull.sub '!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f'Trying to do the following (with .command):
git config --global alias.pull.sub.command '!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f'Results in a section of the gitconfig that looks like this:
[alias "pull.sub"]
command = "!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f"[System Info]
git version:
git version 2.54.0.windows.1
cpu: x86_64
built from commit: 2b8a3ab140826ac423c2845ef81d4c6ac4f7bf3c
sizeof-long: 4
sizeof-size_t: 8
shell-path: D:/git-sdk-64-build-installers/usr/bin/sh
rust: disabled
feature: fsmonitor--daemon
gettext: enabled
libcurl: 8.19.0
OpenSSL: OpenSSL 3.5.6 7 Apr 2026
zlib: 1.3.2
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1
uname: Windows 10.0 26200
compiler info: gnuc: 15.2
libc info: no libc information available
$SHELL (typically, interactive shell): D:\develop\tools\Git\usr\bin\bash.exe
Thanks for the help!
Michael Grossfeld AMD
Re: Bug: Hierarchical Aliases no longer work in 2.54.0
On Thu, Apr 23, 2026 at 06:19:42PM +0000, Grossfeld, Michael wrote:
> Hello all! Seeing this issue on 2.54.0 and it didn't look like anyone had reported it yet.
Thanks for the report. I think you're the first.
Show 6 quoted lines
> > What did you do before the bug happened? (Steps to reproduce your issue)
>
> Attempting to use the hierarchical alias "pull.sub", which was working
> in 2.53.0, is no longer working in 2.54.0.
> It returns the following error: "git: 'pull.sub' is not a git command.
> See 'git --help'."
Here's a shorter reproduction recipe:
git -c alias.foo.bar='!echo ok' foo.bar
With v2.53 it produces "ok", and in v2.54 you get:
git: 'foo.bar' is not a git command. See 'git --help'.
This is due to the introduction of the three-level alias syntax in ac1f12a9de (alias: support non-alphanumeric names via subsection syntax, 2026-02-18). We now allow "git foo" to expand based on both alias.foo and alias.foo.command, the latter of which allows more flexible syntax.
But now we think you are trying to set the "sub" key of the "pull" alias, which is obviously nonsense. I don't think three-level config like this was ever a planned feature in the original alias expansion, but it did indeed work. So I think this is a regression worth fixing.
In the short-term, you can work around it by using the new syntax:
[alias "pull.sub"]
command = ...whatever...
And I think we'd want a fix something like this:
diff --git a/alias.c b/alias.c
index ec9833dd30..58f21ac6ba 100644
--- a/alias.c
+++ b/alias.c
@@ -34,8 +34,20 @@ static int config_alias_cb(const char *var, const char *value,
if (subsection && !subsection_len)
subsection = NULL;
- if (subsection && strcmp(key, "command"))
- return 0;
+ if (subsection && strcmp(key, "command")) {
+ /*
+ * We have historically support the "alias.name" form when
+ * "name" happens to contain dots (e.g., alias.foo.bar to allow
+ * "git foo.bar". But our parsing above would split that into
+ * subsection "foo".
+ *
+ * If we do not understand the final key in a subsection-style
+ * variable, fall back to treating it as a two-level alias.
+ */
+ key = subsection;
+ subsection = NULL;
+ subsection_len = 0;
+ }
if (data->alias) {
int match;
That does still break a historical alias if you happened to call it
"foo.command". I'm not sure if we want to try to be even more thorough
and fall back on that case, or if we're getting now into unlikely
hypotheticals.
-Peff
Re: Bug: Hierarchical Aliases no longer work in 2.54.0
On 4/23/26 8:19 PM, Grossfeld, Michael wrote:
Show 24 quoted lines
> Hello all! Seeing this issue on 2.54.0 and it didn't look like anyone had reported it yet.
>
>> What did you do before the bug happened? (Steps to reproduce your issue)
>
> Attempting to use the hierarchical alias "pull.sub", which was working in 2.53.0, is no longer working in 2.54.0.
> It returns the following error: "git: 'pull.sub' is not a git command. See 'git --help'."
> >> What did you expect to happen? (Expected behavior)
>
> The git alias should have firsted pulled, then updated submodules recursively.
>
>> What happened instead? (Actual behavior)
>
> It reports the following error: "git: 'pull.sub' is not a git command. See 'git --help'."
>
>> What's different between what you expected and what actually happened?
>
> git 2.53.0 to git 2.54.0.
>
>> Anything else you want to add:
>
> The alias was defined in my gitconfig as in 2.53.0, and remains this way:
>
> [alias "pull"]
> sub = "!f() { git pull origin --recurse-submodules=no --ff-only; echo Updating Submodules...; git submodule update --recursive --jobs=16 --progress; }; f"Broken by ac1f12a9de4 (alias: support non-alphanumeric names via subsection syntax, 2026-02-18).
Alias sections were not documented before. How did you discover them?
I think the previous behavior can be brought back while keeping the new feature, except for aliases that end in ".command".
Show 10 quoted lines
> It was written via this command:
> git config --global alias.pull.sub '!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f'
>
> Trying to do the following (with .command):
> git config --global alias.pull.sub.command '!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f'
>
> Results in a section of the gitconfig that looks like this:
>
> [alias "pull.sub"]
> command = "!f() { git pull origin --recurse-submodules=no --ff-only -p; echo Updating Submodules...; git submodule update --recursive --jobs=16; }; f"Show 27 quoted lines
> [System Info]
> git version:
> git version 2.54.0.windows.1
> cpu: x86_64
> built from commit: 2b8a3ab140826ac423c2845ef81d4c6ac4f7bf3c
> sizeof-long: 4
> sizeof-size_t: 8
> shell-path: D:/git-sdk-64-build-installers/usr/bin/sh
> rust: disabled
> feature: fsmonitor--daemon
> gettext: enabled
> libcurl: 8.19.0
> OpenSSL: OpenSSL 3.5.6 7 Apr 2026
> zlib: 1.3.2
> SHA-1: SHA1_DC
> SHA-256: SHA256_BLK
> default-ref-format: files
> default-hash: sha1
> uname: Windows 10.0 26200
> compiler info: gnuc: 15.2
> libc info: no libc information available
> $SHELL (typically, interactive shell): D:\develop\tools\Git\usr\bin\bash.exe
>
> Thanks for the help!
>
> Michael Grossfeld
> AMD
Re: Bug: Hierarchical Aliases no longer work in 2.54.0
> Broken by ac1f12a9de4 (alias: support non-alphanumeric names via
> subsection syntax, 2026-02-18).
> Alias sections were not documented before. How did you discover them?
Sheer dumb luck. I gravitated to it rather than a dash/hyphen based approach when I was creating aliases for my team.
> I think the previous behavior can be brought back while keeping the
> new feature, except for aliases that end in ".command".
> Which works, right?
Yes, doing 'alias.pull.sub.command' works, but for the users on my team that have the old aliases, they are crashing.
Re: Bug: Hierarchical Aliases no longer work in 2.54.0
> In the short-term, you can work around it by using the new syntax:
>
> [alias "pull.sub"]
> command = ...whatever...
Sounds good. I'll likely write a script for my team to convert their existing aliases depending on their git version.
> That does still break a historical alias if you happened to call it
> "foo.command". I'm not sure if we want to try to be even more thorough
> and fall back on that case, or if we're getting now into unlikely
> hypotheticals.
For my purposes, this would be fine and work for me. As the hierarchical aliases are already unlikely, I imagine "foo.command" existing is even more unlikely.
Re: Bug: Hierarchical Aliases no longer work in 2.54.0
That's a curious bug, sorry to hear I broke you/your team's workflow. Yes, three-level aliases were previously accidentally supported, now explicitly but with a new syntax (this was to support non-ascii characters). I'll send a patch fixing this but a release cycle will indeed take time.
Thanks!
[PATCH] alias: restore support for simple dotted aliases
Historically, config entries like alias.foo.bar expanded the alias "foo.bar". The subsection-based alias syntax introduced in ac1f12a9de (alias: support non-alphanumeric names via subsection syntax, 2026-02-18) broke that behavior by treating such entries as if they were subsection syntax.
Restore support for the old dotted form by falling back to the full name when the final key is not "command". Add tests covering execution and help output for simple dotted aliases.
Reported-by: Michael Grossfeld <michael.grossfeld@amd.com>
Helped-by: Jeff King <peff@peff.net>
---
alias.c | 16 ++++++++++++++--
help.c | 9 ++++++++-
t/t0014-alias.sh | 12 ++++++++++++
3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/alias.c b/alias.c
index ec9833dd30..e737c49edd 100644
--- a/alias.c
+++ b/alias.c
@@ -34,8 +34,20 @@ static int config_alias_cb(const char *var, const char *value,
if (subsection && !subsection_len)
subsection = NULL;
- if (subsection && strcmp(key, "command"))
- return 0;
+ if (subsection && strcmp(key, "command")) {
+ /*
+ * We have historically supported the "alias.name" form when
+ * "name" happens to contain dots (e.g., alias.foo.bar to allow
+ * "git foo.bar". But our parsing above would split that into
+ * subsection "foo".
+ *
+ * If we do not understand the final key in a subsection-style
+ * variable, fall back to treating it as a two-level alias.
+ */
+ key = var + strlen("alias.");
+ subsection = NULL;
+ subsection_len = 0;
+ }
if (data->alias) {
int match;
diff --git a/help.c b/help.c
index 3e59d07c37..46241492ce 100644
--- a/help.c
+++ b/help.c
@@ -592,14 +592,21 @@ static int git_unknown_cmd_config(const char *var, const char *value,
/* Also use aliases for command lookup */
if (!parse_config_key(var, "alias", &subsection, &subsection_len,
&key)) {
+ size_t key_len = strlen(key);
+
if (subsection) {
/* [alias "name"] command = value */
if (!strcmp(key, "command"))
add_cmdname(&cfg->aliases, subsection,
subsection_len);
+ else {
+ key = var + strlen("alias.");
+ key_len = strlen(key);
+ add_cmdname(&cfg->aliases, key, key_len);
+ }
} else {
/* alias.name = value */
- add_cmdname(&cfg->aliases, key, strlen(key));
+ add_cmdname(&cfg->aliases, key, key_len);
}
}
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index 68b4903cbf..5144b0effd 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -128,6 +128,12 @@ test_expect_success 'subsection syntax works' '
test_grep "ran-subsection" output
'
+test_expect_success 'simple dotted alias syntax still works' '
+ test_config alias.simple.dotted "!echo ran-simple-dotted" &&
+ git simple.dotted >output &&
+ test_grep "ran-simple-dotted" output
+'
+
test_expect_success 'subsection syntax only accepts command key' '
test_config alias.invalid.notcommand value &&
test_must_fail git invalid 2>error &&
@@ -183,6 +189,12 @@ test_expect_success 'subsection aliases listed in help -a' '
test_grep "förgrena" output
'
+test_expect_success 'simple dotted aliases listed in help -a' '
+ test_config alias.simple.listed "!echo test" &&
+ git help -a >output &&
+ test_grep "simple.listed" output
+'
+
test_expect_success 'empty subsection treated as no subsection' '
test_config "alias..something" "!echo foobar" &&
git something >actual &&
--
2.54.0
Re: [PATCH] alias: restore support for simple dotted aliases
On Fri, Apr 24, 2026, at 17:10, Jonatan Holmgren wrote:
Show 12 quoted lines
> Historically, config entries like alias.foo.bar expanded the alias
> "foo.bar". The subsection-based alias syntax introduced in
> ac1f12a9de (alias: support non-alphanumeric names via subsection
> syntax, 2026-02-18) broke that behavior by treating such entries as
> if they were subsection syntax.
>
> Restore support for the old dotted form by falling back to the full
> name when the final key is not "command". Add tests covering execution
> and help output for simple dotted aliases.
>
> Reported-by: Michael Grossfeld <michael.grossfeld@amd.com>
> Helped-by: Jeff King <peff@peff.net>
> ---
>[snip]
[PATCH] alias: restore support for simple dotted aliases
Historically, config entries like alias.foo.bar expanded the alias "foo.bar". The subsection-based alias syntax introduced in ac1f12a9de (alias: support non-alphanumeric names via subsection syntax, 2026-02-18) broke that behavior by treating such entries as if they were subsection syntax.
Restore support for the old dotted form by falling back to the full name when the final key is not "command". Add tests covering execution and help output for simple dotted aliases.
Reported-by: Michael Grossfeld <michael.grossfeld@amd.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
---
alias.c | 16 ++++++++++++++--
help.c | 9 ++++++++-
t/t0014-alias.sh | 12 ++++++++++++
3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/alias.c b/alias.c
index ec9833dd30..e737c49edd 100644
--- a/alias.c
+++ b/alias.c
@@ -34,8 +34,20 @@ static int config_alias_cb(const char *var, const char *value,
if (subsection && !subsection_len)
subsection = NULL;
- if (subsection && strcmp(key, "command"))
- return 0;
+ if (subsection && strcmp(key, "command")) {
+ /*
+ * We have historically supported the "alias.name" form when
+ * "name" happens to contain dots (e.g., alias.foo.bar to allow
+ * "git foo.bar". But our parsing above would split that into
+ * subsection "foo".
+ *
+ * If we do not understand the final key in a subsection-style
+ * variable, fall back to treating it as a two-level alias.
+ */
+ key = var + strlen("alias.");
+ subsection = NULL;
+ subsection_len = 0;
+ }
if (data->alias) {
int match;
diff --git a/help.c b/help.c
index 3e59d07c37..46241492ce 100644
--- a/help.c
+++ b/help.c
@@ -592,14 +592,21 @@ static int git_unknown_cmd_config(const char *var, const char *value,
/* Also use aliases for command lookup */
if (!parse_config_key(var, "alias", &subsection, &subsection_len,
&key)) {
+ size_t key_len = strlen(key);
+
if (subsection) {
/* [alias "name"] command = value */
if (!strcmp(key, "command"))
add_cmdname(&cfg->aliases, subsection,
subsection_len);
+ else {
+ key = var + strlen("alias.");
+ key_len = strlen(key);
+ add_cmdname(&cfg->aliases, key, key_len);
+ }
} else {
/* alias.name = value */
- add_cmdname(&cfg->aliases, key, strlen(key));
+ add_cmdname(&cfg->aliases, key, key_len);
}
}
diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh
index 68b4903cbf..5144b0effd 100755
--- a/t/t0014-alias.sh
+++ b/t/t0014-alias.sh
@@ -128,6 +128,12 @@ test_expect_success 'subsection syntax works' '
test_grep "ran-subsection" output
'
+test_expect_success 'simple dotted alias syntax still works' '
+ test_config alias.simple.dotted "!echo ran-simple-dotted" &&
+ git simple.dotted >output &&
+ test_grep "ran-simple-dotted" output
+'
+
test_expect_success 'subsection syntax only accepts command key' '
test_config alias.invalid.notcommand value &&
test_must_fail git invalid 2>error &&
@@ -183,6 +189,12 @@ test_expect_success 'subsection aliases listed in help -a' '
test_grep "förgrena" output
'
+test_expect_success 'simple dotted aliases listed in help -a' '
+ test_config alias.simple.listed "!echo test" &&
+ git help -a >output &&
+ test_grep "simple.listed" output
+'
+
test_expect_success 'empty subsection treated as no subsection' '
test_config "alias..something" "!echo foobar" &&
git something >actual &&
--
2.54.0
Re: [PATCH] alias: restore support for simple dotted aliases
Jonatan Holmgren <jonatan@jontes.page> writes:
Show 17 quoted lines
> Historically, config entries like alias.foo.bar expanded the alias
> "foo.bar". The subsection-based alias syntax introduced in
> ac1f12a9de (alias: support non-alphanumeric names via subsection
> syntax, 2026-02-18) broke that behavior by treating such entries as
> if they were subsection syntax.
>
> Restore support for the old dotted form by falling back to the full
> name when the final key is not "command". Add tests covering execution
> and help output for simple dotted aliases.
>
> Reported-by: Michael Grossfeld <michael.grossfeld@amd.com>
> Helped-by: Jeff King <peff@peff.net>
> ---
> alias.c | 16 ++++++++++++++--
> help.c | 9 ++++++++-
> t/t0014-alias.sh | 12 ++++++++++++
> 3 files changed, 34 insertions(+), 3 deletions(-)
Do we lose the extensibility introduced by the new syntax by going this route, though? I would imagine that
[alias "frotz"]
command = !"nitfol"
help = "run nitfol command"
would have been a natural first addition to the current system to give help text to the alias, but this change makes such an extensibility impossible, doesn't it?
If this change robs the extensibility, it makes mse wonder if the three-level "alias" was a mistake, and we should have instead introduced a new "nalias" that is three level from the get go.
Re: [PATCH] alias: restore support for simple dotted aliases
That is a challenge we are going to have to consider. I think reserving `command` is a worthwhile compromise, but obviously we cannot do that for arbitrary future keys such as `help`, `hidden`, etc.
One possible compromise would be to reserve `command` and `alias-*`, as neither seems very likely to exist in users' historical alias names.
A new namespace makes the most sense from a namespace-pollution point of view, but I struggle to see that as good UX. Even a separate namespace only for alias metadata would make more sense to me than moving aliases entirely, since subsection aliases with just `command` will likely be far more common than any future metadata keys, but this is not something I see as a good solution either.
Re: [PATCH] alias: restore support for simple dotted aliases
On Sat, Apr 25, 2026 at 11:57:24AM +0200, Jonatan Holmgren wrote:
> That is a challenge we are going to have to consider. I think reserving
> `command` is a worthwhile compromise, but obviously we cannot do that for
> arbitrary future keys such as `help`, `hidden`, etc.
We don't necessarily have to reserve them. When we see alias.foo.bar, we could consider it as both alias "foo.bar" and the "bar" key of alias "foo", without regard to what is in "bar" (i.e., whether it is "command" or "help", etc). I.e., don't "fall back" but allow two overlapping namespace.s
That is the most backwards-compatible thing we could do, but does create some interesting situations.
If you define alias.foo.command with the intent to allow "git foo", that is also creating the identical alias "git foo.command". Probably nobody cares too much, as if you did not mean to make "foo.command" you would never invoke it. We'd probably want to omit it when listing aliases, though.
If we later introduce alias.foo.help, the same thing applies but with a twist. Running "git foo.help" will invoke that key as an alias command, but it is probably not a sensible command in the first place. But again, I'm not sure why anybody would try to do so.
That said, I don't think reserving "command" or even some future names is that painful in the long run. The three-level syntax is a superset of the old functionality, and in general the best solution will be for users to convert their old aliases to it. The benefits of providing the fallback compatibility are:
1. Users can avoid having to do anything at all. And that will still
be true for the majority, unless they happen to have a three-level
alias that ends with ".command" (for now) or eventually ".help",
etc. We don't have any hard data, but I have to imagine that the
numbers here are vanishingly small. 2. Cross-version compatibility. You can't use alias.pull.sub.command
in Git v2.53 and older, so it's otherwise impossible to have config
that works both there and with v2.54. But as time goes on, wanting to cross that version boundary becomes
less and less likely. If we we eventually introduce ".help" and it
breaks somebody foo.help alias, suggesting alias.foo.help.command
will work all the way back to Git v2.54, which may be sufficient.Show 9 quoted lines
> One possible compromise would be to reserve `command` and `alias-*`, as
> neither seems very likely to exist in users' historical alias names.
>
> A new namespace makes the most sense from a namespace-pollution point of
> view, but I struggle to see that as good UX. Even a separate namespace
> only for alias metadata would make more sense to me than moving aliases
> entirely, since subsection aliases with just `command` will likely be far
> more common than any future metadata keys, but this is not something I see
> as a good solution either.
Yeah. Obviously a totally separate namespace makes all of this go away, but it feels like we are sacrificing the experience going forward in order to accommodate some fairly unlikely historical clashes.
-Peff
Re: [PATCH] alias: restore support for simple dotted aliases
On Sat, Apr 25, 2026 at 07:29:16PM -0400, Jeff King wrote:
Show 14 quoted lines
> On Sat, Apr 25, 2026 at 11:57:24AM +0200, Jonatan Holmgren wrote:
>
> > That is a challenge we are going to have to consider. I think reserving
> > `command` is a worthwhile compromise, but obviously we cannot do that for
> > arbitrary future keys such as `help`, `hidden`, etc.
>
> We don't necessarily have to reserve them. When we see alias.foo.bar, we
> could consider it as both alias "foo.bar" and the "bar" key of alias
> "foo", without regard to what is in "bar" (i.e., whether it is "command"
> or "help", etc). I.e., don't "fall back" but allow two overlapping
> namespace.s
>
> That is the most backwards-compatible thing we could do, but does create
> some interesting situations.
For reference, I mean something like this:
diff --git a/alias.c b/alias.c
index ec9833dd30..07c6bd3645 100644
--- a/alias.c
+++ b/alias.c
@@ -34,16 +34,20 @@ static int config_alias_cb(const char *var, const char *value,
if (subsection && !subsection_len)
subsection = NULL;
- if (subsection && strcmp(key, "command"))
- return 0;
-
if (data->alias) {
int match;
if (subsection)
- match = (strlen(data->alias) == subsection_len &&
- !strncmp(data->alias, subsection,
- subsection_len));
+ /*
+ * alias.foo.command always matches "foo", but for
+ * historical compatibility also match alias.foo.bar as
+ * "foo.bar", even when "bar" is "command" or any other
+ * key we happen to know about.
+ */
+ match = (!strcmp(key, "command") &&
+ strlen(data->alias) == subsection_len &&
+ !strncmp(data->alias, subsection, subsection_len))
+ || !strcmp(data->alias, subsection);
else
match = !strcasecmp(data->alias, key);
@@ -59,8 +63,23 @@ static int config_alias_cb(const char *var, const char *value,
return config_error_nonbool(var);
if (subsection)
+ /*
+ * If it's not alias.foo.command, then either it's a
+ * historical alias (git "foo.bar"), or it's some
+ * metadata not support yet by this version
+ * ("alias.foo.help" or similar).
+ *
+ * We'll guess it's the former and include the whole
+ * "foo.bar" in the list.
+ *
+ * We might want to suppress duplicates when we see both
+ * alias.foo.command and alias.foo.help, since that's
+ * what a hypothetical future version might understand.
+ */
item = string_list_append_nodup(data->list,
- xmemdupz(subsection, subsection_len));
+ !strcmp(key, "command")
+ ? xmemdupz(subsection, subsection_len)
+ : xstrdup(subsection));
else
item = string_list_append(data->list, key);
item->util = xstrdup(value);
-Peff
Re: [PATCH] alias: restore support for simple dotted aliases
I see the appeal of the overlapping-namespace approach for maximum compat.
My hesitation is that it introduces a config model where a single key (`alias.foo.bar`) no longer has a clear interpretation, but instead is implicitly treated as both a historical alias and structured data. That feels harder to reason about and document.
For the regression, I would lean toward a narrower compatibility rule: restore dotted aliases except where they collide with explicitly recognized structured keys (currently `command`). That keeps behavior predictable while still fixing the breakage.
If we want to grow metadata in the future, it might be better to make that expansion explicit at that point rather than baking in ambiguity now.
I think the worst outcome from this thread would be moving the new alias syntax into a different namespace entirely (e.g., `nalias`). If namespace cleanliness is the priority, reserving `command` and `alias-*` still seems like the best path forward to me.
One question: do we consider the historical dotted aliases something we want to preserve indefinitely, or just something to transition away from? My assumption has been that they were an accidental side-effect of the config parsing rather than a designed feature, but I agree they are now part of existing workflows and need to be handled carefully.
Re: [PATCH] alias: restore support for simple dotted aliases
On Sun, Apr 26, 2026 at 09:21:52PM +0200, Jonatan Holmgren wrote:
Show 11 quoted lines
> I see the appeal of the overlapping-namespace approach for maximum compat.
>
> My hesitation is that it introduces a config model where a single key
> (`alias.foo.bar`) no longer has a clear interpretation, but instead is
> implicitly treated as both a historical alias and structured data. That
> feels harder to reason about and document.
>
> For the regression, I would lean toward a narrower compatibility rule:
> restore dotted aliases except where they collide with explicitly
> recognized structured keys (currently `command`). That keeps behavior
> predictable while still fixing the breakage.
Yeah, I agree with you here (and the rest of this email). My earlier message was mostly about laying out the possible alternatives.
Show 5 quoted lines
> One question: do we consider the historical dotted aliases something we
> want to preserve indefinitely, or just something to transition away from?
> My assumption has been that they were an accidental side-effect of the
> config parsing rather than a designed feature, but I agree they are now
> part of existing workflows and need to be handled carefully.
I think it would be OK to consider them a historical curiosity that may eventually be removed, but without an active deprecation timeline. If you do not need to work with older versions of Git it is already a good idea to move to the new syntax because it prevents your alias being caught up if further keys are added. It might be reasonable for the documentation to note that (and of course also mention the downside, which is that older versions of Git will not respect your alias).
We could eventually drop support, but I think it would have to be either:
1. In some distant version such that "pre-2.54" is considered ancient.
2. At some version boundary where we declare a number of breaking
changes. Git 3.0 is probably going to such a version, but I don't
know if we have a concrete timeline (or how long we'd want a
change to be in the "breaking changes" list in the build-up to that
version).There's a related question, too, about whether "alias.foo" (without extra dots) could/should be dropped eventually. I don't see a particular reason to do so, as the cost to carrying support is quite minimal.
-Peff
Re: [PATCH] alias: restore support for simple dotted aliases
Sorry, that wasn't a "hey we should deprecate this" code-wise, I was asking from a documentation point of view, i.e. was curious how you felt about what is "advisable". Shouldn't've included that in my email
Re: [PATCH] alias: restore support for simple dotted aliases
Jonatan Holmgren <jonatan@jontes.page> writes:
> Sorry, that wasn't a "hey we should deprecate this" code-wise, I was
> asking from a documentation point of view, i.e. was curious how you felt
> about what is "advisable". Shouldn't've included that in my email
After this, the discussion went dark, but I think everything that needs saying has been said and we are in agreement that the current patch is a good way forward without closing doors for the future too tightly ;-) Let me mark the topic for 'next'.
Thanks, all.
Re: [PATCH] alias: restore support for simple dotted aliases
On Tue, May 12, 2026 at 01:43:08PM +0900, Junio C Hamano wrote:
Show 10 quoted lines
> Jonatan Holmgren <jonatan@jontes.page> writes:
>
> > Sorry, that wasn't a "hey we should deprecate this" code-wise, I was
> > asking from a documentation point of view, i.e. was curious how you felt
> > about what is "advisable". Shouldn't've included that in my email
>
> After this, the discussion went dark, but I think everything that
> needs saying has been said and we are in agreement that the current
> patch is a good way forward without closing doors for the future too
> tightly ;-) Let me mark the topic for 'next'.
Yeah, sorry I didn't respond to Jonatan. I think the patch as-is is fine, and if we want to push people towards the new form in the documentation, that can be done separately.
-Peff