È possibile eseguire git grep
tutti i rami di un progetto proveniente dal controllo Git? O c'è un altro comando da eseguire?
È possibile eseguire git grep
tutti i rami di un progetto proveniente dal controllo Git? O c'è un altro comando da eseguire?
Risposte:
La domanda " Come grep (ricerca) codice commesso nella cronologia di Git? " Raccomanda:
git grep <regexp> $(git rev-list --all)
Che cerca in tutti i commit, che dovrebbe includere tutti i rami.
Un'altra forma sarebbe:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
Puoi trovare ancora più esempi in questo articolo :
Ho provato quanto sopra su un progetto abbastanza grande che Git si è lamentato della dimensione dell'argomento, quindi se ti imbatti in questo problema, fai qualcosa del tipo:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(vedi un'alternativa nell'ultima sezione di questa risposta, di seguito)
Non dimenticare quelle impostazioni, se le vuoi:
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
Anche questo alias può aiutare:
git config --global alias.g "grep --break --heading --line-number"
Nota: chernjie ha suggerito che git rev-list --all
è eccessivo.
Un comando più raffinato può essere:
git branch -a | tr -d \* | xargs git grep <regexp>
Che ti permetterà di cercare solo le filiali (comprese le filiali remote)
Puoi persino creare un alias bash / zsh per questo:
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>
Aggiornamento agosto 2016: RM raccomanda nei commenti
Ho ottenuto un "
fatal: bad flag '->' used after filename
" quando provavo lagit branch
versione. L'errore era associato a unaHEAD
notazione di aliasing.L'ho risolto aggiungendo una
sed '/->/d'
nel tubo, tratr
ixargs
comandi e.
git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
Questo è:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
git branch
in tr o sed; git branch
è un comando di porcellana destinato al consumo umano. Consulta stackoverflow.com/a/3847586/2562319 per le alternative preferite.
git log
può essere un modo più efficace di cercare testo tra tutti i rami, specialmente se ci sono molte corrispondenze e si desidera prima vedere le modifiche (rilevanti) più recenti.
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
L'elenco di questi comandi di log consente di aggiungere o rimuovere la stringa di ricerca / regex specificata, (generalmente) prima più recente. L' -p
opzione fa sì che il diff rilevante sia mostrato dove il pattern è stato aggiunto o rimosso, in modo da poterlo vedere nel contesto.
Dopo aver trovato un commit pertinente che aggiunge il testo che stavi cercando (ad es. 8beeff00d), trova i rami che contengono il commit:
git branch -a --contains 8beeff00d
Ho trovato questo molto utile:
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
Dovresti modificare gli ultimi argomenti a seconda che tu voglia guardare solo le filiali remote rispetto a quelle locali, ovvero:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
L'alias che ho creato è simile al seguente:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
git for-each-ref
con --sort=-committerdate --count=100
! Grazie per l'idea originale!
È possibile farlo in due modi comuni: alias Bash o Git
Ecco tre comandi:
git grep-branch
- Cerca in tutte le filiali locali e remotegit grep-branch-local
- Cerca solo nelle filiali localigit grep-branch-remote
- Solo filiali remoteL'utilizzo è lo stesso di git grep
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
I comandi dovrebbero essere aggiunti manualmente al ~/.gitconfig
file, perché git config --global alias
valuta il codice complesso che aggiungi e confondilo.
[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 si aggiungono alias e non riescono a funzionare, controllare le barre rovesciate \
che potrebbero richiedere ulteriore escape \\
rispetto ai comandi bash .
git branch -a
- Visualizza tutti i rami;sed -e 's/[ \\*]*//'
- Taglia spazi (da branch -a
) e * (il nome del ramo attivo ce l'ha);grep -v -e '\\->'
- Ignora nomi complessi come remotes/origin/HEAD -> origin/master
;grep '^remotes'
- Ottieni tutte le filiali remote;grep -v -e '^remotes'
- Ottieni filiali ad eccezione di filiali remote;git grep-branch-local -n getTastyCookies
-n
Prefisso il numero di riga su righe corrispondenti.
[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)
L'attuale struttura è:
:
- Separatore
dev
53
modules/factory/getters.php
function getTastyCookies($user)
Come dovresti sapere: i comandi di Bash dovrebbero essere archiviati negli .sh
script o eseguiti in una 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
, che mostra tutti i rami? Suggerirei di usare le opzioni al git branch
comando per separare i braches. Quando si guardano le filiali locali, ce n'è solo una *
, quindi non c'è bisogno di scappare per sed. Quindi: solo git branch | sed -e 's/*/ /' | xargs git grep "TEXT"
per le filiali locali, solo git branch -r | grep -v -- "->" | xargs git grep "TEXT"
per le filiali remote e git branch -a | grep -v -- "->" | xargs git grep "TEXT"
per tutte le filiali
Ecco come lo faccio:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM