Ответ 1
git diff -G <regex>
И укажите регулярное выражение, которое НЕ соответствует вашей номерной строке версии.
Я пытаюсь создать список файлов, которые были изменены в конкретном коммите. Проблема в том, что каждый файл имеет номер версии в комментарии в верхней части файла - и поскольку это коммит вводит новую версию, это означает, что каждый файл изменился.
Меня не интересуют измененные комментарии, поэтому я хотел бы иметь git diff игнорировать все строки, соответствующие ^\s*\*.*$
, так как это все комментарии (часть/* */).
Я не могу найти способ сообщить git diff игнорировать определенные строки.
Я уже пробовал установить атрибут textconv, чтобы заставить git передавать файлы в sed, прежде чем их отличать, чтобы sed мог вычеркнуть нарушающие строки - проблема с этим заключается в том, что git diff --name -status на самом деле не различает файлы, просто сравнивает хэши, и, конечно, все хэши изменились.
Есть ли способ сделать это?
git diff -G <regex>
И укажите регулярное выражение, которое НЕ соответствует вашей номерной строке версии.
Вот решение, которое хорошо работает для меня. Я написал решение и дополнительную дополнительную документацию по опции git (log|diff) -G<regex>
.
В основном, используя те же решения, что и выше, но специально для комментариев, начинающихся с *
или #
, а иногда и пробела перед *
... Но по-прежнему необходимо разрешить #ifdef
, #include
и т.д.
Посмотрите вперед и посмотрите, по-видимому, не поддерживается опцией -G
, а вообще-то ?
, и у меня были проблемы с использованием *
. +
, похоже, работает хорошо.
(обратите внимание, проверено на Git v2.7.0)
git diff -w -G'(^[^\*# ])|(^#\w)|(^\s+[^\*#])'
-w
игнорировать пробелы-G
отображаются только строки разностей, соответствующие следующему регулярному выражению(^[^\*# /])
любая строка, которая не начинается со звезды или хэша или пробела(^#\w)
любая строка, начинающаяся с #
, за которой следует буква(^\s+[^\*#/])
любая строка, начинающаяся с некоторого пробела, за которым следует символ комментарияВ принципе, привязка svn изменяет каждый файл и выходит прямо сейчас и изменяет многострочные блоки комментариев в каждом файле. Теперь я могу отличить мои изменения от svn без информации fyi, что svn падает в комментариях.
Технически это позволит отображать комментарии на python и bash, такие как #TODO
в diff, и если оператор разделения запущен в новой строке в С++, его можно было бы игнорировать:
a = b
/ c;
Также документация на -G
в Git показалась довольно недостаточной, поэтому информация здесь должна помочь:
git diff -G<regex>
-G<regex>
Ищите различия, текст патча содержит добавленные/удаленные строки, которые соответствуют
<regex>
.Чтобы проиллюстрировать разницу между
-S<regex> --pickaxe-regex
и-G<regex>
,
рассмотрите фиксацию со следующим diff в том же файле:+ return !regexec(regexp, two->ptr, 1, ®match, 0); ... - hit = !regexec(regexp, mf2.ptr, 1, ®match, 0);
Пока
git log -G"regexec\(regexp"
покажет это коммит,git log -S"regexec\(regexp" --pickaxe-regex
не будет (потому что количество вхождений этой строки не изменилось).Дополнительную информацию см. в записи кирки в gitdiffcore (7).
(обратите внимание, проверено на Git v2.7.0)
-G
использует основное регулярное выражение.?
, *
, !
, {
, }
{
, }
.()
и OR-ing работает с |
.\s
, \W
и т.д.^$
работают.Обратите внимание, что параметр -G
фильтрует файлы, которые будут различаться.
Но если файл "разнятся", те строки, которые были "исключены/включены" раньше, будут показаны в diff.
Показывать только разницу файлов по крайней мере с одной строкой, в которой упоминается foo
.
git diff -G'foo'
Показать разницу в файлах для всех, кроме строк, начинающихся с #
git diff -G'^[^#]'
Показать файлы с разницами, обозначающими FIXME
или TODO
git diff -G`(FIXME)|(TODO)`
См. также git log -G
, git grep
, git log -S
, --pickaxe-regex
, --pickaxe-all
https://github.com/git/git/search?utf8=%E2%9C%93&q=regcomp&type=
https://github.com/git/git/blob/master/diffcore-pickaxe.c
if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) {
int cflags = REG_EXTENDED | REG_NEWLINE;
if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE))
cflags |= REG_ICASE;
regcomp_or_die(®ex, needle, cflags);
regexp = ®ex;
// and in the regcom_or_die function
regcomp(regex, needle, cflags);
http://man7.org/linux/man-pages/man3/regexec.3.html
REG_EXTENDED
Use POSIX Extended Regular Expression syntax when interpreting
regex. If not set, POSIX Basic Regular Expression syntax is
used.
//...
REG_NEWLINE
Match-any-character operators don't match a newline.
A nonmatching list ([^...]) not containing a newline does not
match a newline.
Match-beginning-of-line operator (^) matches the empty string
immediately after a newline, regardless of whether eflags, the
execution flags of regexec(), contains REG_NOTBOL.
Match-end-of-line operator ($) matches the empty string
immediately before a newline, regardless of whether eflags
contains REG_NOTEOL.
Надеюсь, что это поможет.
Мне было проще использовать git difftool
для запуска внешнего diff:
git difftool -y -x "diff -I '<regex>'"
Найден решение. Я могу использовать эту команду:
git diff --numstat --minimal <commit> <commit> | sed '/^[1-]\s\+[1-]\s\+.*/d'
Чтобы показать файлы с более чем 1 строкой, измененной между коммитами, которая исключает файлы, единственным изменением которых является номер версии в комментариях.
Возможно, bash script как это (я не тестировал код, дайте мне знать, можете ли вы заставить его работать или нет)
#!/bin/bash
git diff --name-only "[email protected]" | while read FPATH ; do
LINES_COUNT=`git diff --textconv "$FPATH" "[email protected]" | sed '/^[1-]\s\+[1-]\s\+.*/d' | wc -l`
if [ $LINES_COUNT -gt 0 ] ; then
echo -e "$LINES_COUNT\t$FPATH"
fi
done | sort -n
Использование 'grep' для вывода git diff:
git diff -w | grep -c -E "(^[+-]\s*(\/)?\*)|(^[+-]\s*\/\/)"
Только изменения в комментариях могут быть рассчитаны. (А)
Использование вывода git diff --stat ':
git diff -w --stat
могут быть рассчитаны все изменения строк. (В)
Чтобы получить счетчик изменений строки исходного кода (NCSL), вычитайте (A) из (B).
Объяснение: На выходе git diff (в котором игнорируются пробелы),
ПРИМЕЧАНИЕ. В подсчете строк комментариев могут возникать незначительные ошибки из-за следующих допущений, и результат должен приниматься как показатель шара.
1.) Исходные файлы основаны на языке C. Файлы Makefile, Shell script имеют разные условные обозначения '#' для обозначения строк комментария и, если они являются частью diffset, строки комментариев не будут считаться.
2.) GIT соглашение о смене строки: если строка изменена, GIT видит, что эта конкретная строка удаляется, и там добавляется новая строка, и она может выглядеть как две строки изменены тогда как в действительности одна строка модифицируется.
В приведенном ниже примере новое определение "FOO" выглядит как изменение строки.
$GIT diff --stat -w abc.h
...
- # define FOO 7
+ # определить FOO 105
...
1 файл изменен, 1 вставка (+), 1 удаление (-)
$
3.) Допустимые строки комментариев, не соответствующие шаблону (или) Допустимые строки исходного кода, соответствующие шаблону, могут вызывать ошибки в вычислении.
В приведенном ниже примере строка "+ blah blah", которая не начинается с "*", не будет отображаться как строка комментария.
+ /*
+ blah blah
+ *
+ */
В приведенном ниже примере строка "+ * ptr" будет считана как строка комментария, так как она начинается с *, хотя это допустимая строка исходного кода.
+ printf("\n %p",
+ *ptr);