Подтвердить что ты не робот

Игнорирование изменений, соответствующих строке в git diff

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

Все изменения имеют форму

-                       "main()",
+                       OOMPH_CURRENT_FUNCTION,

где "main()" может быть именем любой функции. Я хочу создать diff всех изменений, которые не относятся к этой форме.

Параметры -G и -S для git diff туманно близки - они находят изменения, которые соответствуют строке или регулярному выражению.

Есть ли хороший способ сделать это?

Попытки до сих пор

Другой question описывает, как можно переопределять регулярные выражения, используя этот подход, я думаю, что команда должна быть

git diff -G '^((?!OOMPH_CURRENT_FUNCTION).)*$'

но это просто возвращает сообщение об ошибке

fatal: invalid log-grep regex: Invalid preceding regular expression

поэтому я предполагаю, что git не поддерживает эту функцию регулярного выражения.

Я также заметил, что стандартный unix diff имеет параметр -I для "игнорировать изменения, строки которых соответствуют RE". Но я не могу найти правильный способ заменить git собственный diff с помощью инструмента unix diff.

4b9b3361

Ответ 1

Попробуйте следующее:

$ git diff > full_diff.txt
$ git diff -G "your pattern" > matching_diff.txt

Затем вы можете сравнить их так:

$ diff matching_diff.txt full_diff.txt

Если все изменения совпадают с шаблоном, full_diff.txt и matching_diff.txt будут идентичными, а последняя команда diff ничего не вернет.

Если есть изменения, которые не соответствуют шаблону, последний diff выделит их.


Вы можете объединить все вышеперечисленные шаги и не создавать два дополнительных файла:

diff <(git diff -G "your pattern") <(git diff)  # works with other diff tools too

Ответ 2

Используйте git difftool чтобы запустить настоящий diff.

Пример: https://github.com/cben/kubernetes-discovery-samples/commit/b1e946434e73d8d1650c887f7d49b46dcbd835a6
Я создал скрипт, запускающий diff так, как я хочу (здесь я сохраняю curl --verbose данные curl --verbose в curl --verbose, что приводит к скучным изменениям при каждом повторном запуске curl):

diff --recursive --unified=1 --color \
     --ignore-matching-lines=serverAddress \
     --ignore-matching-lines='^\*  subject:' \
     --ignore-matching-lines='^\*  start date:' \
     --ignore-matching-lines='^\*  expire date:' \
     --ignore-matching-lines='^\*  issuer:' \
     --ignore-matching-lines='^< Date:' \
     --ignore-matching-lines='^< Content-Length:' \
     --ignore-matching-lines='--:--:--' \
     --ignore-matching-lines='{ \[[0-9]* bytes data\]' \
     "[email protected]"

И теперь я могу запустить git difftool --dir-diff --extcmd=path/to/above/script.sh и увидеть только интересные изменения.

Важное предостережение о GNU diff -I aka --Ignore-matching-lines: это просто не позволяет таким линиям делать чанк "интерстерирующим", но когда эти изменения появляются в одном и том же фрагменте с другими изменениями, не относящимися к -I, это все равно покажу им. Я использовал --unified=1 выше, чтобы уменьшить этот эффект, делая куски меньше (только 1 контекстная строка выше и ниже каждого изменения).

Ответ 3

Я думаю, что у меня есть другое решение, использующее трубы и grep. У меня было два файла, которые должны быть проверены на наличие различий, которые не включают в себя @@ и g:, так что я сделал это (заимствование здесь и здесь и здесь:

$ git diff -U0 --color-words --no-index file1.tex file2.tex | grep -v -e "@@" -e "g:"

и это, казалось, добилось цели. Цвета еще были там.

Поэтому я предполагаю, что вы можете взять более простую команду/вывод git diff и сделать то же самое. Что мне нравится в этом, так это то, что он не требует создания новых файлов или перенаправления (кроме конвейера).