Сравнительный Анализ Git и Mercurial |
- Statistics
- Participants
- Translate into Russian
- Translation result
- Translation complete.
Анализ Git и Mercurial
Замечание: этот анализ был проведен летом 2008, когда мы впервые начали обзор Распределенных Систем Контроля Версий в поддержку Google Code.
Введение
Этот документ резюмирует начальные исследования для добавления распределенной системы контроля версий в качестве опции для Google Code. Основываясь на популярности двух распределенных систем контроля версий, мы приняли к рассмотрению две: Git и Mercurial.
Этот документ описывает возможности двух систем, и предоставляет обзор работы, необходимой для интегрирования их в Google Code.
Распределенные системы контроля версий
В традиционных системах контроля версий, есть центральный репозиторий, которых содержит всю историю. Клиенты должны взаимодействовать с этим репозиторием чтобы просматривать историю файлов, смотреть другие ветки, или фиксировать изменения. Обычно, клиенты имеют локальную копию тех версий файлов, с которыми они работают, но не имеют локального хранилища предыдущих версий или альтернативных веток
Распределенная Система Контроля Версий (DVCS - Distributed Version Control System) использует другую структуру. С DVCS, каждый пользователь имеет свой локальный репозиторий, с полной историей проекта, ветками и т.д. Переключение на альтернативную ветку, анализ истории, и даже фиксирование изменений - все это локальные операции. Индивидуальные репозитории могут обмениваться информацией через операции проталкивания и притягивания (push и pull). Проталкивание отправляет некоторую локальную информацию в удаленный репозиторий, а притягивание копирует удаленную информацию в локальный репозиторий. Заметьте, что ни один из репозиториев не обязан быть "главным" по отношению к другим. Оба репозитория могут иметь некоторую локальную историю, которую другой еще не имеет. Одна ключевая особенность любой распределенной системы - простое хранение в репозитории однозначного описания истории, которую они хранят (и истории, которую они запрашивают). Git и Mercurial делают это, используя SHA - хэши для идентификации данных (файлов, деревьев, наборов изменений и т.д.)
DVCS предоставляет большую гибкость в трудовом процессе разработчика. Они (DVCS) могут использоваться в стиле, похожем на традиционные системы, с центральным "главным" репозиторием, с которым синхронизируется каждый разработчик. Для проектов побольше, так же возможно хранить иерархию репозиториев, где хозяин каждого репозитория принимает изменения от нижестоящих по иерархии разработчиков и отправляет их вышестоящим. Кроме того, DVCS позволяют разработчикам обмениваться результатами работы между собой напрямую. Например, два разработчика работающие над новой функцией, могут работать над общей веткой и обмениваться результатами независимо от "главного" сервера. Однажды, когда их продукт станет стабильным, он может быть протолкнут в публичный репозиторий для большей аудитории.
Поскольку нет центрального репозитория, термины клиент и сервер необязательны. Когда говорят о двух репозиториях, их обычно называют локальный и удаленный, а не клиент и сервер. Однако в контексте применения DVCS для Google Code, репозиторий, расположенный в Google, будет рассматриваться как сервер, а пользовательский репозиторий будет называться клиентом.
Сравнение функционала
На самом деле, Git и Mercurial очень похожи. Вместо предоставления длинного списка возможностей, которые эквивалентно предоставлены в обоих системах, в этой секции представлена попытка осветить области, где разница между системами существенна.
Преимущества Git
Управление хранением данных. И Mercurial, и Git позволяют пользователям выборочно притягивать ветки из других репозиториев. Это обеспечивает прямой механизм для уменьшения хранимой локально истории. Вдобавок, Git еще и позволяет отменить ранее притянутую ветвь. Git, также позволяет вырезать предыдущие ревизии из локального репозитория (в то время как эти ревизии по-прежнему будут храниться в ветвях). В Mercurial же, если ветка находится в локальном репозитории, то все ее ревизии (вплоть до самой первой фиксации) должны так же присутствовать, и нет способа обрезать ветки, кроме как выборочно притягивать ветки в другую копию репозитория.
(прим. переводчика: для Mercurial есть расширение Mercurial Queues, позволяющее удалять ревизии из локальной копии)
Количество Родителей. Git поддерживает неограниченное количество родителей ревизии во время слияния. Mercurial - только двух. Чтобы осуществить слияние N родителей, в Mercurial придется провести N-1 слияний по 2 родителя. Хотя, во многих случаях, это более предпочтительный способ, в независимости от системы контроля версий, в случае с Git, пользователь может выполнить слияние N родителей за один шаг, если он пожелает.
Перебазирование. В Git есть команда rebase, позволяющая взять локальную ветку, и изменить точку ответвления на более свежую ревизию. Например, если кто-либо работает над новой функцией продукта, его локальная ветка может начинаться с релиза 1.0. Если, за время его работы над опцией, продукт обновился до релиза 1.1, может быть предпочтительно притянуть все изменения 1.0->1.1 в локальную ветку, и интерпретировать ее как ветку от 1.1 вместо 1.0. В большинстве других систем, это делается путем слияния изменений 1.1 с локальной веткой. Слияние - правильный подход с точки зрения SCM, где фокус на "возможности восстановления предыдущих состояний". Однако, когда фокус на "поддерживании чистой истории изменений" - перебазирование превосходный подход. Перебазирование в Git позволит вам сделать ранее нелинейную историю линейной, поддерживая её чистоту . Честно говоря, то же самое достигается простым слиянием каждой фиксации от версии 1.0 до 1.1 индивидуально, и индивидуальной их фиксации. Перебазирование как бы безопасно делает это же самое, и, в добавок, удаляет старые, базированные на 1.0 версии, и они не вносят беспорядок в дерево.
Замечание: Mercurial добавил поддержку перебазирования, после того как данный анализ был проведен.
Преимущества Mercurial
Кривая обучения. У Git кривая обучения более крутая, нежели у Mercurial в связи со множеством факторов. У Git больше команд и опций, их количество может быть пугающим для новых пользователей. Документация Mercurial выглядит более законченной и простой с точки зрения новичков. Терминология Mercurial ближе к Subversion и CVS, что делает его освоение проще для людей мигрирующих с этих систем.
Поддержка Windows. У Git Linux-происхождение, и официальный путь запустить его под Windows - использовать cygwin, который далек от идеала, с точки зрения пользователя Windows. MinGw-порт Git набирает популярность, но Windows, в мире Git, до сих пор подразумевает "гражданин второго сорта". На основании ограниченного тестирования, MinGW-порт показал полный функционал и некоторую медлительность. Операции, которые обычно выполнялись мгновенно на Linux или Mac OS X, занимали десятые доли секунды на Windows. Mercurial написан на Python, и официальный дистрибутив работает хорошо под Windows (так же как и под Linux, Mac OS X, и т.д.)
(прим. переводчика: тем же самым гуглом разработана TortoiseGit, прекрасно работающая под windows, субъективно стабильнее нежели TortoiseHg)
Обслуживание. Git требует периодического обслуживания репозиториев (т.е. git-gc), для Mercurial подобных действий производить не нужно. Однако заметим, что Mercurial намного менее сложен относительно управления дисковым пространством пользователя. (см. "Управление Хранением Данных" выше)
История Священна. Git - инструмент очень мощный, и сделает практически все, что вы его попросите. К сожалению, это так же означает, что Git с удовольствием удалит историю. Например git-push --force может привести к потерянным ревизиям в удаленном репозитории. Репозиторий Mercurial, по большей части, структурирован как постоянно растущая коллекция неприкосновенных объектов. В некоторых случаях (таких как перебазирование), переписывание истории может быть преимуществом, а иногда вести к непредсказуемым результатам. Важно заметить, что Git-сервер может быть настроен на запрет потери данных, так что, здесь, преимущество минимальное.
Другие Различия
Отслеживание переименований/копирований. Git не отслеживает явным образом переименование или копирование файлов. Вместо этого, команды, такие как git-log, ищут файлы, идентичные появлявшимся ранее в истории репозитория, и делают вывод о переименовании или копировании. У Mercurial более привычный подход - он предоставляет конкретные команды переименования и копирования, и сохранения этих действий как истории файла. Каждый подход имеет как преимущества, так и недостатки, и не понятно какой из них "лучше".
Архитектура. Git изначально представляет собой большое количество shell скриптов и unix комманд, реализованных на C. Со временем, общая библиотека, которая использовалась различными командами, развивались, и многие из команд были встроены в основной исполняемый файл Git. Mercurial, по большей части, написан на Python (с небольшим количеством C), с API для расширения, позволяющим сторонними разработчиками наращивать Mercurial с помощью своих Python модулей.
Приватная История. В Git основной режим работы разработчиков - получить свою локальную (и приватную) копию меток/веток/ревизий, и контролировать что станет доступно публично. С Mercurial акцент наоборот - стандартное поведение push/pull раскрывает всю информацию и, с некоторыми дополнительными шагами, становится доступно все подмножество. Данная особенность не описывается как преимущество какой либо из систем, поскольку обе системы способны поддерживать оба вида операций.
Пространство имен веток. В Git, каждый репозиторий имеет свое собственное пространство имен веток, и пользователи настраивают связи между локальными и удаленными пространствами имен. В Mercurial имеется одно пространство имен веток, используемое всеми репозиториями.
Реализация
Хранение данных
И Git и Mercurial работают с похожими данными: ревизиями файлов с небольшим количеством мета-информации (родители, автор и т.д.). Они оба имеют объекты, которые ассоциируют фиксацию с набором версий файлов. В Git это древовидный объект (древовидная структура с древовидными объектами для папок и связи с ревизиями файлов в качестве листвы). А в Mercurial - это манифест (плоский список, указывающий на путь к объектам файловых ревизий). Несмотря на различия в манифесте/дереве, оба очень схожи в способах нахождения и перемещения объектов.
Git использует комбинацию способов хранения - прямого содержания в файловой системе (индексируя с помощью SHA1 хэшей) и, упаковывая несколько объектов в большие сжатые файлы, тогда как Mercurial использует структуру истории изменений (грубо говоря, цепочка изменений, с периодическими полными снимками всей ревизии). В обоих случаях, родное хранилище не будет использоваться и, объекты будут храниться в "большой таблице" вместо этого (прим. переводчика: непонятно что имели ввиду гугловцы тут, видимо свои собственные реалии). Из-за сходства основ хранения объектов данных, проблема выбора по данному критерию не заслуживает внимания.
Единственная ощутимая разница в хранении данных - язык реализации. Если значительный объем кода Git/Mercurial планируется использовать где-либо еще, то важно учесть, что Git написан на C, а Mercurial на Python(или, возможно, на С++ со SWIG-связками)
Интеграция Mercurial
У Mercurial есть отличная поддержка основанного на HTTP механизма проталкивания и притягивания в/из удаленных репозиториев. Разумное количество усилий было потрачено чтобы уменьшить количество циклов взаимодействия между клиентом и сервером, при определении какими данными нужно обмениваться, а выполнив это определение, вся значимая информация пакуется и отправляется одной единственной транзакцией. Это отлично подходит для инфраструктуры Google, и никаких модификаций не требуется на клиентской стороне.
Интеграция GIT
Git включает поддержку проталкивания изменений по HTTP и WebDAV, но реализация подразумевает что сервер не знает ничего о Git. Это реализовано так: вы настраиваете Apache, просто обслуживающий репозиторий Git, как статический контент. Этот метод требует многочисленных синхронных запросов, что не годится для использования в Google Code.
У Git есть свой собственный протокол, который обеспечивает значительно более быстрый обмен информацией, но он плохо подходит к инфраструктуре Google. Дело в том, что крайне желательно использовать независимый HTTP, поскольку уже есть значительная, надежная и эффективная база для подобных транзакций.
Замечание: с тех пор как данный анализ был проведен, в сообществе Git были некоторые обсуждения по улучшению поддержки HTTP.
Резюме
С точки зрения реализации основных действий, Mercurial имеет преимущество благодаря эффективному протоколу поверх HTTP.
С точки зрения возможностей Git более мощен, но это как правило дается ценой сложности использования.
Для теста производительности, были взяты репозитории Git и Mercurial в которых хранилось порядка 1500 файлов суммарным объемом 35 Мб. Сервера были запущены в Чикаго, а клиенты в Маунтин-Вью (пинг 51 мсек). Операция клонирования удаленного репозитория (тоже что первичный checkout в традиционных системах контроля версий) заняло примерно 8.1 сек у Mercurial и 178 сек у Git (в 22 раза медленнее). Один файл в репозитории был изменен 50 раз и клиенты делали pull обновлений. В этом случае у Mercurial это заняло 1.5 сек, тогда как у Git 18 сек (в 12 раз медленнее). Когда был использован протокол Git вместо HTTP, Git справился с задачей сравнительно с Mercurial (8.7 сек для клонирования, 2.8 сек для pull).
