自2011年起,正如OP评论所述,Git支持完整的文件名完成,自~1.8.2版本开始。
但是在Git 2.18(2018年第二季度)中,提供路径列表的shell完成(在contrib/
中)已经得到了一定的优化。
请参见提交78a2d21(2018年4月4日),作者为Clemens Buchacher(drizzd
)。
(由Junio C Hamano -- gitster
--于提交3a940e9中合并,2018年4月25日)
完成
:提高ls-files
过滤器性能
From the output of ls-files
, we remove all but the leftmost path
component and then we eliminate duplicates. We do this in a while
loop,
which is a performance bottleneck when the number of iterations is large
(e.g. for 60000 files in linux.git
).
$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
real 0m11.876s
user 0m4.685s
sys 0m6.808s
Replacing the loop with the cut command improves performance
significantly:
$ COMP_WORDS=(git status -- ar) COMP_CWORD=3; time _git
real 0m1.372s
user 0m0.263s
sys 0m0.167s
The measurements were done with Msys2 bash, which is used by Git for
Windows.
When filtering the ls-files
output we take care not to touch absolute
paths. This is redundant, because ls-files
will never output absolute
paths. Remove the unnecessary operations.
The issue was originally reported Git for Windows issue 1533.
目录遍历代码存在冗余的递归调用,使其性能特征随着树的深度呈指数级增长,这在Git 2.27(2020年第二季度)中得到了修正。
请查看 commit c0af173, commit 95c11ec, commit 7f45ab2, commit 1684644, commit 8d92fb2, commit 2df179d, commit 0126d14, commit cd129ee, commit 446f46d, commit 7260c7b, commit ce5c61a (2020年4月1日) 由 Elijah Newren (newren
) 提交。
请查看 commit 0bbd0e8 (2020年4月1日) 由 Derrick Stolee (derrickstolee
) 提交。
(由Junio C Hamano -- gitster
--合并于commit 6eacc39, 2020年4月29日)
完成
:修复在未跟踪目录下的路径上 'git add
' 的问题
签名作者:Elijah Newren
据git邮件列表报道,自从git-2.25以来,
git add untracked-dir/
已经被tab键补全为
git add untracked-dir/./
造成这种情况的原因是,在
commit b9670c1f5e(“dir:fix checks on common prefix directory”,2019年12月19日,Git v2.25.0-rc0 -
merge)中,
git ls-files -o --directory untracked-dir/
(或等效的git -C untracked-dir ls-files -o --directory)开始报告
untracked-dir/
而不是列出该目录下面的路径。
值得注意的是,实际问题中的命令是
git -C untracked-dir ls-files -o --directory '*'
它等同于:
git ls-files -o --directory 'untracked-dir/*'
对于此问题来说,它的行为相同(“*”可以匹配空字符串),但对于所提出的修复程序变得相关。
起初,基于报告,我决定尝试将其视为回归,并尝试找到一种方法来恢复旧的行为,而不会破坏其他东西,或者至少尽可能少地破坏其他东西。然而,最终,我无法想出一种方法,既不会引起更多问题,又能解决问题。
旧的行为是一个错误:
虽然旧版本的git会避免使用git clean -f .git清除任何内容,但它会使用git clean -f .git/清除该目录下的所有内容。尽管使用的命令不同,但这是相关的,因为完全相同的更改修复了clean并改变了ls-files的行为。
旧版本的git将根据命令git ls-files -o --directory $SUBDIR中$SUBDIR是否有尾随斜杠而报告不同的结果。
旧版本的git违反了文档中未递归到与pathspec匹配的目录时指定--directory的行为。
最后,
commit b9670c1f5e(dir:fix checks on common prefix directory,2019年12月19日,Git v2.25.0-rc0)没有忽略此问题;它明确声明该命令的行为正在被更改以使其符合文档。
(此外,如果有帮助的话,尽管该提交在2.25系列期间合并,但此错误并未在2.25周期内报告,甚至在大多数2.26周期内也没有报告——它是在2.26发布前一天报告的。因此,该更改的影响至少有些小。)
改变ls-files调用的方式,而不是依赖于ls-files报告错误内容的bug,使其抓取深度更深的路径。
通过将“$DIR/*”(匹配“$DIR/”加上0个或多个字符)更改为“$DIR/?*”(匹配“$DIR/”加上1个或多个字符)来实现这一点。
请注意,在尝试完成文件名时不应添加“?”字符(例如,“git ls-files -o --directory merge.c?*”将无法正确返回“[merge.c](https://github.com/git/git/blob/c0af173a136785b3cfad4bd414b2fb10a130760a/merge.c)”当存在这样的文件时),因此我们必须确保仅在到目前为止指定的路径是目录的情况下添加“?”字符。
警告:Git 2.29(2020年第4季度)修复了在2.27周期中引入的回归问题。
请参见提交 cada730(2020年7月20日),作者为Martin Ågren(none
)。
(由Junio C Hamano -- gitster
--于提交82fafc7中合并,2020年7月30日)
dir
:在返回path_excluded
之前检查路径规范
报告者:Andreas Schwab
审核者:Elijah Newren
签署者:Martin Ågren
在
95c11ecc73(“修复易出错的
fill_directory()
API;仅返回匹配项”,2020-04-01,Git v2.27.0-rc0 --
merge列在
batch #5中),我们教
fill_directory()
,或更具体地说是
treat_path()
,检查任何路径规范以便简化调用者。
但是,在这样做时,我们为“排除”情况添加了一个稍微过早的返回。我们最终没有检查路径规范,这意味着当我们应该返回
path_none
时,我们返回
path_excluded
。因此,
git status --ignored -- pathspec
(man)可能会显示实际上不匹配“
pathspec
”的路径。
将“排除”检查移到我们检查任何路径规范之后。
Git 2.38 (Q3 2022) 修复了在 2.27 版本周期中引入的另一个回归问题,该问题可能会影响 git-bash 完成。
在非裸仓库中,当 core.worktree
配置变量指向其子目录作为仓库的目录时,Git 的行为在 Git 2.27 版本中出现了回归问题。
请查看提交d6c9a71,提交2712899(2022年6月16日),作者为Goss Geppert (ggossdev
)。
(由Junio C Hamano -- gitster
--在提交dc6315e中合并,2022年7月14日)
签名者:Goss Geppert
审核者:Elijah Newren
自从
8d92fb2(“
dir
: replace exponential algorithm with a linear one”,2020-04-01,Git v2.27.0-rc0 -
merge列在
batch #5中)开始遍历存储库的目录树时,当遍历开始于存储库的标准位置之外时,遍历存储库的目录树失败,因为遇到的存储库被识别为嵌套的外部存储库。
在此提交之前,在以下任一条件下,用户可以从用户的角度观察到无法遍历存储库的默认工作树位置(可能还有其他条件):
1. 将
core.worktree
位置设置为默认工作树的父目录;或
2. 在工作目录位于存储库的默认工作树位置之外时使用
--git_dir
选项
在这些条件下,无法将文件添加到索引或通过
ls-files
获取未跟踪文件列表的失败遍历存储库的默认工作树位置的症状。
此提交添加了一个检查,以确定在递归路径时遇到的嵌套存储库是否实际上是
the_repository
。如果是,则我们简单地将该目录视为不包含嵌套存储库。
git status
命令,然后知道该输入什么来执行git diff
命令。(但大多数情况下,我使用gitk
来查看差异。) - Paŭlo Ebermann