Как заменить автора и коммитера во всех коммитах Git, сохранив остальную историю?

«Как заменить автора и коммитера во всех коммитах Git, сохранив остальную историю?» — вопрос из категории Git, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для переписывания истории Git с заменой данных автора/коммитера я использую инструмент git filter-repo, который пришел на смену старому git filter-branch. Он быстрее и безопаснее.

Процесс с использованием git filter-repo:

  1. Установите git-filter-repo (например, через pip install git-filter-repo).

  2. Создайте файл соответствия (mailmap). В нем указываем старый и новый email/name.

    # mailmap.txt
    Новое Имя <правильный.email@company.com> <старый.email@gmail.com>
    Новое Имя <правильный.email@company.com> Старое Имя <старый.email@gmail.com>

    Можно указать несколько старых адресов для одного нового.

  3. Запустите переписывание истории. Эта команда создаст новый клон репозитория с измененными данными.

    # Клонируем репозиторий (или работаем с клоном)
    git clone --bare https://github.com/user/repo.git repo.git
    cd repo.git
    # Применяем фильтр с mailmap-файлом
    git filter-repo --mailmap ../mailmap.txt --force

    git filter-repo изменит автора и коммитера во всех коммитах, где email совпадает с указанным в mailmap.

  4. Обновите удаленный репозиторий. Так как история изменена, требуется принудительная отправка.

    git push origin --force --all
    git push origin --force --tags

Критически важные предупреждения:

  • Это разрушающая операция. Она изменяет SHA-хэши всех затронутых коммитов и всех последующих. После этого все, кто работал с репозиторием, должны будут переклонировать его.
  • Согласуйте с командой. Делайте это в период минимальной активности.
  • Сделайте полный бэкап репозитория перед началом.
  • Убедитесь, что CI/CD, тикеты, код-ревью не привязаны к старым SHA.

Для простой замены в одном последнем коммите достаточно git commit --amend --author="Новое Имя <email>".