14

I have the following 1-liner that I use to see who might be a good candidate for help with a peice of code:

git log --pretty=short . | grep ^Auth | sort | uniq -c | sort -nr

which lists authors in order of commits, it's crude but it works OK.

When I add it to my git config however, like this:

[alias]
    guru=!git log --pretty=short . | grep ^Auth | sort | uniq -c | sort -nr

running

git guru

Gives different results to running it from the command line.

stuart@beavis(rp):~/git/apps$ git log --pretty=short . | grep ^Auth | sort | uniq -c | sort -nr
710 Author: dave <dave@b2368a2b-315f-46b9-a0b0-05934f827f41>
415 Author: pete <pete@b2368a2b-315f-46b9-a0b0-05934f827f41>
402 Author: craig <craig@b2368a2b-315f-46b9-a0b0-05934f827f41>

Compared to:

stuart@beavis(rp):~/git/apps$ git guru
859 Author: craig <craig@b2368a2b-315f-46b9-a0b0-05934f827f41>
813 Author: paul <paul@b2368a2b-315f-46b9-a0b0-05934f827f41>
798 Author: dave <dave@b2368a2b-315f-46b9-a0b0-05934f827f41>

As Stefan Näwe notes below, aliases run in the root of your repository, is there any way to run the command on the directory I'm in, or specify?

Stuart Grimshaw
  • 1,522
  • 18
  • 40

3 Answers3

23

is there any way to run the command on the directory I'm in, or specify?

Yes, there is. When you run a git command, your environment gets a GIT_PREFIX variable with the value of the relative path (from toplevel to the path before executing git) so what you need is prefix your git aliases (that run shell commands and need the right pwd) with cd ${GIT_PREFIX:-.} &&.

Simple test, add this to your ~/.gitconfig

[alias] p = !pwd && cd ${GIT_PREFIX:-.} && pwd

Andrei Neculau
  • 946
  • 1
  • 9
  • 14
13

git's aliases using a shell command (i.e. prefixed by !) run in the toplevel of the working directory (where the .git lives). Simple aliases (without !) run at the current directory.

Stefan Näwe
  • 2,982
  • 1
  • 17
  • 19
  • Thanks Stefan, this answered my original question, I've ammeded now to hopefully make it more useful to others in the same situation. – Stuart Grimshaw Jan 12 '12 at 23:52
  • 3
    This is a fairly unintuitive Git behavior. Does anyone know how to run an alias in the current directory? Or if the current directory is available in an env var or something so that an alias can `cd` back to the right place before running? – Jim Stewart Nov 20 '13 at 17:04
  • @JimStewart see Andrei Neculau's answer above, it shows how to do just that :) – waldyrious Apr 04 '16 at 18:45
4

Looking at what you are doing you probably want to use git shortlog -sn instead as this does the task in question already.

git aliases do not all run at the toplevel. As described in the git config manual "Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory." So only shell commands get run at the top level. If you simply alias a git subcommand it will run at the current location. The following session log demonstrates this:

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$ git rev-parse  --show-cdup
../../

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$ git config alias.cdup 'rev-parse --show-cdup'

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$ git cdup
../../

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$ git config alias.cdup2 '!git rev-parse --show-cdup'

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$ git cdup2

pat@FROG /c/src/WiRE.git/wdf/src (pt/wdf)
$

Your example uses an alias command that starts with 'git'. If I try setting 'git rev-parse --show-cdup' as the alias it returns an error stating 'git is not a git command' so I suspect you actually had a exclamation mark too hence running it as a shell command, thus running from the toplevel.

patthoyts
  • 30,898
  • 3
  • 60
  • 89