Подтвердить что ты не робот

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

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

Я хотел бы переключиться на использование распределенной системы (возможно, git), чтобы упростить работу и работу из дома. (Оба из них вполне возможны с Perforce, но рабочий процесс git имеет некоторые преимущества.) Поэтому, хотя "приток развития" будет распространен и не будет ссылаться на общую последовательность ревизий, мы все равно сохраним master git repo что все изменения должны будут загружаться до создания сборки.

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

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

4b9b3361

Ответ 1

Во-вторых, предлагаю использовать 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 состоит из следующих компонентов:

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

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

Ответ 2

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

git log --pretty=oneline | wc -l

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

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

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

Ответ 3

    git rev-list BRANCHNAME --count

это намного менее ресурсоемкий, чем

    git log --pretty=oneline | wc -l

Ответ 4

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

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

Ответ 5

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

Предположительно, у вас есть отдельная ветка, из которой вы выходите из управляемых релизов сборки. В этом случае я бы пометил ранний фиксатор известным форматом тега, а затем использовал 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'

Ответ 6

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

Ответ 7

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

Например,

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

Ответ 8

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

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

См. hg ident