У меня есть проект с богатой историей git от нескольких пользователей, он никогда не форматировался автоматически, и я хотел бы запустить на нем clang-format. Важно сохранить историю git.
Некоторые примеры того, что я имею в виду.
Когда был блок кода от Джо, а затем «a + b» было преобразовано в a + b. Он остается в линии Джо в git blame.
Когда был
void foo()
{
return k;
}
и он был отформатирован в
void foo() { return k; }
Он по-прежнему остается кодом Джо.
и Т. Д.
Какие-нибудь известные решения?
Что заставляет вас думать, что вы теряете историю git из-за ее автоматического форматирования? Вы имеете в виду, что вы больше не можете git blame так легко?
Вы смотрели git filter-branch? Это приведет к потере SHA1 ...
Пожалуйста, посмотрите обновление.





По сути, у вас не может быть обоих способов (то есть с сохранением истории и оптовым автоматическим форматированием), но у вас есть несколько вариантов.
1) В принципе, вы могли бы воссоздать репозиторий, воспроизводя все коммиты один за другим с примененным автоматическим форматированием, но этот новый репозиторий будет другим: все SHA коммитов будут другими. Возможны конфликты, особенно при нелинейной истории (слияниях). Это может быть нетривиальная и полностью автоматическая операция.
2) Вы также можете просто применить форматирование как новую фиксацию (одиночную, огромную), но это затруднит использование git blame.
3) Вы также можете применять автоматическое форматирование на ходу, поскольку файлы изменяются во время разработки. Это будет иметь несколько меньшее влияние, но тоже не идеально.
Есть два аспекта «сохранения истории», оба из которых могут быть выполнены с помощью git:
Внесите изменения поверх существующей истории: это вызовет вину git одной-единственной фиксацией изменений форматирования. Это просто и ничем не отличается от вашего обычного рабочего процесса. Я рекомендую одну единственную фиксацию, а затем принудительно применять форматирование в качестве ловушки перед слиянием и перед фиксацией на стороне сервера и клиента.
Перепишите всю историю, индивидуально форматируя каждую фиксацию. Это делает любые ссылки на хэши коммитов перед перезаписью и т. д. Недействительными, но дает вам чистый git blame / log. Для этого нужна магия с использованием (возможно, низкоуровневых) команд git. Или «простая» «интерактивная» перебазировка, при которой вы вносите поправки в каждый коммит с изменениями форматирования (хотя сохранение исходного коммиттера может вызвать некоторую дополнительную магию).
Последний вариант - исправить код по мере его фиксации. Это приводит к ужасному беспорядку стилей в одном файле и ничего не помогает.
Что вы имеете в виду под сохранением истории?