Seções iMasters
Desenvolvimento

Dica Git da semana: Procurando Padrões

A dica Git da semana é sobre usar grep para encontrar conteúdo.

Às vezes, nem sempre é óbvio onde encontrar a definição de uma função (ou método) quando se investiga o conteúdo de um repositório. Obviamente, as ferramentas do Unix, como grep, permitem que você encontre o conteúdo facilmente, mas se há uma grande quantidade de dados gerados (como código compilado) simplesmente olhar através de todos os arquivos pode ser demorado.

Para encontrar um arquivo com um elemento de conteúdo específico, você poderia usar algo como find . -exec grep pattern ‘{}’ ‘;’. Isso irá executar o comando grep em todos os arquivos no diretório de trabalho. No entanto, há uma maneira mais rápida de conseguir isso com git grep. Vamos dizer que gostaríamos de encontrar o conteúdo de ocorrências no repositório EGit da variável newPushURI. Nós poderíamos usar find para chegar a isto:

EGit (master)$ find . -exec grep newPushURI '{}' ';'
URIish newPushURI = uri;
newPushURI = newPushURI.setPort(GERRIT_DEFAULT_SSH_PORT);
newPushURI = newPushURI.setScheme(Protocol.SSH.getDefaultScheme());
newPushURI = newPushURI.setPort(GERRIT_DEFAULT_SSH_PORT);
newPushURI = prependGerritHttpPathPrefix(newPushURI);
uriText.setText(newPushURI.toString());
scheme.select(scheme.indexOf(newPushURI.getScheme()));

Ok, nós encontramos algumas ocorrências, mas ele não imprime os nomes dos arquivos, o que não é muito útil. Nós poderíamos imprimir o arquivo mais tarde se quiséssemos, mas isso não ajudaria para arquivos que não possuem a equivalência. Ou você poderia escrever algum tipo de script ou alias para lidar com a verificação e teste. Também não é particularmente rápido:

EGit (master)$ time find . -exec grep newPushURI '{}' ';' > /dev/null
real 0m1.605s
user 0m0.541s
sys 0m0.849s

Uma alternativa é usar git grep para examinar o conteúdo da tree de trabalho atual:

EGit (master)$ git grep newPushURI
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: URIish newPushURI = uri;
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setPort(GERRIT_DEFA
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setScheme(Protocol.
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setPort(GERRIT_DEFA
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = prependGerritHttpPathPrefix(ne
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: uriText.setText(newPushURI.toString());
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: scheme.select(scheme.indexOf(newPushURI.getScheme()

Ele não só mostra quais arquivos são localizados, mas também uma ordem de magnitude mais rápida:

EGit (master)$ time git grep newPushURI > /dev/null
real 0m0.024s
user 0m0.014s
sys 0m0.033s

Os argumentos que git grep assume são bem parecidos ao do próprio grep; por exemplo,-l lista os arquivos com correspondências (e -L é sem arquivos),-E permite uma regexp estendida,-i é ignorar e caso e -w é palavra regexp.

Há também algumas opções que são específicas para o git. O exemplo –no-index verifica os arquivos nos diretórios, enquanto –cached busca por blobs no índice.

Bem como o diretório de trabalho atual, git grep também pode ser usado para especificar um treeish (tag, filial, commit) e subpastas dentro de um repositório. Se quiséssemos olhar para o regex extension.point no branch stable-1.0 para correspondências localizadas na pasta org.eclipse.egit.core, poderíamos fazer:

EGit] (master)$ git grep extension.point stable-1.0 -- org.eclipse.egit.core
stable-1.0:org.eclipse.egit.core/plugin.xml: <extension point="org.eclipse.core.runtime.preferences">
stable-1.0:org.eclipse.egit.core/plugin.xml: <extension point="org.eclipse.team.core.repository">

Finalmente, é possível utilizar -p para imprimir o nome de uma função em que ocorre uma correspondência.

EGit (master)$ git grep  -p newPushURI
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java= private void setDefaults(RepositorySelection selection) {
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: URIish newPushURI = uri;
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setPort(GERRIT_DEFA
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setScheme(Protocol.
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = newPushURI.setPort(GERRIT_DEFA
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: newPushURI = prependGerritHttpPathPrefix(ne
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: uriText.setText(newPushURI.toString());
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java: scheme.select(scheme.indexOf(newPushURI.getScheme()

Observe que isso mostra a função anotada por = em vez de um : no final do nome. Isso pode ser usado para localizar rapidamente quais funções contêm uma referência a padrão dado:

EGit] (master)$ git grep  -p newPushURI | grep java=
org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GerritConfigurationPage.java= private void setDefaults(RepositorySelection selection) {

?

Texto original disponível em http://alblue.bandlem.com/2011/08/git-tip-of-week-searching-for-patterns.html

Mensagem do anunciante:

Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

Qual a sua opinião?