Using Git, how could I search for a string across all branches?

94,527

Solution 1

You can do this on a Git repository:

git grep "string/regexp" $(git rev-list --all)

GitHub advanced search has code search capability:

The code search will look through all of the code publicly hosted on GitHub. You can also filter by:

  • the language: language:
  • the repository name (including the username): repo:
  • the file path: path:

Solution 2

If you use @manojlds Git grep command and get an error:

-bash: /usr/bin/git: Argument list too long" 

then you should use xargs:

git rev-list --all | xargs git grep "string/regexp"

Also see How to grep (search) committed code in the Git history

Solution 3

In many cases git rev-list --all can return a huge number of commits, taking forever to scan. If you, instead of searching through every commit on every branch in your repository history, just want to search all branch tips, you can replace it with git show-ref -s --heads. So in total:

git grep "string" `git show-ref -s --heads`

or:

git show-ref -s --heads | xargs git grep "string"

Tip: You can write output in file to view in an editor:

nano ~/history.txt
git show-ref -s --heads | xargs git grep "search string here" >> ~/history.txt

Solution 4

There are a few issues with the solutions listed here (even accepted).

You do not need to list all the hashes as you'll get duplicates. Also, it takes more time.

It builds on this where you can search a string "test -f /" on multiple branches master and dev as

git grep "test -f /" master dev

which is same as

printf "master\ndev" | xargs git grep "test -f /"

So here goes.

This finds the hashes for the tip of all local branches and searches only in those commits:

git branch -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

If you need to search in remote branches too then add -a:

git branch -a -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

Further:

# Search in local branches
git branch | cut -c3- | xargs git grep "string"

# Search in remote branches
git branch -r | cut -c3- | xargs git grep "string"

# Search in all (local and remote) branches
git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string"

# Search in branches, and tags
git show-ref | grep -v "refs/stash" | cut -d' ' -f2 | xargs git grep "string"

Solution 5

You can try this:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches
Share:
94,527

Related videos on Youtube

Ivar
Author by

Ivar

SOreadytohelp

Updated on July 26, 2022

Comments

  • Ivar
    Ivar almost 2 years

    Using Git, how could I search within all files in all local branches for a given string?

    GitHub specific: is it possible to perform the above search across all GitHub branches? (There are several remote branches on my remote GitHub repository that ideally I wouldn't have to bring down for this search...)

  • bean5
    bean5 almost 10 years
    This causes me a segmentation fault. Might be tortoisegitmerge (Windows), though.
  • Daniel
    Daniel almost 8 years
    Also, this seems to be more compatible with other kind of consoles like fishshell
  • Marco
    Marco about 7 years
    This is really not the best way to do this. It doesn't control the amount of git refs that are passed to git grep .... Look to the other answers, they're far better than this one even though it's marked as the accepted answer!
  • hIpPy
    hIpPy about 7 years
    git show-ref --heads lists the hash and the ref name so it (2nd line) will search twice. so git show-ref --heads | cut -d' ' -f2 is better as it will only list the ref names.
  • blamb
    blamb about 7 years
    it would be great if you can add an example for your filters, e.g. path:, because the documentation at a glance doesnt look clear where to apply this filter, im assuming its before the quotes in your query example?
  • harryfeng
    harryfeng almost 7 years
    how can I list branch name only. Currently, it list all the hash contains the string.
  • Sammitch
    Sammitch over 6 years
    I can't believe how many times this question has been asked and answered, yet you're the only one with the correct answer.
  • Ilya Sheershoff
    Ilya Sheershoff over 6 years
    at least for the search in all branches should be: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" or it will fail with -> symbol in files list, which denotes local to remote branches relation
  • Steve
    Steve over 6 years
    git show-ref --heads -s outputs the SHA1 hash only. Also, if there are multiple branches pointing to the same commit, you'll have duplicates. You can remove them with sort -u, like so git show-ref --heads -s | sort -u | xargs git grep ...
  • lacostenycoder
    lacostenycoder over 6 years
    Thanks!!! using ZSH and this worked while @manojlds command gave the error you mentioned! But warning, this can take VERY long time for a large repo with a long history.
  • RedPanda
    RedPanda over 6 years
    Github search is on master branch only. From help.github.com/articles/searching-code: "Only the default branch is indexed for code search. In most cases, this will be the master branch."
  • stuckj
    stuckj almost 6 years
    This will only work on a relatively smallish git repository. A git sha is 40 chars plus a space (or LF in this case) between them. On linux your arg list is limited to ~128kb (~256kb on a Mac). Your argument list will get way too big after a 3k-4k commits (6k - 8k on a Mac). That's not at all unreasonably on a fair sized repository.
  • Russ
    Russ over 5 years
    To find the branch name (having located the commit hash), you can use git branch -a --contains <commit_hash>
  • fIwJlxSzApHEZIl
    fIwJlxSzApHEZIl over 5 years
    This gives Wed Oct 17 02:39 PM liminex: git grep '["]Welcome' $(git rev-list --all) -> bash: /usr/bin/git: Argument list too long
  • AFP_555
    AFP_555 over 5 years
    Here's the function I added to my bashrc. Hope it helps someone: function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
  • dr_
    dr_ almost 5 years
    This should be the accepted answer. Grepping a string across all branches but for the latest content only is a very common use case.
  • Tim Kuipers
    Tim Kuipers about 4 years
    Across all branches: git log --all -s"search_string"
  • barnhillec
    barnhillec almost 4 years
    above needs the capital S
  • Gaetano Piazzolla
    Gaetano Piazzolla over 3 years
    Hi, i'm developing a tool to search in all remote and local repos using this command : github.com/GaetanoPiazzolla/git-search if you want, take a look.
  • user3147973
    user3147973 over 3 years
    This comment, right here above my comment, is the correct answer! It's the only one that didn't error out.
  • Stefan
    Stefan about 3 years
    Is there a way to get the branch names from this?
  • rgov
    rgov over 2 years
    If you are looking in a specific file, you can use: git rev-list --all | xargs -J % git grep "string/rexexp" % -- filename. This will run git grep on blocks of commits that are inserted where the % appears.
  • BrainSlugs83
    BrainSlugs83 over 2 years
    If this only searches one branch, then this doesn't really answer the question.
  • Andras Deak -- Слава Україні
    Andras Deak -- Слава Україні over 2 years
    This also seems to be the first answer that mentions --grep. Actually, that might be because this searches the git log rather than file contents across all branches, doesn't it? So it doesn't exactly fit the question.
  • Anurag Pande
    Anurag Pande about 2 years
    Thanks @IlyaSheershoff ! You need to add cut -d' ' -f 1 to the remote branch search as well.