octopusgrabbus
octopusgrabbus

Reputation: 10695

What mechanism does git use to find its repository?

I have several git repositories. One of these is in $PATH. Today, I accidentally moved to a directory that I thought had a git repository, but did not have one.

cd <another_directory_without_.git>.

So, when I entered git status, the output was confusing.

It appears git found the repository in $PATH, so in this case, git found the repository in ~/bin, which is in my PATH.

Does git search for repositories by looking in $PATH, or is there another search mechanism at work?

Upvotes: 0

Views: 87

Answers (2)

kostix
kostix

Reputation: 55573

According to the git(1) manual page, Git goes like this when it looks for its object store:

  1. If the "--git-dir" command-line option was specified its value is used to locate the repository.

  2. If the GIT_DIR environment variable is available and set its value is used to locate the repository.

    Note that in both of these cases no search/heuristics is done.

  3. Otherwise Git tries to figure out if the current directory is the repository — in case it's a bare repository which has no work tree.

    The logic it uses to carry out this task is explained here. To cite it:

    Test if it looks like we're at a git directory. We want to see:

    - either an objects/ directory _or_ the proper
      GIT_OBJECT_DIRECTORY environment variable
    - a refs/ directory
    - either a HEAD symlink or a HEAD file that is formatted as
      a proper "ref:", or a regular file HEAD that has a properly
      formatted sha1 object name.
    
  4. Failing that, Git tries to find a directory named ".git" in the current directory.

    If it succeeds, it uses the test from the previous step to verify if it's really what it was looking for.

  5. If it fails, it ascends one level up — to the parent directory and tries again.

    The last two steps are carried out until / on POSIX-like systems or the root of the drive — on Windows is hit (and hence there's nothing to ascent). By default, Git also won't cross the boundary of a filesystem of the current directory.

As you can see, no $PATH is involved: this directory is used only to look up executable programs, and Git has no business with it.

Upvotes: 2

JB.
JB.

Reputation: 42154

I can't find a definitive reference for the actual details, but we can infer most of it from the documentation to the git repository variables.

Git looks for its a repository, by order of preference:

  • in a directory provided by the --git-dir argument

  • in a directory provided by the GIT_DIR environment variable

  • in subdirectory .git or the current directory

  • in subdirectory .git of an ancestor directory. Environment variables GIT_CEILING_DIRECTORIES and GIT_DISCOVERY_ACROSS_FILESYSTEMS set a few constraints on that.

Upvotes: 2

Related Questions