Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Git to search for matching filenames in a repository?

Tags:

git

Just say I have a file: "HelloWorld.pm" in multiple subdirectories within a Git repository.

I would like to issue a command to find the full paths of all the files matching "HelloWorld.pm":

For example:

/path/to/repository/HelloWorld.pm /path/to/repository/but/much/deeper/down/HelloWorld.pm /path/to/repository/please/dont/make/me/search/through/the/lot/HelloWorld.pm 

How can I use Git to efficiently find all the full paths that match a given filename?

I realise I can do this with the Linux/Unix find command but I was hoping to avoid scanning all subdirectories looking for instances of the filename.

like image 816
Newbie Git Avatar asked Nov 10 '08 10:11

Newbie Git


2 Answers

git ls-files will give you a listing of all files in current state of the repository (the cache or index). You can pass a pattern in to get files matching that pattern.

git ls-files HelloWorld.pm '**/HelloWorld.pm' 

If you would like to find a set of files and grep through their contents, you can do that with git grep:

git grep some-string -- HelloWorld.pm '**/HelloWorld.pm' 
like image 96
Brian Campbell Avatar answered Nov 16 '22 02:11

Brian Campbell


Hmm, the original question was about the repository. A repository contains more than 1 commit (in the general case at least), but the answers given before search only through one commit.

Because I could not find an answer that really searches the whole commit history I wrote a quick brute force script git-find-by-name that takes (nearly) all commits into consideration.

#! /bin/sh tmpdir=$(mktemp -td git-find.XXXX) trap "rm -r $tmpdir" EXIT INT TERM  allrevs=$(git rev-list --all) # well, nearly all revs, we could still check the log if we have # dangling commits and we could include the index to be perfect...  for rev in $allrevs do   git ls-tree --full-tree -r $rev >$tmpdir/$rev  done  cd $tmpdir grep $1 *  

Maybe there is a more elegant way.

Please note the trivial way the parameter is passed into grep, so it will match parts of filename. If that is not desired anchor your search expression and/or add suitable grep options.

For deep histories the output might be too noisy, I thought about a script that converts a list of revisions into a range, like the opposite of what git rev-list can do. But so far it has remained a thought.

like image 21
Uwe Geuder Avatar answered Nov 16 '22 00:11

Uwe Geuder