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

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

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

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

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


person sfink    schedule 23.09.2008    source источник


Ответы (8)


Я поддерживаю предложение использовать 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 также подходящим для рабочих выпусков.

person Jörg W Mittag    schedule 24.09.2008
comment
Теги не обрабатывают ветки и слияния. Правильный автоматический способ добавить правильную последовательность — подсчитать количество коммитов после текущего коммита. Это объясняется в моем ответе ниже. - person squadette; 06.08.2013

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

git log --pretty=oneline | wc -l

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

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

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

person squadette    schedule 21.02.2013
comment
Проблема с этим подходом в том, что вы не сможете различать ветки. Вы также можете добавить имя ветки в идентификатор сборки. - person timurb; 06.08.2013
comment
Вы создаете определенные двоичные файлы (такие как -beta, -stable, -nightly) из определенных веток. Таким образом, имя ветки является внешним по отношению к номеру сборки. - person squadette; 06.08.2013

    git rev-list BRANCHNAME --count

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

    git log --pretty=oneline | wc -l
person joegiralt    schedule 27.02.2014

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

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

person webmat    schedule 23.09.2008

Вы должны исследовать 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'
person CB Bailey    schedule 23.09.2008

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

person foxxtrot    schedule 23.09.2008

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

Например,

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

person EfForEffort    schedule 24.09.2008
comment
Хорошо, но у меня 1а92б6. У меня есть исправление? - person sfink; 25.09.2008
comment
git rev-list 1a92b6 | grep 064f2ea --› если это что-то дает, значит, оно у вас есть; в противном случае вы этого не сделаете. - person EfForEffort; 11.10.2008
comment
git branch --contains=‹commit› даст вам все ветки, содержащие ‹commit› (часто более полезный) - person Stein G. Strindhaug; 08.04.2011
comment
Вы не можете предполагать, что конечный пользователь имеет доступ к репозиторию GIT или даже знает, что это такое — у них просто есть продукт и номер версии, что, как я полагаю, и делает @sfink. Номера версий, выпущенные для конечного пользователя, необходимо заказывать. - person simon.watts; 15.01.2015

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

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

См. идентификацию hg.

person yanjost    schedule 26.06.2009
comment
Это не строгое увеличение. - person OrangeDog; 14.09.2017