Построение последовательности при использовании распределенного контроля версий - PullRequest
29 голосов
/ 23 сентября 2008

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

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

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

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

Ответы [ 8 ]

30 голосов
/ 21 февраля 2013

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

git log --pretty=oneline | wc -l

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

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

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

28 голосов
/ 24 сентября 2008

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

8 голосов
/ 28 февраля 2014
    git rev-list BRANCHNAME --count

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

    git log --pretty=oneline | wc -l
4 голосов
/ 23 сентября 2008

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

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

2 голосов
/ 24 сентября 2008

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

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

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

например. (используя 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'
1 голос
/ 23 сентября 2008

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

0 голосов
/ 26 июня 2009

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

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

См. HG определить

0 голосов
/ 24 сентября 2008

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

Например,

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

...