All of lore.kernel.org
 help / color / mirror / Atom feed
* git 'new' alias
@ 2011-09-01 19:30 Thiago Farina
  2011-09-01 19:40 ` Matthieu Moy
  0 siblings, 1 reply; 5+ messages in thread
From: Thiago Farina @ 2011-09-01 19:30 UTC (permalink / raw)
  To: Git Mailing List

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} "$@"

?

The former doesn't get auto-completion, while the second yes.

https://git.wiki.kernel.org/index.php/Aliases#What.27s_new.3F

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

* Re: git 'new' alias
  2011-09-01 19:30 git 'new' alias Thiago Farina
@ 2011-09-01 19:40 ` Matthieu Moy
  2011-09-01 21:17   ` Jeff King
  0 siblings, 1 reply; 5+ messages in thread
From: Matthieu Moy @ 2011-09-01 19:40 UTC (permalink / raw)
  To: Thiago Farina; +Cc: Git Mailing List

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 ;-).

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

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

* Re: git 'new' alias
  2011-09-01 19:40 ` Matthieu Moy
@ 2011-09-01 21:17   ` Jeff King
  2011-09-05 16:36     ` Matthieu Moy
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff King @ 2011-09-01 21:17 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Thiago Farina, Git Mailing List

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

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

* Re: git 'new' alias
  2011-09-01 21:17   ` Jeff King
@ 2011-09-05 16:36     ` Matthieu Moy
  2011-09-05 20:41       ` Jeff King
  0 siblings, 1 reply; 5+ messages in thread
From: Matthieu Moy @ 2011-09-05 16:36 UTC (permalink / raw)
  To: Jeff King; +Cc: Thiago Farina, Git Mailing List

Jeff King <peff@peff.net> writes:

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

(which, I've just discovered, should be written as

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

otherwise "git config" messes up with the ; in the line)

> which I think was the original intent (modulo me replacing "git log"
> with "echo" for debugging, of course).

The original intent was mis-specified ;-).

I think I originally made the alias to do

git new               # give me new stuff on current branch
git new origin/master # same, for origin/master

and tried to enrich it to allow

git new master --oneline

without thinking about what

git new --oneline

should do (and obviously, without really testing it, I guess I had one
version of the alias allowing each senario, and none allowing all of
them).

I now have this, which is really ugly in a config file, but does the
DWIMery I want:

	new = "!f () { if echo \"$1\" | grep -q -e '^-' -e '^$'; then r=; else r=$1; shift; fi; git log $r@{1}..$r@{0} \"$@\"; } && f"

(this one has even been vaguely tested ;-) )

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

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

* Re: git 'new' alias
  2011-09-05 16:36     ` Matthieu Moy
@ 2011-09-05 20:41       ` Jeff King
  0 siblings, 0 replies; 5+ messages in thread
From: Jeff King @ 2011-09-05 20:41 UTC (permalink / raw)
  To: Matthieu Moy; +Cc: Thiago Farina, Git Mailing List

On Mon, Sep 05, 2011 at 06:36:48PM +0200, Matthieu Moy wrote:

> >   $ git config alias.one
> >   !f() { r=$1; shift; echo $r@{1}..$r@{0} "$@"; }; f
> 
> (which, I've just discovered, should be written as
> 
> [alias]
>         one = "!f() { r=$1; shift; echo $r@{1}..$r@{0} "$@"; }; f"
> 
> otherwise "git config" messes up with the ; in the line)

Yes, it definitely needs quotes. However, you also need to
backslash-escape the quotes inside, or you get:

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

which will accidentally split any arguments with whitespace.

> I now have this, which is really ugly in a config file, but does the
> DWIMery I want:
> 
> 	new = "!f () { if echo \"$1\" | grep -q -e '^-' -e '^$'; then r=; else r=$1; shift; fi; git log $r@{1}..$r@{0} \"$@\"; } && f"

Instead of piping into grep, I would do:

  case "$1" in
    ""|-*) ;;
    *) r=$1; shift ;;
  esac

which saves a process (and is IMHO a little more obvious).

As far as getting ugly for a config file, I would note that:

  1. You can always drop a git-new script in your PATH. :)

  2. You can backslash-escape literal newlines in config entries. It's
     not amazingly pretty, but it can help:

      [alias]
        new = "! \
          f() { \
            case \"$1\" in \
              ''|-*) ;; \
              *) r=$1; shift ;; \
            esac; \
            git log $r@{1}..$r@{0} \"$@\"; \
          }; \
          f"

-Peff

PS I use a similar alias, and I have found that defaulting to "--oneline
--graph --boundary $r@{0}...@r{1}" is quite nice for seeing how you
differ from upstream.

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

end of thread, other threads:[~2011-09-05 20:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-01 19:30 git 'new' alias Thiago Farina
2011-09-01 19:40 ` Matthieu Moy
2011-09-01 21:17   ` Jeff King
2011-09-05 16:36     ` Matthieu Moy
2011-09-05 20:41       ` Jeff King

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.