Как найти коммит Git, который ввел строку в любую ветку? - PullRequest
349 голосов
/ 28 апреля 2011

Я хочу иметь возможность найти определенную строку, которая была введена в любой коммит в любая ветка, как я могу это сделать? Я нашел что-то (что я модифицировал для Win32), но git whatchanged, похоже, не смотрит в разные ветви (игнорируйте кусок py3k, это просто исправление перевода строки msys / win)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

Неважно, если ваше решение медленное.

Ответы [ 7 ]

600 голосов
/ 28 апреля 2011

Вы можете сделать:

git log -S <whatever> --source --all

Чтобы найти все коммиты, которые добавили или удалили фиксированную строку whatever. Параметр --all означает запуск с каждой ветви, а --source означает, чтобы показать, какая из этих ветвей привела к поиску этого коммита. Часто бывает полезно добавить -p, чтобы показать патчи, которые также будет вводить каждый из этих коммитов.

Версии git начиная с 1.7.4 также имеют похожую опцию -G, которая принимает регулярное выражение . Это на самом деле имеет другую (и довольно более очевидную) семантику, объясненную в этом сообщении в блоге от Джунио Хамано .

Как указывает thameera в комментариях, вам нужно ставить кавычки вокруг поискового запроса, если он содержит пробелы или другие специальные символы, например:

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

Вот пример использования -G для поиска вхождений function foo() {:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all
60 голосов

- обратный также полезен, так как вы хотите первый коммит, который внес изменение:

git log --all -p --reverse --source -S 'needle'

Таким образом, старые коммиты будут появляться первыми.

17 голосов
/ 30 декабря 2012

Ответ Марка Лонгэйра превосходен, но я нашел эту более простую версию для меня.

git log -S whatever
16 голосов
/ 27 апреля 2013

Возиться с такими же ответами:

$ git config --global alias.find '!git log --color -p -S '
  • ! необходимо, потому что иначе git не передает аргумент правильно -S. См этот ответ
  • - цвет и -p помогает точно показать "что изменилось"

Теперь вы можете сделать

$ git find <whatever>

или

$ git find <whatever> --all
$ git find <whatever> master develop
6 голосов
/ 14 марта 2016
git log -S"string_to_search" # options like --source --reverse --all etc

Обратите внимание, чтобы не использовать пробелы между S и "string_to_search". В некоторых установках (git 1.7.1) вы получите сообщение об ошибке:

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
2 голосов
/ 28 октября 2016

Хотя это не дает прямого ответа на ваш вопрос, я думаю, что это может быть хорошим решением для вас в будущем. Я видел часть моего кода, что было плохо. Не знал, кто это написал и когда. Я мог видеть все изменения из файла, но было ясно, что код был перемещен из какого-то другого файла в этот. Я хотел выяснить, кто на самом деле добавил его.

Для этого я использовал Git bisect , что быстро позволило мне найти грешника.

Я запустил git bisect start, а затем git bisect bad, потому что в проверенной версии возникла проблема. Поскольку я не знал, когда возникла проблема, я нацелил первый коммит на «хорошо», git bisect good <initial sha>.

Тогда я просто продолжал искать в репозитории плохой код. Когда я нашел его, я запустил git bisect bad, а когда его там не было: git bisect good.

В ~ 11 шагах я рассмотрел ~ 1000 коммитов и нашел точный коммит, где была представлена ​​проблема. Довольно здорово.

1 голос
/ 13 декабря 2018

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

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...