Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сложности в работе с Git: от разрешения конфликтов до переписывания истории
Одним из самых нетривиальных и сложных кейсов в моей практике работы с Git было проведение крупного рефакторинга монолита на микросервисы с параллельным изменением структуры репозиториев и необходимостью сохранения полной истории коммитов. Этот процесс сочетал в себе несколько сложных аспектов, которые пришлось решать комплексно.
Ключевые сложности проекта:
- Перенос истории: Необходимо было разделить один монолитный репозиторий на несколько независимых, при этом для каждого нового репозитория микросервиса нужно было сохранить только релевантную историю коммитов (только те изменения, которые касались его кода). Простое клонирование и удаление лишних файлов не подходило, так как в истории оставались бы коммиты, касающиеся других сервисов.
- Переписывание истории (History Rewriting): Основным инструментом решения стала команда
git filter-branch(позже мы перешли на более эффективныйgit filter-repo). Это мощный и опасный инструмент. Нужно было тщательно спланировать и выполнить фильтрацию для каждого будущего микросервиса. - Синхронизация переходного периода: На время миграции команды продолжали работать в старом монолите, поэтому нам пришлось настраивать сложную систему кросс-репозиторных cherry-pick для переноса критических хотфиксов из старой ветки в новые репозитории.
Пример процесса фильтрации для одного сервиса:
План действий и ключевые команды для извлечения папки service-auth/ в отдельный репозиторий с чистой историей выглядели так:
- Клонирование и очистка:
# Клонируем монолит git clone <monolith-url> service-auth-repo cd service-auth-repo # Используем git filter-repo для сохранения только нужной папки git filter-repo --path service-auth/ --path pom.xml --force
Здесь `--path` указывает пути, которые нужно сохранить. Мы сохраняли не только код сервиса, но и корневой `pom.xml` (для Maven), чтобы сохранить историю его изменений, если они влияли на наш сервис.
-
Перебазирование ссылок: После
filter-repoвсе SHA-1 хеши коммитов изменяются. Это ломает все внешние ссылки (например, в тикет-системе). Мы создавали и поддерживали файл-матчинг (старый_хеш -> новый_хеш) для критически важных коммитов. -
Проверка целостности: После фильтрации обязательным этапом было:
* Проверка, что `git log --oneline -- service-auth/` показывает логичную историю.
* Запуск сборки (`mvn clean compile`) для каждого значимого тега/коммита в новой истории, чтобы убедиться, что состояние кода консистентно.
* Визуальная проверка сложных мерж-коммитов через `git log --graph`.
Уроки и выводы
- Резервные копии — святое: Перед любой операцией с
filter-branchилиfilter-repoмы создавали полные резервные копии репозитория (git clone --mirror). - Коммуникация с командой: Весь процесс был задокументирован, а команда предупреждена о «сломанной» истории. Мы временно отключили автоматические деплои с тегов.
- Инструменты: Переход с
git filter-branchнаgit filter-repo(от создателей GitHub) сэкономил нам часы времени: он работает в разы быстрее и безопаснее. - Сложность не в командах, а в последствиях: Сами команды Git изучить нетрудно. Гораздо сложнее спрогнозировать impact их выполнения на процессы CI/CD, работу других разработчиков, историю и целостность данных. Этот опыт научил меня, что самые сложные задачи в Git — это всегда задачи, требующие глубокого понимания не только системы контроля версий, но и рабочего процесса (workflow) всей команды и инфраструктуры вокруг нее.