Why does git-bisect have to be run from the top level directory of the working tree?

If one tries to run any of the git-bisect commands from anywhere other than the root directory of the repository, one is told:

You need to run this command from the toplevel of the working tree.

Why is that? I know of no other git command that has this requirement, and I see no obvious reason that bisect should be special. The man page makes no mention of this restriction, either.

It's really not a big deal. I'm mostly just curious.


Looking at some commits in the project, I see one by Marcel M. Cary ([email protected])

He says in a commit (it happens to be about git-pull but I think it is relevant)

"git pull" fails because POSIX shells have a notion of current working directory that is different from getcwd(). The shell stores this path in PWD. As a result, "cd ../" can be interpreted differently in a shell script than chdir("../") in a C program. The shell interprets "../" by essentially stripping the last textual path component from PWD, whereas C chdir() follows the ".." link in the current directory on the filesystem. When PWD is a symlink, these are different destinations. As a result, Git's C commands find the correct top-level working tree, and shell scripts do not.

https://github.com/git/git/commit/08fc0608657ee91bc85276667804c36a93138c7d

SO I'd say part of the reason is because git-bisect is a shell script which can't be trusted to find the toplevel on its own (when symlinks are involved).


The bisecting process needs to check out different revisions of your project. If a particular revision does not contain the current folder, then the current folder will be removed.

In that case, your shell could end up sitting in a folder which is no longer on the filesystem! Git will then be unable to find the toplevel's .git folder and so the bisect process cannot continue without intervention.

A demonstration:

$ git rev-parse --show-toplevel
/path/to/project
$ mkdir tmp
$ cd tmp
$ rmdir ../tmp
$ git rev-parse --show-toplevel
fatal: Unable to read current working directory: No such file or directory

Of course this same problem can occur when doing git checkout, and it can be easily fixed after the fact, e.g. with cd .. (willoller explains why that works in the shell but not in git).

But since bisecting is a process it makes sense to avoid this situation before we begin, especially if we want to use automation such as git bisect run.