更新

更新

在我的zshshell 中,我根据我是否在git存储库内动态更改提示。我正在使用以下 git 命令来检查:

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
...

现在我还想区分当前目录是否被忽略git。所以我在我的if声明中又添加了一项检查:

if $(git rev-parse --is-inside-work-tree >/dev/null 2>&1) && ! $(git check-ignore . >/dev/null 2>&1); then
...

这工作正常,但我想知道是否可以将其简化为一个git命令。由于提示符每次都会刷新ENTER,因此在某些速度较慢的机器上,它往往会显着减慢 shell 的速度。

更新

@Stephen Kitt 接受的解决方案效果很好,但以下情况除外:

我正在跨文件系统使用存储库。假设 git 驻留在/.git(因为我想跟踪 中的配置文件/etc),但我也想跟踪 中的一些文件/var/foo,这是一个不同的分区/文件系统。

当我位于/并执行以下命令时,一切都按预期工作,并且我得到返回代码1(因为/var/foo正在跟踪):

# git check-ignore -q /var/foo

但是当我位于 中的任何位置时/var,相同的命令会失败,并显示错误代码128和以下错误消息:

# git check-ignore -q /var/foo
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

但我认为这只是check-ignore命令的问题。否则 git 似乎可以在文件系统上正常工作。我可以/var/foo很好地跟踪文件。

预期的行为应该是git check-ignore -q /var/foo返回1,如果没有被跟踪,则git check-ignore -q /var/bar返回。0

我该如何解决这个问题?

答案1

git check-ignore ..如果不在存储库中(或发生任何其他错误),则会失败并显示退出代码 128 git,并且仅当不忽略路径时才会显示退出代码 1。所以你只能检查后者:

git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ... 

在 内部,您正在处理git 存储库中被忽略或不被忽略的then情况。.

要使其跨文件系统边界工作,请设置GIT_DISCOVERY_ACROSS_FILESYSTEMtrue

GIT_DISCOVERY_ACROSS_FILESYSTEM=true git check-ignore -q . 2>/dev/null; if [ "$?" -ne "1" ]; then ...

答案2

首先应该是:

if
  git rev-parse --is-inside-work-tree >/dev/null 2>&1 &&
    ! git check-ignore . >/dev/null 2>&1
then...

命令替换 ( $(...)) 是检索命令的输出。在这里,当您将其重定向到时没有输出/dev/null,如果有,它将被视为要执行的命令(并检查其退出状态)。

请注意,仅当第一个命令成功时才会运行第二个命令。

@StephenKitt 展示了如何将这两个命令分解为一个git命令,但如果这仍然对性能没有帮助,您始终可以将信息缓存在关联数组中。

typeset -A is_git # declared globally in your ~/.zshrc
if (( ! $+is_git[$PWD] )); then
  git check-ignore -q . 2> /dev/null
  is_git[$PWD]=$(( $? == 1 ))
fi

if (( $is_git[$PWD] )); then...

如果您重命名目录、删除.git目录或更改忽略文件的列表,该缓存可能会变得过时。您可以使用is_git=()或 重新启动zsh使其无效exec zsh

另一种选择是仅在使用挂钩输入目录时进行检查chpwd

check_git() {
  git check-ignore -q . 2> /dev/null
  (( is_git = $? == 1 ))
}
chpwd_functions+=(check_git)

然后,在您的提示例程中,只需执行以下操作:

if (( is_git )); then...

相关内容