12

一段时间以来,我一直__git_ps1在 bash 的 PS1 提示符(带有PS1='\w$(__git_ps1)')中使用该函数。现在我想根据分支状态为它着色。

我编写了一个 bash 函数来检查当前分支是否被修改,并根据状态将颜色设置为红色或白色。问题是它用于git status检查状态(这是我知道的唯一方法),并且比 慢几倍__git_ps1,这足以在我使用提示时引起烦人的延迟(我处于非常虚弱的状态)上网本)。

所以我问:有没有更快的方法来检查当前 git 文件夹的状态? __git_ps1比手动解析要快得多git branch,所以我想可能还有其他隐藏的 git 功能。

4

6 回答 6

8

不完全是你的答案,但 bash-completion 有这个内置的。

如果将 bash ENV GIT_PS1_SHOWDIRTYSTATE 设置为非空值,则未暂存 (*) 和暂存 (+) 更改将显示在分支名称旁边。您可以使用 bash.showDirtyState 变量配置每个存储库,一旦启用 GIT_PS1_SHOWDIRTYSTATE,该变量默认为 true。

您还可以通过将 GIT_PS1_SHOWSTASHSTATE 设置为非空值来查看当前是否隐藏了某些内容。如果隐藏了某些内容,则分支名称旁边将显示一个“$”。

如果您想查看是否有未跟踪的文件,则可以将 GIT_PS1_SHOWUNTRACKEDFILES 设置为非空值。如果有未跟踪的文件,则分支名称旁边将显示一个“%”。

不确定启用此功能时速度会降低。如果你想做着色:

分阶段文件:

if git rev-parse --quiet --verify HEAD >/dev/null; then
 git diff-index --cached --quiet HEAD -- || color for staged changes
else
  color unstaged changes
fi

隐藏的文件

git rev-parse --verify refs/stash >/dev/null 2>&1 && color for stashed files

未跟踪的文件

if [ -n "$(git ls-files --others --exclude-standard)" ]; then
  Color untrack files
fi

上面的代码片段来自 bash-completion 脚本。

于 2012-06-20T15:37:56.833 回答
6

注意:Git 2.6+(2015 年第三季度)应该会加速这种__git_ps1状态:

请参阅SZEDER Gábor ( )的commit dd160d7commit 6bfab99(2015 年 7 月 19 日) 。(由Junio C Hamano 合并——提交 461c119中,2015 年 8 月 3 日)szeder
gitster

bash 提示:更快的未跟踪状态指示器与未跟踪的目录

如果启用了未跟踪状态指示器,则__git_ps1()通过运行“ git ls-files”来查找未跟踪文件。
如果未跟踪目录包含大量文件,这可能会明显变慢,因为它列出了在未跟踪目录中找到的所有文件,只是立即重定向到/dev/null
这是运行的实际命令__git_ps1()

$ ls untracked-dir/ |wc -l
100000
$ time git ls-files --others --exclude-standard --error-unmatch \
  -- ':/*' >/dev/null 2>/dev/null

real    0m0.955s
user    0m0.936s
sys 0m0.016s

通过另外将“ --directory --no-empty-directory”选项传递给“ git ls-files”以仅显示非空未跟踪目录的名称而不是其所有内容来消除此延迟:

$ time git ls-files --others --exclude-standard --directory \
  --no-empty-directory --error-unmatch -- ':/*' >/dev/null 2>/dev/null

real    0m0.010s
user    0m0.008s
sys 0m0.000s

这遵循ea95c7b(完成:改进文件名完成的未跟踪目录过滤,2013-09-18,git 1.8.5)。


确保使用 Git 2.29(2020 年第四季度),因为在影响git ls-files.

请参阅Elijah Newren ( ) 的commit eceba53commit dad4f23(2020 年 8 月 18 日(由Junio C Hamano 合并 -- --提交 ad00f44中,2020 年 8 月 24 日)newren
gitster

dir: 修复有问题的 API 以避免内存泄漏

签字人:以利亚·纽伦

dir结构似乎有许多泄漏和问题。

首先我注意到了这一点parent_hashmap并且recursive_hashmap被泄露了(尽管 Peff 在我之前注意到并提交了修复)。

然后我注意到在之前的提交中clear_directory()只负责其中的一个字段子集,dir_struct,尽管我们在内部分配了 entry[] 和 ignored[] 到dir.c.
当然,这导致许多调用者泄漏或随意尝试释放这些数组及其内容。

进一步挖掘,我发现尽管顶部附近有非常清晰的文档,当用户不再需要时dir.h,人们应该调用,但有四个调用者根本不打扰这样做。 然而,他们中的两个人清楚地考虑了泄漏,因为他们有一个指令,这对我来说表明释放数据的方法太不清楚了。 我怀疑 API 的不明显性及其漏洞导致人们避免使用它,然后滚雪球般地引发更多问题,包括、和问题。clear_directory()dir_struct,
UNLEAK(dir)
entries[]ignored[]parent_hashmap,recursive_hashmap

重命名clear_directory()dir_clear()更符合 git 中的其他数据结构,并引入 adir_init()来处理建议的 memsettingdir_struct到全零。
我希望像"dir_clear()" 这样的名称更清楚,并且 的存在dir_init()将为那些查看代码的人提供提示,他们需要查找 adir_clear()或 adir_free()并引导他们找到dir_clear().

这会影响:

  • git add
  • git check-ignore
  • git clean
  • git grep
  • git ls-files
  • git stash
  • git merge
于 2015-08-16T21:08:30.137 回答
5

git diff --quiet如果工作目录发生更改,则返回 1,并且git diff --quiet --cached对索引执行相同操作。

你可以用它来做:

git diff --quiet
    || echo "There be changes!"
于 2012-06-20T18:36:22.147 回答
2
! git diff-index --cached --quiet HEAD      # fastest staged-changes test
! git diff-files --quiet                    # fastest unstaged-changes test
! git diff-index --quiet          HEAD      # fastest any-changes test
stdbuf -oL git ls-files -o | grep -qs .     # fastest untracked-files test
git rev-parse -q --verify refs/stash >&-    # fastest any-stash test

如果忽略状态对未跟踪文件很重要,请使用--exclude-standard -oi未跟踪-忽略和--exclude-standard -o未跟踪和未忽略。

我知道获得 HEAD 绰号(分支名称或 sha)的最快方法是

{ git symbolic-ref -q --short HEAD || git rev-parse -q --short --verify HEAD; } 2>&-

如果你不在回购中,它会留下一个返回码,所以你可以例如

if HEAD=`{ git symbolic-ref -q --short HEAD || git rev-parse -q --verify HEAD;  } 2>&-`
then
        : in a git repo, $HEAD is the branch name or sha
fi

请注意,未跟踪文件测试取决于使用shopt -s lastpipefor运行bashzshksh默认以这种方式操作。

于 2019-05-04T17:45:07.970 回答
0

我正在使用 ksh 并且遇到了同样的问题。最重要的是,我的 Git 存储库位于 NFS 挂载上,这使得响应时间更慢。

要直接回答有关速度的问题,请尝试使用:

git ls-files -m

在首次进入不同的存储库后,似乎比“git status -s”快得多。一旦进入存储库,操作系统和 NFS 缓存似乎会大大加快此命令的速度。当深入到 git 工作目录树的底部时,这个命令也显得非常快速。

于 2014-05-23T15:16:55.437 回答
0

所有解决方案git最终都会限制git运行速度。您可以git通过将一些 fs-monitoring hooks 输入 git 来让自己运行得比这更快:

或者你可以做更少的工作,比如--directory --no-empty-directory但更进一步:

于 2020-05-14T03:48:52.597 回答