在 Fish 中,如何使用 .git 目录 cd 到最近的父目录?

在 Fish 中,如何使用 .git 目录 cd 到最近的父目录?

我用的是鱼壳。有时,我发现自己处于子目录的子目录的子目录中,有几层,我想用一个.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

相关内容