我用的是鱼壳。有时,我发现自己处于子目录的子目录的子目录中,有几层,我想用一个.git
目录返回到最近的父目录,因为这个目录代表根项目目录,可以这么说。
例如,假设我有这样的布局:
./
└── countries/
├── .git/
└── regions/
└── cities/
无论我是在countries/
或countries/regions/
或countries/regions/cities/
,我都希望此命令将目录更改为countries/
,因为它是包含.git
.
我如何在 Fish 中执行此操作?
答案1
git rev-parse
有一个“--show-cdup”选项,它将打印一个参数给 cd:
set -l cd (git rev-parse --show-cdup 2>/dev/null); and cd $cd
这2>/dev/null
会消除“不是 git 存储库”错误,并且在这种情况下会返回 falsey,因此如果在 git 存储库之外使用,git rev-parse --show-cdup
这不会执行任何操作。cd
或者你可以使用git rev-parse --show-toplevel
.我有理由确信这--show-cdup
将会发生身体的工作目录,因此如果您通过符号链接最终进入 git 存储库,它可能会打印错误的答案。
答案2
这是完成此任务的函数:
function cdroot
set directory_x (pwd)
while test -n "$directory_x" -a ! -e "$directory_x/.git"
set parts (string split '/' $directory_x)
set --erase parts[(count $parts)]
set directory_x (string join '/' $parts)
end
if test -n "$directory_x"
cd "$directory_x"
else
echo "Could not find closest root directory with .git child" >&2
return 1
end
end
要安装它,请将其放入~/.config/fish/functions/cdroot.fish
答案3
虽然git rev-parse
可以使这个变得微不足道,但这里有一个简单的通用解决方案,可以适应非.git
用例。
set start "$PWD"
while test ! -e .git
if ! cd .. ; or test "$PWD" = /
break
end
end
if test ! -e .git
cd "$start"
end