git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* why can't one alias `git stash`?
@ 2025-08-15  0:33 Christoph Anton Mitterer
  2025-08-15  1:23 ` Junio C Hamano
  0 siblings, 1 reply; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-15  0:33 UTC (permalink / raw)
  To: git

Hey.

Personally, I've always disliked that `git stash` already does the
`push` and would have much more preferred it, if it did a `stash list`.

So I tried to solve this via an alias like:
[alias]
        stash = "!c(){ if [ \"$#\" -eq 0 ]; then git stash list; else git stash \"$@\"; fi; }; c"

which seems however to be ignored when the alias name is "stash" (it
works as it should when I use e.g. foo = ...).


Any idea why that doesn't work?


Also when using such shell functions seems to be not extensively
documented (or I didn't find it)... the example in git-config gives the
"!c()..." syntax but doesn't seem to tell what the ! is for?

Are these functions executed in a separate shell execution environment
(or could I accidentally override a function from some git shell
script)?

Is there any sanitisation of the environment that the shell gets (or
does it simply get whatever the user has)?
I mean a badly set IFS or similar could easily cause troubles.


Thanks,
Chris.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15  0:33 why can't one alias `git stash`? Christoph Anton Mitterer
@ 2025-08-15  1:23 ` Junio C Hamano
  2025-08-15  2:02   ` Christoph Anton Mitterer
  0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2025-08-15  1:23 UTC (permalink / raw)
  To: Christoph Anton Mitterer; +Cc: git

Christoph Anton Mitterer <calestyo@scientia.org> writes:

> So I tried to solve this via an alias like:
> [alias]
>         stash = "!c(){ if [ \"$#\" -eq 0 ]; then git stash list; else git stash \"$@\"; fi; }; c"
>
> which seems however to be ignored when the alias name is "stash" (it
> works as it should when I use e.g. foo = ...).

Look for "alias.*" in "git help config".

        To avoid
	confusion and troubles with script usage, aliases that
	hide existing Git commands are ignored. 

> Also when using such shell functions seems to be not extensively
> documented (or I didn't find it)... the example in git-config gives the
> "!c()..." syntax but doesn't seem to tell what the ! is for?

	If the alias expansion is prefixed with an exclamation
        point, it will be treated as a shell command.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15  1:23 ` Junio C Hamano
@ 2025-08-15  2:02   ` Christoph Anton Mitterer
  2025-08-15  4:04     ` Elijah Newren
  0 siblings, 1 reply; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-15  2:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Hey.

On Thu, 2025-08-14 at 18:23 -0700, Junio C Hamano wrote:
> Look for "alias.*" in "git help config".
> 
>         To avoid
> 	confusion and troubles with script usage, aliases that
> 	hide existing Git commands are ignored. 

Can't one add some kind of override for this? Cause AFAIU, my command
from below would not hide the other commands, or would it?


> 	If the alias expansion is prefixed with an exclamation
>         point, it will be treated as a shell command.

Well I kinda thought that... still wouldn't though if it was detailed
what exactly happens :-)

Thanks,
Chris.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15  2:02   ` Christoph Anton Mitterer
@ 2025-08-15  4:04     ` Elijah Newren
  2025-08-15 11:22       ` rsbecker
                         ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Elijah Newren @ 2025-08-15  4:04 UTC (permalink / raw)
  To: Christoph Anton Mitterer; +Cc: Junio C Hamano, git

On Thu, Aug 14, 2025 at 7:15 PM Christoph Anton Mitterer
<calestyo@scientia.org> wrote:
>
> Hey.
>
> On Thu, 2025-08-14 at 18:23 -0700, Junio C Hamano wrote:
> > Look for "alias.*" in "git help config".
> >
> >         To avoid
> >       confusion and troubles with script usage, aliases that
> >       hide existing Git commands are ignored.
>
> Can't one add some kind of override for this?

No.  And there won't be one in the future either; see e.g.
https://lore.kernel.org/git/alpine.DEB.1.00.0903070407480.10279@pacific.mpi-cbg.de/

> Cause AFAIU, my command
> from below would not hide the other commands, or would it?

The documentation you are responding to didn't talk about "other"
commands, it talked about "existing" commands.  Your alias, meant to
invoke `git stash` with different arguments, would hide the existing
`git stash` command.

It might also be an infinite loop of sorts, since your `git stash`
alias invokes `git stash ...` which is...itself.

And it'd mean that other folks who use git commands in their scripts
now can't rely on any git commands doing what their documentation
claims.

> >       If the alias expansion is prefixed with an exclamation
> >         point, it will be treated as a shell command.
>
> Well I kinda thought that... still wouldn't though if it was detailed
> what exactly happens :-)

Doesn't it detail what happens already?

           If the alias expansion is prefixed with an exclamation
point, it will be treated as a shell command. For example, defining
alias.new = !gitk --all --not
           ORIG_HEAD, the invocation git new is equivalent to running
the shell command gitk --all --not ORIG_HEAD. Note that shell commands
will be executed from the
           top-level directory of a repository, which may not
necessarily be the current directory.  GIT_PREFIX is set as returned
by running git rev-parse --show-prefix
           from the original current directory. See git-rev-parse(1).

What is missing from this explanation?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: why can't one alias `git stash`?
  2025-08-15  4:04     ` Elijah Newren
@ 2025-08-15 11:22       ` rsbecker
  2025-08-16  2:03         ` Christoph Anton Mitterer
  2025-08-15 15:27       ` Junio C Hamano
  2025-08-16  1:35       ` Christoph Anton Mitterer
  2 siblings, 1 reply; 12+ messages in thread
From: rsbecker @ 2025-08-15 11:22 UTC (permalink / raw)
  To: 'Elijah Newren', 'Christoph Anton Mitterer'
  Cc: 'Junio C Hamano', git

On August 15, 2025 12:04 AM, Elijah Newren wrote:
>On Thu, Aug 14, 2025 at 7:15 PM Christoph Anton Mitterer
><calestyo@scientia.org> wrote:
>>
>> Hey.
>>
>> On Thu, 2025-08-14 at 18:23 -0700, Junio C Hamano wrote:
>> > Look for "alias.*" in "git help config".
>> >
>> >         To avoid
>> >       confusion and troubles with script usage, aliases that
>> >       hide existing Git commands are ignored.
>>
>> Can't one add some kind of override for this?
>
>No.  And there won't be one in the future either; see e.g.
>https://lore.kernel.org/git/alpine.DEB.1.00.0903070407480.10279@pacific.mpi-
>cbg.de/
>
>> Cause AFAIU, my command
>> from below would not hide the other commands, or would it?
>
>The documentation you are responding to didn't talk about "other"
>commands, it talked about "existing" commands.  Your alias, meant to invoke `git
>stash` with different arguments, would hide the existing `git stash` command.
>
>It might also be an infinite loop of sorts, since your `git stash` alias invokes `git stash
>...` which is...itself.
>
>And it'd mean that other folks who use git commands in their scripts now can't rely
>on any git commands doing what their documentation claims.
>
>> >       If the alias expansion is prefixed with an exclamation
>> >         point, it will be treated as a shell command.
>>
>> Well I kinda thought that... still wouldn't though if it was detailed
>> what exactly happens :-)
>
>Doesn't it detail what happens already?
>
>           If the alias expansion is prefixed with an exclamation point, it will be treated as
>a shell command. For example, defining alias.new = !gitk --all --not
>           ORIG_HEAD, the invocation git new is equivalent to running the shell
>command gitk --all --not ORIG_HEAD. Note that shell commands will be executed
>from the
>           top-level directory of a repository, which may not necessarily be the current
>directory.  GIT_PREFIX is set as returned by running git rev-parse --show-prefix
>           from the original current directory. See git-rev-parse(1).
>
>What is missing from this explanation?

Aside from the above, hiding an existing command would potentially allow a
man-in-the-middle attack. Imagine changing git clone to be something else,
like cloning a hostile repository. Hiding existing commands could result in a
HIGH severity CVE in git - I would consider it as such. Please ensure that no
fix/enhancement is done to support this request.

--Radall


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15  4:04     ` Elijah Newren
  2025-08-15 11:22       ` rsbecker
@ 2025-08-15 15:27       ` Junio C Hamano
  2025-08-16  2:11         ` Christoph Anton Mitterer
  2025-08-16  1:35       ` Christoph Anton Mitterer
  2 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2025-08-15 15:27 UTC (permalink / raw)
  To: Elijah Newren; +Cc: Christoph Anton Mitterer, git

Elijah Newren <newren@gmail.com> writes:

> The documentation you are responding to didn't talk about "other"
> commands, it talked about "existing" commands.  Your alias, meant to
> invoke `git stash` with different arguments, would hide the existing
> `git stash` command.

Correct.

> It might also be an infinite loop of sorts, since your `git stash`
> alias invokes `git stash ...` which is...itself.

True.  But we do not do a very good job preventing this to happen.

    $ git -c alias.loop='loop foo' loop foo
    fatal: recursive alias: loop
    $ git -c alias.loop='!git loop foo' alias foo ;# does not come back
    ^C

To be honest, I do not offhand see a foolproof way to "fix" the
latter.

> And it'd mean that other folks who use git commands in their scripts
> now can't rely on any git commands doing what their documentation
> claims.

It is true that it would break common expectations for script
writers (to help other Git users) and those who help other Git users
at their keyboards if we allowed to alias the basic command away and
to change its behaviour radically.  But with so many configuration
variable to alter behaviour for Porcelain commands, I am not sure
how much it is helping the latter helpers these days.  For the
former helpers, those who write their scripts with Porcelain
commands are beyond salvation X-<.

Thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15  4:04     ` Elijah Newren
  2025-08-15 11:22       ` rsbecker
  2025-08-15 15:27       ` Junio C Hamano
@ 2025-08-16  1:35       ` Christoph Anton Mitterer
  2 siblings, 0 replies; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-16  1:35 UTC (permalink / raw)
  To: Elijah Newren; +Cc: git

On Thu, 2025-08-14 at 21:04 -0700, Elijah Newren wrote:
> No.  And there won't be one in the future either; see e.g.
> https://lore.kernel.org/git/alpine.DEB.1.00.0903070407480.10279@pacific.mpi-cbg.de/

At least the "it makes it hard for users to understand" argument seems
a bit weak.

I mean isn't that's also the case with shell aliases and the whole
point of them is to customise the behaviour for the user (which is btw
also done by many git-config options, which another user that uses my
settings may not be familiar with).



> And it'd mean that other folks who use git commands in their scripts
> now can't rely on any git commands doing what their documentation
> claims.

TBH, I wasn't even aware that git aliases are applied from scripts.

Isn't that anyway a pretty dangerous game?
I mean I could define an alias that works right now, as it doesn't hid
an actual command... my script relies on that alias working.
And the next git version introduces a command of the same name (and my
script breaks).

There's good reason that shell aliasing is per default not active in
non-interactive shells.

> Doesn't it detail what happens already?
> 
>            If the alias expansion is prefixed with an exclamation
> point, it will be treated as a shell command. For example, defining
> alias.new = !gitk --all --not
>            ORIG_HEAD, the invocation git new is equivalent to running
> the shell command gitk --all --not ORIG_HEAD. Note that shell
> commands
> will be executed from the
>            top-level directory of a repository, which may not
> necessarily be the current directory.  GIT_PREFIX is set as returned
> by running git rev-parse --show-prefix
>            from the original current directory. See git-rev-parse(1).
> 
> What is missing from this explanation?

Well, what I've said in my initial post.
Is the shell execution environment in any way sanitised (like which
IFS, PATH, whatever are set) or does it even share the env from some
git shell script that may execute the alias shell command (as in dot
sourcing).
Perhaps also *which* shell is used? Is it always /bin/sh or whatever
shell the user has configured as login shell?
Will e.g. profile/rc files be loaded or not.

Admittedly some information might be overkill, but at least I'd wanna
know if using the wrong function/var names in my alias command, could
cause troubles for git.


Cheers,
Chris.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15 11:22       ` rsbecker
@ 2025-08-16  2:03         ` Christoph Anton Mitterer
  0 siblings, 0 replies; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-16  2:03 UTC (permalink / raw)
  To: rsbecker, 'Elijah Newren'; +Cc: 'Junio C Hamano', git

On Fri, 2025-08-15 at 07:22 -0400, rsbecker@nexbridge.com wrote:
> > 
> Aside from the above, hiding an existing command would potentially
> allow a
> man-in-the-middle attack. Imagine changing git clone to be something
> else,
> like cloning a hostile repository. Hiding existing commands could
> result in a
> HIGH severity CVE in git - I would consider it as such. Please ensure
> that no
> fix/enhancement is done to support this request.

This I don't understand.

I mean I hopefully never get a remote git config file e.g. just by
cloning some remote repo[0].

So - if git aliases were to be only applied when called from
interactive shells - how exactly could there be a MitM without the
attacker having already compromised at least one’s user account?


Cheers,
Chris.


[0] Perhaps a bit off topic (my apologies for that) but I had wanted to
ask this for a long time - or maybe I've had even brought it up back
then, but there was no outcome):

I vaguely remember the CVE that cause the introduction of
safe.bareRepository, which AFAICS was CVE-2022-24765.

I'm not an expert but even back then I had already some doubts whether
this really *fully* fixed the issue (for all niche cases), did it?

I mean when I do a plain
  git clone http://hackerz.com/rogue/repo.git
then the resulting repo/.git/config cannot contain any configs from an
attacker (e.g. rogue alises).


What if repo.git itself contained e.g. a ./x/.git subdir with configs?
My understanding was, that with safe.bareRepository = explicit, such
subrepo .git would never get cloned, so that would be safe.
Right?


But what if I untar such rogue repo... or perhaps more likely, stumble
over it on some network mount?
To many users it may not be obvious, that this is a risk. And I guess
it might even be exploitable by just cd-ing into the wrong directory
(if e.g. git prompt is used).

It's also not really clear to me whether any 3rd party git utils/libs
(libgit2, etc. pp.) may fall for such attack?

And IMO that is different from downloading some untrusted binary and
executing it, as e.g. already a cd could cause troubles.


Is that the situation as assumed? Are there any plans about doing
something against it?

One could e.g. keep a central list of pathname of directories that are
actually considered repositories... and things like aliases/etc. would
only get executed if they belong to these.
A git clone could automatically add the new repo to that list (but e.g.
un-taring some repo wouldn't cause it to be used as that).

Or, in order to allow moving the repo to another pathname without
having to re-register it, any "allowed/trusted" repo could get some
magic cookie in it's .git dir, which is signed by some key from the
user.
Could even allow more than one such cookie, so that multiple users
could work on a shared repo.

Of course this would only fully protect, if all other interfaces/libs
to git would also adhere to that.

And of course, one could make it configurable, i.e. safe.ignore-
untrusted-repos ... for all those who think the whole thing is annoying
and rubbish.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-15 15:27       ` Junio C Hamano
@ 2025-08-16  2:11         ` Christoph Anton Mitterer
  2025-08-16  9:15           ` Matthias Aßhauer
  2025-08-19  1:01           ` Junio C Hamano
  0 siblings, 2 replies; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-16  2:11 UTC (permalink / raw)
  To: Junio C Hamano, Elijah Newren; +Cc: git

On Fri, 2025-08-15 at 08:27 -0700, Junio C Hamano wrote:
>     $ git -c alias.loop='!git loop foo' alias foo ;# does not come
> back
>     ^C
> 
> To be honest, I do not offhand see a foolproof way to "fix" the
> latter.

I assume every aliasing step causes a new invocation of git - or are
aliases resolved in one process?

If the former, what about:
For every aliasing you append to some special env var the name of the
alias, and if the same is encountered again (or some maximum env var
size has been reached) you bail out with an error?

It's of course still not 100% foolproof, e.g. if users manually clear
the var or somehow else uses it.
And it requires that at least one char (that can be held by an env var)
is not allowed as an alias name, to be used as separator.


> It is true that it would break common expectations for script
> writers (to help other Git users) and those who help other Git users
> at their keyboards if we allowed to alias the basic command away and
> to change its behaviour radically.

As mentioned in the other thread, IMO it sounds rather brittle if
aliases are considered at all in scripting.


> But with so many configuration
> variable to alter behaviour for Porcelain commands, I am not sure
> how much it is helping the latter helpers these days.  For the
> former helpers, those who write their scripts with Porcelain
> commands are beyond salvation X-<.

Well I'd also be happy with a special porcelain option that allows be
to override the default of git stash O:-)


Thanks,
Chris.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-16  2:11         ` Christoph Anton Mitterer
@ 2025-08-16  9:15           ` Matthias Aßhauer
  2025-08-19  1:01           ` Junio C Hamano
  1 sibling, 0 replies; 12+ messages in thread
From: Matthias Aßhauer @ 2025-08-16  9:15 UTC (permalink / raw)
  To: Christoph Anton Mitterer; +Cc: Junio C Hamano, Elijah Newren, git



On Sat, 16 Aug 2025, Christoph Anton Mitterer wrote:

> As mentioned in the other thread, IMO it sounds rather brittle if
> aliases are considered at all in scripting.

How would they not be considered? There is no --ignore-aliases option 
(because it would currently do nothing usefull), so git doesn't know if 
its called from a script. And if we where to add such an option, existing 
scripts wouldn't use it.

Best regards

Matthias

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-16  2:11         ` Christoph Anton Mitterer
  2025-08-16  9:15           ` Matthias Aßhauer
@ 2025-08-19  1:01           ` Junio C Hamano
  2025-08-19 21:38             ` Christoph Anton Mitterer
  1 sibling, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2025-08-19  1:01 UTC (permalink / raw)
  To: Christoph Anton Mitterer; +Cc: Elijah Newren, git

Christoph Anton Mitterer <calestyo@scientia.org> writes:

> As mentioned in the other thread, IMO it sounds rather brittle if
> aliases are considered at all in scripting.

As a program, how would you tell when you are run by a script?

If you are a shell, you go into "interactive" mode when you are
taking your command stream from a tty, and otherwise assume you are
not interactive.  The same trick would not work at all for programs
started by a shell, would it?

Asking script writers to pass "--no-alias" option to all of their
"git" invocation will probably not be a viable way forward, either.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: why can't one alias `git stash`?
  2025-08-19  1:01           ` Junio C Hamano
@ 2025-08-19 21:38             ` Christoph Anton Mitterer
  0 siblings, 0 replies; 12+ messages in thread
From: Christoph Anton Mitterer @ 2025-08-19 21:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Mon, 2025-08-18 at 18:01 -0700, Junio C Hamano wrote:
> As a program, how would you tell when you are run by a script?
> 
> If you are a shell, you go into "interactive" mode when you are
> taking your command stream from a tty, and otherwise assume you are
> not interactive.  The same trick would not work at all for programs
> started by a shell, would it?

Not for all, but it might still give enough "teaching" to prevent
people from using aliases in scripts.

Checking whether the parent process is a well known shell would
probably not help, as it would also be for the interactive case, where
aliasing is wanted.


> Asking script writers to pass "--no-alias" option to all of their
> "git" invocation will probably not be a viable way forward, either.

Again at least not a safe one. And doing the opposite, i.e. requring --
enable-aliasing (which people would then have to set as shell alias),
would probably end up in generating quite a few annoyed people. ;-)

It could be made optional. E.g. some gitconf option that per default
enables aliasing always but allows to require a --aliasing option
(which then again is intended to be set via a shell alias) in order for
git aliasing to be enabled.

Whether it's worth the effort is of course another question.


Cheers,
Chris.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-08-19 21:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-15  0:33 why can't one alias `git stash`? Christoph Anton Mitterer
2025-08-15  1:23 ` Junio C Hamano
2025-08-15  2:02   ` Christoph Anton Mitterer
2025-08-15  4:04     ` Elijah Newren
2025-08-15 11:22       ` rsbecker
2025-08-16  2:03         ` Christoph Anton Mitterer
2025-08-15 15:27       ` Junio C Hamano
2025-08-16  2:11         ` Christoph Anton Mitterer
2025-08-16  9:15           ` Matthias Aßhauer
2025-08-19  1:01           ` Junio C Hamano
2025-08-19 21:38             ` Christoph Anton Mitterer
2025-08-16  1:35       ` Christoph Anton Mitterer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).