What is GIT_WORK_TREE, why have I never needed to set this ENV var, why now?
Asked Answered
T

3

73

I'm using Git under Ubuntu Linux to sync and deploy my projects.

I have a Repo on my local Linux working machine and two repos on my server, one bare repo and the one as a deployed app.

It always worked fine, but now I've created another repo for my other website I get this error:

root@vserver5:/var/www/ninethsky# git pull origin master
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.

So I have to set a GIT_WORKING_TREE ENV-Var, but what is this exactly, where to set it?

This is my repo's .git/config:

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = /home/git/ninethsky/.git
        fetch = +refs/heads/*:refs/remotes/origin/*

There is another repo with bare = true and a repo on my local working machine.

Then I removed all the repos but the initial one, and now I get:

root@vserver5:/var/www/ninethsky# git init
fatal: GIT_WORK_TREE (or --work-tree=<directory>) not allowed without specifying GIT_DIR (or --git-dir=<directory>)
root@vserver5:/var/www/ninethsky# git init --git-dir=/var/www/ninethsky
error: unknown option `git-dir=/var/www/ninethsky'

I solved the git init problem by unsetting GIT_WORK_TREE, which was set to blank. GIT_WORK_TREE and GIT_DIR are unset. git init works again, still there is a problem with git add . and so on when it comes to git actions in the cloned repo, which was set to bare.

Thanks, Joern.

Trinitrophenol answered 12/3, 2011 at 15:1 Comment(6)
Is /var/www/ninethsky a working directory, i.e. does /var/www/ninethsky/.git exist? Or is /var/www/ninethsky itself a git directory?Harmonium
/var/www/ninethsky/.git existsTrinitrophenol
Do other git operations in /var/www/ninethsky work? e.g. does git status also produce an error? Do you have any other git environment variables set when you get that error? (env|egrep GIT)Aspergillum
@Joern Akkermann: I've updated my answer to respond to your additional points.Aspergillum
The most crucial bit of information that is still missing is what you have set in the environment - what does env|grep GIT show?Aspergillum
You mention GIT_WORKING_TREE (note the added "ING"); is that a typo?Homburg
A
128

If you have a non-bare git repository, there are two parts to it:

  • the working tree.
    The working tree has your checked out source code, with any changes you might have made.

  • the git directory.
    The git directory is normally called .git, and is in the top level of your working tree - this contains all the history of your project, configuration settings, pointers to branches, the index (staging area) and so on.
    Your git directory is the one that contains files and directories that look like a bit like this:

    branches description HEAD index logs ORIG_HEAD refs config FETCH_HEAD hooks info objects packed-refs


While what I've described above is the default layout of a git repository, you can actually set any directories in the filesystem to be your git directory and working tree.

You can change these directories from their defaults

  • either with the --work-tree and --git-dir options to git
  • or by using the GIT_DIR and GIT_WORK_TREE environment variables. Usually, however, you shouldn't need to set these.

The error that you see is from one of the first checks that git pull does - it must be run from a working tree. I assume that this is due to you having set the GIT_DIR or GIT_WORK_TREE environment variables.
Otherwise, my best guess is that your .git directory is not accessible or corrupted in some way.

  • If you list the contents of /var/www/ninethsky/.git, does it look like the listing I quoted above?
  • Are all of those files and directories readable and writable by the user you're running the command as, or might they have had their permissions changed?

Update: In answer to the points in the additional information you updated your question with:

  • git init presumably fails because you still have the GIT_WORK_TREE environment variable set, and, as the error message says, if you're specifying the work tree, you also have to specify the git directory.
  • The second variant (git init --git-dir=/var/www/ninethsky) fails because the --git-dir should come before the init.

However, in this situation, you don't need to specify the work tree at all 1, so I would make sure that you unset the GIT_WORK_TREE and GIT_DIR environment variables.

1 That said, it could be considered a bad idea to keep your .git directory under /var/www in case you accidentally set the permissions such that it is web accessible. So this might be an instance where you want to keep the git directory elsewhere. However, since these options are clearly already causing confusion for you, perhaps it's better to keep the git part simple and deny access to the .git directory with other means.

Aspergillum answered 12/3, 2011 at 15:35 Comment(3)
How do you unset GIT_WORK_TREE?Kessel
@Sisir: well, temporarily (in bash, dash, etc.) with unset GIT_WORK_TREE, but presumably if this is a problem then it's been set in a startup file (e.g. ~/.bashrc) or a wrapper script so you'd need to remove the setting from there.Aspergillum
With the release of the git worktree in git 2.5 I believe that the GIT_DIR environment variable should be used with care and you may need to use GIT_COMMON_DIR from worktrees. This is a recent development that occurred after this answer was posted and would be good to mention.Bader
D
4

Perhaps it's better to keep the git part simple and deny access to the .git directory with other means.

You can use .htaccess to deny public access to the .git directory

Dallapiccola answered 13/11, 2012 at 17:16 Comment(2)
Why would you do this when it is so easy to create symlinks and just point the public and served web directory to the build files of your repo that is somewhere under the public directory?Decadent
Because it's the last suggestion on the accepted answer and crd23 posted a link on how to do it. @Dallapiccola probably should have updated the other post and put the link under the referenced text, but they're a noob still so we'll forgive them!Toft
C
0

You may also run into this error if you've renamed the path (working-tree) of a git submodule. In my case I had updated the path in .gitmodules to match my new path and thought I was good. But when I did a git pull later it added new files in the old path. This is because there are two places the module path is defined. You need to also update your "working-tree" as defined in the .git/modules/{modulename}/config file.

Coretta answered 28/3, 2018 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.