Mercurial has a way of printing the root directory (that contains .hg) via
hg root
Is there something equivalent in git to get the directory that contains the .git directory?
Mercurial has a way of printing the root directory (that contains .hg) via
hg root
Is there something equivalent in git to get the directory that contains the .git directory?
Yes:
git rev-parse --show-toplevel
If you want to replicate the Mercurial command more directly, you can create an alias:
git config --global alias.root 'rev-parse --show-toplevel'
and now git root will function just as hg root.
Note: In a submodule this will display the root directory of the submodule and not the parent repository. If you are using Git >=2.13 or above, there is a way that submodules can show the superproject's root directory. If your git is older than that, see this other answer.
The man page for git-config (under Alias) says:
If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command. [...] Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory.
So, on UNIX you can do:
git config --global --add alias.root '!pwd'
How about "git rev-parse --git-dir" ?
F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git
The --git-dir option seems to work.
From git rev-parse manual page:
--git-dir
Show $GIT_DIR if defined else show the path to the .git directory.
You can see it in action in this git setup-sh script.
If you are in a submodule folder, with Git >=2.13, use:
git rev-parse --show-superproject-working-tree
If you are using git rev-parse --show-toplevel, make sure it is with Git 2.25+ (Q1 2020).
If you're already in the top-level or not in a git repository cd $(git rev-parse --show-cdup) will take you home (just cd). cd ./$(git rev-parse --show-cdup) is one way of fixing that.
This shell alias works whether you are in a git subdir, or at the top level:
alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'
updated to use modern syntax instead of backticks:
alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'
Since Git 2.13.0, it supports a new option to show the path of the root project, which works even when being used from inside a submodule:
git rev-parse --show-superproject-working-tree
I wanted to expand upon Daniel Brockman's excellent comment.
Defining git config --global alias.exec '!exec ' allows you to do things like git exec make because, as man git-config states:
If the alias expansion is prefixed with an exclamation point, it will be treated as a shell command. [...] Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory.
It's also handy to know that $GIT_PREFIX will be the path to the current directory relative to the top-level directory of a repository. But, knowing it is only half the battle™. Shell variable expansion makes it rather hard to use. So I suggest using bash -c like so:
git exec bash -c 'ls -l $GIT_PREFIX'
other commands include:
git exec pwd
git exec make
In case anyone needs a POSIX compliant way of doing this, without needing git executable:
#$1: Path to child directory
git_root_recurse_parent() {
# Check if cwd is a git root directory
if [ -d .git/objects -a -d .git/refs -a -f .git/HEAD ] ; then
pwd
return 0
fi
# Check if recursion should end (typically if cwd is /)
if [ "${1}" = "$(pwd)" ] ; then
return 1
fi
# Check parent directory in the same way
local cwd=$(pwd)
cd ..
git_root_recurse_parent "${cwd}"
}
git_root_recurse_parent
If you just want the functionality as part of a script, remove the shebang, and replace the last git_root_recurse_parent line with:
git_root() {
(git_root_recurse_parent)
}