Удобные git-diff’ы в терминале с FZF
Иногда команда git diff ощущается немного неудобной. Она вываливает на экран кучу информации разом. Я пользуюсь git diff не только чтобы проверить изменения перед коммитом, но и чтобы просматривать pull-request’ы или искать баги, появившиеся между двумя коммитами. Когда изменённых файлов много, бесконечная прокрутка вверх-вниз быстро начинает раздражать.

Хочется чего-то по-типу IDE: список файлов слева, diff — справа. При этом покидать терминал совсем не хочется. Я думал, что для такого придётся городить какой-то хитрый bash-скрипт. Но оказалось, что всё можно сделать довольно просто — с помощью инструмента fzf.
Самое интересное: FZF и как его настроить
FZF — это мощный fuzzy-finder. Он принимает список строк и делает его удобным для поиска. Посмотреть его можно тут: https://github.com/junegunn/fzf. Базовая установка выглядит так:
brew install fzf
Если запустить fzf без параметров, он покажет список файлов в текущей директории, и ввод сразу начнёт фильтровать этот список!

Ещё одна удобная фишка FZF — это окно предварительного просмотра, куда можно выводить результат выполнения другой команды. Например, можно использовать fzf вместе с bat, чтобы красиво вывести содержимое файла — вот так. bat — это альтернатива cat с подсветкой синтаксиса. {-1} — это выбранный файл.
fzf --preview 'bat {-1} --color=always'

А что если передать вывод git diff прямо в fzf? Если вдруг ещё не приходилось этим пользоваться, то пайп — это оператор |, который отправляет вывод команды слева на вход команды справа. Имея под рукой git diff, fzf и |, можно сварить что-то интересное. План такой:
- Получить список изменённых файлов с
git diff --name-only - Передать его в
fzf - В превью показывать diff файла через
git diff --color=always
Смешиваем всё вместе — и получаем аккуратную функцию ниже. $@ — это специальная переменная, означающая «все параметры», так что мы сохраняем возможность передавать любые параметры git diff. Часть с превью вынесена на отдельную строку, чтобы её было проще читать. Положите это в свой .bashrc или .zshrc и перезагрузите оболочку.
fd() {
preview="git diff $@ --color=always -- {-1}"
git diff $@ --name-only | fzf -m --ansi --preview $preview
}
Теперь можно просто запускать fd и получать тот самый IDE-опыт.

Поскольку мы сохранили возможность использовать функцию как обычный git diff, можно делать, например, вот такое:
# сравнить текущую ветку с master fd master... # сравнить изменения между двумя коммитами fd 4c674950..6d88a7bfd8

Важно: эта команда работает только из корня git-проекта. git diff --name-only возвращает пути относительно корня, и из-за этого могут возникать странности.
Надеюсь, это окажется вам полезным.