23

Summary: the current working directory of commands run through git aliases is wrong.

The easiest way to demonstrate this is to have a git alias like so:

[alias]
    pwd = !pwd

So git pwd is just running the bash command pwd. One would think that the two commands' outputs would be the same. Now, let's try this out a few times:

$ cd ~
$ pwd && git pwd
/home/limpchimp
/home/limpchimp    # great!
$ mkdir foo && cd foo && git init
Initialized empty Git repository in /home/limpchimp/foo/.git/
$ pwd && git pwd
/home/limpchimp/foo
/home/limpchimp/foo  # great!
$ mkdir bar && cd bar
$ pwd && git pwd
/home/limpchimp/foo/bar
/home/limpchimp/foo   # uuhhhhhhhh...?

It seems that git is changing the current working directory to be the first parent directory that has a .git folder (if one exists). This is very problematic; it's screwing up certain scripts that I've written, which are meant to operate in a specific directory, and making me unable to use certain things as git aliases. Is there a way around this? How can I fix it?

limp_chimp
  • 13,475
  • 17
  • 66
  • 105
  • 2
    Possible duplicate of [Why does running command as git alias gives different results?](http://stackoverflow.com/questions/8832799/why-does-running-command-as-git-alias-gives-different-results) – Jonathan Wakely Apr 07 '16 at 12:53

2 Answers2

27

TL;DR: add cd -- \"${GIT_PREFIX:-.}\"; in front of the rest of the alias, e.g.:

[alias]
    pwd = !cd -- \"${GIT_PREFIX:-.}\"; pwd

This is a (mis?)feature, but you can work around it with $GIT_PREFIX as noted in this other stackoverflow question and answer:

#! /bin/sh
# script to do stuff in a git dir
# since we're sometimes run from a git alias we need
# to cd back into $GIT_PREFIX if it's set
[ "$GIT_PREFIX" != "" ] && cd -- "$GIT_PREFIX"
... rest of script ...

(As Tom Hale noted in a comment, one can shorten this using the sh / bash / POSIX-shell feature ${var:-default}, where an unset or empty-string variable value expands to the default given after the colon-dash character pair. We use the -- because bash has added options to the cd command, so for robustness we should handle a case where the prefix variable contains, say, -e. The double quotes are not necessary either: I used them above for symmetry with the test command, which the longer version above spells as [.)

mtraceur
  • 3,254
  • 24
  • 33
torek
  • 448,244
  • 59
  • 642
  • 775
11

This is clearly specified in the documentation as by design along with a workaround if needed.

Git Config Alias

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

Andrew C
  • 13,845
  • 6
  • 50
  • 57
  • 5
    "This is clearly specified..." - if by clearly specified you mean the explanation for non-obvious, surprising and non-intuitive behavior being buried in a manpage that's more than 2500 lines long. – Michael Burr Sep 06 '20 at 01:53