How to set GIT_DIR & GIT_WORK_TREE when maintaining multiple repositories

Much like this SO post, I have the following workflow that i would like to maintain with git:

  1. Multiple people develop locally
  2. Commit a few things
  3. Commit more things
  4. Push to Staging
  5. Test new code on Staging
  6. Push to Production

Our staging server serves many different sites. I would like to set up the repository for each in a different folder in a user’s home directory. Each repository will have a post-receive hook (ala the Daniel Messier article) that checks out the changes into the web root for that site/repository.

It’s number six that is giving me trouble.

When I try to run any git commands, I get the error “fatal: This operation must be run in a work tree”. I get this error whether I am running ‘git status’ from the repository (/home/gituser/website1.git – which I don’t believe should work anyway..) or from the web root (/var/www/website1).

However, if I specify the GIT_DIR and GIT_WORK_TREE, then I am able to run git commands. Both of these work:

$ git --git-dir /home/gituser/website1.git --work-tree /var/www/website1 status
$ GIT_DIR=/home/gituser/website1.git GIT_WORK_TREE=/var/www/website1 git status 

So I need:

  1. An alternative to typing the directory and work tree along with every command
  2. An alternative to setting them as persistent environment variables, because that would only work for website1, not website2, website3, etc

Am I going about this correctly? How can I get git the directory info it needs for each repository?

  • How to delete my repository on Git using command line?
  • Why can't I clone a git repo for readthedocs to build the documentation?
  • wrong git repo owner
  • Efficient “linking” of two GIT repositories (open and closed source)
  • How to publish code of multiple repositories to <username> (Github Pages)
  • Git: File that must be distributed, but ignored / not reuploaded?
  • GitLab: Could not read from remote repository
  • SVN: how to compare working copy with repository revision?
  • 4 Solutions collect form web for “How to set GIT_DIR & GIT_WORK_TREE when maintaining multiple repositories”

    If I understand correctly, you’ve got a different repository for each web root. If that’s the case, you can set the work tree at the repository level (in the .git/config file): core.worktree. It won’t work if the repo is configured as bare:

        bare = false
        worktree = /webroot/dir/for/this/repo

    Once that’s set, Git commands (like git status) should work from the repository folder again, and any commands that use the work tree (git status, git checkout, etc.) will use the core.worktree location. (Note that Git commands still won’t work from the work tree location, because it’s not a repository.)

    Just a suggestion.

    Implement a script file called “git” that is placed in a directory that preceeds the user’s path before the git executable in /usr/bin. git, the shell script, is just a thin wrapper on top of /usr/bin/git. The first thing it does is detect what directory git is being called from and tries to auto-infer what repo it is working in. Perhaps by having a “my.config” file in the root of each repository that the script can read. Then the script calls “/usr/bin/git –git-dir” and sets GIT_DIR and GIT_WORK_TREE vars and then calls /usr/bin/git with the same command line params.

    Three options:

    1) Add a local alias:

    $ git config alias.root '!pwd'

    2) Add a global alias ($HOME/.gitconfig):

     findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [`pwd`]" && exit 0; cd .. && echo "IN `pwd`" && f;}; f"

    3) A script, e.g

    f () { [[ -d ".git" ]] && echo "Found git in [`pwd`]" && exit 0; cd .. && f;}

    You can always press up arrow to get all that info and then just delete the command and replace with another one. You shouldn’t need to retype the whole thing.

    If you’ve issued a number of other commands and don’t want to “up arrow” through history too much, you can press CTRL-R and start typing “tree” or “work”. You should get the point in history where one of these was run.

    Otherwise, script setting those variables as already suggested.

    Git Baby is a git and github fan, let's start git clone.