Git has two option --git-dir
and --work-tree
. What is the use for them?
Usually, when we create a project repository in dir ~/projects/foo
via git init
command. The git directory is ~/projects/foo/.git
, where all the
repository info is stored like the following:
.git
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 0c
│ │ └── fa957df522a120551c8d6147cacbeffd97d4e1
│ ├── 5e
│ │ └── fb9bc29c482e023e40e0a2b3b7e49cec842034
│ ├── e6
│ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
The repository’s work tree is the root directory of this project, i.e.,
~/projects/foo
. When we use git command such as git status
inside in git
repository, git will find .git
directory in the directory or upward until it
finds the .git
directory. So we do not need to specify where the .git
dir
is.
When we want to get the info a repository outside it, we now need to specify
the --git-dir
and --work-tree
to tell git which repository we refer to:
# outside ~/projects/foo
git --git-dir=$HOME/projects/foo/.git --work-tree=$HOME/projects/foo status
Note that the path to --git-dir
and --work-tree
can be an absolute or
relative path (relative to current working directory). If it is an absolute
path, tilde ~
won’t be expanded
. You need to use $HOME
or absolute path.
As a matter of fact, the .git
and work-tree for a repository does not need to
be in the same location. For example, run the following command:
mkdir a b
git init --separate-git-dir a/ b/
Directory a/
will act as .git
directory storing all the info for work-tree
root at b/
. If you look at the b/.git
, it will a plain file pointing to the
absolute path of a/
directory:
gitdir: /path/to/a/dir
To get info about this repository, we can run git like this:
git --git-dir=a/ --work-tree=b/ status
Refs:
- What is the difference in Git between being in a directory (cd) and using the
work-tree
parameter? - Can I store the .git folder outside the files I want tracked?
- https://git-scm.com/docs/git#Documentation/git.txt---git-dirltpathgt
- https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables
- What is GIT_WORK_TREE, why have I never needed to set this ENV var, why now?