Что такое эквивалент Git для номера ревизии? - PullRequest
226 голосов
/ 08 ноября 2010

Мы используем SVN на работе, но для моих личных проектов я решил использовать Git.Поэтому я установил Git вчера, и мне интересно, что такое номер редакции эквивалент в Git .

Допустим, мы работаем над версией 3.0.8, и каждое исправлениеего собственный номер ревизии, который мы можем использовать, когда говорим об этом исправлении ошибки.Так что, если я помечу код в Git на 3.0.8, что тогда я смогу использовать в качестве номера ревизии или какого-то другого более детального вида идентификации?Я считаю, что хэш не так удобен для людей.

Ответы [ 18 ]

161 голосов
/ 16 сентября 2013

С современным Git (1.8.3.4 в моем случае) и без использования веток вы можете сделать:

$ git rev-list --count HEAD
68
140 голосов
/ 08 ноября 2010

Хорошая или плохая новость для вас, этот хэш - номер редакции.У меня также были проблемы с этим, когда я переключился с SVN на git.

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

Главное, что нужно понять, это то, что git не может иметь номера ревизий - подумайте о децентрализованной природе.Если пользователи A и B фиксируют свои локальные репозитории, как git может разумно назначить последовательный номер редакции?A не знает о B до того, как они передадут / вытянут изменения друг друга.

Другая вещь, на которую стоит обратить внимание, - это упрощенное ветвление для веток с исправлениями ошибок:

Начните с выпуска: 3.0.8.Затем, после этого выпуска, сделайте следующее:

git branch bugfixes308

Это создаст ветку для исправлений ошибок.Извлеките ветку:

git checkout bugfixes308

Теперь внесите все необходимые исправления ошибок.

git commit -a

Передайте их и переключитесь обратно в основную ветку:

git checkout master

Затем извлеките эти изменения из другой ветки:

git merge bugfixes308

Таким образом, у вас есть отдельная ветвь исправления ошибок, зависящая от выпуска, но вы по-прежнему вносите изменения исправления в основную магистраль разработчика.

95 голосов
/ 08 ноября 2010

Команда git describe создает немного более удобочитаемое имя, которое относится к конкретному коммиту.Например, из документации:

С чем-то вроде текущего дерева git.git я получаю:

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

т.е. текущий заголовок моей "родительской" ветви основан наv1.0.4, но так как он имеет несколько коммитов, в конце описания добавлено число дополнительных коммитов («14») и сокращенное имя объекта для самого коммита («2414721») в конце.

Пока вы используете тэги с разумными именами для маркировки определенных выпусков, это можно считать примерно эквивалентным SVN "номер редакции".

67 голосов
/ 04 июня 2012

Остальные постеры правы, «номер редакции» отсутствует.

Я думаю, что лучший способ - использовать теги для «релизов»!

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

Показать«текущая ревизия» «HEAD» моделируется с помощью этого:

git rev-list HEAD | wc -l

Но что, если клиент сообщит мне, что в «revision» 1302 есть ошибка?

Для этого я добавил следующее в раздел [alias] моего ~ / .gitconfig:

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

, используя git show-rev-number 1302, затем напечатает хэш для «ревизии»:)

Я сделал сообщение в блоге (на немецком языке) об этой «технике» некоторое время назад.

25 голосов
/ 08 ноября 2010

Git не имеет той же концепции номеров ревизий, что и subversion. Вместо этого каждый данный снимок, сделанный с фиксацией, помечается контрольной суммой SHA1. Зачем? Существует несколько проблем с запуском revno в распределенной системе контроля версий:

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

Во-вторых, номера ревизий могут генерироваться на разных машинах. Это значительно усложняет синхронизацию чисел, особенно потому, что связь односторонняя; у вас может даже не быть доступа ко всем машинам, на которых есть хранилище.

В-третьих, в git, в некоторой степени впервые использовавшейся ныне несуществующей системой OpenCM, идентификатор коммита (что такое коммит) эквивалентен имени (идентификатор SHA) , Эта концепция naming = identity очень сильна. Когда вы сидите с именем коммита в руке, он также идентифицирует коммит не поддающимся обработке способом. Это, в свою очередь, позволяет проверять все ваши коммиты обратно на первый начальный на наличие повреждений с помощью команды git fsck.

Теперь, поскольку у нас есть DAG (направленный ациклический граф) ревизий, и они составляют текущее дерево, нам нужны некоторые инструменты для решения вашей проблемы: как мы различаем разные версии. Во-первых, вы можете опустить часть хэша, если данный префикс, скажем, 1516bd уникально идентифицирует ваш коммит. Но это тоже довольно надумано. Вместо этого, хитрость заключается в использовании тегов и / или ветвей. Тег или ветка похожи на «желтую заметку», которую вы прикрепляете к данному SHA1-идентификатору коммита. По сути, теги должны быть неподвижными, тогда как ветвь будет перемещаться, когда в ее HEAD будут сделаны новые коммиты. Существуют способы ссылки на коммит вокруг тега или ветви, см. Справочную страницу git-rev-parse.

Обычно, если вам нужно поработать над определенным фрагментом кода, этот фрагмент претерпевает изменения и должен как таковой быть ветвью с говорящим названием темы. Создание большого количества веток (20-30 на каждого программиста не является неслыханным, с некоторыми 4-5, опубликованными для других, чтобы работать над ними) - хитрость для эффективного git. Каждая часть работы должна начинаться как отдельная ветвь, а затем объединяться во время тестирования. Неопубликованные ветви могут быть полностью переписаны, и эта часть разрушающей истории является силой мерзавца.

Когда изменение принято в мастер , оно несколько застывает и становится археологическим. В этот момент вы можете пометить его, но чаще всего ссылка на конкретный коммит делается в трекере ошибок или трекере ошибок через сумму sha1. Тэги, как правило, зарезервированы для выпусков версий и точек ветвления для ветвей обслуживания (для старых версий).

17 голосов
/ 26 июля 2012

Если вам интересно, я управлял номерами версий автоматически из информации git здесь в формате

<major>.<minor>.<patch>-b<build>

где build - общее количество коммитов. Вы увидите интересный код в Makefile. Вот соответствующая часть для доступа к другой части номера версии:

LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"

VERSION  = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION    = $(shell  git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR      = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR      = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH      = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits       
BUILD      = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")

#REVISION   = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR    = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)
9 голосов
/ 21 февраля 2013

Функция Bash:

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

выводит что-то вроде

$ git_rev
2:0f8e14e:20130220

То есть

commit_count:last_abbrev_commit:date_YYmmdd
8 голосов
/ 08 ноября 2010

Хэш SHA1 коммита эквивалентен номеру ревизии Subversion.

6 голосов
/ 28 апреля 2015

Это то, что я сделал в своем make-файле на основе других решений. Обратите внимание, что это не только дает вашему коду номер редакции, но также добавляет хеш, который позволяет вам воссоздать релиз.

# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID
5 голосов
/ 20 ноября 2013

Я написал несколько утилит PowerShell для получения информации о версии из Git и упрощения тегов

Функции: Get-LastVersion, Get-Revision, Get-NextMajorVersion, Get-NextMinorVersion, TagNextMajorVersion, TagNextMinorVersion:

# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
  $lastTagCommit = git rev-list --tags --max-count=1
  $lastTag = git describe --tags $lastTagCommit
  $tagPrefix = "v"
  $versionString = $lastTag -replace "$tagPrefix", ""
  Write-Host -NoNewline "last tagged commit "
  Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
  Write-Host -NoNewline " revision "
  Write-Host -ForegroundColor "yellow" "$lastTagCommit"
  [reflection.assembly]::LoadWithPartialName("System.Version")

  $version = New-Object System.Version($versionString)
  return $version;
}

# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
   $lastTagCommit = git rev-list HEAD
   $revs  = git rev-list $lastTagCommit |  Measure-Object -Line
   return $revs.Lines
}

# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $major = $version.Major+1;
    $rev = Get-Revision
    $nextMajor = New-Object System.Version($major, 0, $rev);
    return $nextMajor;
}

# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $minor = $version.Minor+1;
    $rev = Get-Revision
    $next = New-Object System.Version($version.Major, $minor, $rev);
    return $next;
}

# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
    $version = Get-NextMinorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next minor version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
    $version = Get-NextMajorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next majo version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...