在bash中获取git状态的最快方法

Mal*_*rba 11 git bash

有一段时间我一直__git_ps1在我的bash的PS1提示符中使用该函数(with PS1='\w$(__git_ps1)').现在我想根据分支状态对其进行着色.

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

所以我问:有没有更快的方法来检查当前git文件夹的状态? __git_ps1比手动解析快很多git branch,所以我想可能还有一些隐藏的git函数.

Pet*_*oes 7

不完全是你的答案,但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
Run Code Online (Sandbox Code Playgroud)

藏匿文件

git rev-parse --verify refs/stash >/dev/null 2>&1 && color for stashed files
Run Code Online (Sandbox Code Playgroud)

未跟踪的文件

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

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

  • 很好的答案,但第一个脚本不适合我。看来 `git rev-parse --quiet --verify HEAD >/dev/null` 总是返回 `0`,无论暂存/未暂存状态如何。 (2认同)

Von*_*onC 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
Run Code Online (Sandbox Code Playgroud)

通过将“ --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
Run Code Online (Sandbox Code Playgroud)

这遵循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 以避免内存泄漏

签字人: Elijah Newren

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

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

然后我注意到在之前的提交中clear_directory()只负责其中的一部分字段,dir_struct,尽管我们在内部分配了条目 [] 和忽略 [] 给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


ver*_*nzt 5

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

您可以使用它来执行以下操作:

git diff --quiet
    || echo "There be changes!"
Run Code Online (Sandbox Code Playgroud)