我有一个包含几个分支和悬空提交的Git存储库。我想在存储库中搜索所有这样的提交,查找特定字符串。
我知道如何获取所有历史提交记录的日志,但这些不包括分支或悬空的blob,只包括HEAD的历史记录。我想要获取它们全部,以找到一个被错放的特定提交。
我还想知道如何在Mercurial中执行此操作,因为我正在考虑切换。
你可以使用 git log -g
命令查看悬挂提交。
-g, --walk-reflogs
Instead of walking the commit ancestry chain, walk reflog entries from
the most recent one to older ones.
所以,您可以这样做来查找悬挂的提交消息中的特定字符串:
git log -g --grep=search_for_this
或者,如果您想要搜索特定字符串的更改,您可以使用拾取搜索选项"-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)
最后,您可以使用gitk可视化悬空提交:
gitk --all $(git log -g --pretty=format:%h)
然后使用其搜索功能查找丢失的文件。所有这些都是基于缺失的提交没有“过期”并且未被垃圾回收的情况下进行的,如果它悬挂了30天并且您到期了reflogs或运行了一个到期命令,则可能会发生这种情况。
!git fsck --unreachable | sed -ne 's/^unreachable commit //p' | xargs git log --no-walk
- dubiousjimgit log -g --all --pretty=format:"%h - %an, %ar : %s" | grep -i <authorNameHere>
。 - Adriano hg log --keyword
在提交消息中搜索关键字,使用 hg log --user
来搜索特定用户。有关限制日志的其他方法,请参见 hg help log
。hg log -k
搜索提交用户名和更改集中的文件名(我在 commands.py:log 中看到了这一点),这是我在 hg 中不理解的少数几件事之一。应该有单独的选项来搜索提交消息和文件名。似乎 hg log --template '{desc}\n'|grep
是确定的方法。 - Geoffrey Zhenghg grep --all <term>
。 - Jonathangit log -g --grep=<regexp>
或git grep -e <regexp> $(git log -g --pretty=format:%h)
的richq答案之外,还可以查看Junio C Hamano撰写的以下博客文章,他是当前Git维护者之一:
git grep和git log --grep都是行定位(line oriented)的,即它们查找与指定模式匹配的行。
您可以使用git log --grep=<foo> --grep=<bar>
(或在内部转换为两个--grep
的git log --author=<foo> --grep=<bar>
)来查找与任一模式相匹配的提交(隐含OR语义)。
由于是面向行的,因此有用的AND语义是使用git log --all-match --grep=<foo> --grep=<bar>
来查找具有两个匹配行的提交(commit)。
使用 git grep
命令可以结合多个模式(所有模式都必须使用 -e <regexp>
格式)并用 --or
(默认)、--and
、--not
、(
和 )
进行匹配。对于 grep,--all-match
表示文件必须具有与每个备选项匹配的行。
在rq的回答基础上,我发现这一行代码可以满足我的需求:
git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")
这将报告提交ID、文件名以及匹配行,就像这样:
91ba969:testFile:this is a test
有人认为这会是一个不错的选择,可以加入到标准的git grep命令中吗?
使用Mercurial时,您需要进行以下操作:
$ hg grep "search for this" [file...]
还有其他选项可以缩小搜索的修订范围。
hg grep --all
。 - Jonathanhg histgrep
,请参阅 hg help histgrep
。 - jesusbrialesgit rev-list
手册中记录的--all
选项,如下所示: --all
Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
command line as <commit>.
git log -Sstring --all
将显示所有提及 string
并且可以从分支或标记访问的提交(我假设您的悬挂提交至少使用标记命名)。git grep
命令中,似乎不需要使用--all
参数,而是会将其翻译为/使用为--all-match
。在Git 1.7.2.3中存在这个问题,我认为这是一个错误。使用$(git rev-list --all)
可以解决这个问题。 - blueyed不了解git,但在Mercurial中,我会将hg log的输出导入到一些sed/perl/whatever脚本中,以搜索您要查找的内容。如果您愿意,可以使用模板或样式自定义hg log的输出,以便更容易地进行搜索。
这将包括存储库中的所有命名分支。据我所知,Mercurial没有类似于悬空blob的东西。
在git中有一个命令,我认为查找字符串更容易:
git log --pretty=oneline --grep "string to search"
在Git 2.0.4中有效