Як досягти схеми чисельної версії з Git?


131

Моя організація розглядає можливість переходу від SVN до Git. Одним із аргументів проти переміщення є такий:

Як ми робимо версію?

У нас є дистрибутив SDK на базі платформи NetBeans. Оскільки версії SVN є простими числами, ми можемо використовувати їх для розширення номерів версій наших плагінів та SDK-версій. Як ми впораємося з цим, коли переходимо до Git?

Можливі рішення:

  • Використання номера збірки з Хадсона (Проблема: ви повинні перевірити Хадсона, щоб співвіднести це з фактичною версією Git)
  • Оновлення версії вручну для нічних та стабільних (Проблема: Крива навчання, помилка людини)

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


3
Чи можете ви отримати ваш сервер Хадсон (не дженкінс ?) Автоматично додавати gitтег після кожної успішної збірки? Це матиме додаткову перевагу в тому, що це дає зрозуміти, які gitкоміти мають проблеми зі складанням або тестовими помилками, оскільки вони залишаться без тегів.
Марк Бут


Як бічну примітку, ви можете додати кількість тегів до тегу, відстежуючи час збирання .
Шахбаз

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

Відповіді:


152

Використовуйте теги для позначення комітетів номерами версій:

git tag -a v2.5 -m 'Version 2.5'

Push теги вгору - це не робиться за замовчуванням:

git push --tags

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

git describe --tags --long

Це дає вам рядковий формат:

v2.5-0-gdeadbee
^    ^ ^^
|    | ||
|    | |'-- SHA of HEAD (first seven chars)
|    | '-- "g" is for git
|    '---- number of commits since last tag
|
'--------- last tag

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

20
Невеликі поліпшення: git describe --long --tags --dirty --always. "Брудне" скаже вам, чи були місцеві зміни, коли було зроблено "опис" (це означає, що він не може повністю описати стан репо). "Завжди" означає, що ви не отримаєте помилку, коли немає тегів. Він буде відновлюватися до просто хеш-фіксації. Тож можна взяти 76001f2-dirtyза приклад. Очевидно, що бачити "брудне" означає, що хтось заплутався.
Майк Веллер

1
Як це може працювати, коли тег генерується останнім часом . Зазвичай ви хочете, щоб збірки йшли вперед, щоб мати наступну версію свого продукту. Але вони завжди будуть змушені використовувати в цьому випадку останню версію. Тільки остаточне, що поставляється, буде мати відповідну кількість.
void.pointer

@ void.pointer: Безумовно, номер цієї версії відповідає на питання "на якій версії базувався цей випуск?" Наприклад, якщо ви позначаєте тег HEADяк v2.5, ви можете так само добре інтерпретувати це як початок циклу випуску 2.5, а потім тег v2.5-releaseабо все, що вам подобається.
Джон Перді

8
Ще одне невелике поліпшення. Якщо ви також хочете мати інші теги, але використовувати спеціально з малюнком тег для генерації версій, ви можете скористатися таким --matchваріантом:git describe --long --tags --dirty --always --match 'v[0-9]\.[0-9]'
Олександр Амелкін

42

Це придумали кілька проектів для мене. Найкраще рішення, яке я мав поки що, - це генерувати номер такої версії:

xy <кількість комітетів> .r <git-hash>

Як правило, він генерується нашою системою збирання за допомогою комбінації якогось статичного файла або тегу для отримання основних номерів редагування git rev-list HEAD | wc -l(що було швидше, ніж використання git log) та git rev-parse HEAD. Міркування були такими:

  1. Нам потрібна можливість, щоб версії на високому рівні відбувалися явно (тобто)
  2. Коли паралельна розробка відбувалася, нам НІКОЛИ не потрібно було генерувати той самий номер версії.
  3. Ми хотіли легко простежити, звідки походить версія.
  4. Коли паралельні лінії були об'єднані, ми хотіли, щоб нова версія була вирішена вище, ніж будь-яка з гілок.

Число 2 незрозуміло для більшості людей, але воно дійсно важливе і дуже важко з розподіленим контролем джерел. SVN допомагає в цьому, надаючи вам єдиний номер редакції. Виявляється, що кількість фіксів наближається до моменту, коли ви навіть магічно вирішуєте номер 4. За наявності гілок це все ще не унікально, і в цьому випадку ми додаємо хеш, який також акуратно вирішує №3.

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

У випадку, якщо вам цікаво, ми вирішили поставити r перед хешем через деяку дивність, як упаковка Python обробляє букви у номерах версій (тобто ae менше 0, що означає, що "1.3.10.a1234" < "1.3.10" <"1.3.10.1234").


1
btw, як ви вирішили проблему з курячим яйцем щодо визначення git-hash, перш ніж перевірити його? Ви використовували якусь форму .gitignore чи якусь іншу хитрість?
kfmfe04

3
Я цього не зробив. Я не використовую хеш, поки не складеться час створення пакету, який буде дуже довгим після реєстрації. У різних мовах є різні способи ввести це. Для Python я використовую './setup.py egg_info -b ". $ {BUILD_VERSION}" sdist ". Для C і C ++ я визначаю макрос під час компіляції з 'CFLAGS = -D "$ {BUILD_VERSION}"'. Для Go я визначаю символ під час посилання з 'go install -ldflags appmodule.BuildVersion "-X. $ {BUILD_VERSION}"'.
Джейсон

1
Це має бути найкращою відповіддю.
альвінабад

дуже хороша відповідь
haelix

9

Це може бути трохи зайвим, але я дам вам знати, як ми це робимо.

Ми використовуємо гіллясту структуру, дуже схожу на цю .

Хадсон будує наші "розробляти" гілки та прирости номери побудови, починаючи з 0. Номер збирання унікальний для кожного проекту та позначається в контролі версій. Причина полягає в тому, що ви можете точно сказати, з якої галузі побудови розробленої галузі 42, наприклад, (кожен проект може мати кілька гілок розвитку паралельно, тому що кожен проект може мати декілька команд, що працюють над різними аспектами проекту).

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

Приклад: збірка 2.1.0 1337

Це означає, що для конкретного випуску продукту ви можете сказати, яка була остання команда, яка працювала над ним, і ви можете запитати git на всі зобов'язання, що ведуть до випуску, щоб діагностувати проблему, якщо вам потрібно.


8

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

Погляньте на процес використання "git-опису" за допомогою GIT-VERSION-GEN та на те, як ви можете додати це за допомогою процесу збирання, коли ви додаєте теги до релізу.

Ось приємний блог, який наводить приклад того, як отримати те, що ви хочете:

http://cd34.com/blog/programming/using-git-to-generate-an-automatic-version-number/


0

Джон Перді має правильну ідею. git flowполегшує і власне управління цими філіями, і управління філіями є аргументом для переходу git.

Почнемо з базового проходу git, оскільки ви приїжджаєте з точки зору svn-to- git. Розглянемо gitнаступне:

master--...............-.....-..............-
        \             /     /              /
         ---develop---------............../
                            \            /
                             --feature---

Вище, ви розгалужується masterв develop(позначеному \), і гілка developдо featureгілки. Ми об'єднуємо ці гілки назад (позначаються /), з комірами ( -) вздовж гілки. (Якщо немає коміту, але злиття - це шлях праворуч, є .індикатори, які показують, що наступним -є наступне виконання).

Досить просто. Що робити, якщо у головному випуску у нас є виправлення?

master--...............-.....-................-...........-.........-
        \             /     /                / \         /|        /
         \           /     /                /   -hotfix-- V       /
          ---develop---------............../..............-...----
                             \            / \             V   /
                              --feature---   --feature2...----

Вгорі, developрозгалужене з master. Виявлена ​​помилка masterбула виправлена ​​за допомогою розгалуження master, виправлення та об’єднання назад у master. Потім ми об'єдналися masterв develop, а потім developуfeature2 , які перекотили новий код з hotfixцих гілок.

Коли ви feature2повертаєтесь назад develop, її історія включається developдо hotfix. Аналогічно, developзливається feature2з новим кодом від master, так що злиття developназад masterбуде відбуватися без замикання, оскільки воно засноване на фіксації в masterтой час - як ніби ви відключилися з masterтого моменту.

Тож ось ще один спосіб зробити це.

master--..........-........-
        \        /\       /
         ---1.0--  --1.1-- 

Ваші 1.0 релізи отримати tagged- 1.0.1, 1.0.2, 1.0.3і так далі.

Тепер ось хитрість: ви виявили помилку в 1.0, і вона впливає на 1,1, 1,2 та 1,3. Що ти робиш?

Ви відгалужуєте свій останній чи найдавніший підтримуваний випуск та виправляєте його. Потім злити свій новий hotfixфіліал в 1.3й в 1.2, 1.1і 1.0. Не від'єднуйтесь до кожної з гілок версії технічного обслуговування; не зливаються 1.0в masterабо зливатися masterназад в 1.0. Візьміть одну hotfixгілку і з'єднайте її з усіма версіями вашої версії. Якщо є конфлікти, це вам скаже; перегляньте свій код, щоб переконатися, що зміни правильні ( git diffце ваш друг).

Тепер ця конкретна зміна застосовується повсюдно. Рядок розгалужений, але це нормально. Це не випадково. Позначте 1.3голову як 1.3.17, з’єднайте її з усіма незавершеними функціями, які розгалужуються 1.3, і рухайтеся далі.

git flowРозширення допомагає керувати цим обслуговування, функцією і гілкою виправлень для вас. Після того, як ви скоротите робочий процес, це тривіально і доставляє величезну кількість проблем з управління вихідним кодом.

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


-6

Pro Git у розділі 7.2 «Атрибути Git» у розділі «Ключове слово» містить розкішний приклад використання розмитих та чистих фільтрів для створення ключових слів у стилі RCS. Ви можете використовувати ту саму техніку для вбудовування рядка-версії в код, відформатованого та обчисленого відповідно до ваших правил . Ви все ще можете використовувати git describeв якості зору, але у вас є можливість перетворитись у будь-яку більш відповідну форму і отримати з v2.5-14-honobdaed, наприклад, чистий 2.5.14


9
-1 за те, що зруйнував хорошу відповідь, абсолютно не вимагаючи атаки ad hominem.
Йорг W Міттаг

9
Хто може сказати, що це грізні хлопці вас голосували. Це легко можуть бути люди, які віддають перевагу трохи уважності .
Марк Бут

FYI, я щойно відредагував відповідь.
Кіт Томпсон

git describeвиводить ім'я тегу, якщо його --longне передано або не відбудеться комісій з останнього тегу, тому він вже ідеально чистий. Якби ви не змінювали стандартні налаштування, це дало б вам саме те, що ви хотіли.
strcat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.