My assumption is that when I run git status
it will search the current directory for a .git
file and if it does not exist it will search the parent directory for it. Is this correct?
That, with some minor corrections and a lot of caveats, is indeed the heart of the algorithm. Some details are Git-version-specific, some are OS-dependent, and some are compile-time options.
The minor correction that is version-dependent is that .git
may be required to be a directory (or folder, if you prefer that term). The ability to have a .git
file, containing the path name of the actual repository directory, went in about the same time as new git worktree
code, around Git 2.5, I think.
The biggest caveat is that if the environment variable GIT_DIR
is set, it must contain the pathname under which the repository will be found. When it is not set, Git implements the searching method you described: start in the current working directory (getcwd
from C code, os.getcwd
in Python, etc), and if no .git
can be found, climb up one level—adding one ..
, or stripping off one path name component—and try again. The search stops when:
- Git reaches
/
so there is no higher position, or
- Git reaches a file system mount point, on those systems that have it and have this compiled in, and environment variable
GIT_DISCOVERY_ACROSS_FILESYSTEM
is not set.
The front end command, git
, actually does this, and sets GIT_DIR
in the environment for the underlying implementation command so that the search need not be repeated. Note that the front end command executes any -C
(change-directory) directives first. Hence, if $GIT_DIR
is set and contains a relative path name, it is used after the -C
directive is run.