openjdk.ruOpenJDK на русском

JEP 357: Migrate from Mercurial to Git

Переход с Mercurial на Git

AuthorsErik 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:

  1. Размер метаданных системы контроля версий
  2. Доступные инструменты
  3. Доступные варианты хостинга

Первые прототипы сконвертированных репозиториев показывают значительное уменьшение размера метаданных системы контроля версий. Например, каталог .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}/ ": " Text

SummaryLine : "Summary: " Text

ReviewersLine : "Reviewed-by: " Username (", " Username)* "\n"

ContributedByLine : "Contributed-by: " Text

Username : /[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 можно проверить, что все метаданные заданного коммита сконвертированы правильно, а также что деревья исходного кода двух коммитов идентичны.

Риски и допущения

Основной риск состоит в том, что при конвертации могут появиться ошибки. Этот риск будет снижен за счёт тщательной проверки, описанной выше.

Зависимости