Это просто работает?
git diff branch-a branch-b -- '*.js'
Если вы хотите получить более полное представление:
git diff branch-a branch-b -- $(cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b) | sort | uniq | grep '\.js$')
Что делает эта супердлинная команда?
Эта часть должна быть очевидной, --
в конце этой части означает, что все последующие аргументы являются путями к файлам, а не параметрами
git diff branch-a branch-b --
Давайте посмотрим на эту гигантскую команду:
$(cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b) | sort | uniq | grep '\.js$')
Во-первых, это:
cat <(git ls-tree --name-only -r branch-a) <(git ls-tree --name-only -r branch-b)
При этом используется git ls-tree
для вывода списка всех файлов в коммитах и использование cat
для сбора вывода файлов в двух ветвях.<()
является заменой оболочки, которая заменяется именем канала.Другая сторона канала, по-видимому, является выводом git ls-tree
.
| sort | uniq | grep '\.js$'
Сортировка и фильтрация объединенных файлов - на практике они могут дублироваться, поэтому uniq
удаляет дублирующиеся данные.grep '\.js$'
в конце фильтров показывает только файлы, путь которых заканчивается на .js
.
Результатом длинной команды в $()
является объединение .js
файлов в обеих ветвях, которое затем передаетсяgit diff
для фильтрации файлов сравнения.Это именно то, что вы хотите, если я правильно понимаю.
Как насчет упаковки этого в удобный сценарий оболочки для дальнейшего использования?
#!/bin/sh
SOURCE=${1:-master}
TARGET=${2:-HEAD}
FILTER=${3:-.*}
exec git diff $SOURCE $TARGET -- $(cat <(git ls-tree --name-only -r $SOURCE) <(git ls-tree --name-only -r $TARGET) | sort | uniq | grep "$FILTER")
Использование:
./diff-all.sh branch-a branch-b '\.js$'