2011-03-09 70 views
26

我愛git grep搜索檢入到回購協議的所有文件。這很棒。但是有可能使用它(或其他git命令)來查找文件(獨立於內容)?如何在git repo中grep文件?

目前,我這樣做:

$ find . | grep middleware 

其作品,但它不使用git的指數,這意味着它會通過每一個找到的文件,它在所匹配.gitignore文件的報告。

聰明的技巧的任何想法?

回答

38

也許你想要git ls-files它列出索引中的文件? (並自動調整你的git工作目錄內的當前目錄)

+0

這是正確的答案。我會做git ls-files | grep'你要找的名字'來過濾git ls-files將返回的大文件列表。 (因爲我經常使用它,所以我還將ls-files別名爲ls) – I82Much 2011-03-09 11:42:24

+3

我們可以用命令''git ls-files「* .sh」'''或''git ls-files | grep .sh'' – 2014-04-15 04:54:21

+0

我一直有別名:'find =! git ls-files | grep「,但有時我真的想限制搜索到一個特定的路徑,例如'git find foo bar/baz'。任何想法如何實現? – JFlo 2015-03-07 19:17:00

19

我認爲git ls-files會爲你做的伎倆。

所以:

git ls-files "*middleware*" 
+0

+1。我總是做'git ls-tree -r HEAD | grep'toSearchFor'' – 2011-03-09 13:04:44

+0

這真的很酷,但是用'git ls-files | grep ...'我在我的指尖獲得了grep的權力,並且由於我默認情況下在grep上突出顯示了顏色,所以它顯示得更好。 – 2011-03-11 09:25:22

4

你可以考慮在這種情況下,非git的解決方案。

find本身做你想做的事,更有效的方式比管道的成果轉化爲grep的能力:

find . -name 'middleware*' 

您需要引用模式,使*沒有展開在被殼傳遞給find之前。

有一個叫ack強大的程序就是好,better than grep,我最喜歡的一個用來ack正是你所提到的 - 尋找匹配樹內的模式的文件。 ack使用perl regexps,而不是shell fileglobs。

ack -g middleware 

如果你想搜索這些文件,ack讓你這樣做更容易比寫作過的findgrep s各自文件中的結果的外殼環。比較兩個,看看你更喜歡哪一個:

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

ack -G 'middleware' 'pattern in file' 

我強烈建議ack的東西添加到您的工具箱。

+0

這太棒了!感謝您向我介紹'ack'!只需要注意:「'-G'選項已被刪除,命令行中的兩個正則表達式被認爲太混亂;要模擬'-G'的功能,可以使用新的'-x'選項來管道從一次調用ack到另一次的文件名「。來自['ack(1)'](https://beyondgrep.com/documentation/ack-2.22-man.html)。如果我找出修復,我會編輯這個答案。 – askewchan 2018-02-16 18:00:03

-2

純git的解決方案

git grep已經內置支持grep的限制文件的水珠。 其他答案都使用外部工具來做實際的grepping,這就錯過了一點。

來自git grepman page的示例。

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

會在所有跟蹤的.C time_t的和.h文件在工作目錄及其子目錄。

從選項說明。

-- 表示選項結束;其餘的參數是限制器。

<pathspec>…​ 如果給出,則將搜索限制爲匹配至少一個模式的路徑。兩個前導路徑匹配並支持glob(7)模式。

所以翻譯的例子(其中不包括一些但將搜索範圍限制,所以我在這裏添加):

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

你會做:

$ git grep middleware -- '*.txt' 
+1

這不回答這個問題。 OP在'git-grep'是'grep'的一個git限制的味道同樣的意義上要求一個git限制的'find'味道。即,OP想要按名稱而不是按內容搜索被跟蹤的文件。 – 2016-12-01 23:20:35

0

我有經常遇到同樣的問題,我只是去了黑客git find - 如果您不使用Debian package,您可以將git-find腳本複製到/usr/lib/git-core/(或可比較的)和enj哦,它。

它可以在多種模式下使用,最簡單的它確實是:

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

組合也有可能(幾乎爲靈活的定期find,你只需要編寫-a明確):

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

它有一對夫婦更多的選擇,其中大部分處理與過濾名稱或完全(部分,即低於當前的工作目錄)的路徑,他們中的一些不區分大小寫(-iname和朋友s)和兩個全局選項,一個用於在POSIX Basic(默認)和POSIX Extended之間切換正則表達式,另一個用於切換符號鏈接(默認開啓);這僅僅通過設計找到文件(和符號鏈接),而不是目錄或子模塊(「gitlinks」)。

它也可以通過文件列表定期find(1)如果它不是太長(必須在命令行上傳遞),這使得喜歡的事情......

git find -- -mtime -100 

...在輕微的文件系統成本(find不會訪問文件系統),但另一方面,find幾乎所有(不是搜索深度特定的東西)的作品,你只能操作「索引」中的文件,即已知的git(存在於HEAD commit或git add編)。

雖然未解決的衝突有點挑剔。如果您發現任何問題,請給我留言(在這裏,或通過IRC)。PS:隨意遊說官方的git人員去子樹合併git-find存儲庫,我很樂意將它整合到git中(許可證更加自由,你只需要最近(50應該是足夠的)版本,但是它是現今最普遍的Unix shell,所以沒關係)。

相關問題