В то время как the answer given by GoZoner работает для некоторых (? Сто) файлов, он выполняет git diff
несколько раз (в случае xargs
) или выходит из строя (в случае git diff … -- `find …`
), если для diff существует большое количество файлов. Это может быть проблемой или нет, в зависимости от вашего варианта использования.
Возможным решением является создание коммита, содержащего только изменения в интересующих файлах и diff commit. На основании an answer on unstaging files matching some pattern я пришел с этим решением:
git co <new_branch> --detach
git reset --soft <old_branch>
Теперь git status --porcelain | grep <pattern>
показывает все файлы, которые должны быть сопоставлены. Все остальные файлы могут быть перечислены путем передачи -v
в grep
, то есть git status --porcelain | grep -v <pattern>
. Эти файлы должны быть сброшены в состояние <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
Вы можете использовать все опции или аргументы, которые вы любите.
Примечание. Это решение не подвергается экстенсиональному тестированию и может потерпеть неудачу, например.на файлы со специальными символами или другими специальными случаями ... Предложения по улучшению решений приветствуются ;-)
Это похоже на то, что просто 'git diff', но не содержит последний файл. – Zantier
Возможно, последний файл не изменился. Пожалуйста, отлаживайте мои предложения выше. Если все еще неясно, опубликуйте результаты моих отладочных предложений в исходном вопросе. – GoZoner
'git diff - только имя-только | grep AssemblyInfo.cs' действительно дает правильные имена файлов, как и следовало ожидать, но мне нужен полный вывод diff. Оба «находят». -name AssemblyInfo.cs | xargs git diff - 'и' find. -name AssemblyInfo.cs | xargs git diff --name-status - 'предоставляют файлы, которые не являются« AssemblyInfo.cs »(например, файлы .sql). – Zantier