git diff --check показывает изменения не связанных веток / файлов
Фон
Я пытаюсь увидеть пробельные ошибки текущей ветви (игнорируя CR на eol). Большинство файлов используют CRLF, и у меня нет установленного конфигурации core.whitespace.
Это оригинальная команда:
git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD
HEAD относится к ветви, созданной поверх старой версии master (" oldmaster ").
Проблема в том, что git diff --check
ведет себя неожиданным образом: он показывает не только ошибки в master..HEAD, но и ошибки в oldmaster..master.
Вопросы
Это происходит потому, что
git diff --check
сравнивает целые снимки в заданном диапазоне ревизий?Почему
git log
а такжеgit diff
вести себя по-другому в этом случае?не должны
git diff --check
сравнить только измененные строки в измененных файлах?
Информация
мастер против старого мастера (числа совпадают):
$ git log --oneline oldmaster..master | wc -l
115
$ git diff --name-only oldmaster..master | wc -l
115
Это показывает соответствующие коммиты правильно:
$ git log --oneline master..HEAD | wc -l
4
Это показывает правильные файлы:
$ git log --oneline --name-only master..HEAD -- | grep -E '^[a-zA-Z]+/' \
| sort -u | wc -l
4
К ним, по некоторым причинам, также относятся файлы, измененные в oldmaster..master:
$ git diff --name-only master..HEAD -- | wc -l
119
$ git -c core.whitespace=trailing-space,cr-at-eol diff --name-only \
master..HEAD -- | wc -l
119
Оба из них также показывают несвязанные файлы:
$ git diff --check master..HEAD -- | grep -E '^[a-zA-Z]+/' | cut -d : -f 1 \
| sort -u | wc -l
30
$ git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD \
-- | grep -E '^[a-zA-Z]+/' | cut -d : -f 1 | sort -u | wc -l
9
1 ответ
За исключением комбинированных различий (которые вы здесь не используете), git diff
строго сравнивает два снимка.1 Используемый синтаксисgit diff A B
против git diff A..B
- здесь неактуально. Git извлекает снимок A, извлекает снимок B и сравнивает эти два снимка. Любые параметры флага, которые вы используете, такие как --check
, применяются к этому конкретному сравнению. совершить A
не должен быть предком B
ни наоборот; Git не смотрит ни на один из коммитов "между" этими двумя коммитами; это просто извлекает A
затем извлекает B
и отличает тех.2
git log
Команда делает что-то совсем другое: она просматривает граф ревизий. Дано git log A..B
Git находит все коммиты, доступные из B
которые недоступны из A
, Для ясного определения достижимости см. Think Like (a) Git.
Обратите внимание, что при использовании -p
с git log
просматривать коммиты как патчи, git log
сравнивает каждый коммит с его (единственным) родителем. Если в A..B
диапазон, например, git log -p A..B
первые шоу B
и работает git diff B^ B
затем показывает B^
и работает git diff B^^ B^
и последние шоу B^^
и работает git diff B^^^ B^^
, (Предполагается, что в диапазоне нет коммитов слияния, но git log
в любом случае по умолчанию пропускает патчи для фиксации слияния.)
1 Чтобы увидеть комбинированный дифференциал, используйте git show
на коммит слияния. git diff
Команда также будет создавать комбинированные различия с некоторыми конкретными аргументами, иногда неправильно: в частности, синтаксис с тремя точками, git diff A...B
, предназначен для сравнения базы слияния A
а также B
совершать B
, но иногда делает что-то другое. Кроме того, когда вы используете индекс и индекс содержит конфликтующее слияние, обычный git diff
будет производить комбинированные различия.
2 Технически ему даже не нужно извлекать два снимка - он просто работает непосредственно с их древовидных объектов. Он должен извлечь различные капли, чтобы вычислить разницу. Для идентичных сгустков, git diff
знает, что они идентичны, потому что их хэш-идентификаторы совпадают. Но об этом проще рассуждать как "извлекать и сравнивать".