Обзор нововведений Git 2.54
В апреле 2026 года был выпущен Git 2.54, включающий ряд новых возможностей и исправлений. Данная статья рассматривает наиболее значимые из них: новые команды и опции, изменения в поведении существующих инструментов, а также внутренние архитектурные улучшения.
1. Команда git history
Git располагает развитым инструментарием для переработки истории коммитов, центральное место в котором занимает git rebase -i. Эта команда позволяет переупорядочивать, объединять, редактировать и удалять коммиты. Однако существует сложность: интерактивный rebase изменяет рабочее дерево и индекс, а при возникновении конфликтов требует их ручного разрешения перед продолжением.
Для сценариев, не требующих столь широких возможностей, Git 2.54 вводит новую экспериментальную команду git history. В текущей версии она поддерживает две операции: reword и split.
git history reword
git history reword <commit> открывает редактор с сообщением указанного коммита и переписывает его на месте, обновляя все ветки, являющиеся потомками данного коммита. В отличие от git rebase, команда не затрагивает рабочее дерево и индекс, и может работать даже в bare репозитории.
Пример:
Чтобы исправить опечатку в сообщении коммита abc123, не задействуя интерактивный rebase:
git history reword abc123
Git откроет редактор с текущим сообщением коммита. После сохранения изменений все дочерние ветки будут автоматически обновлены.
git history split
git history split <commit> позволяет интерактивно разбить один коммит на два, выбирая, какие фрагменты (hunks) следует выделить в отдельный родительский коммит. Интерфейс идентичен git add -p.
Пример:
Чтобы разделить последний коммит на два независимых:
git history split HEAD
Git последовательно предложит выбрать, какие изменения перейдут в новый родительский коммит. Невыбранные изменения останутся в исходном коммите.
Следует отметить преднамеренные ограничения: git history не поддерживает истории с коммитами слияния и отказывается от операций, которые привели бы к конфликту. Команда построена на ядре git replay, что обеспечивает работу без изменения рабочего дерева и делает её пригодной для использования в скриптах и системах автоматизации.
2. Хуки на основе конфигурации
Исторически хуки Git могли существовать только в виде исполняемых скриптов в каталоге $GIT_DIR/hooks (или в пути, заданном параметром core.hooksPath). Это делало распространение единого хука на множество репозиториев трудоёмкой задачей: приходилось либо копировать скрипты вручную, либо настраивать core.hooksPath на общую директорию — но тогда все репозитории получали идентичный набор хуков без возможности индивидуальной настройки.
Git 2.54 вводит новый способ объявления хуков — непосредственно в конфигурационных файлах.
[hook «linter»]
event = pre-commit
command = ~/bin/linter —cpp20
[hook «no-leaks»]
event = pre-commit
command = ~/bin/leak-detector
Поскольку хуки теперь являются конфигурационными записями, они могут находиться в пользовательском файле ~/.gitconfig, системном /etc/gitconfig или в локальной конфигурации конкретного репозитория. При совпадении события несколько хуков выполняются последовательно, в порядке их появления в конфигурации. Традиционные скриптовые хуки из каталога $GIT_DIR/hooks сохраняют обратную совместимость и выполняются последними.
Пример:
Чтобы применить общий хук для проверки стиля кода ко всем репозиториям текущего пользователя, не копируя скрипт в каждый из них:
Достаточно добавить в ~/.gitconfig:
[hook «style»]
event = pre-commit
command = ~/bin/check-style
Хук будет применяться глобально. Для отключения в конкретном репозитории: git config hook.style.enabled false
Просмотр всех активных хуков с указанием источника конфигурации выполняется командой git hook list <event>. Отдельный хук можно деактивировать без удаления его конфигурации, установив hook.<name>.enabled = false.
3. Геометрическая перепаковка как стратегия по умолчанию изменение умолчания
Стратегия geometric в команде git maintenance была введена в Git 2.52. Её принцип состоит в анализе содержимого репозитория с целью определения, можно ли объединить группу pack-файлов так, чтобы их размеры образовывали геометрическую прогрессию по числу объектов. Если такое объединение возможно, Git выполняет геометрическую перепаковку — уплотнение данных без полной сборки мусора.
В Git 2.54 стратегия geometric становится стратегией по умолчанию для ручного обслуживания репозитория. Это означает, что выполнение git maintenance run без указания стратегии теперь использует геометрический подход вместо традиционного gc.
Геометрическая стратегия избегает дорогостоящих операций объединения всех объектов в один pack-файл, которые характерны для gc. Вместо этого она инкрементально объединяет pack-файлы там, где это целесообразно, и прибегает к полному gc лишь тогда, когда результатом будет единственный pack-файл для всего репозитория. Параллельно поддерживаются в актуальном состоянии граф коммитов, reflogs и вспомогательные структуры данных.
Пример:
Чтобы выполнить обслуживание репозитория с явным указанием геометрической стратегии (поведение, которое теперь является умолчанием):
git maintenance run —strategy=geometric
Для возврата к прежнему поведению: git config maintenance.strategy gc
4. Улучшения git add -p
Команда git add -p, предназначенная для интерактивного выбора фрагментов изменений при индексировании, получила ряд улучшений в части удобства использования.
При навигации между фрагментами с помощью клавиш J и K Git теперь отображает, был ли каждый фрагмент ранее принят или пропущен — это устраняет необходимость запоминать предыдущие решения.
Помимо этого, введён новый флаг —no-auto-advance, изменяющий поведение при переходе между файлами. По умолчанию, когда пользователь принял решение по каждому фрагменту в текущем файле, сессия автоматически переходит к следующему. С флагом —no-auto-advance сессия остаётся на текущем файле, предоставляя возможность перемещаться между файлами вручную с помощью клавиш < и >.
Пример:
Чтобы проиндексировать изменения интерактивно с возможностью самостоятельно управлять переходом между файлами:
git add -p —no-auto-advance
После просмотра всех фрагментов в файле сессия не переключится автоматически. Переход к следующему файлу — клавишей >, к предыдущему — <.
5. Развитие git replay экспериментальная
git replay — экспериментальная команда для воспроизведения (replaying) коммитов на новую базу без изменения рабочего дерева — продолжает развиваться. В данном выпуске реализованы следующие улучшения.
Обновления ссылок теперь выполняются атомарно по умолчанию, вместо вывода команд update-ref в стандартный вывод. Добавлен режим —revert, обращающий изменения из заданного диапазона коммитов. Реализована возможность пропуска коммитов, становящихся пустыми в процессе воспроизведения, а также поддержка воспроизведения вплоть до корневого коммита.
Пример:
Чтобы откатить изменения, внесённые в ветке feature относительно main, не изменяя рабочее дерево:
git replay —revert —onto main feature~5..feature
Git создаст серию коммитов, обращающих изменения из указанного диапазона, и выполнит атомарное обновление ссылок.
6. Обработка HTTP 429 в транспортном слое
Прежде ответ сервера с кодом HTTP 429 («Too Many Requests») воспринимался Git как фатальная ошибка и прерывал выполнение операции. Начиная с Git 2.54, транспортный уровень HTTP умеет повторять запрос, соблюдая при этом заголовок Retry-After, если сервер его предоставляет.
Для управления поведением при повторных попытках введены новые конфигурационные параметры: http.retryAfter задаёт задержку при отсутствии заголовка Retry-After, http.maxRetries ограничивает число попыток, а http.maxRetryTime — суммарное время ожидания.
Пример:
Чтобы настроить до 5 повторных попыток с максимальным суммарным временем ожидания 60 секунд при работе с ограничивающими частоту запросов серверами:
git config http.maxRetries 5
git config http.maxRetryTime 60
git config http.retryAfter 5
Параметр http.retryAfter задаёт задержку в секундах, используемую при отсутствии заголовка Retry-After в ответе сервера.
7. Интеграция git log -L со стандартным diff-конвейером
Команда git log -L, отслеживающая историю изменений заданного диапазона строк в файле или функции, исторически использовала собственный путь формирования вывода, обходящий большую часть стандартного diff-механизма Git. Следствием этого была несовместимость с рядом полезных опций — в частности, с опциями «кирки» (-S и -G) для фильтрации по содержимому изменений.
В данном выпуске git log -L переработана так, что её вывод маршрутизируется через стандартный diff-конвейер. Теперь опции -S, -G, —word-diff и —color-moved корректно работают в сочетании с -L.
Пример:
Чтобы найти коммиты, в которых функция parse_config() в файле config.c изменялась таким образом, что в неё добавлялась или из неё удалялась строка, содержащая слово timeout:
git log -L :parse_config:config.c -S timeout —oneline
До этого выпуска опция -S молча игнорировалась при использовании с -L. Теперь обе опции работают совместно: -L ограничивает историю функцией, а -S фильтрует коммиты по содержимому изменений внутри неё.
8. Опция —trailer в git rebase
При необходимости добавить трейлер (trailer) к серии коммитов ранее приходилось прибегать к обходным решениям, таким как: git rebase -x ‘git commit —amend —no-edit —trailer=»…»‘. Git 2.54 вводит встроенную опцию —trailer для git rebase, которая добавляет трейлер к каждому перемещённому коммиту, используя механизм interpret-trailers.
Пример:
Чтобы добавить трейлер Reviewed-by ко всем коммитам ветки feature, начиная с точки её отхождения от main:
git rebase main —trailer «Reviewed-by: A. Reviewer <reviewer@example.com>»
Трейлер будет добавлен к каждому коммиту в процессе rebase без необходимости использовать -x и git commit —amend.
9. Псевдонимы с Unicode-символами
Конфигурация псевдонимов Git исторически была ограничена символами ASCII: буквами, цифрами и дефисом. Это исключало возможность использования имён вроде «hämta» (шведский аналог «fetch») или символов из нелатинских алфавитов.
Git 2.54 снимает это ограничение, вводя новый синтаксис на основе подсекций:
[alias «状態»]command = status
[alias «hämta»]command = fetch
Традиционный синтаксис [alias] co = checkout сохраняет работоспособность для ASCII-имён. Новая форма поддерживает любые символы, за исключением символов новой строки и нулевого байта, сопоставление ведётся с учётом регистра на уровне байтов. Автодополнение командной строки (shell completion) обновлено с учётом новых псевдонимов.
Пример:
Чтобы создать псевдоним с кириллическим именем для команды git status:
В файле ~/.gitconfig:
[alias «статус»]
command = status
После этого git статус выполняет git status.
10. Прочие улучшения
git status — новый параметр status.compareBranches. По умолчанию git status сравнивает текущую ветку с её upstream. Новый параметр позволяет дополнительно сравнивать с push-remote, что полезно в треугольных рабочих процессах, где fetch и push выполняются из разных удалённых репозиториев.
git blame —diff-algorithm. Команда git blame получила новую опцию, позволяющую выбирать алгоритм diff (histogram, patience, minimal) при вычислении аннотаций. Выбор алгоритма может существенно влиять на качество результата в зависимости от характера истории изменений репозитория.
Корректная обработка подписей с истёкшим ключом GPG. Ранее подписи, созданные ключом GPG, срок действия которого впоследствии истёк, отображались с тревожной красной подсветкой, что могло вводить в заблуждение. Git теперь корректно распознаёт такие подписи как действительные.
git backfill — поддержка ревизий и pathspec. Экспериментальная команда для загрузки отсутствующих blob-объектов в частичных клонах обучилась принимать аргументы в виде диапазонов ревизий (например, main~100..main) и путевых шаблонов (например, — ‘*.c’), что делает её значительно практичнее для работы с крупными репозиториями.
Рефакторинг внутренней архитектуры базы объектов (ODB). API источника объектов переработан по принципу подключаемых бэкендов: функции read_object(), write_object() и for_each_object() теперь диспетчеризуются через указатели функций на уровне каждого источника. Данные изменения не видны пользователю напрямую, однако закладывают основу для альтернативных бэкендов хранения объектов в будущем.
Улучшение качества вывода алгоритма histogram diff. Исправлена ситуация, при которой фаза «уплотнения» (compaction), следующая за работой алгоритма, могла перемещать группы изменений через опорные строки, выбранные histogram-алгоритмом, порождая корректный, но визуально избыточный diff. Git теперь обнаруживает подобные случаи и повторно вычисляет diff для затронутого региона.
