Построение последовательности при использовании распределенного контроля версий

StackOverflow https://stackoverflow.com/questions/122424

  •  02-07-2019
  •  | 
  •  

Вопрос

Сейчас мы используем Perforce для контроля версий.Он имеет удобную функцию строго увеличивающегося номера изменения, который мы можем использовать для ссылки на сборки, например: «Вы получите исправление ошибки, если ваша сборка не ниже 44902».

Я хотел бы перейти на использование распределенной системы (вероятно, git), чтобы упростить разветвление и работу из дома.(И то, и другое вполне возможно с помощью Perforce, но рабочий процесс git имеет некоторые преимущества.) Таким образом, хотя «дочерняя разработка» будет распространяться и не будет относиться к общей последовательности изменений, мы все равно будем поддерживать главное репозиторий git, в котором будут храниться все изменения. необходимо ввести до создания сборки.

Каков наилучший способ сохранить строго увеличивающиеся идентификаторы сборки?Самый простой способ, который я могу придумать, - это иметь какой-то хук после фиксации, который срабатывает всякий раз, когда основное репозиторий обновляется, и регистрирует (хэш) новый объект дерева (или объект фиксации?Я новичок в git) с централизованной базой данных, которая выдает идентификаторы.(Я говорю «база данных», но я бы, вероятно, сделал это с тегами git и просто искал следующий доступный номер тега или что-то в этом роде.Таким образом, «база данных» на самом деле будет .git/refs/tags/build-id/.)

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

Это было полезно?

Решение

Я поддерживаю предложение использовать git describe.При условии, что у вас разумная политика управления версиями и вы не делаете никаких сумасшедших вещей со своим репозиторием, git describe всегда будет монотонным (по крайней мере настолько монотонным, насколько это возможно, если ваша история изменений представляет собой DAG, а не дерево) и уникальным.

Небольшая демонстрация:

git init
git commit --allow-empty -m'Commit One.'
git tag -a -m'Tag One.' 1.2.3
git describe    # => 1.2.3
git commit --allow-empty -m'Commit Two.'
git describe    # => 1.2.3-1-gaac161d
git commit --allow-empty -m'Commit Three.'
git describe    # => 1.2.3-2-g462715d
git tag -a -m'Tag Two.' 2.0.0
git describe    # => 2.0.0

Выход git describe состоит из следующих компонентов:

  1. Самый новый тег, доступный из коммита, который вы просите описать.
  2. Количество коммитов между фиксацией и тегом (если не ноль)
  3. (Сокращенный) идентификатор коммита (если #2 не равен нулю).

№2 — это то, что делает вывод монотонным, №3 — то, что делает его уникальным.#2 и #3 опускаются, когда фиксация является тег, делая git describe также подходит для производственных выпусков.

Другие советы

Монотонно увеличивающееся число, соответствующее текущему коммиту, может быть сгенерировано с помощью

git log --pretty=oneline | wc -l

который возвращает одно число.Вы также можете добавить к этому номеру текущий sha1, чтобы добавить уникальности.

Этот подход лучше, чем git describe, поскольку он не требует добавления каких-либо тегов и автоматически обрабатывает слияния.

Могут возникнуть проблемы с перебазированием, но в любом случае перебазирование — «опасная» операция.

    git rev-list BRANCHNAME --count

это гораздо менее ресурсоемко, чем

    git log --pretty=oneline | wc -l

git tag может быть достаточно для того, что вам нужно.Выберите формат тегов, который все согласятся не использовать в противном случае.

Примечание:когда вы помечаете локально, git push не будет обновлять теги на сервере.Использовать git push --tags для этого.

Вам следует расследовать git describe.Он дает уникальную строку, которая описывает текущую ветку (или любой переданный идентификатор фиксации) с точки зрения последнего аннотированного тега, количества коммитов с момента этого тега и сокращенного идентификатора фиксации главы ветки.

Предположительно, у вас есть одна ветка, из которой вы выполняете контролируемые выпуски сборок.В этом случае я бы пометил раннюю фиксацию известным форматом тега, а затем использовал git описать с опцией --match, чтобы описать текущий HEAD относительно известного тега.Затем вы можете использовать результат git описать как есть, или, если вам действительно нужно только одно число, вы можете использовать регулярное выражение, чтобы вырезать это число из тега.

Предполагая, что вы никогда не перематываете ветку, количество последующих коммитов всегда будет определять уникальную точку в истории ветки.

например(используя bash или аналогичный)

# make an annotated tag to an early build in the repository:
git tag -a build-origin "$some_old_commitid"

# describe the current HEAD against this tag and pull out a build number
expr "$(git describe --match build-origin)" : 'build-origin-\([0-9]*\)-g'

Я бы использовал «Ярлыки». Создайте метку всякий раз, когда у вас есть успешная (или даже неудачная) сборка, и вы сможете идентифицировать эту сборку навсегда.Это не совсем то же самое, но он предоставляет эти номера сборок, сохраняя при этом преимущества распределенной разработки.

Как вы, вероятно, знаете, git вычисляет хеш (число), которое однозначно идентифицирует узел истории.Их использование, хотя они и не увеличиваются строго, кажется, было бы достаточно хорошо.(Еще лучше, они всегда соответствуют источнику, поэтому, если у вас есть хэш, у вас тот же код.) Это большие числа, но в большинстве случаев вы можете обойтись примерно шестью ведущими цифрами.

Например,

Эта ошибка была исправлена ​​в 064f2ea...

В Mercurial вы можете использовать следующую команду:

# get the parents id, the local revision number and the tags
[yjost@myhost:~/my-repo]$ hg id -nibt
03b6399bc32b+ 23716+ default tip

Видеть hg идентифицировать

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top