Как выполнить поиск по всем Git и Mercurial фиксирует в репозитории определенную строку?

У меня есть репозиторий Git с несколькими ветвями и оборванными коммитами. Я хотел бы искать все такие коммиты в репозитории для определенной строки.

Я знаю, как получить журнал всех фиксаций в истории, но они не включают ветки или оборванные капли, только историю HEAD. Я хочу получить их все, чтобы найти конкретную фиксацию, которая была потеряна.

Я также хотел бы знать, как это сделать в Mercurial, поскольку я рассматриваю переключатель.

Ответ 1

Вы можете видеть оборванные фиксации с помощью git log -g.

-g, --walk-reflogs
 Instead of walking the commit ancestry chain, walk reflog entries from
 the most recent one to older ones. 

Итак, вы можете сделать это, чтобы найти определенную строку в сообщении фиксации, которое свисает:

git log -g --grep=search_for_this

В качестве альтернативы, если вы хотите искать изменения для определенной строки, вы можете использовать опцию поиска кирки, "-S":

git log -g -Ssearch_for_this
# this also works but may be slower, it only shows text-added results
git grep search_for_this $(git log -g --pretty=format:%h)

Git 1.7.4 будет добавить параметр -G, позволяя вам передать -G <regexp> чтобы найти, когда строка, содержащая <regexp> был перемещен, что -S не может сделать. -S будет сообщать вам только об изменении общего количества строк, содержащих строку (например, добавление/удаление строки).

Наконец, вы можете использовать gitk для визуализации оборванных коммитов с помощью:

gitk --all $(git log -g --pretty=format:%h)

И затем используйте его функции поиска, чтобы искать неулокальные файлы. Все эти работы, предполагающие, что отсутствующий коммит не "истек", и были собраны мусор, что может произойти, если оно свисает в течение 30 дней, и вы истекаете рефлоги или запускаете команду, которая их истекает.

Ответ 2

В Mercurial вы используете hg log --keyword для поиска ключевых слов в сообщениях фиксации и hg log --user для поиска определенного пользователя. См. hg help log для других способов ограничения журнала.

Ответ 3

В дополнение к richq answer использования git log -g --grep=<regexp> или git grep -e <regexp> $(git log -g --pretty=format:%h): посмотрите следующие записи в блогах от Junio ​​C Hamano, текущего git сопровождающего


Резюме

Оба git grep и git log - -grep являются ориентированными на линию, поскольку они ищут строки, соответствующие указанному шаблону.

Вы можете использовать git log --grep=<foo> --grep=<bar> (или git log --author=<foo> --grep=<bar>, который внутренне переводит на два --grep), чтобы найти коммиты, которые соответствуют или шаблонам (неявный OR семантический).

Из-за того, что он ориентирован на линию, полезная семантика И заключается в использовании git log --all-match --grep=<foo> --grep=<bar> для поиска фиксации, которая имеет и соответствие строк в первую очередь и где-то второе место.

С помощью git grep вы можете комбинировать несколько шаблонов (все, что должно использовать форму -e <regexp>), с --or (по умолчанию), --and, --not, ( и ). Для grep --all-match означает, что файл должен иметь строки, соответствующие каждой из альтернатив.

Ответ 4

Основываясь на ответе rq, я нашел, что эта строка делает то, что я хочу:

git grep "search for something" $(git log -g --pretty=format:%h -S"search for something")

Что сообщит идентификатор фиксации, имя файла и отобразит соответствующую строку, например:

91ba969:testFile:this is a test

... Кто-нибудь согласен с тем, что это будет хороший вариант для включения в стандартную команду git grep?

Ответ 5

Любая команда, которая принимает ссылки как аргументы, примет параметр --all, задокументированный на странице руководства для git rev-list следующим образом:

   --all
       Pretend as if all the refs in $GIT_DIR/refs/ are listed on the
       command line as <commit>.

Итак, например, git log -Sstring --all отобразит все коммиты, которые упоминают string и которые доступны из ветки или из тега (я предполагаю, что ваши оборванные коммиты по крайней мере названы с тегом).

Ответ 6

С Mercurial вы делаете

$ hg grep "search for this" [file...]

Существуют и другие варианты, которые сужают диапазон поисковых запросов.

Ответ 7

Не знаю о git, но в Mercurial я просто передаю вывод hg-журнала на какой-нибудь sed/perl/whatever script, чтобы искать то, что вы ищете. Вы можете настроить вывод журнала hg с помощью шаблона или стиля, чтобы облегчить поиск, если хотите.

Это будет включать все названные ветки в репо. Mercurial не имеет ничего похожего на свисающие капли afaik.

Ответ 8

если вы пользователь vim, вы можете установить tig (apt-get install tig) и использовать/такую ​​же команду для поиска по vim

https://blogs.atlassian.com/2013/05/git-tig/

Ответ 9

Чтобы добавить еще одно еще не упомянутое решение, я должен был сказать, что использование графического окна поиска gitg было самым простым решением для меня. Он выберет первое вхождение, и вы можете найти следующий с помощью Ctrl-G.

Ответ 10

Одна команда в git, мне кажется, что гораздо проще найти строку:

git log --pretty=oneline --grep "string to search"

работает в git 2.0.4