245

I am trying to run git from a different directory than I am in. So for example if I am in:

cd /home/domain/
git status << runs perfect ie
# On branch master
# Your branch is ahead of 'origin/master' by 6 commits.

So now I want to run this command from a different directory using the --git-dir option.

So lets say I'm in root/ and try this:

git --git-dir="/home/domain/" status
## Error 
fatal: Not a git repository: '/home/domain/'

I've also tried to include the .git folder i.e.

git --git-dir="/home/domain/.git/" status

But this looks like it's trying to run git from the root, i.e. deleting everything from my domain folder and adding everything in root.

Hope someone can advise on what I'm doing wrong.

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137
Lee
  • 20,034
  • 23
  • 75
  • 102
  • 5
    Now I got status working perfect but pull is giving errors. ie root@erx [/]# git --git-dir=/home/domain/.git --work-tree=/home/domain/ pull origin master fatal: /usr/local/libexec/git-core/git-pull cannot be used without a working tree. But status works ?? any ideas Jon – Lee Sep 06 '09 at 18:51
  • 6
    This is the biggest bug in git right now. Not respecting the --work-tree and/or --git-dir parameters. – Adam Dymitruk Jun 24 '11 at 23:27
  • 5
    Starting git 1.8.5, you will have the choice to *not* set `--git-dir` and `--work-tree` for a simple command: see [my answer below](http://stackoverflow.com/a/20115678/6309) – VonC Nov 21 '13 at 08:20

4 Answers4

350

You have to define the working dir as well. Confusing I know but it's a flexibility thing.

git --git-dir=/mycode/.git --work-tree=/mycode status

You can read a little more here

pimlottc
  • 3,066
  • 2
  • 29
  • 24
Jon Gretar
  • 5,372
  • 1
  • 23
  • 22
  • 4
    Thanks this worked! Agreed that this is confusing. Its called Keep It Simple Stupid. You can almost always allow flexibility while at the same time giving defaults that make the most sense VS having a command not work at all. – Nay Jan 18 '12 at 06:34
  • 4
    @Nick agreed, you'd think if `--git-dir` wasn't specified, it would check if `/mycode/.git` existed and use that before throwing an error. – GP89 Nov 20 '12 at 15:58
  • 6
    @NickYeates seconded! Also I had a problem when using ~ to refer to my home directory, for example `git --git-dir=~/src/s3cmd/.git --work-tree=~/src/s3cmd pull` didn't work but `git --git-dir=/home/username/src/s3cmd/.git --work-tree=/home/username/src/s3cmd pull` did – Jamie Cook Feb 12 '13 at 03:16
  • 1
    Note that not all commands require the work-tree, for example, "git --git-dir=/mycode/.git log" works fine. Agreed on this being confusing though! – yoyo Jun 13 '13 at 21:25
  • I assume the issue has to do with your current directory in relation to the --work-tree directory. Git can't tell if you're deep inside some sub-directories, or at the root of your project. Normally git would walk up until it found the .git directory to find the root, but when you use --git-dir to create the repository, it's not found. I think git log works because it doesn't need to know about the root. Thanks for the info, Jon! – Harry Pehkonen Feb 06 '14 at 17:59
  • 4
    Little clarification: `git --git-dir="$HOME/foo/.git" --work-tree="$HOME/foo" status` – Haris Krajina Feb 17 '14 at 11:36
  • I would not refer to setting `--git-dir` and `--work-tree` as "defining the working dir". Not only because defining the working dir is different (see `-C` option in `man git`). – Kalle Richter Aug 31 '15 at 00:57
159

Starting git 1.8.5 (which should be out next week), it will be even simpler:

 git -C "/home/domain/" status

No need to set --git-dir and --work-tree anymore!

However, as noted by OmarL in the comments:

I have found that -C is not quite equivalent to --git-dir --work-tree, because -C does not override the GIT_DIR environment variable.


See commit 44e1e4 by Nazri Ramliy:

It takes more keypresses to invoke git command in a different directory without leaving the current directory:

  1. (cd ~/foo && git status) git --git-dir=~/foo/.git --work-tree=~/foo status GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
  2. (cd ../..; git grep foo)
  3. for d in d1 d2 d3; do (cd $d && git svn rebase); done

The methods shown above are acceptable for scripting but are too cumbersome for quick command line invocations.

With this new option, the above can be done with fewer keystrokes:

  1. git -C ~/foo status
  2. git -C ../.. grep foo
  3. for d in d1 d2 d3; do git -C $d svn rebase; done
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
43

Based on your comment above, it sounds like you are still running into a problem:

root@erx [/]# git --git-dir=/home/domain/.git --work-tree=/home/domain/ pull origin master
fatal: /usr/local/libexec/git-core/git-pull cannot be used without a working tree

It sounds like you might be intending to run this from crontab or something. You may be better off using cd to switch to your working directory first. For example:

root@erx [/]# (cd /home/domain && git pull origin master)

This will temporarily (in a subshell, which is what the parentheses do) change the current directory to /home/domain, and then run git pull origin master. After the command is complete, your current directory remains whatever it was before the command.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Using a subshell is simple and elegant. I don't know why I didn't think of that before! – Ehtesh Choudhury May 14 '12 at 18:09
  • Sorry @Greg, voted up the other answer by Jon as it answered the question asked - but I think you are spot on with spotting and answering the intention and your insight i.e. the ()s, is exactly what I was looking for +10 – Darren Bishop May 31 '12 at 10:25
2
git --git-dir="/home/domain/" status
## Error 
fatal: Not a git repository: '/home/domain/'

With Git 2.26 (Q1 2020), the documentation is clearer.

One effect of specifying where the GIT_DIR is (either with the environment variable, or with the "git --git-dir=<where> cmd" option) is to disable the repository discovery.

This has been placed a bit more stress in the documentation, as new users often get confused.

See commit d82ad54 (30 Jan 2020) by Heba Waly (HebaWaly).
(Merged by Junio C Hamano -- gitster -- in commit 17e4a1b, 12 Feb 2020)

git: update documentation for --git-dir

Signed-off-by: Heba Waly
Helped-by: Junio C Hamano

git --git-dir <path> is a bit confusing and sometimes doesn't work as the user would expect it to.

For example, if the user runs git --git-dir=<path> status, git will skip the repository discovery algorithm and will assign the work tree to the user's current work directory unless otherwise specified.
When this assignment is wrong, the output will not match the user's expectations.

This patch updates the documentation to make it clearer.

So the documentation for git --git-dir now includes:

--git-dir=<path>:

Set the path to the repository (".git" directory).
This can also be controlled by setting the GIT_DIR environment variable.
It can be an absolute path or relative path to current working directory.

Specifying the location of the ".git" directory using this option (or GIT_DIR environment variable) turns off the repository discovery that tries to find a directory with ".git" subdirectory (which is how the repository and the top-level of the working tree are discovered), and tells Git that you are at the top level of the working tree.

If you are not at the top-level directory of the working tree, you should tell Git where the top-level of the working tree is, with the --work-tree=<path> option (or GIT_WORK_TREE environment variable)

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250