Re: Weird behavior of shell variables in git aliases

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

 



Jeff King <peff@xxxxxxxx> writes:

> On Tue, Mar 22, 2011 at 02:35:10PM +0100, Lasse Makholm wrote:
>
>> On 22 March 2011 14:28, Jeff King <peff@xxxxxxxx> wrote:
>> > But I think that is a little too magic for my taste. Although the false
>> > positives ("!echo 'literal $#'") and false negatives (you want "!foo" to
>> > _ignore_ its parameters) are pretty obscure, I would prefer to keep
>> > things simple.
>> 
>> Then how about simply:
>> 
>> diff --git a/Documentation/config.txt b/Documentation/config.txt
>> index 6468a68..8097480 100644
>> --- a/Documentation/config.txt
>> +++ b/Documentation/config.txt
>> @@ -586,9 +586,16 @@ 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.
>> +"gitk --all --not ORIG_HEAD". Note that any arguments you pass
>> +when running aliases are simply appended to the shell command.
>> +This means that "alias.foo = !echo $# args: $1, $2 and $3" will
>> +not do what you expect. To use alias arguments as positional
>> +parameters, wrap your command in a shell function:
>> +"alias.foo = !foo () { echo $# args: $1, $2 and $3; }; foo"
>> ++
>> +Shell commands will be executed from the top-level directory
>> +of a repository, which may not necessarily be the current
>> +directory.
>
> Yeah, that certainly improves the situation.

The first addition is indeed a huge improvement.

    Note that any argument you pass when running aliases are simply
    appended to the shell command.

The original didn't explicitly say it but it really should have.  The
example that comes before it, "alias.new = !...", should be updated with
an invocation that takes a parameter, perhaps like this:

    With this alias defined:

	[alias] since = "!gitk --all --since"

    you can view commits in the last week with:

        $ git since 7.days

    because this expands to "gitk --all --since 7.days" by concatenating
    the arguments supplied at runtime to the alias.

Then say that "Note ..." to stress that point.  The description at that
point has become much better.

With that understanding already there,

    This means that "alias.foo = !echo $# args: $1, $2 and $3" will
    not do what you expect.

is no longer true; nobody sane would expect that if you made them realize
that "simply appended" already.  Just dropping that sentence would make
the resulting text flow much better.

    If you want to refer to arguments given to the alias, you can
    wrap it as a shell script, e.g.

	[alias] reversed = "!sh -c 'echo $2 $1' -"

    or a shell function, e.g.

	[alias] reversed = "!reversed() { echo $2 $1 } && reversed"

    and invoke it like so:

	$ git reversed one two
        two one

I personally think the former "sh -c <str> -" is the more traditional and
well understood form (iow, an idiom) for people who breathe shells.

> +----------------------
> +alias.foo = !echo $# args: $1, $2 and $3
> +----------------------

While I totally agree with the formatting advice you gave here, we may
want to avoid this notation; neither "git config alias.foo = !echo ..."
nor writing "alias.foo = ..."  in .git/config file would work.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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]