-1

I noticed that when I'm inside a subdirectory of a git directory, it is still able to recognize the parent .git file. How does it work?

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?

To give an example, I have this directory lay out:

~/folder/
    .git
    subfolder/
        subsubfolder/

If I run git status while inside the subsubfolder, it is able to show the file changes that is registered in .git.

Ivan
  • 1,352
  • 2
  • 13
  • 31
eastern_muffin
  • 181
  • 2
  • 7
  • Try to see this complete answer https://stackoverflow.com/questions/36922197/how-does-git-status-work-internally – Elidor00 Mar 15 '20 at 22:12

1 Answers1

2

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.

torek
  • 448,244
  • 59
  • 642
  • 775