JEP 357: Migrate from Mercurial to Git
Переход с Mercurial на Git
| Authors | Erik Duveblad, Joe Darcy |
| Ответственный | Joe Darcy |
| Тип | Infrastructure |
| Область | JDK |
| Статус | Closed / Delivered |
| Выпуск | 16 |
| Компонент | infrastructure |
| Обсуждение | discuss at openjdk dot java dot net |
| Трудоёмкость | L |
| Длительность | M |
| Связан с | JEP 369: Migrate to GitHub |
| Рецензенты | Mark Reinhold |
| Одобрен | Mark Reinhold |
| Создан | 2019/07/12 02:20 |
| Обновлён | 2021/01/27 21:56 |
| Задача | 8227614 |
Аннотация
Перевести репозитории исходного кода сообщества OpenJDK с Mercurial (hg) на Git.
Цели
- Перевести все однорепозиторные проекты OpenJDK с Mercurial на Git
- Сохранить всю историю системы контроля версий, включая теги
- Переформатировать сообщения коммитов в соответствии с рекомендуемыми практиками Git
- Портировать на Git инструменты jcheck, webrev и defpath
- Создать инструмент для преобразования хэшей Mercurial в хэши Git и обратно
Что не является целью
-
Мы не будем переводить многорепозиторные проекты OpenJDK, такие как JDK 8 Updates Project. Эти проекты смогут перейти на Git, если и когда они объединятся в один репозиторий.
-
Мы не будем менять систему отслеживания ошибок JBS.
-
Мы не будем поспешно выводить из эксплуатации существующие репозитории Mercurial или предпринимать другие действия, из-за которых преждевременно станут недействительными многочисленные URL, указывающие на эти репозитории, например в комментариях к ошибкам в JBS. Существующие основные репозитории Mercurial будут сохранены как минимум в виде архивов только для чтения на определённый переходный период. В более долгосрочной перспективе может быть введён преобразователь URL Mercurial в URL Git.
-
Этот JEP не решает вопрос о том, будут ли Git-репозитории OpenJDK размещаться на собственных серверах или у внешнего провайдера. Этому вопросу посвящён JEP 369: Migrate to GitHub.
-
Мы не будем предлагать изменения в текущем процессе разработки JDK, хотя этот JEP и делает такие изменения возможными.
Мотивация
Есть три основные причины перехода на Git:
- Размер метаданных системы контроля версий
- Доступные инструменты
- Доступные варианты хостинга
Первые прототипы сконвертированных репозиториев показывают значительное уменьшение размера метаданных системы контроля версий. Например, каталог .git репозитория jdk/jdk занимает примерно 300 МБ в Git, а каталог .hg в Mercurial — около 1,2 ГБ, в зависимости от используемой версии Mercurial. Уменьшение объёма метаданных экономит место на локальном диске и сокращает время клонирования, так как по сети нужно передавать меньше данных. Кроме того, в Git есть поверхностные клоны (shallow clones), которые клонируют только часть истории, так что у пользователей, которым не нужна вся история, метаданных ещё меньше.
Инструментов для работы с Git гораздо больше, чем для Mercurial:
-
Во всех текстовых редакторах есть интеграция с Git, встроенная или в виде плагинов, в том числе в Emacs (плагин magit), Vim (плагин fugitive.git), VS Code (встроенная) и Atom (встроенная).
-
Почти все интегрированные среды разработки (IDE) также поставляются с готовой интеграцией с Git, в том числе IntelliJ (встроенная), Eclipse (встроенная), NetBeans (встроенная) и Visual Studio (встроенная).
-
Существует несколько десктопных клиентов для локальной работы с Git-репозиториями.
Наконец, есть множество вариантов хостинга Git-репозиториев, как на собственных серверах, так и в виде сервиса.
Описание
Мы уже создали прототип программы, которая конвертирует репозиторий Mercurial в репозиторий Git. Она использует протокол git-fast-import для импорта наборов изменений Mercurial в Git и приводит существующие сообщения коммитов в соответствие с рекомендуемыми практиками Git. Сообщение коммита в репозитории Mercurial jdk/jdk имеет следующую структуру:
JdkHgCommitMessage : BugIdLine+ SummaryLine? ReviewersLine ContributedByLine?
BugIdLine : /[0-9]{8}/
": "TextSummaryLine :
"Summary: "TextReviewersLine :
"Reviewed-by: "Username (", "Username)* "\n"ContributedByLine :
"Contributed-by: "TextUsername : /[a-z]+/
Text : /[^\n]+/ "
\n"
Сообщение коммита в Git-репозитории jdk/jdk будет иметь несколько иную структуру:
JdkGitCommitMessage : BugIdLine+ Body? Trailers
BugIdLine : /[0-9]{8}/ ": " Text
Body : BlankLine Text
*Trailers : BlankLine Co-authors? Reviewers
Co-authors : (BlankLine Co-author )+
Co-author :
"Co-authored-by: "Real-name<Email>Reviewers :
"Reviewed-by: "Username (", "Username)* "\n"BlankLine = "\n"
Username : /[a-z]+/
Text : /[^\n]+/ "\n"
Структуру сообщения меняем по следующим причинам:
-
Инструмент командной строки Git настоятельно рекомендует использовать заголовок (одну строку, за которой следует пустая строка).
-
Благодаря заголовку тело сообщения может иметь произвольную форму.
-
Экосистема Git распознаёт трейлеры (trailers), то есть строки, отделённые от тела сообщения переводом строки. Например, и GitHub, и GitLab распознают трейлер
Co-authored-by:и понимают, что у коммита несколько авторов.
В Git в метаданных коммита есть дополнительное поле, обозначающее коммиттера, отдельно от автора. Мы будем использовать поле коммиттера для обозначения спонсорства: в случае спонсируемого коммита автор будет указан в поле author коммита, а спонсор — в поле committer. Если спонсор также является соавтором, будет добавлен соответствующий трейлер Co-authored-by; такую ситуацию невозможно отразить в существующей структуре сообщений Mercurial.
Отдельное поле коммиттера можно также использовать для обозначения коммитов, переносящих изменения (backport) из выпусков Feature Release (функциональный выпуск) в выпуски обновлений; такой перенос обычно выполняет не автор исходного коммита, а кто-то другой.
Поля автора и коммиттера будут иметь вид Real-name <Email>, поскольку не каждый автор коммита является OpenJDK Author. Чтобы показать, что автор или коммиттер также является OpenJDK Author, будет использоваться специальный адрес электронной почты: <openjdk-username>@openjdk.org.
Вот пример сообщения коммита в Git:
76543210: Crash when starting the JVM
Fixed a tricky race condition when the JVM is starting up by using a Mutex.
Co-authored-by: Robin Westberg <rwestberg@openjdk.org>
Reviewed-by: darcy
Поля автора и коммиттера для такого коммита будут такими:
Author: Erik Duveblad <ehelin@openjdk.org>
Commit: Erik Duveblad <ehelin@openjdk.org>
При конвертации коммит будет считаться спонсируемым, если автор не указан в строке Contributed-by:. В этом случае первый человек в строке Contributed-by: будет считаться автором, спонсор — коммиттером, а все остальные участники — соавторами.
Примеры сконвертированных репозиториев доступны по адресу https://github.com/openjdk/.
Инструменты
Мы уже создали прототипы обратно совместимых портов инструментов Mercurial jcheck, webrev и defpath.
Мы также создали прототип нового инструмента git-translate. Этот инструмент использует файл .hgcommits, который генерируется инструментами конвертации и добавляется коммитом в Git-репозитории. Этот файл состоит из последовательности строк, каждая из которых содержит два шестнадцатеричных хэша: первый — хэш набора изменений Mercurial, второй — хэш коммита Git, полученного при конвертации этого набора изменений Mercurial. Инструмент git-translate просто выполняет запросы к файлу .hgcommits:
$ git translate --to-hg 0f8927e8b5bf88e7e2c7c453b4cd75e01eeccaf4
bd613b97c7c88658801b0f0c603a55345dfef022
$
Альтернативы
Продолжать использовать Mercurial.
Тестирование
С помощью описанного выше файла соответствий .hgcommits можно проверить, что все метаданные заданного коммита сконвертированы правильно, а также что деревья исходного кода двух коммитов идентичны.
Риски и допущения
Основной риск состоит в том, что при конвертации могут появиться ошибки. Этот риск будет снижен за счёт тщательной проверки, описанной выше.