Mercurial提供了一种通过以下方式打印根目录(包含.hg文件夹)的方法:
hg root
在Git中是否有类似的功能可以获取包含.git目录的目录?
Mercurial提供了一种通过以下方式打印根目录(包含.hg文件夹)的方法:
hg root
在Git中是否有类似的功能可以获取包含.git目录的目录?
git rev-parse --show-toplevel
git config --global alias.root 'rev-parse --show-toplevel'
git root
将像hg root
一样正常工作。
git config --global alias.exec '!exec '
,这样我就可以执行类似于git exec make
的操作。这是因为Shell别名始终在顶层目录中执行。 - Daniel Brockmanhg root
的作用。它会打印出你检出仓库的顶级目录,但不会切换到该目录(实际上也无法这样做,因为当前目录和你的 shell 交互的整个概念的限制)。 - Omnifarious~/my.proj/foo/bar
目录下,并且~/my.proj
是一个符号链接,指向~/src/my.proj
,那么上面的命令将把你移动到~/src/my.proj
。如果之后需要对目录树结构敏感,这可能会成为一个问题。 - Franci Penov.git
目录时,它不起作用。 - Dennis--show-toplevel
是最近才添加到 git rev-parse
中的吗?为什么没有人提到它?
来自 git rev-parse
的 man 页面:
--show-toplevel
Show the absolute path of the top-level directory.
git-rev-parse
-- 因为它的名称暗示它是关于处理修订规范的。顺便说一句,我很高兴看到 git --work-tree
的工作方式类似于 git --exec-path[=<path>]
:"如果没有给出路径,git 将打印当前设置";至少,在我看来,这将是寻找此类功能的一个逻辑位置。 - imz -- Ivan Zakharyaschevroot = rev-parse --show-toplevel
设置为别名。 - Mechanical snailgit config --global alias.root "rev-parse --show-toplevel"
,然后 git root
就能完成这个任务。 - nonopolaritygit rev-parse --show-toplevel
命令,成功获取了 Git 子模块的根目录。请问你执行该命令后输出的是什么? - wisbuckygit-config
的man
页(在别名下)说道:
所以,在UNIX上你可以这样做:如果别名扩展以感叹号开头,它将被视为一个shell命令。[...] 请注意,shell命令将从存储库的顶级目录执行,这可能不一定是当前目录。
git config --global --add alias.root '!pwd'
.zshrc
文件中,并定义alias cg="cd $(git root)"
,那么$()部分会在源代码时间进行评估,并且始终指向~/dotfiles,因为那是我的zshrc所在的位置。 - zelk试试使用“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-toplevel
会触发(在该裸库中)一个"fatal: this operation must be run in a work tree
" 的错误信息。
--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+ (2020年第一季度)。.git
提供了一个相对路径。(至少,在msysgit上是这样。) - Blair Holloway.git/
文件夹。 - joeytwiddlegit root
git config --global alias.root "rev-parse --show-toplevel"
~/.bashrc
中:alias cdroot='cd $(git root)'
cdroot
命令进入你的代码库的顶层。cd $(git rev-parse --show-cdup)
会将你带回到主目录(即执行 cd 命令)。cd ./$(git rev-parse --show-cdup)
是解决这个问题的一种方式。cd "$(git rev-parse --show-cdup)"
。这种方式有效,因为 cd ""
不会返回 $HOME
,而是不会有任何反应。无论如何,最佳实践是引用 $() 调用,以防其输出包含空格(尽管在此情况下此命令不会输出空格)。 - ctrueden$PWD
。此示例将解析git的根目录相对于$PWD
而不是realpath $PWD
。 - Damien与子模块、钩子和 .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"
}
在重新启动您的shell后,通过输入git_root
来执行它(使用以下命令重新启动: exec bash
)
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
,但这并不包括命名为.git
以外的外部$GIT_DIR
。 - Tom Halegit rev-parse --show-cdup
命令。然而,还有一些特殊情况需要处理:
Most answers suggest prepending the output with `./` so that an empty output becomes `"./"` before it is fed to `cd`.
Prepending `./` is wrong in this situation. If a `./` is prepended to an absolute path, it becomes a relative path (and they only refer to the same location if the cwd is the root directory of the system).
This really only applies in the second case, but it has an easy fix: use double quotes around the command substitution (and any subsequent uses of the value).
cd "./$(git rev-parse --show-cdup)"
,但这在第二个边缘情况下会出错(如果我们省略双引号,则在第三个边缘情况下也会出错)。cd ""
视为无操作,因此对于这些shell,我们可以执行cd "$(git rev-parse --show-cdup)"
(双引号保护空字符串作为第一个边缘情况的参数,并保留第三个边缘情况中的空格)。POSIX规定cd ""
的结果是未指定的,因此最好避免做出这种假设。cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"
cd
。cd .
,那么条件可以在参数的扩展中完成。cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"
git root
',就像你上面的答案所使用的那样? - Jason Axelson为了在shell脚本中计算当前git根目录的绝对路径,请使用readlink和git rev-parse的组合:
gitroot=$(readlink -f ./$(git rev-parse --show-cdup))
git-rev-parse --show-cdup
命令会给出从当前工作目录到根目录的正确数量的"..", 如果你已经在根目录,则会返回空字符串。
然后在空字符串情况下添加"./", 并使用readlink -f
将其转换为完整路径。
你也可以在PATH中创建一个名为git-root
的命令,它是一个shell脚本,使用这种技术:
cat > ~/bin/git-root << EOF
#!/bin/sh -e
cdup=$(git rev-parse --show-cdup)
exec readlink -f ./$cdup
EOF
chmod 755 ~/bin/git-root
(上述内容可粘贴到终端中创建git-root并设置执行位;实际脚本在第2、3和4行)
然后您就可以运行git root
来获取当前树的根目录。请注意,在shell脚本中,使用“-e”使shell在rev-parse失败时退出,以便您可以正确获取退出状态和错误消息(如果您不在git目录中)。
readlink -f
在BSD上的工作方式不同。请参见此SO以获取解决方法。Python答案可能无需安装任何内容即可正常工作:python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)"
。 - Bluu:/
。# this adds the whole working tree from any directory in the repo
git add :/
# and is equal to
git add $(git rev-parse --show-toplevel)
git rev-parse --git-dir
答案。 - VonC