Используя Git, как я могу найти строку во всех ветвях?

170

Используя Git, как я могу найти данную строку во всех файлах во всех локальных ветвях?

Особенность GitHub: возможно ли выполнить вышеуказанный поиск по всем веткам GitHub? (В моем удаленном репозитории GitHub есть несколько удаленных веток, которые в идеале мне не пришлось бы сбрасывать для этого поиска ...)

Ивар
источник
1
Возможно, вам нужен git-grep , но я еще не уверен, какие варианты вам понадобятся ...
Джонни

Ответы:

170

Вы можете сделать это в репозитории Git:

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

Расширенный поиск GitHub имеет возможность поиска кода:

Поиск кода просматривает весь код, размещенный на GitHub. Вы также можете фильтровать по:

  • язык: language:
  • имя хранилища (включая имя пользователя): repo:
  • путь к файлу: path:
manojlds
источник
Это вызывает у меня ошибку сегментации. Может быть, черепаха (Windows), хотя.
bean5
6
Это действительно не лучший способ сделать это. Он не контролирует количество git-ссылок, которые передаются git grep .... Посмотрите на другие ответы, они намного лучше, чем этот, даже если он помечен как принятый ответ!
ОДС
1
было бы здорово, если бы вы могли добавить пример для своих фильтров, например path:, потому что в краткой документации не ясно, где применять этот фильтр, предполагая, что он используется перед кавычками в вашем примере запроса?
болтать
3
Как я могу перечислить только название филиала. В настоящее время в нем перечислены все хэши, содержащие строку.
harryfeng
4
Поиск Github находится на главной ветке только . Из help.github.com/articles/searching-code : «Для поиска кода индексируется только ветвь по умолчанию. В большинстве случаев это будет основная ветвь».
RedPanda
124

Если вы используете команду @manojlds Git grep и получаете сообщение об ошибке:

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

тогда вы должны использовать xargs :

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

Также см. Как получить (найти) зафиксированный код в истории Git.

teastburn
источник
Кроме того, это кажется более совместимым с другими видами консолей, такими как fishshell
Daniel
1
Спасибо!!! используя ZSH, и это работало, в то время как команда @manojlds выдавала указанную вами ошибку! Но предупреждение, это может занять ОЧЕНЬ много времени для большого репо с длинной историей.
lacostenycoder
54

Во многих случаях git rev-list --allможет возвращаться огромное количество коммитов, которые можно сканировать вечно. Если вы вместо того, чтобы искать каждый коммит по каждой ветке в своей истории репозитория, просто хотите найти все подсказки по веткам, вы можете заменить их на git show-ref --heads. Итак, всего:

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

или:

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

Совет: вы можете записать вывод в файл для просмотра в редакторе:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt
Zitrax
источник
6
git show-ref --headsперечисляет хеш и имя ссылки, поэтому он (2-я строка) будет искать дважды. так git show-ref --heads | cut -d' ' -f2лучше, так как он будет перечислять только имена ссылок.
СЧАСТЛИВЫЙ
4
Я не могу поверить, сколько раз на этот вопрос задавали и отвечали, но вы единственный, кто правильно ответил.
Саммит
1
git show-ref --heads -sвыводит только хеш SHA1. Кроме того, если есть несколько веток, указывающих на один и тот же коммит, у вас будут дубликаты. Вы можете удалить их sort -u, например,git show-ref --heads -s | sort -u | xargs git grep ...
Стив
Вот функция, которую я добавил в свой bashrc. Надеюсь, это кому-нибудь поможет:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555
Это должен быть принятый ответ. Использование строки во всех ветвях, но только для самого последнего контента, является очень распространенным случаем использования.
dr_
21

Есть несколько проблем с решениями, перечисленными здесь (даже приняты).

Вам не нужно перечислять все хэши, так как вы получите дубликаты. Кроме того, это занимает больше времени.

Он основан на этом, где вы можете искать строку "test -f /"по нескольким ветвям masterи devкак

git grep "test -f /" master dev

который так же, как

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

Так что здесь идет.

Это находит хэши для кончика всех локальных веток и ищет только в тех коммитах:

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

Если вам нужно искать и в удаленных ветках, добавьте -a:

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

Дальше:

# 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"
хиппи
источник
5
по крайней мере, для поиска во всех ветвях должно быть: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" или это не удастся с ->символом в списке файлов, который обозначает отношение локальных к удаленным ветвям
Илья Ширсхофф,
7

Вы можете попробовать это:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches
Виктор Чой
источник
1
По всем веткам:git log --all -s"search_string"
Тим Кейперс