Хотите исключить файл из «git diff»

229

Я пытаюсь исключить файл ( db/irrelevant.php) из Git diff. Я попытался поместить файл в dbподкаталог, названный .gitattributesстрокой, irrelevant.php -diff и я также попытался создать файл, .git/info/attributesсодержащий db/irrelevant.php.

Во всех случаях db/irrelevant.phpфайл включается в diff как двоичный патч Git. Я хочу, чтобы изменения в этом файле игнорировались командой diff. Что я делаю не так?

Майкл
источник

Ответы:

325

OMG, драйвера и awk, чтобы исключить паршивый файл? С git 1.9 вы можете:

git diff -- . ':(exclude)db/irrelevant.php' ':(exclude)db/irrelevant2.php'

Ах, элегантность! Смотрите цитируемый ответ и для подробностей этот ответ @torek

Mr_and_Mrs_D
источник
4
ПРИМЕЧАНИЕ. Если вы хотите исключить конкретное имя файла, вам нужно поставить перед звездочкой префикс, отличный от .gitignoreсинтаксиса файла. Например, :!*shrinkwrap.yamlвместо :!shrinkwrap.yaml.
вон
7
Исключите больше файлов, например, у меня есть файлы * .min.css и * .min.js, чтобы избежать их из git diff. Итак, я использую командуgit diff -- . ':(exclude)*.min.js' ':(exclude)*.min.css'
maheshwaghmare
4
Синтаксис Windows : git diff -- . ":(exclude)db/irrelevant.php"(двойные кавычки вместо одинарных кавычек)
cnlevy
4
Спасибо! Такой эзотерический синтаксис ... Я должен искать его каждый раз.
Даниэль Уолтрип
1
@cnlevy или без кавычек! git diff -- . :(exclude)db/irrelevant.php
Матиас,
62

Вы можете настроить собственный драйвер diff с помощью команды no op и назначить его тем файлам, которые следует игнорировать.

С помощью этой команды создайте специфичный для репозитория драйвер diff

git config diff.nodiff.command /bin/true

или для всех ваших репо с --global.

(Если /bin/trueне существует в MacOS, альтернативы будут использовать /usr/bin/trueили echo).

Затем назначьте новый драйвер diff тем файлам, которые вы хотите игнорировать в своем .git/info/attributesфайле.

irrelevant.php    diff=nodiff

Если это состояние должно быть совместно с другими разработчиками , вы могли бы использовать .gitattributesвместо .git/info/attributesи разделить git configкоманду со своими коллегами (через файл документации или что - то).

KurzedMetal
источник
2
Это именно то, что я искал - как описано в kerneltrap.org/mailarchive/git/2008/10/17/3711254 Я отредактировал ~ / .gitconfig, добавив: [diff "nodiff"] `command = / bin / true`, а затем создал файл с именем .git / info / attribute, в которые я добавил: irrelevant.php diff=nodiff
Майкл
12
Этот ответ работал намного лучше для меня: stackoverflow.com/questions/1016798/…
Нил Форрестер
3
Интересно, что этот подход не работает с git diff --stat. В этом случае можно использовать git diff ... | diffstatв качестве обходного пути.
ddkilzer
@ Майкл, эта ссылка, похоже, не работает, есть другая?
DickieBoy
3
просто дополнение: если вы хотите заставить git diff отображать его в любом случае, используйте--no-ext-diff
Florian Klein
35

Вы также можете использовать программу filterdiff из коллекции программ patchutils, чтобы исключить некоторые части diff. Например:

git diff | filterdiff -p 1 -x db/irrelevant.php
Силард Пфайффер
источник
4
Обратите внимание, что -pиз man-страницы (1) это «-pn, --strip-match = n При сопоставлении игнорируйте первые n компонентов пути». Мне потребовалось некоторое время, чтобы понять, что -p 1это убирает dbдеталь с пути ОП. Если вы просто хотите указать имя файла и игнорировать все возможности path / dir, вы можете использовать -p 99.
Тайлер Коллир
32

Этот метод короче принятых ответов.

git diff 987200fbfb 878cee40ba --stat -- ':!*.cs'

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

Чиль тен бринке
источник
Имейте в виду, что фильтр применяется только ко всем файлам в вашем текущем каталоге.
Чиль тен
Это был лучший ответ. Я смог упростить это немного больше: stackoverflow.com/a/58845608/3886183
dlsso
2
Я бы удалил часть --stat или хотя бы объяснил, что она делает, поскольку ни один из других ответов не содержит ее.
mix3d
Флаг статистики показывает вам файлы и их разность, что позволяет вам легко проверить, работает ли фильтр так, как вы планировали.
Чиль тен Бринке
17

Это однострочное решение не требует других утилит / загрузок:

git diff `git status -s |grep -v ^\ D |grep -v file/to/exclude.txt |cut -b4-`

Где file/to/exclude.txt, конечно, имя файла, который вы хотели бы исключить.

Изменить: кредит Ksenzee для исправления удаленных файлов, нарушающих различий.

Бен Ру
источник
Я пытаюсь адаптировать ваш лайнер git diff --stat masterбез особого успеха - не могли бы вы помочь?
Mr_and_Mrs_D
13

Действительно хороший ответ от KurzedMetal за то, что мне нужно было сделать, а именно способность видеть, что файл изменился, но не генерировать diff, который мог бы быть огромным, в моем случае.

Но мой коллега предложил подход, который был еще проще и работал для меня:

добавление .gitattributesфайла в каталог, в котором находится файл, который будет игнорироваться, git diffсо следующим содержимым:

file-not-to-diff.bin -diff

Это все еще позволяет git status"видеть", изменился ли файл. git diffтакже «увидит», что файл изменился, но не будет генерировать diff.

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

user3589608
источник
11

Самый простой ответ

git diff ':!db/irrelevant.php'

Это только ':!<path to file>'после вашей команды diff. Команда diff может быть настолько сложной, насколько вам нравится, и вы можете использовать подстановочные знаки, такие как *.min.jsили добавлять несколько исключений (пробел разделяет блоки в кавычках), если хотите.

dlsso
источник
5

Относительно корневого каталога git

git diff принимает необязательное исключение

git diff -- ":(exclude)thingToExclude"

Вы можете добавить несколько подстановочных знаков

git diff -- ":(exclude)*/thingToExclude/*"

Целевые типы файлов

git diff -- ":(exclude)*/$1/*.png"

Или напишите небольшой скрипт для ваших точечных файлов

Такие как .bash_profileили.zshrc

gde() {
    # git diff exclude files or folders 
    # usage: 
    # gde fileOrFolderNameToExclude
    git diff -- ":(exclude)*/$1/*"
}
jasonleonhard
источник
это просто не работает для меня, я не получаю diff вообще, с обоими синтаксисами, используя (исключить) или!. У меня есть GIT 2.21.0
Olivvv
Вы можете использовать git diff для неустановленных или промежуточных файлов. Если вы добавили git, они станут инсценированными. Если они поставлены, вы можете сделать git diff --stagedНадеюсь, что это поможет вам.
Джейсон Леонард
Синтаксически, что делает двоеточие?
Иона
2

Это очень просто, вы можете исключить то, что вы хотите, используя стандартные команды Unix, эти команды доступны в git bash даже в среде Windows. В приведенном ниже примере показано, как исключить diff для файлов pom.xml, сначала проверьте, что diff для master только для имен файлов, затем с помощью 'grep -v' исключите ненужные файлы, а затем снова запустите diff для master с предварительно подготовленным списком:

git diff master `git diff --name-only master | grep -v pom.xml`
Nieznany Anonimiec
источник
1

похоже на решение Бена Ру , но все равно делится:

git status --porcelain | grep -v $PATTERN_TO_EXCLUDE | awk '{print $2}' | xargs git diff

или, если изменения уже были зафиксированы локально:

git diff --name-only origin/master | grep -v $PATTERN_TO_EXCLUDE | xargs git diff origin/master

Примеры:

git status --porcelain | grep -v docs | awk '{print $2}' | xargs git diff origin/master

git diff --name-only origin/master | grep -v docs | xargs git diff origin/master
Крис Монторо
источник
1

Я делаю следующее:

git add *pattern_to_exclude*
git diff
git reset HEAD .

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

BlueMagma
источник
0

Если вы хотите сделать это только для визуальной проверки различий, инструмент визуального сравнения (например, Meld ) позволит вам сделать это с помощью короткой команды, которую легко запомнить.

Во-первых, настройте инструмент сравнения, если вы еще этого не сделали.

$ git config --global diff.tool = meld

Затем вы можете запустить каталог diff.

$ git difftool --dir-diff

Вы сможете просматривать различия (по файлам) в Meld (или по вашему выбору). Просто не открывайте файл, который хотите игнорировать.

mkasberg
источник