Показать все коммиты, diff которых содержат определенную строку
Как говорится в названии, я хочу найти каждое сообщение, чей diff содержит определенную строку.
В настоящий момент я использую
git log -p 'filename'
который показывает менее похожий интерфейс каждого diff, где я ищу строку.
Затем я возвращаюсь, чтобы найти фактическое сообщение об ошибке.
Простая альтернатива может заключаться в том, чтобы pipe git log -p в grep, но я не могу найти идентификатор или сообщение commit таким образом.
Ответы
Ответ 1
Здесь однострочная оболочка script (разбита на несколько строк для целей форматирования), которая извлекает оборотные номера коммитов текущей-ветки, влияющих на path
, где git show -p
содержит заданный pattern
, Он не идеален (он будет соответствовать сообщениям фиксации, а также различиям), но это должно быть легко настроить, как вам нравится, отсюда.
git rev-list HEAD -- path |
while read rev; do
if git show -p $rev | grep pattern >/dev/null; then
echo $rev
fi
done
Обратите внимание, что вы можете заменить git show
на, например, git diff $rev^ $rev
(обратите внимание, что это только сравнивается с первичным родителем, если это слияние) или git whatchanged $rev
, или что угодно. Основной трюк состоит в том, чтобы начать с git rev-list
, чтобы извлечь все кандидаты (фиксации влияют на данный путь; опустите часть -- path
, чтобы получить все фиксации, начиная с HEAD
). См. git -rev-list (1) для многих других вещей, которые вы можете сделать с помощью git rev-list
.
Ответ 2
git log -p -S'string'
может использоваться для поиска коммитов, которые добавляют или удаляют строку. Он не ведет себя точно так же, потому что он соответствует только коммитам, которые фактически добавляют или удаляют экземпляр шаблона, а не (например) коммитам, где это происходит в контексте diff. Но, может быть, это достаточно хорошо для вас.
Ответ 3
Я знаю, что на этот вопрос был дан ответ на некоторое время, но я тоже натолкнулся на это, и нашел другое решение, поэтому решил, что поделюсь. Git-log -G-переключатель должен делать то, что вы делаете, где -S-переключатель будет выводить только то, что число вхождений совпадающего изменения строки.
Из Git-log man-страница:
-G Ищите различия, текст патча которых содержит добавленные/удаленные строки, которые соответствуют.
Чтобы проиллюстрировать разницу между -S --pickaxe-regex и -G, рассмотрите фиксацию со следующим diff в том же файле:
+ return !regexec(regexp, two->ptr, 1, ®match, 0);
...
- hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
В то время как git log -G "regexec (regexp" покажет это commit, git log -S "regexec (regexp" --pickaxe-regex не будет (поскольку количество вхождений этой строки не изменилось).
Для получения дополнительной информации см. запись кирка в gitdiffcore (7).
Ответ 4
git log --all -G'my_search' -i -m -p
мнемоника: git log all GIMP
-
--all
: поиск по всем возможным путям, а не только через HEAD. -
-G
: более общий, чем -S
потому что -S
ищет только различия, которые показывают разное количество вхождений my_search
. -G
ищет полные различия и принимает регулярные выражения. -
-i
[опционально]: заставить -G игнорировать регистр. -
-m
: по умолчанию git log не выводит diff для коммитов слияния. -m
изменяет это поведение по умолчанию, делая слияние фиксирует вывод полных различий. Это очень важно: если неправильно сформированный коммит слияния изменил вашу строку, вы не сможете увидеть без -m
. -
-p
: также выводить полный патч для каждого найденного коммита.
Вы даже можете подключить это к VIM. Я нахожу это очень полезным:
git log --no-color --all -G'regex' -i -m -p | vim -
здесь я использую --no-color
потому что vim выделяет для меня патчи.
Ответ 5
Если вы используете linux, проведите его через egrep и выполните поиск в регулярном выражении
git log -p 'filename' | egrep '(yourstring|commit-message)'
Ответ 6
Считаете ли вы использование команды pipe и grep?
Пример:
git log -p | grep 'filename'
Ответ 7
Вы можете использовать git для этого, например:
git log --grep="filename"
Или в определенном файле:
git log --grep="filename" README