Как найти коммит Git, который ввел строку в любую ветку?
Я хочу, чтобы найти определенную строку, которая была введена в любом коммите в
любая отрасль, как я могу это сделать? Я нашел что-то (что я изменил для 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>
Не имеет значения, медленно ли ваше решение.
Ответы
Ответ 1
Вы можете сделать:
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 my car?" --source --all
Вот пример использования -G
, чтобы найти вхождения function foo() {
:
git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all
Ответ 2
- обратный также полезен, так как вы хотите, чтобы первое коммитирование сделало это изменение:
git log --all -p --reverse --source -S 'needle'
Таким образом, сначала появятся старшие коммиты.
Ответ 3
Ответ Mark Longairs превосходный, но я нашел эту более простую версию для работы для меня.
git log -S whatever
Ответ 4
Беседа с теми же ответами:
$ git config --global alias.find '!git log --color -p -S '
- ! требуется, потому что иначе, git не правильно передает аргумент -S. См. этот ответ
- - цвет и -p позволяет точно показать "whatchanged"
Теперь вы можете сделать
$ git find <whatever>
или
$ git find <whatever> --all
$ git find <whatever> master develop
Ответ 5
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
Ответ 6
Хотя это прямо не отвечает на ваш вопрос, я думаю, что это может быть хорошим решением для вас в будущем. Я видел часть своего кода, что было плохо. Не знал, кто написал это или когда. Я мог видеть все изменения из файла, но было ясно, что код был перенесен из другого файла в этот. Я хотел найти, кто на самом деле добавил его в первую очередь.
Чтобы сделать это, я использовал Git bisect, который быстро позволил мне найти грешника.
Я запустил git bisect start
, а затем git bisect bad
, потому что в проверке исправления возникла проблема. Поскольку я не знал, когда возникла проблема, я нацелил первую фиксацию на "хороший", git bisect good <initial sha>
.
Затем я просто продолжал искать репо для плохого кода. Когда я нашел его, я побежал git bisect bad
, а когда его там не было: git bisect good
.
В ~ 11 шагах я рассмотрел ~ 1000 коммитов и нашел точную фиксацию, где была введена проблема. Довольно здорово.
Ответ 7
Не уверен, почему принятый ответ не работает в моей среде, наконец, я запускаю команду ниже, чтобы получить то, что мне нужно
git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"