gpt4 book ai didi

git grep 主要仓库和特定子模块

转载 作者:太空狗 更新时间:2023-10-29 13:43:45 25 4
gpt4 key购买 nike

我在主存储库中有两个子模块,它们与主存储库中的代码紧密耦合。如此之多,以至于在执行 git grep 时,我希望将主仓库与这两个特定的子模块一起进行 grep。我不能为每个“git grep ... || true”做一个完整的 git 子模块,因为我还有其他非常大的子模块,并且 grep 遍历这些子模块每个子模块可能需要 15-20 秒。

因此,我需要一个比 git submodule foreach 更具体的解决方案,它允许我指定要 grep 的特定子模块,以及 grep 我的主仓库。

我的两个子模块是 foosubmodules/bar

这是我目前的解决方案。这让我可以说 git gpx -i something.*interesting 等。我在创建 git 别名方面还是个新手,所以我希望这个解决方案可以得到改进。

[alias]
inr = "!f() { cd $1 && $2 ;}; f"
gprs = "!f() { for r in $1; do git inr $r \"git grep $2\" | perl -pe \"s|^|$r/|\"; done ;}; f"
gpx = "!f() { git grep $*; git gprs 'foo submodules/bar' \"$*\" ;}; f"

编辑:我发现的一个问题是我丢失了正则表达式周围的引号,所以我不能这样调用:git gpx -i "foo bar",因为它被翻译成这样:git grep -i foo bar。我想不出一个干净的方法来避免这种情况。

最佳答案

重做:我用那个脚本编写了一个 bash 脚本来执行分页(在底部提到),但注意到您的示例已经在搜索路径前添加了前缀。我稍微修改了您的别名,现在发现这对我有用:

[alias]
gpx = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git grep $@ | perl -pe \"s|^|$r/|\"; ); done ;}; f"

如果您使用子 shell,那么您可以折叠“inr”功能“( cd $1; cmd; ... )”(因为它隔离了 chdir),如果您添加一个“.”然后它也会搜索 super 模块。我用类似的东西测试了它

git --no-pager gpx 'foo submodules/bar' --color=always -nIE '\w+\(\w*\)' | less -R

它似乎很适合转义(打算使用 git-rev-parse --sq-quote 但似乎 git 已经为你处理了)。这似乎比下面列出的脚本内容更优雅,也许我可以使用带有函数前缀的别名样式并替换/简化许多该功能。话虽如此,感谢您展示这一点!

试图为传呼机的东西使用 gpx 创建另一个别名,但是转义有点麻烦,所以我也创建了另一个别名:

[alias]
gpxp = "!f() { list=$1; shift; for r in . $list; do ( cd $r; git --no-pager grep --color=always $@ | perl -pe \"s|^|$r/|\"; ); done | less -R ;}; f"

然后就变成了

git gpxp 'foo submodules/bar' -nIE '\w+\(\w*\)'

注意:如果出现错误,这些错误将显示在 grep 文本结果中。

原创:

我遇到了 similar problems转义和使用 git 别名。

我一直在为 git-submodule 编写一个小扩展,它允许您进行约束迭代。该功能的帮助在 git-submodule-ext foreach [-c | --constrain](helpimplementation)。安装说明在这里:README

如果您希望将迭代限制为foosomething/bar,您可以在 super 模块中执行

git config scm.focusGroup 'foo something/bar'

然后做你的greppage

git --no-pager submodule-ext foreach -t -r -c -k git grep 'expression'

或者如果你使用别名安装,

git --no-pager tsfer -c -k git grep 'expression'

git --no-pager 选项是为了防止每个子模块在每次搜索后 pull 起 $GIT_PAGER。我向脚本添加了一个 --keep-going 选项,这样如果 grep 没有返回任何内容(导致非零状态),它不会停止迭代。另一种解决方案是使用 git tsfer -c -k 'git grep "expression"|| 在子模块文档中执行示例:',它们等效地工作。

如果您的表达式很复杂,例如查找函数调用 '\w+\(\w*\)',您需要将整个表达式括在双引号中:

git --no-pager tsferp -c -k "git grep -E '\w+\(\w*\)'"

如果转义是一个大问题并且您使用的是 bash,则导出一个函数以在迭代中使用(我修改的扩展脚本使用的是 bash,而不是 Git 的标准 /bin/sh)

greppage() {
git grep -E 'some(really)?complex.*\(expression\)'
}
export -f greppage
git --no-pager tsfer -c -k greppage

希望对您有所帮助。

注意:目前的一个缺点是可能很难找出匹配项位于哪个子模块。可以通过某种方式在子模块的 $name 前面添加修复,但是我查看了 git grep 的选项,但找不到类似的东西。我稍微修改了命令并想出了这个,呃,'紧凑',命令:

git --no-pager sube -q foreach -t -r -c -k "echo [ \$name ]'\n'; git grep --color=always -E '\w+\(\w*\)'; echo '\n\n'" | less -R

这会使 foreach 安静(抑制“Entering”输出),并添加一些大括号和换行符以便更容易看到子模块之间的划分。让我看看我是否可以为此创建一个函数/别名以使其更容易。

编辑:这是拼凑在一起的脚本,不是那么优雅。我只是把它变成了一个 bash 函数来简化事情

git-greps() { git --no-pager sube -q foreach -t -r -c -k "git grep --color=always $(git rev-parse --sq-quote "$@") | perl -pe \"s|^|\$name/|\"" | less -R; }

例子

git-greps -nIE '\w+\(\w*\)'

关于git grep 主要仓库和特定子模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17057901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com