简体   繁体   English

如何在存储库中搜索特定字符串的所有Git和Mercurial提交?

[英]How to search through all Git and Mercurial commits in the repository for a certain string?

I have a Git repository with few branches and dangling commits. 我有一个Git存储库,有很少的分支和悬挂提交。 I would like to search all such commits in repository for a specific string. 我想在存储库中搜索所有此类提交以获取特定字符串。

I know how to get a log of all commits in history, but these don't include branches or dangling blobs, just HEAD's history. 我知道如何记录历史上所有提交的日志,但这些不包括分支或悬空blob,只是HEAD的历史记录。 I want to get them all, to find a specific commit that got misplaced. 我希望得到所有这些,找到一个错位的特定提交。

I would also like to know how to do this in Mercurial, as I'm considering the switch. 我也想知道如何在Mercurial中做到这一点,因为我正在考虑转换。

You can see dangling commits with git log -g . 您可以使用git log -g查看悬空提交。

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

So you could do this to find a particular string in a commit message that is dangling: 所以你可以这样做,在悬挂的提交消息中找到一个特定的字符串:

git log -g --grep=search_for_this

Alternatively, if you want to search the changes for a particular string, you could use the pickaxe search option, "-S": 或者,如果要搜索特定字符串的更改,可以使用pickaxe搜索选项“-S”:

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 will add the -G option , allowing you to pass -G<regexp> to find when a line containing <regexp> was moved, which -S cannot do. Git 1.7.4将添加-G选项 ,允许您传递-G <regexp>以查找何时移动包含<regexp>的行,-S无法执行。 -S will only tell you when the total number of lines containing the string changed (ie adding/removing the string). -S只会告诉你包含字符串的行总数何时发生变化(即添加/删除字符串)。

Finally, you could use gitk to visualise the dangling commits with: 最后,您可以使用gitk来显示悬空提交:

gitk --all $(git log -g --pretty=format:%h)

And then use its search features to look for the misplaced file. 然后使用其搜索功能查找放错位置的文件。 All these work assuming the missing commit has not "expired" and been garbage collected, which may happen if it is dangling for 30 days and you expire reflogs or run a command that expires them. 所有这些工作假设丢失的提交没有“过期”并且被垃圾收集,如果它悬挂30天并且您使explog到期或运行使它们到期的命令,则可能发生这种情况。

In Mercurial you use hg log --keyword to search for keywords in the commit messages and hg log --user to search for a particular user. 在Mercurial中,您使用hg log --keyword在提交消息中搜索关键字,使用hg log --user搜索特定用户。 See hg help log for other ways to limit the log. 有关限制hg help log的其他方法,请参阅hg help log日志。

In addition to richq answer of using git log -g --grep=<regexp> or git grep -e <regexp> $(git log -g --pretty=format:%h) : take a look at the following blog posts by Junio C Hamano, current git maintainer 除了richq答案用的git log -g --grep=<regexp>git grep -e <regexp> $(git log -g --pretty=format:%h)看看下面的博客文章作者:Junio C Hamano,现任git维护者


Summary 摘要

Both git grep and git log --grep are line oriented , in that they look for lines that match specified pattern. git grepgit log --grep都是面向行的 ,因为它们寻找与指定模式匹配的行。

You can use git log --grep=<foo> --grep=<bar> (or git log --author=<foo> --grep=<bar> that internally translates to two --grep ) to find commits that match either of patterns (implicit OR semantic). 您可以使用git log --grep=<foo> --grep=<bar> (或git log --author=<foo> --grep=<bar> ,内部转换为两个--grep )来查找提交匹配任何一种模式(隐含语义)。

Because of being line-oriented, the useful AND semantic is to use git log --all-match --grep=<foo> --grep=<bar> to find commit that has both line matching first and line matching second somewhere. 因为是面向行的,有用语义是使用git log --all-match --grep=<foo> --grep=<bar>找到提交 同时具有线路匹配第一和线路匹配第二某处。

With git grep you can combine multiple patterns (all which must use the -e <regexp> form) with --or (which is the default), --and , --not , ( and ) . git grep可以组合多个模式(所有这些都必须使用-e <regexp>用形式) --or (这是默认值), --and--not() For grep --all-match means that file must have lines that match each of alternatives. 对于grep --all-match意味着该文件必须具有与每个备选项匹配的行。

Building on rq's answer, I found this line does what I want: 基于rq的答案,我发现这条线做了我想要的:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

Which will report the commit ID, filename, and display the matching line, like this: 这将报告提交ID,文件名,并显示匹配的行,如下所示:

91ba969:testFile:this is a test

... Does anyone agree that this would be a nice option to be included in the standard git grep command? ...有没有人同意这是一个很好的选择,可以包含在标准的git grep命令中?

Any command that takes references as arguments will accept the --all option documented in the man page for git rev-list as follows: 任何以引用作为参数的命令都将接受git rev-list手册页中记录的--all选项,如下所示:

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

So for instance git log -Sstring --all will display all commits that mention string and that are accessible from a branch or from a tag (I'm assuming that your dangling commits are at least named with a tag). 因此,例如git log -Sstring --all将显示所有提交string提交,并且可以从分支或标记访问(我假设您的悬挂提交至少以标记命名)。

With Mercurial you do a 使用Mercurial,你可以做到

$ hg grep "search for this" [file...]

There are other options that narrow down the range of revisions that are searched. 还有其他选项可以缩小搜索范围。

Don't know about git, but in Mercurial I'd just pipe the output of hg log to some sed/perl/whatever script to search for whatever it is you're looking for. 不知道git,但是在Mercurial中我只是将hg日志的输出传递给某些sed / perl /无论什么脚本来搜索你正在寻找的任何东西。 You can customize the output of hg log using a template or a style to make it easier to search on, if you wish. 如果您愿意,可以使用模板或样式自定义hg日志的输出,以便于搜索。

This will include all named branches in the repo. 这将包括repo中的所有命名分支。 Mercurial does not have something like dangling blobs afaik. Mercurial没有类似悬挂blob的东西。

if you are a vim user, you can install tig (apt-get install tig), and use /, same command to search on vim 如果您是vim用户,可以安装tig(apt-get install tig),并使用/,相同的命令在vim上搜索

https://blogs.atlassian.com/2013/05/git-tig/ https://blogs.atlassian.com/2013/05/git-tig/

To add just one more solution not yet mentioned, I had to say that using gitg's graphical search box was the simplest solution for me. 要添加一个尚未提及的解决方案,我不得不说使用gitg的图形搜索框对我来说是最简单的解决方案。 It will select the first occurrence and you can find the next with Ctrl-G. 它将选择第一个匹配项,您可以使用Ctrl-G找到下一个匹配项。

One command in git that I think it's much easier to find a string: 在git中的一个命令,我认为找到一个字符串要容易得多:

git log --pretty=oneline --grep "string to search"

works in Git 2.0.4 适用于Git 2.0.4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM