如何在Git分支中搜索文件或目录?

在Git中,如何在多个分支中按路径搜索文件或目录?

我在一个分支中写了一些东西,但我不记得是哪一个了。现在我需要找到它。

澄清:我正在寻找我在我的一个分支上创建的文件。我想通过路径找到它,而不是通过它的内容,因为我不记得内容是什么。

171196 次浏览

Git ls-tree可能会有所帮助。要在所有现有分支中搜索:

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

这样做的好处是,您还可以使用正则表达式搜索文件名。

你可以使用gitk --all搜索提交的“触摸路径”和你感兴趣的路径名。

git log + git branch将为您找到它:

% git log --all -- somefile


commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800


added somefile




% git branch -a --contains 55d2069
otherbranch

也支持globbing:

% git log --all -- '**/my_file.png'

单引号是必要的(至少在使用Bash shell时),因此shell将glob模式原形不变地传递给git,而不是展开它(就像Unix find一样)。

虽然ididak的反应非常酷,并且Handyman5提供了一个脚本来使用它,但我发现使用这种方法有点受限。

有时需要搜索可能随着时间出现/消失的内容,那么为什么不搜索所有提交呢?除此之外,有时需要详细的响应,而其他时候只提交匹配。以下是这些选项的两个版本。把这些脚本放在你的路径上:

git-find-file

for branch in $(git rev-list --all)
do
if (git ls-tree -r --name-only $branch | grep --quiet "$1")
then
echo $branch
fi
done

git-find-file-verbose

for branch in $(git rev-list --all)
do
git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

现在你可以

$ git find-file <regex>
sha1
sha2


$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

使用getopt,你可以修改该脚本,以交替搜索所有提交、refs、refs/heads、been verbose等。

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

签出https://github.com/albfan/git-find-file以获得可能的实现。

及复印件;粘贴这个来使用git find-file SEARCHPATTERN

打印所有搜索分支:

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

只打印带有结果的分支:

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

这些命令将把一些最小的shell脚本直接添加到你的~/.gitconfig作为全局git别名

可以在这里找到Git存储库的find命令的一个相当不错的实现:

https://github.com/mirabilos/git-find

这个命令查找引入指定路径的提交:

git log --source --all --diff-filter=A --name-only -- '**/my_file.png'