I'm writing a script for some colleagues to use on their Git repositories, and I'm confused about how to reliably find the root of the repo's work-tree:
Typically, if the current directory is inside a work-tree, the commands...
git rev-parse --git-dir
git rev-parse --show-toplevel
...would return the roots of the .git
directory and work-tree, respectively. However, if the current directory happens to be inside a .git
directory, then only the first command works. The command git rev-parse --show-toplevel
does not show the top-level of the work-tree (at least, not for me, using git 1.8.4.4 on Linux).
Assuming that git rev-parse --is-bare-repository
returns false
, I would normally guess that the parent directory of git rev-parse --git-dir
is either the working directory (or somewhere inside the working directory), but if the user's GIT_DIR
is set that the .git
directory isn't inside the working directory, that won't work. (For example, when the user is working with submodules, their GIT_DIR might not be inside their work tree.)
What I find confusing is that, when run inside a GIT_DIR
, git rev-parse --show-toplevel
prints no error messages and returns 0:
$ cd $(git rev-parse --git-dir); git rev-parse --show-toplevel ; echo $?
0
Whereas running the same command somewhere that's clearly not a git repository returns an error code:
$ cd /; git rev-parse --show-toplevel ; echo $?
fatal: Not a git repository (or any of the parent directories): .git
128
If there'a a way to find the work-tree from the GIT_DIR
, could someone tell me how...or if it's simply not possible to derive the location of the work tree from the .git directory, help me understand why, philosophically, the .git directory doesn't keep a reference to its work tree?
Thanks in advance for help/pointers!
The . git folder contains all information that is necessary for the project and all information relating commits, remote repository address, etc. It also contains a log that stores the commit history. This log can help you to roll back to the desired version of the code.
Use the terminal to display the . git directory with the command ls -a . The ls command lists the current directory contents and by default will not show hidden files. If you pass it the -a flag, it will display hidden files.
git folder are known as the Git working tree. The working tree is the set of all files and folders a developer can add, edit, rename and delete during application development. The status command can provide insight into how the Git working tree behaves.
In order to see what branches are currently active as working trees, you need to tell Git to list them with the Git worktree list command. The main working tree is listed first, followed by each of the linked working trees.
why, philosophically, the .git directory doesn't keep a reference to its work tree?
Because you can set said work tree anywhere you want (with the --work-tree
option or the GIT_WORK_TREE
environment variable), including in a place which (and it is the goal) doesn't include the .git
folder.
The git config
man page does mention:
The value can be an absolute path or relative to the path to the
.git
directory, which is either specified by--git-dir
orGIT_DIR
, or automatically discovered.
If--git-dir
orGIT_DIR
is specified but none of--work-tree
,GIT_WORK_TREE
andcore.worktree
is specified, the current working directory is regarded as the top level of your working tree.
So it is more a convention based on the working tree folder (in order to find the .git
) instead of the reverse (deducing working tree from the .git
folder).
That being said, I list all the commands which can give you an idea of the working tree folder in "How to find the path of the local git repository when I am possibly in a subdirectory".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With