Mercurial有一种打印根目录(包含.hg)的方法
hg root
git中是否有等价的东西来获取包含.git目录的目录?
Mercurial有一种打印根目录(包含.hg)的方法
hg root
git中是否有等价的东西来获取包含.git目录的目录?
当前回答
今天必须自己解决这个问题。在c#中解决了它,因为我需要它的程序,但我猜它可以轻松重写。考虑到这是公共领域。
public static string GetGitRoot (string file_path) {
file_path = System.IO.Path.GetDirectoryName (file_path);
while (file_path != null) {
if (Directory.Exists (System.IO.Path.Combine (file_path, ".git")))
return file_path;
file_path = Directory.GetParent (file_path).FullName;
}
return null;
}
其他回答
下面是我编写的处理这两种情况的脚本:1)带工作区的存储库,2)裸存储库。
https://gist.github.com/jdsumsion/6282953
Git-root(可执行文件在你的路径):
#!/bin/bash
GIT_DIR=`git rev-parse --git-dir` &&
(
if [ `basename $GIT_DIR` = ".git" ]; then
# handle normal git repos (with a .git dir)
cd $GIT_DIR/..
else
# handle bare git repos (the repo IS a xxx.git dir)
cd $GIT_DIR
fi
pwd
)
希望这对你们有帮助。
在这里写一个简单的答案,这样我们就可以用
git root
要完成这项工作,只需使用
git config --global alias.root "rev-parse --show-toplevel"
然后你可能想在~/.bashrc中添加以下内容:
alias cdroot='cd $(git root)'
这样你就可以用croot到回购的顶部。
Yes:
git rev-parse --show-toplevel
如果你想更直接地复制Mercurial命令,你可以创建一个别名:
git config --global alias.root 'rev-parse --show-toplevel'
现在git根和hg根一样。
注意:在子模块中,这将显示子模块的根目录,而不是父存储库。如果您使用的是Git >=2.13或更高版本,有一种方法可以让子模块显示超级项目的根目录。如果你的git比这更老,请参阅另一个答案。
“git rev-parse——git-dir”怎么样?
F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git
——git-dir选项似乎可以工作。
它甚至可以在裸库中工作,而git rev-parse——show- topllevel会触发(在裸库中)“致命:此操作必须在工作树中运行”。
从git rev-parse手册页:
--git-dir
Show $GIT_DIR if defined else show the path to the .git directory.
您可以在这个git setup-sh脚本中看到它的作用。
如果你在子模块文件夹中,Git >=2.13,使用:
git rev-parse --show-superproject-working-tree
如果你正在使用git rev-parse——show-toplevel,请确保使用的是git 2.25+ (Q1 2020)。
在钩子和.git目录中使用子模块的简短解决方案
这是大多数人想要的简短答案:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"
这将在git工作树中的任何地方工作(包括在.git目录中),但假设存储库目录被称为.git(这是默认的)。对于子模块,这将转到包含最外层存储库的根。
如果你想获得当前子模块的根,使用:
echo $(r=$(git rev-parse --show-toplevel) && ([[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) ))
为了在你的根模块中轻松地执行一个命令,在你的.gitconfig中的[alias]下,添加:
sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"
这允许您轻松地执行git sh ag <string>之类的操作
健壮的解决方案,支持不同命名或外部。git或$GIT_DIR目录。
注意,$GIT_DIR可能指向外部的某个地方(而不是被称为.git),因此需要进一步检查。
把这个放在你的。bashrc中:
# Print the name of the git working tree's root directory
function git_root() {
local root first_commit
# git displays its own error if not in a repository
root=$(git rev-parse --show-toplevel) || return
if [[ -n $root ]]; then
echo $root
return
elif [[ $(git rev-parse --is-inside-git-dir) = true ]]; then
# We're inside the .git directory
# Store the commit id of the first commit to compare later
# It's possible that $GIT_DIR points somewhere not inside the repo
first_commit=$(git rev-list --parents HEAD | tail -1) ||
echo "$0: Can't get initial commit" 2>&1 && false && return
root=$(git rev-parse --git-dir)/.. &&
# subshell so we don't change the user's working directory
( cd "$root" &&
if [[ $(git rev-list --parents HEAD | tail -1) = $first_commit ]]; then
pwd
else
echo "$FUNCNAME: git directory is not inside its repository" 2>&1
false
fi
)
else
echo "$FUNCNAME: Can't determine repository root" 2>&1
false
fi
}
# Change working directory to git repository root
function cd_git_root() {
local root
root=$(git_root) || return 1 # git_root will print any errors
cd "$root"
}
通过输入git_root来执行它(在重新启动shell后:exec bash)