All Posts

Git Loves the Environment
by

One of the things that people that come from the Subversion world tend
to find pretty cool about Git is that there is no .svn directory in
every subdirectory of your project, but instead just one .git directory
in the root of your project. Actually, it's even better than that.
The .git directory does not even need to actually be within your project.
Git allows you to tell it where your .git directory is, and there are
a couple of ways to do that.

Let's say you have your project and want to move the .git directory
somewhere else. First let's see what happens when we move our .git
directory without telling Git.

Well, since Git can't find a .git directory, it appears that you are
simply in a directory that is not controlled by Git. However, it's
pretty easy to tell Git to look elsewhere by providing the --git-dir
option to any Git call:

There are a number of ways to customize Git functionality via specific
environment variables. You can also tell Git where your working directory
is with GIT_WORK_TREE, so you can run the Git commands from any
directory you are in, not just the current working directory. To see this,
first we'll change a file and then change directories and run git status.

Now Git is comparing your last commit to what is in your current working
directory. However, you can tell it where your real Git working directory
is without being in it, either with the --work-tree option or by exporting
the GIT_WORK_TREE variable:

Now you're doing operations on a Git repository outside of your working
directory, which you're not even in.

The last interesting variable you can set is your staging area. That
is normally in the .git/index file, but again, you can set it somewhere
else, so that you can have multiple staging areas that you can switch
between if you want.

This is not quite as useful in day to day work, but it is pretty cool for
building arbitrary trees and whatnot. We'll explore how to use that to
do neat things in a future post when we talk more about some of the lower
level Git plumbing commands.