É possível executar git grep
dentro de todas as ramificações de um projeto de controle de origem do Git? Ou existe outro comando para executar?
É possível executar git grep
dentro de todas as ramificações de um projeto de controle de origem do Git? Ou existe outro comando para executar?
Respostas:
A pergunta " Como grep (pesquisar) código confirmado no histórico do git? " Recomenda:
git grep <regexp> $(git rev-list --all)
Isso pesquisa todos os commits, que devem incluir todos os branches.
Outra forma seria:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
Você pode encontrar ainda mais exemplos neste artigo :
Eu tentei o acima em um projeto grande o suficiente para que o git se queixasse do tamanho do argumento, portanto, se você enfrentar esse problema, faça algo como:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(veja uma alternativa na última seção desta resposta, abaixo)
Não esqueça essas configurações, se você as quiser:
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
Esse alias também pode ajudar:
git config --global alias.g "grep --break --heading --line-number"
Nota: chernjie sugeriu que isso git rev-list --all
é um exagero.
Um comando mais refinado pode ser:
git branch -a | tr -d \* | xargs git grep <regexp>
O que permitirá pesquisar apenas ramificações (incluindo ramificações remotas)
Você pode até criar um alias do bash / zsh para ele:
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>
Atualização em agosto de 2016: a RM recomenda nos comentários
Recebi um "
fatal: bad flag '->' used after filename
" ao tentar agit branch
versão. O erro foi associado a umaHEAD
notação de alias.Eu o resolvi adicionando um
sed '/->/d'
no pipe, entretr
osxargs
comandos e.
git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
Isso é:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
git branch
para tr ou sed; git branch
é um comando de porcelana destinado ao consumo humano. Consulte stackoverflow.com/a/3847586/2562319 para alternativas preferidas.
git log
pode ser uma maneira mais eficaz de pesquisar texto em todos os ramos, especialmente se houver muitas correspondências, e você desejar ver alterações mais recentes (relevantes) primeiro.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
Esses comandos de log listam confirmações que adicionam ou removem a sequência de pesquisa / regex especificada, (geralmente) mais recentes primeiro. A -p
opção faz com que o diff relevante seja mostrado onde o padrão foi adicionado ou removido, para que você possa vê-lo em contexto.
Depois de encontrar um commit relevante que adiciona o texto que você estava procurando (por exemplo, 8beeff00d), encontre os ramos que contêm o commit:
git branch -a --contains 8beeff00d
Achei isso mais útil:
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
Você precisaria ajustar os últimos argumentos, dependendo se deseja examinar apenas as ramificações remotas e locais, ou seja:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
O alias que eu criei tem a seguinte aparência:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
git for-each-ref
com --sort=-committerdate --count=100
! Obrigado pela ideia original!
É possível fazer isso de duas maneiras comuns: aliases Bash ou Git
Aqui estão três comandos:
git grep-branch
- Pesquisa em todas as filiais locais e remotasgit grep-branch-local
- Pesquisar apenas em agências locaisgit grep-branch-remote
- Apenas ramificações remotasO uso é o mesmo que git grep
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
Os comandos devem ser adicionados manualmente ao ~/.gitconfig
arquivo, porque git config --global alias
avalie o código complexo que você adiciona e estrague tudo.
[alias]
grep-branch = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | xargs git grep $@; };f "
grep-branch-remote = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | grep '^remotes' | xargs git grep $@; };f"
grep-branch-local = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' -e '^remotes' | xargs git grep $@; };f "
Nota: Quando você adiciona aliases e eles não são executados - verifique as barras invertidas, \
eles podem exigir escape adicional \\
em comparação aos comandos bash .
git branch -a
- Exibir todos os ramos;sed -e 's/[ \\*]*//'
- Aparar espaços (de branch -a
) e * (o nome do ramo ativo possui);grep -v -e '\\->'
- Ignore nomes complexos como remotes/origin/HEAD -> origin/master
;grep '^remotes'
- Obtenha todas as filiais remotas;grep -v -e '^remotes'
- Obter filiais, exceto filiais remotas;git grep-branch-local -n getTastyCookies
-n
Prefixe o número da linha às linhas correspondentes.
[user@pc project]$ git grep-branch-local -n getTastyCookies
dev:53:modules/factory/getters.php:function getTastyCookies($user);
master:50:modules/factory/getters.php:function getTastyCookies($user)
A estrutura atual é:
:
- Separador
dev
53
modules/factory/getters.php
function getTastyCookies($user)
Como você deve saber: Os comandos Bash devem ser armazenados em .sh
scripts ou executados em um shell.
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | xargs git grep "TEXT"
git grep-branch "find my text"
:fatal: ambiguous argument 'client': both revision and filename
-a
, que mostra todos os ramos? Eu sugeriria o uso de opções no git branch
comando para separar braches. Ao olhar para as filiais locais, há apenas uma *
, portanto não há necessidade de escapar dela por sed. Assim: git branch | sed -e 's/*/ /' | xargs git grep "TEXT"
somente para filiais locais, somente git branch -r | grep -v -- "->" | xargs git grep "TEXT"
para filiais remotas e git branch -a | grep -v -- "->" | xargs git grep "TEXT"
para todas as filiais
Aqui está como eu faço:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
Se você atribuir a qualquer commit um valor de hash SHA-1 git grep
, ele deverá pesquisar neles, em vez da cópia de trabalho.
Para pesquisar todos os galhos, você pode obter todas as árvores com git rev-list --all
. Coloque tudo com
git grep "regexp" $(git rev-list --all)
... e tenha paciência