在所有 Git 历史记录中搜索字符串 [重复]
Posted
技术标签:
【中文标题】在所有 Git 历史记录中搜索字符串 [重复]【英文标题】:Search all of Git history for a string [duplicate] 【发布时间】:2011-05-26 23:37:29 【问题描述】:我有一个代码库,我想将它作为开源推送到 GitHub。在这个 Git 控制的源代码树中,我有某些包含密码的配置文件。我确保不跟踪此文件,并将其添加到 .gitignore
文件中。但是,我想绝对肯定的是,不会推送任何敏感信息,也许是因为在提交之间有什么东西滑倒了。我怀疑我这样做是否足够粗心,但我想积极。
有没有办法“grep”所有的 Git?我知道这听起来很奇怪,但是“全部”是指曾经存在的每个文件的每个版本。我想如果有一个命令可以为每次提交转储差异文件,那可能有效吗?
【问题讨论】:
它的局限性在于它只会搜索一个分支(master?),但它非常接近你想要的 github.com/divinity76/SearchGithubHistory.js/blob/master/… / 尽管有“正确答案”,但您的要求是检查某些信息是否未公开提交——“git”答案仅在您提交整个历史记录时才相关。当然,如果您只提交当前版本,没有历史记录(使用例如“git archive”),那么一个简单的“grep”就足够了。 不是重复的。另一个问题只是关于日志,这个问题是关于 git 历史的 all 的。这些是不同的。 【参考方案1】:git rev-list --all | (
while read revision; do
git grep -F 'password' $revision
done
)
【讨论】:
+1:我会做“在`git rev-list --all`中进行修订;做git grep ...完成”,但是您的方法更具反应性,因为它在修订时grep被发现。 是否可以在远程存储库(如 github)上使用它? @reesd:当然,只有你克隆它。 为了避免看到来自vendor/cache/
和public/assets/
的匹配项,请将此答案中的grep
行更改为:git grep -F 'password' $revision | grep -v ':vendor/cache/' | grep -v ':public/assets/'
您只能获取文件名(没有提交哈希)也已排序且没有重复。检查我的答案。感谢这个答案的 OP,我从中获得了灵感。 Here is my answer【参考方案2】:
Git 可以使用 -S 选项搜索差异(称为 pickaxe in the docs)
git log -S password
这将找到添加或删除字符串 password
的任何提交。这里有几个选项:
-p
: 将显示差异。如果您提供文件 (-p file
),它将为您生成补丁。
-G
:查找添加或删除的行与给定正则表达式匹配的差异,而不是 -S
,后者“查找引入或删除字符串实例的差异”。
--all
:搜索所有分支和标签;或者,使用--branches[=<pattern>]
或--tags[=<pattern>]
【讨论】:
如果某些事情最终被提交,有没有简单的方法可以删除它?假设在这种情况下,我想保留一个配置文件,但其中一行包含一个密码,我想从我的所有 git 历史记录中删除该密码。有什么简单的方法可以在不重写每个提交的情况下做到这一点? 在这种特殊情况下,我还会输入-i
以使搜索不区分大小写。
仅供参考,上面的命令对我并没有真正起作用。我做了以下事情:git log -p -S <YOUR_SEARCH_TERM>
我从this informative article about git pickaxe.偷了这个信息
我不知道这是否是新的,但链接的文档说-S
寻找“改变指定字符串出现次数的差异”(添加了重点。)因此,如果提交添加了您正在寻找的术语,但也将其从其他地方删除,-S
将找不到它。 -G
,OTOH,不这样做。
谢谢!因为这是一个非常有用的参考,我要补充一点,-- path/filename
会将搜索限制在文件中。【参考方案3】:
尝试以下命令在所有以前跟踪的文件中搜索字符串:
git log --patch | less +/searching_string
或
git rev-list --all | GIT_PAGER=cat xargs git grep 'search_string'
需要从您要进行搜索的父目录运行。
【讨论】:
以上是关于在所有 Git 历史记录中搜索字符串 [重复]的主要内容,如果未能解决你的问题,请参考以下文章