woj*_*ojo 613 git version-control
Mercurial有一种打印根目录(包含.hg)的方法
hg root
Run Code Online (Sandbox Code Playgroud)
在git中是否有类似的东西来获取包含.git目录的目录?
bau*_*ack 1013
是:
git rev-parse --show-toplevel
Run Code Online (Sandbox Code Playgroud)
注意:在子模块中,这将显示子模块的根目录,而不是父存储库.
小智 95
(Alias下)的man
页面说:git-config
如果别名扩展以感叹号为前缀,则将其视为shell命令.[...]请注意,shell命令将从存储库的顶级目录执行,该目录可能不一定是当前目录.
所以,在UNIX上你可以这样做:
git config --global --add alias.root '!pwd'
Run Code Online (Sandbox Code Playgroud)
mar*_*her 87
有--show-toplevel
最近才加入git rev-parse
或为什么没人提呢?
从git rev-parse
手册页:
--show-toplevel
Show the absolute path of the top-level directory.
Run Code Online (Sandbox Code Playgroud)
Von*_*onC 46
" git rev-parse --git-dir
"怎么样?
F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git
Run Code Online (Sandbox Code Playgroud)
该--git-dir
选项似乎有效.
--git-dir
Show $GIT_DIR if defined else show the path to the .git directory.
Run Code Online (Sandbox Code Playgroud)
您可以在此git setup-sh
脚本中看到它的运行情况.
如果您在子模块文件夹中,使用Git 2.20,请使用:
git rev-parse --show-superproject-working-tree
Run Code Online (Sandbox Code Playgroud)
nop*_*ole 34
在这里写一个简单的答案,以便我们可以使用
git root
Run Code Online (Sandbox Code Playgroud)
要完成这项工作,只需使用配置您的git即可
git config --global alias.root "rev-parse --show-toplevel"
Run Code Online (Sandbox Code Playgroud)
然后你可能想要将以下内容添加到你的~/.bashrc
:
alias cdroot='cd $(git root)'
Run Code Online (Sandbox Code Playgroud)
这样你就可以用到cdroot
你的回购顶部了.
Kar*_*arl 26
如果您已经在顶级或不在git存储库中,cd $(git rev-parse --show-cdup)
则会将您带回家(只需cd). cd ./$(git rev-parse --show-cdup)
是解决这个问题的一种方法.
Chr*_*sen 17
正如其他人所说,解决方案的核心是使用git rev-parse --show-cdup
.但是,有一些边缘情况需要解决:
当cwd已经是工作树的根时,该命令产生一个空字符串.
实际上它产生一个空行,但命令替换剥离了尾随行.最终结果是一个空字符串.
大多数答案都建议在输出前加上./
一个空输出,"./"
然后输出cd
.
当GIT_WORK_TREE设置为不是cwd的父级的位置时,输出可以是绝对路径名.
./
在这种情况下,前置是错误的.如果a前./
置于绝对路径,则它将成为相对路径(如果cwd是系统的根目录,则它们仅指向相同的位置).
输出可能包含空格.
这实际上仅适用于第二种情况,但它有一个简单的解决方法:在命令替换(以及值的任何后续使用)周围使用双引号.
正如其他答案所指出的那样,我们可以这样做cd "./$(git rev-parse --show-cdup)"
,但这会在第二个边缘情况下出现(如果我们不加双引号,则会出现第三个边缘情况).
许多shell cd ""
视为无操作,因此对于我们可以做的那些shell cd "$(git rev-parse --show-cdup)"
(双引号在第一个边缘情况下保护空字符串作为参数,并在第三个边缘情况下保留空白).POSIX表示结果cd ""
未指定,因此最好避免做出这种假设.
适用于所有上述情况的解决方案需要进行某种测试.明确地完成,它可能看起来像这样:
cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"
Run Code Online (Sandbox Code Playgroud)
cd
对第一个边缘情况没有做.
如果运行cd .
第一个边缘情况是可以接受的,那么条件可以在参数的扩展中完成:
cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"
Run Code Online (Sandbox Code Playgroud)
Emi*_*Sit 16
要计算当前git根目录的绝对路径,比如在shell脚本中使用,请使用readlink和git rev-parse的这种组合:
gitroot=$(readlink -f ./$(git rev-parse --show-cdup))
Run Code Online (Sandbox Code Playgroud)
git-rev-parse --show-cdup
从你的cwd中获取正确数量的".."以获取根目录,如果你位于根目录,则输入空字符串.然后在前面加上"./"来处理空字符串case并用于
readlink -f
转换为完整路径.
您还可以git-root
在PATH中创建一个命令作为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
Run Code Online (Sandbox Code Playgroud)
(以上内容可以粘贴到终端创建git-root并设置执行位;实际脚本位于第2,3和4行.)
然后你就可以运行git root
以获取当前树的根目录.请注意,在shell脚本中,如果rev-parse失败,请使用"-e"使shell退出,以便在不在git目录中时可以正确获取退出状态和错误消息.
Nic*_*kin 13
如果您正在将此路径提供给Git本身,请使用 :/
# 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)
Run Code Online (Sandbox Code Playgroud)
Tom*_*ale 11
使用子模块,挂钩和.git
目录内部的简短解决方案
以下是大多数人想要的简短答案:
r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"
Run Code Online (Sandbox Code Playgroud)
这将在git工作树中的任何位置工作(包括在.git
目录内),但假定调用存储库目录.git
(这是默认值).使用子模块,这将转到最外面的包含存储库的根目录.
如果要获取当前子模块的根目录,请使用:
echo $(r=$(git rev-parse --show-toplevel) && ([[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) ))
Run Code Online (Sandbox Code Playgroud)
要轻松执行子模块根目录中的命令,请[alias]
在您的下面.gitconfig
添加:
sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"
Run Code Online (Sandbox Code Playgroud)
这可以让你轻松做到这样的事情 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"
}
Run Code Online (Sandbox Code Playgroud)
键入git_root
(重启shell后exec bash
)执行它:
小智 10
从Git 2.13.0开始,它支持一个新选项来显示根项目的路径,即使在子模块内部使用时该选项也有效:
git rev-parse --show-superproject-working-tree
Run Code Online (Sandbox Code Playgroud)
对我们来说不幸的是,如果我们不在子模块中,它不会打印任何内容。在这种情况下,--show-toplevel
仍然有效。无论我们是否在子模块中,此 Bash 代码都会完成这项工作:
git rev-parse --show-superproject-working-tree
Run Code Online (Sandbox Code Playgroud)
要修改"git config"答案:
git config --global --add alias.root '!pwd -P'
Run Code Online (Sandbox Code Playgroud)
并清理道路.非常好.
如果你正在寻找一个好的别名来做这个加上cd
如果你不是一个git目录就不要爆炸:
alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'
Run Code Online (Sandbox Code Playgroud)
git-extras
添加$ git root
请参阅https://github.com/tj/git-extras/blob/master/Commands.md#git-root
$ pwd
.../very-deep-from-root-directory
$ cd `git root`
$ git add . && git commit
Run Code Online (Sandbox Code Playgroud)
$ brew install git-extras
$ apt-get install git-extras
无论您是在git子目录中还是在顶层,这个shell别名都有效:
alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'
Run Code Online (Sandbox Code Playgroud)
更新为使用现代语法而不是反引号:
alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'
Run Code Online (Sandbox Code Playgroud)
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'
Run Code Online (Sandbox Code Playgroud)
其他一切都失败了,无论是去主页目录还是惨不忍睹.这是回到GIT_DIR的最快捷,最短的方式.
这是我编写的一个脚本,它处理两种情况: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
)
Run Code Online (Sandbox Code Playgroud)
希望这很有帮助.