git 如何在git repo中grep文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5245223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:18:45  来源:igfitidea点击:

How to grep files in git repo?

gitgrep

提问by Peter Bengtsson

I love git grepto search in all files checked in to a repo. It's great. But is it possible to use it (or some other git command) to just use to find files (independent of content)?

我喜欢git grep在所有签入 repo 的文件中进行搜索。这很棒。但是是否可以使用它(或其他一些 git 命令)来仅用于查找文件(独立于内容)?

At the moment I do this:

目前我这样做:

$ find . | grep middleware

which works but it's not using the git index which means it's going through every found file and it reports on files that are matching the .gitignore.

它可以工作,但它没有使用 git 索引,这意味着它会遍历每个找到的文件,并报告与 .git 文件匹配的文件.gitignore

Any ideas for clever tricks?

任何聪明的技巧的想法?

回答by araqnid

Maybe you want git ls-fileswhich lists the files in the index? (and automatically adjusts for your current directory inside the git work directory)

也许您想要git ls-files哪个列出索引中的文件?(并自动调整您在 git 工作目录中的当前目录)

回答by Steven

I think git ls-fileswill do the trick for you.

我想git ls-files会为你做的伎俩。

So:

所以:

 git ls-files "*middleware*"

回答by Mike Seplowitz

You might consider a non-git solution in this case.

在这种情况下,您可能会考虑使用非 git 解决方案。

finditself has the ability to do what you want in a more efficient manner than piping its results into grep:

find本身有能力以更有效的方式做你想做的事情,而不是将结果输入grep

find . -name 'middleware*'

You will need to quote the pattern so that the *isn't expanded by the shell before being passed to find.

您将需要引用该模式,以便*在传递给find.

There is a powerful program called ackthat is, well, better than grep, and one of my favorite uses for ackis exactly what you've mentioned -- finding files that match a pattern within a tree. ackuses perl regexps, not shell fileglobs, though.

有一个功能强大的程序ack,它比 grep 更好,而我最喜欢的用途之一ack正是您提到的 —— 在树中查找与模式匹配的文件。ack不过,使用 perl regexp,而不是 shell fileglob。

ack -g middleware

If you want to search withinthose files, acklets you do that more easily than writing a shell loop over the results of findthat greps within each file. Compare the two and see which one you prefer:

如果你想搜索的那些文件,ack让你这样做更容易比在结果编写shell循环findgreps各自文件中。比较两者,看看你更喜欢哪一个:

for f in $(find . -name 'middleware*')
do
    grep 'pattern in file' $f
done

versus

相对

ack -G 'middleware' 'pattern in file'

I highly recommend ackas something to add to your toolkit.

我强烈建议ack将其添加到您的工具包中。

回答by mirabilos

I have the same problem regularily, and I just went and hacked git find– if you don't use the Debian packageyou can just copy the git-findscript to /usr/lib/git-core/(or comparable) and enjoy it.

我经常git find遇到同样的问题,我只是去黑了- 如果你不使用Debian 包,你可以将git-find脚本复制到/usr/lib/git-core/(或类似的)并享受它。

It can be used in several modes, the easiest of which is indeed:

它可以在多种模式下使用,其中最简单的确实是:

git find \*middleware\*        # or
git find '*middleware*'        # which is short for
git find -name '*middleware*'

Combining is also possible (and almost as flexible as regular find, you just have to write the -aexplicitly):

组合也是可能的(几乎和常规一样灵活find,你只需要-a明确地写):

git find \( -name \*.java -o -name \*.js \) -a ! -ipath \*/test/\*

It has a couple more options, most of which handle with filtering the name or full (partial, i.e. below the current working directory) path, some of them case-insensitively (-inameand friends), and two global options, one to toggle regexp between POSIX Basic (default) and POSIX Extended, the other toggles symlinks (default on); this finds only files (and symlinks), not directories or submodules (“gitlinks”) by design.

它有几个选项,其中大部分处理过滤名称或完整(部分,即在当前工作目录下方)路径,其中一些不区分大小写(-iname和朋友),以及两个全局选项,一个用于在正则表达式之间切换POSIX Basic(默认)和 POSIX Extended,另一个切换符号链接(默认开启);这仅查找文件(和符号链接),而不是设计的目录或子模块(“gitlinks”)。

It can also pass the file list to regular find(1)if it's not too long (it must be passed on the command line), which allows for things like…

如果文件列表不太长(必须在命令行上传递),它还可以将文件列表传递给常规的find(1),这允许诸如……

git find -- -mtime -100

… at slight filesystem cost (finddoes access the filesystem), but on the other hand, almost all (not search depth-specific stuff) of findworks, and you only get to operate on files “in the index”, i.e. known to git (present in the HEAD commit or git added).

...以很小的文件系统成本(find确实访问文件系统),但另一方面,几乎所有(不是搜索特定深度的东西)的find工作,你只能对“索引”中的文件进行操作,即git已知(存在于 HEAD 提交或git added 中)。

It's a bit picky about unresolved conflicts though. If you notice any problems with it, just drop me a note (here, or via IRC).

不过,对未解决的冲突有点挑剔。如果您发现它有任何问题,请给我留言(在这里,或通过 IRC)。

PS: Feel free to lobby the official git people to subtree-merge the git-find repository, I'd be more than happy to have it integrated into git proper (the licence is even more liberal, you just need the mkshshell in a somewhat recent (50 should be sufficient) version, but it's the most widespread Unix shell nowadays so that's okay).

PS:请随意游说官方 git 人员对 git-find 存储库进行子树合并,我很乐意将它集成到 git 中(许可证更加自由,您只需要mksh稍微有点最近的(50 个应该足够了)版本,但它是当今最流行的 Unix shell,所以没关系)。

回答by user214810

git now has matured search functionality (as the previous poster mentioned). You can search file names, extensions, by programming language.. You can search inside at file contents... etc.

git 现在具有成熟的搜索功能(如上一个海报所述)。您可以通过编程语言搜索文件名、扩展名……您可以在文件内容中搜索……等。

You search when you log into GitHub, at the search field in the upper - left of the screen.

您在登录 GitHub 时在屏幕左上角的搜索字段中进行搜索。

See this for details: https://help.github.com/en/articles/searching-code

详情请参阅:https: //help.github.com/en/articles/searching-code

回答by Joakim

Pure git solution

纯git解决方案

git grephas built-in support to limit the grep to a glob of files. The other answers all use external tools to do the actual grepping, which misses the point.

git grep具有内置支持以将 grep 限制为一团文件。其他答案都使用外部工具来进行实际的 grepping,这没有抓住重点。

Example from the git grepman page.

git grep手册页中的示例。

git grep 'time_t' -- '*.[ch]'

Looks for time_t in all tracked .c and .h files in the working directory and its subdirectories.

在工作目录及其子目录中所有跟踪的 .c 和 .h 文件中查找 time_t。

From the option descriptions.

从选项说明。

--Signals the end of options; the rest of the parameters are limiters.

<pathspec>…?If given, limit the search to paths matching at least one pattern. Both leading paths match and glob(7) patterns are supported.

--表示期权结束;其余参数是限制器。

<pathspec>…?如果给定,则将搜索限制为匹配至少一种模式的路径。支持前导路径匹配和 glob(7) 模式。

So to translate your example (which did not include something to limit the search however so I added it here):

因此,要翻译您的示例(其中不包含限制搜索的内容,因此我将其添加到此处):

$ find . -name '*.txt' | grep middleware

You would do:

你会这样做:

$ git grep middleware -- '*.txt'