При работе с Git-репозиториями часто нужно выполнять множество одинаковых действий: фиксировать изменения, переключать ветки, синхронизировать репозитории. Всё это требует ввода соответствующих команд в терминале. Когда частота ввода повышается до утомительной, на помощь могут прийти различные GUI-инструменты. В статье расскажу об одном из них — Lazygit, легковесном консольном клиенте для Git, который облегчает и упрощает работу с репозиториями.
Об инструменте
Автор проекта — Jesse Duffield, разработчик из Мельбурна. Начиналось всё как хобби: по словам Jesse, он хотел чтобы и другие разработчики могли быть такими же ленивыми, как он сам. На текущий момент вокруг утилиты собралось довольно большое сообщество. В разработке поучаствовало уже 178 контрибьюторов. У проекта 32 тыс. звезд на GitHub.
Lazygit написан на Go, распространяется под лицензией MIT и работает под всеми доступными операционными системами.
GUI сделан на основе библиотеки gocui, с помощью которой можно реализовать полноценные окна и взаимодействие с ними в терминале.
Установка утилиты
Разработчики подготовили сборки для всех существующих ОС, даже для FreeBSD (!).
Стоит отметить, что я сам активно пользуюсь этой программой на протяжении последних двух–трех лет. Поэтому успел протестировать ее на множестве ОС, начиная с различных Linux и macOS и заканчивая той самой FreeBSD.
В нашем случае тесты проводятся на macOS, поэтому для установки воспользуемся Homebrew:
brew install lazygit
После установки запустить программу можно командой lazygit
. Если в каталоге, в котором вы находитесь, уже инициализирован Git-репозиторий, он сразу же будет подхвачен, и можно начинать работать. Если репозитория нет, программа спросит, нужно ли его там создать, предоставив на выбор два варианта: создать или отказаться (во втором случае программа не запустится).
Обзор интерфейса
Для примера рассмотрим репозиторий werf. Склонируем его, перейдем в каталог и запустим утилиту:
$ git clone git@github.com:werf/werf.git
Cloning into 'werf'...
remote: Enumerating objects: 119179, done.
remote: Counting objects: 100% (66/66), done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 119179 (delta 34), reused 13 (delta 8), pack-reused 119113
Receiving objects: 100% (119179/119179), 47.85 MiB | 4.24 MiB/s, done.
Resolving deltas: 100% (78239/78239), done.
$ lazygit
Главный интерфейс программы разделен на несколько окон:
Files — здесь отображаются измененные файлы, если они есть.
Local branches — локальные ветки в склонированном репозитории.
Commits — все последние коммиты.
Diff — дифф изменений.
Command log — лог работы.
Рассмотрим подробнее основные возможности программы.
Работа с ветками
Переключение на удаленную ветку
В некоторых окнах можно переключиться на другой режим. Например, в окне с ветками можно просмотреть не только локальные, но и все ветки в удаленном репозитории, переключившись на режим Remotes. Для этого выбираем нужный репозиторий и нажимаем клавишу Enter.
Если ваш терминал поддерживает работу с мышью — как, например, iTerm2 в macOS, — можно просто нажать на нужную строку.
После выбора репозитория появится список всех доступных удаленных веток. В окне Diff при этом отобразится структура коммитов в соответствии с этими ветками:
Чтобы начать работать с веткой, на нее нужно переключиться — например, с помощью Space. При этом название локальной ветки, если необходимо, можно изменить:
После этого она станет доступна в разделе Local Branches.
Обновление веток
Если состояние текущей ветки актуально, она помечается зеленой галочкой.
Если локальная ветка «отстала» от мейнстрима, вместо галочки будет отображена стрелка, соответствующая состоянию отличий:
стрелка вниз — требуется скачать новые коммиты из удаленного репозитория;
стрелка вверх — нужно отправить изменения.
На примере выше отображены две ветки: fix-in-usage-style
в актуальном состоянии, и main
, отставшая от мейнстрима на 14 коммитов.
Любую ветку можно обновить, выполнив fetch
или pull
. Программа позволяет сделать это с помощью горячих клавиш: переходим на нужную ветку и нажимаем клавишу f или p в зависимости от команды, которую нужно выполнить.
Горячая клавиша может не сработать, если включена русская раскладка. Регистр также имеет значение — в этом конкретном случае нужно нажимать на маленькую f или p.
Создание новой ветки
Создать новую ветку можно с помощью клавиши n, выбрав ту ветку, от которой нужно ветвиться. Программа предложит ввести название новой ветки. После ввода будет создана новая, готовая к работе локальная ветка; она сразу появится в окне Local Branches.
Обратите внимание, что программа автоматически ничего никуда не отправляет, и созданная ветка будет только на вашей машине. Для отправки ее в удаленный репозиторий нужно, как обычно, сделать commit
и push
.
Merge веток
Выполнить merge веток можно горячей клавишей M. Для этого сначала нужно переключиться на целевую ветку, затем выбрать ту, из которой будут вноситься изменения, и нажать M.
Внесение изменений, commit и push
Commit изменений
После того, как новая ветка создана, можно вносить изменения в код. По завершении в левом верхнем окне программы (Files) появится список изменившихся файлов, которые можно закоммитить в репозиторий:
В правом окне Diff будут отображаться все изменения, внесенные в конкретный файл.
Чтобы зафиксировать изменения, нажимаем клавишу a (git add
). Все измененные файлы позеленеют, то есть будут готовы к коммиту.
Чтобы закоммитить изменения, нажимаем клавишу c и в открывшемся окне вводим описание коммита.
Новый коммит появится в нижнем левом окне Commits.
Изменение описания коммита
Чтобы исправить описание коммита, переходим в окно Commits и выбираем нужный коммит. Нажимаем клавишу r (rename) — после этого возвращаемся в то же самое окно, в котором можно изменить текст.
Push в удаленный репозиторий
Для отправки зафиксированных изменений в удаленный репозиторий используется сочетание клавиш Shift + P.
Если вы делаете это впервые, программа спросит, с каким удаленным репозиторием предстоит работать и в какую ветку отправлять изменения.
Здесь лучше оставить всё как есть: локальный репозиторий и удаленный должны быть одинаковыми во избежание неприятных казусов в будущем.
Если именовать ветки по-разному, в будущем можно запутаться в том, что и куда должно отправляться. Это может привести к неприятным ситуациям, когда изменения будут отправлены не в ту ветку, а также к потраченному впустую времени на поиск правильного пути.
Перейдем к более сложным задачам.
Squah, rebase и force-push коммитов
Squash и force-push
Часто требуется делать промежуточные коммиты, чтобы не потерять наработки или зафиксировать важную часть прогресса по задаче. При этом коммиты нужно отправить в свою ветку с изменениями в удаленном репозитории.
Например, мы создали промежуточный комментарий, назвав его просто +++
.
Отправим изменения в репозиторий (Shift + P).
Теперь продолжим работу до момента, когда понадобится закончить текущую правку и объединить предыдущий коммит с последним. Как обычно, закоммитим изменения:
Далее необходимо «слить» последний коммит с предыдущим. Сделать это можно горячей клавишей s. Программа, запросив подтверждение, сделает squash коммита со следующим, расположенным ниже по списку.
Теперь два последних коммита объединены в один. Осталось их переименовать (по умолчанию имя общего коммита содержит описания обоих коммитов). Нажимаем r и удаляем лишнее (+++
):
Отправим изменения в удаленный репозиторий. Так как локальная ветка отличается от удаленной, необходимо не просто выполнить push изменений, а сделать это в режиме –force, чтобы изменения перезаписались.
Обратите внимание, что push с force нужно выполнять только тогда, когда есть четкое понимание, для чего это делается. Операция перезаписывает содержимое всей удаленной ветки, что может привести к потере данных. Например, два человека одновременно работают с одной веткой над какой-то небольшой правкой, и оба по очереди перезаписали удаленную ветку своими изменениями. Если не уследить за своевременной синхронизацией, вероятность потери данных сильно возрастает. Также нужно помнить, что ни в коем случае не следует выполнять такой push к главной ветке репозитория (master или main).
Для отправки изменений снова нажимаем Shift + P. Программа определит, что удаленная ветка отличается от локальной и сама предложит сделать push с force.
Rebase ветки
Рассмотрим еще один частый случай. Например, во время работы текущая ветка отстала от мейнстрима, и необходимо актуализировать состояние с помощью rebase.
Для этого нужно:
переключиться на ветку, rebase которой будем выполнять;
выбрать ветку, на которую будет производиться rebase.
На скриншоте показан пример rebase ветки fix-in-usage-style
на ветку main
:
В случае успешного завершения процесса в дереве коммитов появятся все «новые» коммиты, соответствующие актуальному состоянию ветки main
. Последние коммиты, внесенные в ветку fix-in-usage-style
, будут всё так же сверху.
Чтобы зафиксировать изменения в удаленном репозитории, необходимо выполнить push (Shift + P).
Вызов справки
В любом из окон можно вызвать справку с перечнем всех доступных горячих клавиш, нажав x.
Конфигурация
Программу можно гибко настраивать под себя, начиная с цветовой гаммы и заканчивая добавлением новых команд или горячих клавиш. Все настройки лежат в файле config.yml
, который размещается в разных каталогах в зависимости ОС:
Linux:
~/.config/lazygit/config.yml
MacOS:
~/Library/Application Support/lazygit/config.yml
Windows:
%APPDATA%\lazygit\config.yml
Более подробно о всех доступных настройках написано в официальной документации.
Завершение работы
Для выхода из программы необходимо нажать горячую клавишу q.
Итог
Lazygit — полезная программа, которая упрощает работу с Git. Она не занимает много места, не требует дополнительных знаний и умений помимо тех, которые требует сам Git. Программа предоставляет очень удобный интерфейс для привычных каждодневных операций, таких как управление ветками в репозитории и их rebase, squash коммитов и push ветки в удаленный репозиторий с force.
Мне кажется, автору Lazygit удалось реализовать задуманное — облегчить работу с Git простым, понятным и «ленивым» средством.
P.S.
Читайте также в нашем блоге: