Как выполнить поиск по всем коммитам Git и Mercurial в хранилище для определенной строки? - PullRequest
287 голосов
/ 14 апреля 2009

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

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

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

Ответы [ 10 ]

327 голосов
/ 14 апреля 2009

Вы можете увидеть висячие коммиты с 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 , чтобы найти, когда была перемещена строка, содержащая , что -S не может сделать. -S сообщит вам только об изменении общего количества строк, содержащих строку (т.е. добавление / удаление строки).

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

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

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

54 голосов
/ 21 мая 2009

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

22 голосов
/ 17 апреля 2009

В дополнение к richq ответу об использовании 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), чтобы найти коммиты, которые соответствуют или шаблонов (неявный ИЛИ семантический).

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

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

11 голосов
/ 27 мая 2010

Опираясь на ответ 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 голосов
/ 20 апреля 2009

С Mercurial вы делаете

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

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

5 голосов
/ 14 апреля 2009

Любая команда, которая принимает ссылки в качестве аргументов, примет опцию --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 и которые доступны из ветви или из тега (я предполагаю, что ваши оборванные коммиты, по крайней мере, названы тегом).

2 голосов
/ 14 апреля 2009

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

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

1 голос
/ 06 декабря 2014

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

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

работает в Git 2.0.4

1 голос
/ 27 октября 2013

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

1 голос
/ 12 сентября 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...