git log -G<regex> -p
замечательный инструмент для поиска в истории кодовой базы изменений, соответствующих указанному шаблону. Тем не менее, это может быть огромным, чтобы найти соответствующий кусок в diff / patch патч в море в основном нерелевантных блоков.
Конечно, можно искать в git log
исходной строке / регулярном выражении вывод , но это мало что делает для уменьшения визуального шума и отвлечения многих несвязанных изменений.
Читая дальше git log
, я вижу --pickaxe-all
, что есть полная противоположность того, что я хочу: он расширяет вывод (до всего набора изменений), тогда как я хочу ограничить его (до конкретного блока).
По сути, я ищу способ «интеллектуально» разбить diff / patch на отдельные фрагменты, а затем выполнить поиск по каждому блоку (нацеливаясь только на измененные строки), отбросить фрагменты, которые не совпадают, и вывести те что делать.
Существует ли такой инструмент, как я описываю? Есть ли лучший подход, чтобы получить согласованные / затронутые фрагменты?
Некоторое начальное исследование, которое я сделал ...
Если бы это было возможно для
grep
diff / patch и сделать значения параметров контекста динамическими, скажем, с помощью регулярных выражений вместо количества строк, этого могло бы быть достаточно. Ноgrep
не совсем так (и я не обязательно запрашиваю эту функцию).Я нашел пакет patchutils , который поначалу звучал так, как будто бы он соответствовал моим потребностям. Но после прочтения его
man
страниц инструменты не обрабатывают подходящие фрагменты, основанные на регулярных выражениях. (Хотя они могут принять список хуков ...)В конце концов я наткнулся на splitpatch.rb , который, кажется, хорошо справляется с разбором патча, но его нужно значительно расширить, чтобы обрабатывать чтение патчей
stdin
, сопоставлять нужные фрагменты, а затем выводить фрагменты.
Ответы:
здесь /programming//a/35434714/5305907 описан способ сделать то, что вы ищете. эффективно:
git diff -U1 | grepdiff 'console' --output-matching=hunk
Он показывает только те фрагменты, которые соответствуют заданной строке "console".
источник
grepdiff
это в основном то, что я хочу; Должно быть, я пропустил его вариант соответствия! однако ... информация о коммите git удаляетсяgrepdiff
, поэтому, как только вы найдете соответствующий блок, вы должны отделить коммит sha от объекта / blob sha в заголовке diff - довольно дорогая операция. (см. stackoverflow.com/a/223890/2284440 ) это было бы что-то вродеgit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
grepdiff
которая более приемлема с точки зрения принятых аргументов. обратите внимание, что когда совпавший ханк - последний ханк в diff, он неправильно включает заголовок git commit следующего коммита - что меня полностью смущало, пока я не понял, что происходит!Не совсем то, что вы просите, но один из способов разобраться в этом - это интерактивный режим добавления. Для этого необходимо проверить коммит после интересующего вас патча.
затем вернитесь еще на один шаг в VCS, но не в рабочий каталог
(На этом этапе разница между индексом и рабочим каталогом будет соответствовать интересующему вас патчу.)
Теперь вы можете выполнить
git add -p
. Это запустит интерактивный сеанс с/
опцией, которая позволяет вам найти фрагменты, в которых какая-либо строка соответствует регулярному выражению. Особенно полезно, если вы действительно хотите дополнительно обработать эти патчи (например, подготовить частичную вишню).К сожалению, по крайней мере сейчас
/
командаadd -p
работает только в одном файле, поэтому вам может потребоваться пропустить несколько ненужных файлов.источник
Основываясь на приведенном выше ответе @nagu и других связанных ответах, я смог
git log -G
показать только соответствующие фрагменты.Сначала создайте сценарий где-нибудь в вашем $ PATH с этим содержимым:
Вызовите
git log -G
и скажите Git использоватьpickaxe-diff
скрипт в качестве внешнего драйвера diff:Это будет использовать скрипт pickaxe-diff только для генерации различий, поэтому остальная часть
git log
вывода (хеш коммита, сообщение и т. Д.) Останется нетронутой.Предостережение
Способ работы кирки Git заключается в том, что она ограничивает вывод файлами, чьи фрагменты изменяют данную строку / регулярное выражение. Это означает, что если другой блок в этих файлах также содержит строку поиска / регулярное выражение, но не меняет ее, он все равно будет отображаться с помощью приведенного выше сценария. Это ограничение grepdiff. В проекте patchutils есть открытый запрос на извлечение флага для добавления
--only-matching
к grepdiff, который обеспечит необходимую функциональность для правильной фильтрации этих блоков.Я сделал описание моего решения в этой сути .
источник