#version-control #mercurial
#контроль версий #mercurial
Вопрос:
Краткий вопрос по Mercurial. Предположим, у меня и моего коллеги есть обновленная копия trunk. Мы оба вносим изменения, затем мы оба подталкиваем / вытягиваем изменения друг у друга.
Я предполагаю, что Mercurial сохраняет изменения в порядке, основанном на дате фиксации (поскольку нет увеличивающейся ревизии, только GUID). Итак, что произойдет, если дата моего компьютера отстает на один день, а я совершаю коммит на полдня позже своего коллеги. Мое изменение появится на полдня раньше, чем у моего коллеги?
Комментарии:
1. Это интересный вопрос! Основаны ли хэши HG на временных метках? Я всегда предполагал, что они были, но, подумав об этом, почему они должны быть?
2. @Neil: Нет центрального авторитетного сервера (как в CVS / SVN) для поддержания порядка коммитов. Я не могу придумать ничего, кроме метки времени, чтобы поддерживать порядок, когда коммиты децентрализованы. При отправке / извлечении коммитов могут быть некоторые проверки, но это не позволит узнать, была ли дата неправильной при фиксации, а затем исправлена перед отправкой / извлечением. Я полагаю, я мог бы протестировать это, чтобы увидеть, является ли это проблемой, но я хотел бы получить больше информации о том, как это обрабатывается внутренне, является ли это проблемой или нет.
3. Ниже у меня есть длинный ответ, но просто для того, чтобы продолжить, вам не нужно путаться с датой вашего компьютера. Вы можете установить дату фиксации, используя
--date
опцию. Они носят чисто декоративный характер.
Ответ №1:
у @Martijn есть ваш правильный ответ, но, похоже, он не срабатывает. Если это что-то прояснит, выберите его:
- Время фиксации наборов изменений Mercurial не имеет абсолютно никакого отношения к тому, как они объединяются, чередуются или комбинируются
Mercurial и другие DVCS выполняют все отслеживание истории, полностью основываясь на DAG (ориентированном ациклическом графике), что означает:
- единственная часть метаданных, которая имеет значение, — это родительский элемент или родительские элементы набора изменений
Перед фиксацией вы можете увидеть, каким будет родительский элемент вашего набора изменений, введя hg parents
, и как только вы зафиксируете, вы сможете увидеть это в hg log
.
В ваших примерах, если вы извлекли наборы изменений вашего коллеги и обновили свой рабочий каталог, чтобы отразить их ( hg pull ; hg update
), то его или ее набор изменений будет родительским для вашего набора изменений. Если вы не извлекли / обновили, чтобы отразить его или ее набор изменений, то оба ваших набора изменений будут иметь одного и того же родителя — они будут родными братьями и сестрами — когда они будут объединены, ни один из них никоим образом не будет иметь приоритета над другим.
Порядок, в котором вы выполняете a hg log
, определяется порядком, в котором набор изменений поступил в ваш локальный репозиторий, и может отличаться от репозитория к репозиторию в зависимости от того, откуда они были извлечены первыми — вот почему вы не можете использовать целые числа, указанные рядом с наборами изменений, для операций перекрестного репо — глобальным является только хэш.
Короче говоря, дата никогда не указывается в обычных операциях и является чисто метаданными, имеющими не больше значения, чем автор или описание коммита.
Комментарии:
1. Спасибо, это было очень полезно. Главное, что мне было нужно: временные метки используются только для отображения, у каждого пользователя фактически есть своя ветвь (из-за того, что у него один и тот же родитель и они являются братьями и сестрами), порядок ведения журнала может варьироваться на разных компьютерах в зависимости от того, когда были извлечены наборы изменений… Итак, если бы у вас был «центральный» репозиторий (например, bitbucket), его порядок определялся бы тем, когда загружаются наборы изменений. Если бы каждый разработчик очистил свои локальные репозитории и извлек их из bitbucket, у всех них был бы одинаковый порядок ведения журналов до этого момента времени. Имеет смысл…
2. Да, похоже, у вас все есть. Хорошая сделка.
Ответ №2:
Действительно, ваши наборы изменений имеют временные метки (внутренне хранятся как секунды, начиная с эпохи UNIX, и смещение часового пояса), и при отображении набора изменений они упорядочены по временной метке, и ваши наборы изменений будут отображаться в неправильном месте, поскольку их временные метки неверны. Смотрите https://www.mercurial-scm.org/wiki/ChangeSet
На самом деле это не такая уж большая проблема; временные метки не имеют никакого отношения к тому, как ваши изменения объединяются с изменениями вашего коллеги. Здесь важны только идентификаторы набора изменений, а при объединении используется общий предок. Он проследит за графиком ваших наборов изменений вниз в поисках идентификатора набора изменений, который также есть у вашего коллеги, а затем объединит ваши и его изменения с самого начала. Смотрите https://www.mercurial-scm.org/wiki/Merge
Таким образом, слияния не затрагиваются, только отображение наборов изменений, где ваши наборы изменений будут отсортированы в неправильном месте. Это собьет с толку вас и вашего коллегу, но сами ваши изменения безопасны.
Комментарии:
1. Хорошо, но если мы оба переименуем одну и ту же переменную, «последний» (возможно, неверный) набор изменений выиграет? Что, если мой коллега переименовал переменную в
abc.cs
вfoo
. Полдня спустя я переименовываю ту же переменную вbar
и добавляю,def.cs
на какие ссылкиbar
. Мы нажимаем / вытягиваем. Теперь у нас естьabc.cs
withfoo
(его изменение появляется последним), ноdef.cs
имеетbar
. Код не компилируется.2. Это конфликт слияния, и вам придется его разрешить. Ни одно из изменений не выигрывает. Смотрите mercurial.selenic.com/wiki/Conflict
3. Верно, поскольку изменился тот же текст — давайте попробуем другой сценарий. Он добавляет
abc.cs
сfoo
помощью и фиксирует. Я извлекаю его изменения, создаю,def.cs
какие ссылкиfoo
и фиксирую полдня спустя. Как мой коммит хранится локально, поскольку я совершил его «за полдня до» его изменения? Могу ли я вообще зафиксировать более раннюю дату, чем последняя фиксация в моем репозитории? Перенесет ли это дельту из его коммита в предыдущий (назовем его начальным) коммит, вставит ли мой посередине, затем сгенерирует дельту между initial-> mine и mine-> his?4. …Если он вставляет мой коммит перед его, я ссылаюсь на несуществующую переменную. Если он добавляет мой коммит в конце, то он не может использовать временную метку моего компьютера …?
5. Опять же, даты не используются для сравнения наборов изменений, только для отображения списков наборов изменений в упорядоченном виде. Итак, да, вы можете зафиксировать, нет, это не будет удалено. Ваши коммиты относительны (связаны в виде графика) к вашему собственному корневому рабочему каталогу (набору изменений) и сравниваются в виде графика с вашим коллегой, полностью игнорируя временные метки. Все это подробно объясняется в статьях, на которые я ссылался. Для повторной итерации ваши изменения и его изменения являются отдельными строками на графике, поэтому вы никогда не вставляете «между» его наборами изменений. Ваши графики объединяются с новым коммитом, соединяя строки.
Ответ №3:
Временная метка в наборах изменений не влияет на порядок наборов изменений. Порядок определяется исключительно порядком, в котором были созданы наборы изменений в вашем локальном репозитории.
Mercurial имеет архитектуру только для добавления, поэтому при извлечении из другого репозитория наборы изменений, которые вы извлекаете, размещаются после ваших собственных наборов изменений, независимо от временных меток в новых наборах изменений.
Номера версий (локальный целочисленный счетчик) — это просто счетчик: каждый новый набор изменений получает следующий доступный номер версии. Простой оператор range в Mercurial работает непосредственно с номерами ревизий, и поэтому X:Y
означает «дайте мне наборы изменений с номерами ревизий от X до Y (включительно)». Это не так полезно, когда номера ревизий основаны только на порядке, в котором были созданы наборы изменений или перенесены в репозиторий.
Вместо этого используйте X::Y
, который предоставляет вам наборы изменений, являющиеся потомками X и предками Y, т. Е. он следует за ветвями в истории.
Комментарии:
1. Я знал, что номера версий мало что значат. Спасибо за подтверждение порядка, который поддерживает то, что сказал @Ry4an (порядок, в котором вы выполняете hg log, определяется порядком, в котором набор изменений поступил в ваш локальный репозиторий) и противоречит тому, что сказал @Martijn (при отображении набора изменений они упорядочены по временной метке).