现在实现(git 1.9/2.0,2014 年第一季度),在 commit ef79b1f 和 commit 1649612 中引入了 pathspec magic :(exclude) 及其缩写形式 :!,由
Nguyễn Thái Ngọc Duy (pclouds),文档可以在here找到。
您现在可以记录除子文件夹内容之外的所有内容:
git log -- . ':(exclude)sub'
git log -- . ':!sub'
或者您可以排除该子文件夹中的特定元素
-
一个特定的文件:
git log -- . ':(exclude)sub/sub/file'
git log -- . ':!sub/sub/file'
-
sub 中的任何给定文件:
git log -- . ':(exclude)sub/*file'
git log -- . ':!sub/*file'
git log -- . ':(exclude,glob)sub/*/file'
您可以使排除项不区分大小写!
git log -- . ':(exclude,icase)SUB'
作为Kenny Evitt noted
如果您在 bash shell 中运行 git,请不要忘记使用单引号或在双引号中正确转义,例如':!sub' 或 ":\!sub"。否则你会遇到bash: ... event not found errors
注意:Git 2.13(2017 年第二季度)将添加同义词 ^ 到 !
参见Linus Torvalds (torvalds)commit 859b7f1、commit 42ebeb9(2017 年 2 月 8 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 015fba3,2017 年 2 月 27 日)
pathspec 魔术:添加 '^' 作为 '!' 的别名
为否定路径规范选择“!”最终不仅不匹配
我们为修订所做的事情,对于shell来说也是一个可怕的角色
扩展,因为它需要引用。
所以添加“^”作为排除路径规范条目的替代别名。
请注意,在 Git 2.28(2020 年第三季度)之前,在收集工作树中包括未跟踪路径在内的路径时,使用负路径规范已被破坏。
见Elijah Newren (newren)commit f1f061e(2020 年 6 月 5 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 64efa11,2020 年 6 月 18 日)
dir:修复否定路径规范的处理
报告人:John Millikin
签字人:Elijah Newren
do_match_pathspec() 以match_pathspec_depth_1() 开始,为了正确起见,应该只从match_pathspec_depth() 调用。 match_pathspec_depth() 后来重命名为 match_pathspec(),所以我们今天期望的不变式是 do_match_pathspec() 在 match_pathspec() 之外没有直接调用者。
不幸的是,这两个函数的重命名失去了这个意图,并且在提交75a6315f74 中添加了对do_match_pathspec() 的额外调用(“ls-files:为子模块添加路径规范匹配”,2016-10-07, Git v2.11.0-rc0 -- merge 列在 batch #11) 和 89a1f4aaf7 ("dir: 如果我们的路径规范可能匹配目录下的文件,递归到它",2019-09-17,Git v2 .24.0-rc0)。
当然,do_match_pathspec() 比 match_pathspec() 有一个重要的优势——match_pathspec() 会将标志硬编码为两个值之一,而这些新调用者需要为标志传递一些其他值。
另外,虽然直接调用do_match_pathspec() 是不正确的,但可观察到的最终输出可能没有任何区别,因为该错误只是意味着fill_diretory() 会递归到不需要的目录中。
由于后续对目录下各个路径的 dos-this-path-match 检查会导致这些额外路径被过滤掉,因此与使用错误函数的唯一区别是不必要的计算。
对do_match_pathspec() 的第二次错误调用涉及到(通过直接移动或通过复制+编辑)到后来的一些重构中。
查看提交 777b420347 ("dir: 同步 treat_leading_path() 和 read_directory_recursive()", 2019-12-19, Git v2.25.0-rc0 -- merge), 8d92fb2927 ("@987654393 @: 用线性算法替换指数算法”, 2020-04-01, Git v2.27.0-rc0 -- merge 列在batch #5), 和95c11ecc73 ("Fix-prone fill_directory() API;让它只返回匹配项”,2020-04-01,Git v2.27.0-rc0 -- merge 列在 batch #5 中)。
最后一个在单个文件中引入了do_match_pathspec() 的用法,从而导致返回不应该返回的单个路径。
调用do_match_pathspec() 而不是match_pathspec() 的问题是任何否定模式,例如'`:!unwanted_path`` 都会被忽略。
添加一个新的match_pathspec_with_flags() 函数来满足指定特殊标志的需求,同时仍然正确检查否定模式,在do_match_pathspec() 上方添加一个大注释以防止其他人滥用它,并将do_match_pathspec() 的当前调用者更正为使用match_pathspec() 或match_pathspec_with_flags()。
最后一点是,DO_MATCH_LEADING_PATHSPEC 在使用 DO_MATCH_EXCLUDE 时需要特别考虑。
DO_MATCH_LEADING_PATHSPEC 的意义在于,如果我们有类似的路径规范
*/Makefile
我们正在检查类似的目录路径
src/module/component
我们希望将其视为匹配项,以便我们递归到目录中,因为它_might_ 在下面某处有一个名为Makefile 的文件。
但是,当我们使用排除模式时,即我们有一个类似的路径规范
:(exclude)*/Makefile
我们不想说像这样的目录路径
src/module/component
是一个(否定的)匹配。
虽然可能在该目录下的某处有一个名为“Makefile”的文件,但也可能有其他文件,我们不能先发制人地排除该目录下的所有文件;我们需要递归然后检查单个文件。
调整DO_MATCH_LEADING_PATHSPEC 逻辑,只为正路径规范激活。