Как найти git commit, который ввел строку в любой ветви?
Я хочу иметь возможность найти определенную строку, которая была введена в любой фиксации в любой филиал, как я могу это сделать? Я нашел что-то (что я изменил для Win32), но!--1--> похоже, не смотрит в разные ветви (игнорируйте кусок py3k, это просто исправление подачи msys / win)
git whatchanged -- <file> |
grep "^commit " |
python -c "exec("import sys,msvcrt,osnmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)nfor l in sys.stdin: print(l.split()[1])")" |
xargs -i% git show origin % -- <file>
на самом деле не имеет значения, если ваше решение медленное.
6 ответов
вы можете сделать:
git log -S <whatever> --source --all
чтобы найти все коммиты, которые добавили или удалили фиксированная строка whatever
. The --all
параметр означает запуск из каждой ветви и --source
означает показать, какая из этих ветвей привела к нахождению этой фиксации. Часто полезно добавить -p
чтобы показать патчи, которые каждый из этих коммитов также представит.
версии git с 1.7.4 также имеют аналогичный -G
опция, которая принимает обычный выражение. Это на самом деле имеет другую (и более очевидную) семантику, объясненную в это сообщение в блоге от Junio Hamano.
As 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
-- reverse - это тоже полезно, Так как вы хотите первый коммит, который внес изменения:
git log --all -p --reverse --source -S 'needle'
таким образом, сначала появятся старые коммиты.
Марк Longair это отлично, но я нашел эту более простую версию, чтобы работать на меня.
git log -S whatever
возиться с теми же ответами:
$ git config --global alias.find '!git log --color -p -S '
- ! необходимо, потому что иначе, git не передают аргумент правильно-S. см. этот ответ
- --color и - p помогает показать именно "whatchanged"
Теперь вы можете сделать
$ git find <whatever>
или
$ git find <whatever> --all
$ git find <whatever> master develop
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
пока это не прямо ответить на ваш вопрос, я думаю, что это может быть хорошим решением для вас в будущем. Я увидел часть своего кода, что было плохо. Не знал, кто это написал и когда. Я мог видеть все изменения из файла, но было ясно, что код был перенесен из какого-то другого файла в этот. Я хотел узнать, кто на самом деле добавил его в первую очередь.
для этого я использовал git bisect, что быстро позволило мне найти грешника.
я побежал git bisect start
а то git bisect bad
, потому что проверенная ревизия имела проблему. Поскольку я не знал, когда возникла проблема, я нацелил первый коммит на "хорошо",git bisect good <initial sha>
.
затем я просто продолжал искать РЕПО для плохого кода. Когда я нашел его, я побежал git bisect bad
, а когда его не было:git bisect good
.
в ~11 шагах я покрыл ~1000 коммитов и нашел точную фиксацию, где проблема была введена. Очень здорово.