Що таке еквівалент Git для ревізійного номера?


244

Ми використовуємо SVN на роботі, але для моїх особистих проектів я вирішив використовувати Git. Тож я вчора встановив Git, і мені цікаво, що еквівалентний номер редакції в Git .

Скажімо, ми працюємо над версією 3.0.8, і для кожного виправлення помилок є свій номер ревізії, який ми можемо використовувати, коли говоримо про цю помилку. Тож якщо я позначаю код в Git до 3.0.8, що тоді я можу використовувати як номер редакції чи інший більш детальний вид ідентифікації? Я вважаю хеш не таким зручним для людей.



Там є стаття для одного з можливих рішень. Це може виглядати трохи важко, але вбудоване у вихід "git log" та не вимагає додаткових команд, крім "git push / pull / fetch".
Дмитро Павленко

Невдале пов’язана стаття від @DmitryPavlenko знаходиться на мертвому домені: gitsvn.x10.mx. Не маючи вказівки на тему, комусь буде важко знайти її в іншому місці.
Майкл Доноуе

Примітка: не більше Abbrev необхідно з мерзотником описати: см stackoverflow.com/a/41308073/6309
VonC

1
Ні, Лоранс Гонсальвес, це не дублікат "як змусити рахувати git commit?" - мова йде про номер версії, і хоча кількість
фіксованих файлів

Відповіді:


149

Хороша чи погана новина для вас, що хеш - це номер редакції. У мене також були проблеми з цим, коли я перейшов з 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

Таким чином, у вас є окрема гілка виправлень, специфічна для випуску, але ви все ще втягуєте зміни виправлення у свій основний стовбур розробника.


11
Я зрозумів, що хеш - це номер редакції, але сподівався, що це не так :-))) дякую за дуже приємне пояснення та пропозицію зараз розібратися з ним.
Радек

3
Ласкаво просимо. Мене дуже розчарувало git, коли я вперше взяв його з SVN, але тепер я розмахував іншим способом ...
makdad

4
ТАКОЖ, минуло деякий час, коли я опублікував це, але пам’ятайте, що ви також можете зробити "git checkout -b new_branch_name", щоб зробити "git branch foo" та "git checkout foo" як однолінійний.
makdad

1
Чи я правда, що хеші є "справжніми" хешами, а навіть не віддаленими послідовними? Отже, що важливо, якщо база даних про помилки говорить fixed in 547cc3e..c4b2eba, і у вас є інша редакція, ви не знаєте, чи повинен ваш код містити виправлення ?! Безумовно, гетс у git-central має рішення для цього?!?!
Олі

3
У SVN факт, що помилка виправлена ​​в r42, не говорить вам про те, чи вона також виправлена ​​в r43, як тільки ви фактично використовуєте гілки.
Матьє Мой

186

З сучасним Git (1.8.3.4 в моєму випадку) та не використовуючи гілки ви можете:

$ git rev-list --count HEAD
68

22
Подумайте про використанняgit rev-list --count --first-parent HEAD
Flimm

8
З огляду на цю інформацію (число 68), чи є спосіб визначити версію для повторного придбання коду? Припустимо, "редакція 68" випущена в тестове середовище, розробка триває, і пізніше розробнику потрібно знову придбати "редакцію 68" з управління джерелами. Як він націлиться на конкретну версію для клонування? Або я пропускаю щось про Git, що робить це непотрібним?
Девід

9
Майте на увазі, що це рішення дасть різні результати для різних розробників. Крім того, обчислення зворотного значення від "рахунку" до фіксації призведе до різних комісій для різних розробників !! Це пояснюється розподіленим характером Git і тим, що коміти відбуваються в різних сховищах за один і той же час, але вони не можуть враховуватися git rev-list --count HEADзалежно від того, коли були зроблені останні поштовхи та витяги.
Джейсон

2
@Jason, коментар Девіда щодо додавання --first-parentвирішує вашу проблему? Мені б не хотілося уникати, здавалося б, найпростішого рішення через рідкісний випадок, якщо існує однаково просте рішення або спосіб зробити його більш надійним.
MarkHu

4
@MarkHu, --first-parentдопомагає. Поки не робиться повторне оновлення і завжди використовується одна і та ж гілка для створення випусків (і, звичайно, обчислення цього номера випуску), я думаю, це можна було б використовувати. Хоча я все ще не впевнений, що це завжди однозначно визначить прихильність, з якої вийшов реліз. Тут так багато речей, які можуть піти не так ... але на даний момент я не можу придумати щось, що напевно це порушило би (з огляду на мої вищевикладені твердження "до тих пір, як" заяви). git describeЗгадувалося в іншому відповіді метод є шлях. Створіть тег, якщо хочете щось читабельне для людей.
Джейсон

104

git describeКоманда створює читане ім'я трохи людяніше , що відноситься до конкретної фіксації. Наприклад, з документації:

Маючи щось на кшталт поточного дерева git.git, я отримую:

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

тобто поточний керівник моєї "батьківської" гілки базується на v1.0.4, але оскільки у неї є кілька комірок поверх цього, опис додав кількість додаткових комітів ("14") та скорочене ім'я об'єкта для комітів себе ("2414721") наприкінці.

Поки ви використовуєте розумно названі теги для тегування певних випусків, це можна вважати приблизно еквівалентним SVN "ревізійному номеру".


7
Я хотів би лише зазначити, що це працює лише в тому випадку, якщо у вашому gitсховищі вже є теги; якщо цього не відбувається, ви можете отримати git description fails з "fatal: Не знайдено імен, нічого не можна описати". - Переповнення стека ; це означає, що вам доведеться самостійно налаштовувати теги.
sdaau

14
@sdaau: Якщо ви використовуєте це в сценарії чи щось і хочете, git describeщоб ніколи не виходило з ладу, використовуйте git describe --alwaysпараметр.
Грег Хьюгілл

Чи може вихід git describeякийсь спосіб використовувати джерело фіксації джерела? Я маю на увазі відсутність ручного підрахунку комітетів у журналі.
Лій

@Lii: Що ви маєте на увазі під "джерелом"? І найближчий тег ( v1.0.4), і останній ідентифікатор 2414721комісії ( ) вже є частиною виходу опису git.
Грег Хьюгілл

@GregHewgill: Так, дякую, коли я задав питання, я не розумів, що "скорочене ім'я об'єкта" - це значення, яке можна використати для ідентифікації комітів. Це геніально!
Лій

67

Інші афіші вірні, "редакційного номера" немає.

Я думаю, що найкращий спосіб - використовувати Теги для "релізів"!

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

Показати "поточну редакцію" "HEAD" моделюється за допомогою цього:

git rev-list HEAD | wc -l

Але що робити, якщо клієнт мені скаже, що в "ревізії" 1302 є помилка?

Для цього я додав у розділ [псевдонім] мого ~ / .gitconfig наступне:

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

використовуючи git show-rev-number 1302потім роздрукувати хеш для «перегляду» :)

Я зробив повідомлення в блозі (німецькою мовою) про цю "техніку" деякий час тому.


@Radek - "іноді потрібно знати, що" зміни коду = фіксація "виправлено щось" - тоді git bisect(посилання) є відповідним інструментом для визначення того, що змінилося, коли ким.
Майкл

@Radek Так, це постійно зростаюча кількість. Він просто підраховує зміни, які ви зареєстрували на HEAD. Тож кожне зобов'язання - це нова редакція. Це не спрацює для різних галузей.
OderWat

1
Мені подобається ваше рішення. Зауважте, що ви можете спростити це: show-rev-number =! Sh -c 'git rev-list - зворотний HEAD | awk NR == $ 0 '
avner

@avner Дякую! Я не використовував багато ані в своєму житті, очевидно :)
OderWat

3
Мені довелося скористатисяgit rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Геррі

27

Git не має тієї ж концепції ревізійних номерів, що і підривна. Натомість кожен даний знімок, зроблений з фіксацією, позначається контрольною сумою SHA1. Чому? У розповсюдженій системі управління версіями є кілька проблем із запущеним revno:

По-перше, оскільки розробка взагалі не є лінійною, вкладення номера є досить важким, як вирішити проблему таким чином, щоб задовольнити ваші потреби програміста. Спроба виправити це за допомогою додавання числа може швидко стати проблематичним, коли число поводиться не так, як ви очікували.

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

По-третє, в git, дещо піонером теперішньої системи OpenCM, ідентичність комітету (те, що відбувається) є еквівалентною його імені (ідентифікатор SHA). Ця концепція називання = ідентичність дуже сильна. Коли ви сидите з назвою комітету в руці, він також ідентифікує виконання на незабутній спосіб. Це, в свою чергу, дозволяє перевірити всі свої зобов'язання назад до першого початкового на предмет корупції з git fsckкомандою.

Тепер, оскільки у нас є DAG (спрямований ациклічний графік) модифікацій, і вони складають поточне дерево, нам потрібні деякі інструменти для вирішення вашої проблеми: як ми дискримінуємо різні версії. По-перше, ви можете опустити частину хешу, якщо певний префікс, скажімо, 1516bd , однозначно ідентифікує ваш коміт . Але це теж досить надумано. Натомість хитрість полягає у використанні тегів та / або гілок. Тег або гілка схожа на "жовту паличку, яку ви помічаєте", яку ви додаєте до заданого комітету SHA1-id. По суті, теги покликані не рухатись, тоді як гілка буде переміщуватися, коли нові комісії вносяться до її HEAD. Існують способи посилання на комітку навколо тегу чи гілки, дивіться довідкову сторінку git-rev-розбору.

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

Коли зміна приймається в майстер, вона дещо застигає і стає археологією. У цей момент ви можете позначити її тегом, але частіше посилання на певний фіксатор робиться в трекері помилок або видає трекер через суму sha1. Теги, як правило, зарезервовані для ударів версій та точок філій для гілок обслуговування (для старих версій).


18

Якщо вас цікавить, я керував номерами версій автоматично з git infos тут під форматом

<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

Функція 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

Така річ може бути корисною, але якщо когось цікавлять додаткові номери версій, вони поміняють місцями позиції поля, щоб хеш (неінкрементальний) був останнім.
MarkHu

8

SHA1 хеш фіксації є еквівалентом номер ревізії Subversion.


7
На жаль, він має зовсім інші властивості від ревізійного номера. Він досить довгий, і не збільшується монотонно. Здогадайтесь, що це ціна, яку потрібно заплатити за розповсюдження ...
CodesInChaos

1
@CodeInChaos: Я знаю, до чого ви потрапляєте, але, як правило, можна посилатися на git-коміти лише з першими 6 або 8 символами хеш-коду.
Кріс Пітман

5
@Radek: Вони не гарантовані унікальністю (хоча якщо ви зіткнетесь, ви можете виграти невелику кількість знаменитостей).
Slartibartfast

8
@Radek Відповідно до en.wikipedia.org/wiki/Collision_attack , з 4 символами хеша у вас 16-бітний ідентифікатор, це означає, що в репо з 256 (= 2 ^ (16/2)) комітів є 50 % ймовірність того, що два коміти мають однаковий префікс з чотирма знаками (і при 65536 команд це точно, оскільки тоді діапазон 4-знакових ідентифікаторів вичерпаний). Коли ви додасте один char, у вас є 20-бітний Id, що означає, що поріг 50% становить 1024 коміти. Але оскільки це статистичний параметр, ніщо не гарантує, що подібні зіткнення не відбудуться раніше.
Руді

2
Оскільки хеш ґрунтується на вмісті, все ж є ймовірність того, що два коміти мають однаковий хеш-префікс, а не визначеність. При 65536 комісіях дуже ймовірно, що двоє матимуть однаковий префікс з чотирма знаками, але це все одно не точно. Як і в стороні, повний хеш не має колізії ще, але мерзотник працює на ньому :) stackoverflow.com/questions/3475648 / ...
goodeye

6

Це я зробив у своєму makefile на основі інших рішень. Зверніть увагу, що це не лише надає вашому коду ревізійний номер, він також додає хеш, який дозволяє відтворити випуск.

# 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

3
Здається, найбезпечнішим способом git-describeуникнути помилок є те, з git describe --always --dirty --long --tagsякою працює у всіх випадках, про які я можу придумати.
MarkHu

5

Проблема з використанням git-хешу як номера збірки полягає в тому, що він не монотонно збільшується. OSGi пропонує використовувати позначку часу для номера збірки. Схоже, кількість комісій для гілки може бути використана замість номера підривної чи зміни змін.


5

Я написав деякі утиліти 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
}

4

Кожна комісія має унікальний хеш. Крім того, у Git немає номерів ревізії. Якщо вам потрібно більше зручності користування, вам потрібно буде позначати теги.


3

Я просто хотів би відзначити інший можливий підхід - а це за допомогою git git-notes (1) , що існує з версії 1.6.6 ( Note to Self-Git ) (я використовую gitверсію 1.7.9.5).

В основному я git svnклонував gitсховище SVN з лінійною історією (без стандартного макета, без гілок, без тегів), і хотів порівняти номери ревізій у клонованому сховищі. Цей клон git не містить тегів за замовчуванням, тому я не можу його використовувати git describe. Тут стратегія, ймовірно, працювала б лише для лінійної історії - не впевнена, як це вийде зі злиттями тощо; але ось основна стратегія:

  • Попросіть git rev-listсписок усіх історій фіксації
    • Оскільки rev-listза замовчуванням є "зворотний хронологічний порядок", ми використовуємо його --reverseперемикач, щоб отримати список комітетів, відсортований спочатку за найстарішими
  • Використовуйте bashоболонку для
    • збільшити змінну лічильника на кожен комісій як лічильник перегляду,
    • генерувати та додавати "тимчасову" примітку до git для кожного комітету
  • Потім, переглядати журнал за допомогою git logз --notes, який також буде звалище коммітов Відзначимо, що в даному випадку буде «номер редакції»
  • Після закінчення стерти тимчасові нотатки ( Примітка: я не впевнений, чи ці нотатки зроблені чи ні; вони насправді не відображаютьсяgit status )

Спочатку зазначимо, що нотатки gitза замовчуванням мають нотатки, але ви також можете вказати ref(erence) для нотаток - які зберігатимуть їх у іншому каталозі під .git; наприклад, перебуваючи в gitпапці repo, ви можете зателефонувати, git notes get-refщоб побачити, який саме каталог буде:

$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever

Варто зазначити, що якщо ви маєте notes adda --ref, ви також повинні потім скористатися цим посиланням ще раз - інакше ви можете отримати помилки типу " Не знайдено примітки для об'єкта XXX ... ".

Для цього прикладу я вирішив назвати refнотатки "linrev" (для лінійного перегляду) - це також означає, що ймовірно, що процедура не буде перешкоджати вже існуючим нотаткам. Я також використовую --git-dirперемикач, оскільки будучи gitновачком, у мене виникли деякі проблеми з його розумінням - тому я хотів би "запам'ятати на потім" :); і я також використовую --no-pagerдля придушення нересту lessпри використанні git log.

Отже, якщо припустити, що ви знаходитесь в каталозі, з підпапкою, myrepo_gitяка є gitсховищем; можна було б зробити:

### check for already existing notes:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done

# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"

### check status - adding notes seem to not affect it:

$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)

### note is saved - now let's issue a `git log` command, using a format string and notes:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000:  >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000:  >>initial test message 1<< (r1)

### test git log with range:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)

### erase notes - again must iterate through rev-list

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD remove $ih"; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

Так, принаймні в моєму конкретному випадку повністю лінійної історії без гілок, номери редагування, схоже, збігаються з цим підходом - і крім того, схоже, що цей підхід дозволить використовувати git logз діапазонами редагування, отримуючи при цьому правильні номери редакції - YMMV з іншим контекстом, хоча ...

Сподіваюся, це допоможе комусь,
ура!


EDIT: Гаразд, тут трохи простіше, gitпсевдоніми для вищезгаданих циклів називаються setlinrevі unsetlinrev; у своїй папці сховища git, зробіть ( зауважте, що неприємне проскакуванняbash , див. також # 16136745 - Додайте псевдонім Git, що містить крапку з комою ):

cat >> .git/config <<"EOF"
[alias]
  setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD\"; \n\
    done; \n\
    echo \"Linear revision notes are set.\" '"

  unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD remove $ih\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD 2>/dev/null\"; \n\
    done; \n\
    echo \"Linear revision notes are unset.\" '"
EOF

... так що ви можете просто викликати, git setlinrevперш ніж намагатися робити журнал, що включає примітки лінійної редакції; і git unsetlinrevвидалити ці нотатки, коли закінчите; приклад з каталогу git repo:

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

Час, який знадобиться оболонці для завершення цих псевдонімів, залежатиме від розміру історії сховища.


2

Для людей, у яких є процес складання мурашок , ви можете створити номер версії для проекту на git із цією ціллю:

<target name="generate-version">

    <exec executable="git" outputproperty="version.revisions">
        <arg value="log"/>
        <arg value="--oneline"/>
    </exec>

    <resourcecount property="version.revision" count="0" when="eq">
        <tokens>
            <concat>
                <filterchain>
                    <tokenfilter>
                        <stringtokenizer delims="\r" />
                    </tokenfilter>
                </filterchain>
            <propertyresource name="version.revisions" />
            </concat>
        </tokens>
    </resourcecount>
    <echo>Revision : ${version.revision}</echo>

    <exec executable="git" outputproperty="version.hash">
        <arg value="rev-parse"/>
        <arg value="--short"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Hash : ${version.hash}</echo>


    <exec executable="git" outputproperty="version.branch">
        <arg value="rev-parse"/>
        <arg value="--abbrev-ref"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Branch : ${version.branch}</echo>

    <exec executable="git" outputproperty="version.diff">
        <arg value="diff"/>
    </exec>

    <condition property="version.dirty" value="" else="-dirty">
        <equals arg1="${version.diff}" arg2=""/>
    </condition>

    <tstamp>
        <format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
    </tstamp>
    <echo>Date : ${version.date}</echo>

    <property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />

    <echo>Version : ${version}</echo>

    <echo file="version.properties" append="false">version = ${version}</echo>

</target>

Результат виглядає приблизно так:

generate-version:
    [echo] Generate version
    [echo] Revision : 47
    [echo] Hash : 2af0b99
    [echo] Branch : master
    [echo] Date : 2015-04-20.15:04:03
    [echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03

Брудний прапор є тут, коли у вас файли (файли) не скоєні під час генерації номера версії. Тому що зазвичай, коли ви створюєте / пакуєте свою програму, кожна зміна коду повинна бути в сховищі.


1

Поряд із ідентифікатором SHA-1 комісії, дата та час роботи сервера допомогли б?

Щось на зразок цього:

фіксація трапилася о 11:30:25, 19 серпня 2013 року буде показано як 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025


1

У посібнику Git теги - це яскрава відповідь на це питання:

Створити помічений тег у Git дуже просто. Найпростіший спосіб - вказати -a під час запуску команди тегів:

$ git tag -a v1.4 -m 'my version 1.4'

$ git tag
v0.1
v1.3
v1.4

Перевірте 2.6 Основи Git - Позначення тегів


Шкода, що вам доведеться стрибати через обручі, щоб змінити типові налаштування:By default, the git push command doesn’t transfer tags to remote servers.
MarkHu

1

Ми використовуємо цю команду для отримання версії та редакції від git:

git describe --always --tags --dirty

Це повертається

  • виконувати хеш як редагування, коли не використовується тегів (наприклад gcc7b71f)
  • назва тегу як версія, коли використовується в тезі (наприклад v2.1.0, використовується для випусків)
  • ім'я тегу, номер редакції з останнього тегу та введення хеша, коли після тегу (наприклад v5.3.0-88-gcc7b71f)
  • те ж, що вище, плюс "брудний" тег, якщо робоче дерево має локальні модифікації (наприклад v5.3.0-88-gcc7b71f-dirty)

Дивіться також: https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt


0

Подія складання для Visual Studio

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }

-1

Подумайте про використання

git-rev-label

Надає інформацію про перегляд репозиторію Git у такому форматі master-c73-gabc6bec. Може заповнити рядок або файл шаблону змінними середовища та інформацією з Git. Корисно надати інформацію про версію програми: відділення, тег, введення хешу, підрахунок, брудний статус, дата та час. Однією з найкорисніших речей є підрахунок комітетів, не враховуючи об’єднаних гілок - лише перший батько.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.