grep用法 - git log grep




如何在git歷史中grep(搜索)提交的代碼? (9)

我過去曾在某個文件中刪除過一個文件或一些代碼。 我可以在內容中grep(不在提交消息中)嗎?

一個非常糟糕的解決方案是grep日誌:

git log -p | grep <pattern>

但是,這不會立即返回提交散列。 我玩弄git grep無濟於事。


@ Jeet的答案在PowerShell中起作用。

git grep -n <regex> $(git rev-list --all)

以下顯示任何提交中包含password所有文件。

# store intermediate result
$result = git grep -n "password" $(git rev-list --all)

# display unique file names
$result | select -unique { $_ -replace "(^.*?:)|(:.*)", "" }

git log可以成為跨所有分支搜索文本的更有效方式,尤其是在有很多匹配的情況下,並且您希望首先查看更新(相關)的更改。

git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'

這些日誌命令列出提交,添加或刪除給定的搜索字符串/正則表達式,(通常)更新的第一個。 -p選項會使相關的diff顯示在添加或刪除模式的位置,因此您可以在上下文中查看它。

找到了一個相關的提交,添加了您正在查找的文本(例如8beeff00d),找到包含提交的分支:

git branch -a --contains 8beeff00d

任何修訂版本中搜索任何文件

git rev-list --all | xargs git grep <regexp>

僅在某些給定文件中搜索,例如xml文件:

git rev-list --all | xargs -I{} git grep <regexp> {} -- "*.xml"

結果行應如下所示:6988bec26b1503d45eb0b2e8a4364afb87dde7af:bla.xml:找到的行的文本...

然後您可以使用git show獲取更多信息,例如作者,日期和差異:

git show 6988bec26b1503d45eb0b2e8a4364afb87dde7af

在我的情況下,我需要搜索一個短提交和列出的解決方案不幸的是不工作。

我設法做到:(替換REGEX令牌)

for commit in $(git rev-list --all --abbrev-commit)
do
    if [[ $commit =~ __REGEX__ ]]; then 
        git --no-pager show -s --format='%h %an - %s' $commit
    fi
done

對於試圖在SourceTree中執行此操作的其他人,UI中沒有直接命令(從版本1.6.21.0開始)。 但是,您可以通過打開終端窗口(主工具欄中可用的按鈕)並在其中復制/粘貼來使用接受答案中指定的命令。

注意:SourceTree的搜索視圖可以部分為您進行文本搜索。 按Ctrl + 3轉到搜索視圖(或點擊底部的搜索選項卡)。 從最右側,將搜索類型設置為文件更改 ,然後鍵入要搜索的字符串。 與上述命令相比,此方法具有以下限制:

  1. SourceTree僅在其中一個更改的文件中顯示包含搜索詞的提交 。 查找包含搜索文本的確切文件也是一項手動任務。
  2. RegEx不受支持。

我拿了@ Jeet的答案,並將其分配給Windows(感謝這個答案 ):

FOR /F %x IN ('"git rev-list --all"') DO @git grep <regex> %x > out.txt

請注意,對我來說,出於某種原因,刪除此正則表達式的實際提交沒有出現在命令的輸出中,而是出現在它之前的一個提交中。


為了簡單起見,我建議使用GUI: gitk - Git存儲庫瀏覽器 ,它非常靈活

  1. 搜索代碼:
  2. 搜索文件:
  3. 因為它也支持正則表達式:

您可以使用向上/向下箭頭瀏覽結果


要搜索提交內容 (即實際的源代碼行,而不是提交消息等),您需要做的是:

git grep <regexp> $(git rev-list --all)

更新git rev-list --all | xargs git grep expression 如果遇到“參數列表太長”的錯誤, git rev-list --all | xargs git grep expression將起作用

如果你想限制搜索某個子樹(例如“lib / util”),你需要將它傳遞給rev-list子命令和grep

git grep <regexp> $(git rev-list --all -- lib/util) -- lib/util

這將grep通過所有提交文本的正則表達式。

在兩個命令中傳遞路徑的原因是因為rev-list將返回所有對lib/util的更改發生的修訂列表,但是您還需要傳遞給grep以便它僅在lib/util上進行搜索。

試想一下以下情況: grep可能會在rev-list返回的同一版本中包含的其他文件上找到相同的<regexp> (即使該版本上的該文件沒有更改)。

以下是一些其他搜索源的有用方法:

搜索工作樹以查找正則表達式正則表達式的文本:

git grep <regexp>

搜索與正則表達式regexp1或regexp2匹配的文本行的工作樹:

git grep -e <regexp1> [--or] -e <regexp2>

搜索工作樹中與正則表達式regexp1和regexp2匹配的文本行,僅報告文件路徑:

git grep -e <regexp1> --and -e <regexp2>

搜索工作樹以查找具有匹配正則表達式regexp1的文本行和匹配正則表達式regexp2的文本行的文件:

git grep -l --all-match -e <regexp1> -e <regexp2>

搜索工作樹以更改文本匹配模式的行:

git diff --unified=0 | grep <pattern>

搜索文本匹配正則表達式正則表達式的所有修訂:

git grep <regexp> $(git rev-list --all)

搜索文本匹配正則表達式regexp的rev1和rev2之間的所有修訂:

git grep <regexp> $(git rev-list <rev1>..<rev2>)

git rev-list --all | xargs -n 5 git grep EXPRESSION

是對@Jeet解決方案的調整,因此它在搜索時顯示結果,而不僅僅是結尾(在大型回購中可能需要很長時間)。





diff