Я хотел бы, чтобы результаты git diff
были отфильтрованы по имени файла.
В частности, мне нужен diff для всех файлов с именем "AssemblyInfo.cs", но расположенных где-нибудь в репозитории git.
Я использую git для Cygwin, если это имеет значение.
Я хотел бы, чтобы результаты git diff
были отфильтрованы по имени файла.
В частности, мне нужен diff для всех файлов с именем "AssemblyInfo.cs", но расположенных где-нибудь в репозитории git.
Я использую git для Cygwin, если это имеет значение.
Аргументы файла для git diff
должны быть разделены символом --
- попробуйте следующее:
find . -name <pattern> | xargs git diff --
xargs позволяет корректно обрабатывать пробелы, табуляции, новые строки и т.д.
Вы можете отладить его с аргументом --name-status
до git diff
. Вы также можете попробовать:
git diff --name-only | grep <pattern>
[edit] Попробуйте:
git diff --name-status -- `find . -name '<pattern>'`
[email protected](98)$ git diff --name-status -- `find . -name '*.scm'`
M scheme/base/boolean.scm
M surf/compiler/common.scm
M surf/compiler/compile.scm
M surf/compiler/expand.scm
Самый простой способ - просто использовать подстановочный знак:
git diff -- '*AssemblyInfo.cs'
По крайней мере, это работает на моем Git v1.8.4, bash 3.2 и zsh 5.7.
Вы можете использовать pipeline
find . -name AssemblyInfo.cs | git diff
Используйте find
для фильтрации всех файлов с именем "AssemblyInfo.cs", затем используйте вывод в качестве параметра git diff
.
В то время как ответ, заданный GoZoner, работает для некоторых (сотни?) файлов, он выполняет git diff
несколько раз (в случае xargs
) или не работает (в случае git diff … -- `find …`
), если для diff существует большое количество файлов. Это может быть проблемой или нет, в зависимости от вашего варианта использования.
Возможное решение состоит в создании коммита, содержащего только изменения в интересующих файлах и diff commit. Основываясь на ответе на неподходящие файлы, соответствующие некоторому шаблону, я придумал это решение:
git co <new_branch> --detach
git reset --soft <old_branch>
Теперь git status --porcelain | grep <pattern>
отображает все файлы, которые нужно сравнить. Все остальные файлы можно перечислить, передав -v
в grep
, т.е. git status --porcelain | grep -v <pattern>
. Эти файлы должны быть reset для состояния <old_branch>
:
# Remove the destination of renamed and copied files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^R \|^C ' | sed 's/.* -> //' | xargs git rm -f --
# Remove added files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^A ' | cut -c 4- | xargs git rm -f --
# Restore deleted files not matching <pattern>
git status --porcelain | grep -v <pattern> | grep '^M \|^D ' | cut -c 4- | xargs git checkout HEAD --
(Обратите внимание, что использование xargs
не является проблемой в этом случае, поскольку вызов git rm
и git checkout
несколько раз в порядке.)
Теперь индекс (и рабочая копия) содержит только изменения в файлах, соответствующих <pattern>
. Следующее, что нужно сделать, это выполнить следующие изменения:
git commit -m "Changes between <old_branch> and <new_branch> in files matching <pattern>"
Что это! Теперь мы можем использовать git diff
, как обычно:
git diff HEAD^..HEAD
Вы можете использовать все параметры или аргументы, которые вам нравятся.
Примечание. Это решение не тестируется широко и может завершиться неудачно, например. на файлы со специальными символами или другие специальные случаи... Предложения по улучшению решения приветствуются; -)
find . -iregex AssemblyInfo\.cs -exec git diff {} +
вы можете заменить AssemblyInfo\.cs
своим регулярным выражением.
Вероятно, самый простой вариант - использовать:
git diff "*/*AssemlyInfo.cs"
работает с git 2.20.1