Исключить каталог из git diff

179

Мне интересно, как я могу исключить весь каталог из моего Git diff. (В данном случае / спец). Я создаю diff для всей нашей версии программного обеспечения с помощью команды git diff. Однако изменения в спецификациях не имеют значения для этой процедуры и просто создают головную боль. теперь я знаю, что могу сделать

git diff previous_release..current_release app/

Это создаст diff для всех изменений в каталоге приложения, но не, например, в каталоге lib /. Кто-нибудь знает, как выполнить эту задачу? Спасибо!

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

Mysrt
источник
4
Я нашел этот удивительный вопрос, потому что я стремился игнорировать подмодули . В этом случае, если вы так же наивны, как и я, этот вопрос может быть более полезным.
Brandizzi
Странно, что у нас до сих пор нет встроенного переключателя Git для этого в сентябре 2016 года
Michael Z

Ответы:

138

Предполагая, что вы используете bash и включили расширенный globbing ( shopt -s extglob), вы можете обработать это со стороны оболочки:

git diff previous_release current_release !(spec)

Избавляет вас от необходимости перечислять все остальные вещи.

Или оболочечный:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

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

Cascabel
источник
1
PS Globbing не соответствует скрытым файлам, поэтому, если вы одержимы, вы можете выбрать, .!(.|)чтобы соответствовать всем, начиная с .кроме .и ...
Каскабель
Похоже, что это не работает для файлов, которые являются новыми или удалены в разных филиалах. Я получаю ошибки, которые останавливают выполнение скрипта, говоря, что он не может противостоять ему.
Грэм Кристенсен
2
@Graham: я считаю, что --я только что добавил, должен это исправить.
Каскабель
1
Потрясающий ответ. Я хотел, чтобы отображались только имена (не фактические различия), поэтому мне пришлось добавить и --name-onlyв самом конце.
август
1
После игры с ним, просто хочу добавить, что если вы измените имя файла, он выдаст ошибку, но все, что вам нужно сделать, это добавить, -- path/of/new/fileи он это
выяснит
322

На основании этого ответа вы также можете использовать:

git diff previous_release..current_release -- . ':!spec'

Это новая функция git, которая позволяет исключить определенные пути. Он должен быть более надежным, чем различные оболочки оболочки.

Я публикую это здесь, потому что этот вопрос по-прежнему является хитом № 1 для "git diff exclude path".

cdleonard
источник
4
Люблю этот ответ. Если вы добавляете опции, делайте это до двойной черты. Например: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor
Не понимал, что могу использовать имена ветвей для - current_releaseи previous_releaseзаставил меня улыбнуться, когда я понял это.
trueheart78
2
Что сработало для меня git diff --stat dev -- . ':!/Mopy/Docs/*'. Что не работает для меня git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'и вариаций
Mr_and_Mrs_D
Действительно полезно. Вот синтаксис, чтобы увидеть, если какие-либо файлы изменены, кроме database.yml:git diff --check -- . ':!config/database.yml'
Дэн Кон
17
Также можно исключить несколько элементов, например так:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise
37

Если вы хотите указать более одного пути для исключения в git diff, вы просто добавляете дополнительные параметры исключения в конец, например, чтобы исключить все в каталогах vendor и bin из статистики: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'
Дэвид Грэм
источник
33

Вы можете попытаться сбросить атрибут diff для любых файлов в каталоге lib.
.gitattributes:

lib/* -diff

racl101 добавляет в комментариях :

Просто чтобы добавить к этому, для тех из вас, кто хочет ограничить git diffвывод файлов определенного типа, в пределах определенного каталога и его подкаталогов, как, например, весь JavaScript, сгенерированный упаковкой ваших .jsфайлов Webpack , вы можете добавить это к .gitattributes:

dist/js/**/*.js -diff

Тогда вы не видите весь этот шум в выводе git diff, а просто показывает: Binary files ... differчто более полезно.

VonC
источник
это удалит спецификации из всех моих различий, хотя. Я все еще хочу видеть свои различия в папке spec как обычно, но не тогда, когда я запускаю этот 'релиз' diff
Mysrt
2
@Mystr: Вы можете установить этот .gitattributesфайл в специальную ветку, созданную только для этого вида 'release' diff;) Перебазируйте эту специальную ветку поверх current_releaseи сделайте ваш diff оттуда.
VonC
Похоже, что это тоже не работает для файлов, которые удаляются по веткам. Удаленные файлы по-прежнему показывают полный diff.
Грэм Кристенсен
Не работает для меня _ Пути являются особенными? _site/* -diff
Мариус
@MariusAndreiana Нет, '_' не является особенным. Можете ли вы проверить, какое правило gitattributes применяется для файла из этой папки, с помощью: git-scm.com/docs/git-check-attr
VonC
22

Git diff теперь принимает пользовательский формат исключения: git diff -- ':(exclude)lib/*'

Будьте осторожны, если у вас много повторяющихся имен папок ('/ app', '/ lib' и т. Д.), Так как это исключит файлы относительно текущего рабочего каталога и корневого каталога git.

MaxPRafferty
источник
1
вам не хватает точки, не так ли лучше git diff -- . ':(exclude)lib/*'?
Николас Дермин
1
@NicolasDermine Нет, хотя то, что вы написали, эквивалентно. «Включающая» часть пути также необязательна. Вот почему вы можете просто делать git diffвсе, что связано с вашим текущим путем, а не требоватьgit diff -- .
MaxPRafferty
Примечание: на машинах с Windows используйте двойные кавычки, напримерgit diff -- ":(exclude)lib/*"
cnlevy
Понятия не имею почему, но для меня это работает только с точкой, как предложено @NicolasDermine. Я использую Cmder на win10.
Оливвв
3

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

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

git diff -- ":(exclude)thingToExclude"

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

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

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

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

Некоторый синтаксический сахар применяется

git diff -- ":!/\$1/"

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

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

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}
jasonleonhard
источник