git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>
Cc: Thiago Farina <tfransosi@gmail.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Re: git 'new' alias
Date: Thu, 1 Sep 2011 17:17:47 -0400	[thread overview]
Message-ID: <20110901211747.GA16308@sigill.intra.peff.net> (raw)
In-Reply-To: <vpqei00m4pf.fsf@bauges.imag.fr>

On Thu, Sep 01, 2011 at 09:40:28PM +0200, Matthieu Moy wrote:

> Thiago Farina <tfransosi@gmail.com> writes:
> 
> > Hi,
> >
> > Could we change the 'new' alias in the wiki page,
> >
> > from:
> > new = !sh -c 'git log $1@{1}..$1@{0} "$@"'
> >
> > to:
> > new = !git log $1@{1}..$1@{0} "$@"
> >
> > ?
> 
> Go on. I think I'm the one who added it, and I didn't know $1 and $@
> would work without "sh -c", but I guess my version results in calling
> stg like sh -c "sh -c 'git log ...'" which is a bit overkill ;-).

Hmm. Aren't both of these somewhat wrong?

Git will assume your alias is a shell snippet, append the
space-separated shell-quoted arguments provided to the alias to your
snippet, and then hand the result to the shell.

We can simulate the first one with:

  $ git config alias.one
  !sh -c 'echo $1@{1}..$1@{0} "$@"'

which gives:

  $ git one foo
  @{1}..@{0}

Oops, that's not right. You need a placeholder for $0. So make it:

  $ git config alias.one
  !sh -c 'echo $1@{1}..$1@{0} "$@"' --

and now you get:

  $ git one foo
  foo@{1}..foo@{0} foo

Wait, what's that extra "foo" on the end? I'm not sure of the intent.
Either it is totally superfluous, or perhaps it was meant to pass along
other options, like path limiters. In the former case, you just want:

  !sh -c 'echo $1@{1}..$1@{0}' --

and in the latter case, you actually want to shift off $1 and provide
the rest of the options. Of course, for this particular alias, it so
happens that adding an extra $1 is equivalent to $1@{0}, which is
superfluous but harmless. More on that in a minute.

How about the second one:

  $ git config alias.two
  !echo $1@{1}..$1@{0} "$@"

which yields:

  $ git two foo
  foo@{1}..foo@{0} foo foo

Now we have two extra foos! One is from a superfluous use of "$@", which
is no longer necessary to pass along extra args, since we aren't
invoking a subshell. So we are better off with:

  $ git config alias.two
  !echo $1@{1}..$1@{0}

which yields:

  $ git two foo
  foo@{1}..foo@{0} foo

Better, but we still get our superfluous "foo" at the end. And there's
no way to get rid of it here, since it is appended to our shell snippet.
We can't just shift it away.

So in this particular alias, you can live without the subshell wrapper,
and the final alias.two I mentioned is OK. If you're satisfied with
that, you can stop reading now. I still find the repeated refname a
little hack-ish, though, as it doesn't extend to other aliases
naturally.

You mentioned the ugliness in having the shell call itself. Weep for the
quoting nightmare that is:

  $ git config alias.one
  !sh -c 'echo $1@{1}..$1@{0} "$@"' --

  $ GIT_TRACE=1 git one foo
  trace: exec: 'sh' '-c' 'sh -c '\''echo $1@{1}..$1@{0} "$@"'\'' -- "$@"' 'sh -c '\''echo $1@{1}..$1@{0} "$@"'\'' --' 'foo'

Fortunately, we can do a little better using shell functions. I would
write this as:

  $ git config alias.one
  !f() { r=$1; shift; echo $r@{1}..$r@{0} "$@"; }; f

  $ git one foo
  foo@{1}..foo@{0}

  $ git one foo bar
  foo@{1}..foo@{0} bar

which I think was the original intent (modulo me replacing "git log"
with "echo" for debugging, of course). And if you peek at GIT_TRACE
output, we only invoke a single shell.

Now back to the original complaint: no shell completion. For that, I
would simply add:

  _git_new() {
    __git_complete_revlist
  }

to my .bashrc. Yeah, it's a little more work than having the completion
automatically figure out that "new" takes the same arguments as "git
log", but it works in the general case.

-Peff

  reply	other threads:[~2011-09-01 21:17 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-01 19:30 git 'new' alias Thiago Farina
2011-09-01 19:40 ` Matthieu Moy
2011-09-01 21:17   ` Jeff King [this message]
2011-09-05 16:36     ` Matthieu Moy
2011-09-05 20:41       ` Jeff King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110901211747.GA16308@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=Matthieu.Moy@grenoble-inp.fr \
    --cc=git@vger.kernel.org \
    --cc=tfransosi@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).