... but am I doing anything illegal from a Git point of view?
No. It is, however, important to recognize a few things about this slightly odd state.
Git has just one repository, and --git-dir
tells it where to find that one repository.
Git has just one work-tree,1 and --work-tree
tells it where to find that one work-tree (and overrides the core.bare
setting).
Git has just one HEAD
(but see footnote 1), and --git-dir
tells it where to find that one HEAD file.
Git has just one index,2 and ... --git-dir
tells it where to find that one index, if not overridden by an environment variable setting.
It's these last bits that trip people up, mainly when using post-receive
scripts to deploy some particular branches.
If you only deploy one branch to one work-tree, the one index is not a problem. If you start deploying two or more branches to two work-trees, the one index becomes a problem.
Similarly, the single HEAD file is usually not an issue, especially if you deploy only branch master
when the bare repository was created in the usual way, with master
as its current branch. (A bare repository still has a current branch, which is the one in its HEAD
file.) When people clone the bare repository, their clones default to checking out whichever branch is current in the bare repository—so if you start deploying several different branches, people can get surprised by their clones starting out in repository QA
or test
or develop
or whatever, instead of master
.
(The HEAD
thing just requires that people be aware that their default clone branch might surprise them, and they should check out the development branch if that's what they want. It's the single index file that causes real trouble, so see footnote 1.)
1If you use git worktree add
, available in Git 2.5 and later, this is no longer true. The extra work-trees of course provide their own work-tree, but also provide their own separate HEAD
, and also their own index.
You can provide your own index using the environment variable GIT_INDEX_FILE
, which always overrides Git's normal calculations. This also provides a way to do multiple branch deployments: let one branch use the default index, and give the rest their own index file (one each).
Using multiple worktrees and the new updateInstead
mode for push.denyCurrentBranch
may be a better way to automate deployments, but I have not actually tested this.
2Recent versions of Git have introduced a "split index", in which very large index files are "split" into the parts that don't change much, and the parts that do, in an effort to make Git faster. The index splitting is slightly magic (though obviously deterministic and predictable in the end) and knows how to deal with alternate index files, so you don't really need to know anything about this, but it makes the "one index file" claim a bit suspect. In any case, added worktrees from git worktree add
still get their own index file (or index-pair), since this is necessary.