Автор оригинала Скотт Чакон — сооснователь GitHub и основатель нового клиента GitButler. Этот клиент ставит во главу угла рабочий процесс и удобство разработки, в том числе код-ревью, и не является просто очередной обёрткой над CLI git.
Далее в нашей серии постов из трёх частей у нас новые фичи! Здесь я расскажу про пять относительно новых вещей в git, о которых вы могли не слышать, потому что ну почему вы?
Мы взглянем на:
- Штуки с git branch.
- Принудительный безопасный пуш.
- Подписывание коммитов ключом SSH.
- Подписывание пушей.
- Обслуживание Git.
Штуки с git branch
Это довольно вторично, но одна вещь в git всегда жужжала у меня над ухом. Я часто запускаю git branch
, чтобы посмотреть, какие вообще у меня есть ветки, но порядок у них глупейший из возможных (алфавитный), а через время их станет миллион.
В какой-то момент я начал именовать ветки так, чтобы отчасти управиться с этим. Каждая ветка оказывалась чем-то типа sc-0831-my-thing
, означая, что это была «моя штуковина», она создана 31 августа, sc
— мои инициалы, чтобы можно было группировать по тому, где чья ветка. Много дурацких метаданных ради попытки зазубрить ветки просто потому, что они так перечислены.
Но теперь мы можем попросить git помочь: сортировать ветки по objectsize
, authordate
, committerdate
, creatordate
, или taggerdate
опцией --sort
, или установить значение опции по умолчанию параметром конфигурации branch.sort
.
Так, для примера, если я хочу сортировать по убыванию даты последнего коммита, то могу выполнить:
git config --global branch.sort -committerdate
И теперь по умолчанию в самом верху будет показана ветка, в которую я коммитил последний раз.
У -commiterdate
одна (-), а не две (--) чёрточки. Это противоположное значение. Я видел, как люди путались и что-нибудь ломалось.
Когда у меня куча веток, на один экран они не помещаются. Грустно. Но теперь Git умеет брать список ветвей, пытаясь разделить его на колонки, чтобы лучше использовать пространство экрана. Воспользоваться этим можно через новую опцию --column
, или через настройку column.ui
.
Проверим:
Приятная сортировка вывода моих веток по столбцам
Ещё кое-что забавное. В Git реализовали терминальную команду преобразования списка в столбцы, которая сортирует что-нибудь из Git, эта команда называется git column
:
На всякий случай преобразуйте столбцы во что-то ещё, не связанное с Git.
Принудительный безопасный пуш
Следующая интересная вещь, которую добавили в git совсем недавно, — гораздо более безопасный способ делать принудительные пуши. В основном большинство из нас не делает их, поскольку всегда есть шанс переписать чьи-то коммиты. Давайте представим ситуацию:
- Вы делаете коммит и пуш чего-нибудь на GitHub.
- Кто-то другой вытягивает вашу работу, коммитит и пушит обратно.
- Вы меняете коммит, переписываете историю и пушите принудительно, не зная, что с вашим коммитом работал кто-то другой.
- Точно удаляется то, что сделал другой человек.
Что действительно нужно сделать, так это проверить, не пушил ли кто-то другой, и пушить принудительно, только если ответ — «нет». Однако здесь всегда есть что-то вроде состояния гонки: даже если вы сначала сделаете проверку, а затем вам придётся пушить, за это время из другого места может прилететь что-нибудь ещё. Так что в Git дописали новую опцию принудительного пуша — --force-with-lease
, которая проверит, находится ли на сервере то, что вы запушили в последний раз, и только после этого обновит ветку.
Неудавшийся push --force-with-lease
Если кто-нибудь обновит ссылку на удалённом сервере (по ходу дела), то пуш завершится ошибкой stale info
. Если вы часто делаете правки коммитов и перебазирование, возможно, стоит написать короткий алиас, ведь это почти всегда лучше, чем --force
:
git config --global alias.fpush push --force-with-lease
Да пребудет с вами force.
Подписывание коммитов ключом SSH
Мы умопомрачительно подробно писали об этом несколько месяцев назад, ведь GitButler делает это для вас автоматически через настройку конфигурации. Но если вам хочется подписывать коммиты в командной строке, читайте дальше.
Уже какое-то время Git умеет подписывать коммиты с GPG, но GPG обычно довольно трудно заставить работать правильно или трудно понять до конца, если вы не пользовались ей раньше. Недавно OpenSSH представили новый способ подписывать данные, используя существующий ключ SSH, и в Git интегрировали это как опцию, чтобы делать то же самое без GPG.
А ещё, что важно, GitHub и GitLab проверят эти подписи, если вы загрузите их открытые ключи в аккаунт. Сделать это достаточно просто. Установите gpg.format
в значение ssh
и скажите настройке, где ваш ключ подписи:
git config gpg.format ssh
git config user.signingKey ~/.ssh/id_rsa.pub
Если теперь выполнить git commit -S
, она попробует подписать ваш коммит с этим ключом. А если получится и вы загрузите открытый ключ на Github (в Signing Keys), то получите значок verified для коммитов:
Будьте бдительны
Подписывание пушей
Я не хочу погружаться в тонны подробностей, ведь этим пользуются не слишком часто, но может быть кому-нибудь интересно. Git сейчас может подписывать не только коммиты, но и пуши.
Поскольку ни один из основных Git-хостингов (GitHub, GitLab, Bitbucket) не поддерживает эту функцию, это возможно только в случае, если вы используете собственный сервер. Но если это так, вы можете выполнить git push --signed
, чтобы подписать обновление ссылки на сервере, который где-нибудь сохранит прозрачный лог с проверяемой подписью.
Если интересно, хорошая запись про это есть на kernel.org.
Push it real good [автор намекает на песню, ссылку на которую в оригинале не приводит].
Обслуживание Git
Последняя забавная штука, о которой расскажу, — git maintenance
. Команду обслуживания ввели, кажется, в Git 2.30. Она, по сути, даёт способ добавить в репозиторий задачи cron, которые выполняются раз в день, в час или в неделю.
Включить их можно, выполнив эту команду:
git maintenance start
Это изменит файл .git/config
и добавит значение maintenance.strategy
, установленное на incremental
, — это короткая запись для значений ниже:
gc
— отключена;
commit-graph
— раз в час;
prefetch
— раз в час;
loose-objects
— раз в день;
incremental-repack
— раз в день.
Это означает, что каждый час ваш граф коммитов перестраивается, выполняется prefetch — предварительное извлечение (об этих понятиях расскажу в следующем посте). Один раз в день Git убирается в рыхлых объектах. Директория объектов помещается в pack-файлы при помощи multi-pack-index
(подробности читайте в невероятном посте Тейлора Блау из GitHub).
В основном эта конфигурация просто много чего делает быстрее, автоматически и в фоновом режиме.
Ещё git maintenance
по-разному поставит cron-задачи в расписание в зависимости от операционной системы. На Маке в LaunchAgent
будет добавлено что-то такое:
Если любопытно, как выглядят файлы plist, то это примерно так:
Про git maintenance
и её разные опции можно почитать тут
Окей, а теперь переходим к следующему посту, где рассказывается про граф коммитов и предварительное извлечение (prefetch). Вгрызаемся в реально большие репозитории.