Удобные git-diff’ы в терминале с FZF

Удобные 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 и |, можно сварить что-то интересное. План такой:

  1. Получить список изменённых файлов с git diff --name-only
  2. Передать его в fzf
  3. В превью показывать 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 возвращает пути относительно корня, и из-за этого могут возникать странности.

Надеюсь, это окажется вам полезным.

Report Page