Git tag также помечает все предыдущие коммиты - PullRequest
0 голосов
/ 26 мая 2018

В настоящее время я пытаюсь сделать мою библиотеку доступной на github.В двух версиях: 0.1 и 0.2.Я знаю, что pip может найти версию пакета по его тегу на git, поэтому я подумал о тегировании.

Когда я делаю:

git add .
git commit -m "msg1"
git tag -a 0.1 -m "lib v0.1"
git push origin master --tag 0.1

Первый коммит помечается как 0.1

Но когда я что-то изменяю в коде, и я делаю почти то же самое:

git add .
git commit -m "msg2"
git tag -a 0.2 -m "lib v0.2"
git push origin master --tag 0.2

Последний коммит помечается как 0.2, но первый коммит помечается как 0.2 и 0.1.Я делаю что-то неправильно?Или это так, как должно быть?

@ Редактировать.Вот как это выглядит на моем git:

первый коммит: enter image description here

второй коммит: enter image description here

Releases вкладка:

enter image description here

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

TL; DR

Все хорошо.

Long

GitHub пытается скрыть большую часть сложности Git от пользователей GitHub.Я считаю, что это ошибка.Хотя Git общеизвестно недружелюбен к пользователю (см., Например, «10 вещей, которые я ненавижу в Git» * или xkcd # 1597 ), некоторые такой сложности действительноНеобходимый. 1

В случае тегов Git, что нужно понять о тегах, так это то, что любой тег - это просто удобочитаемое имя для некоторого определенного хеш-идентификатора.Хеш-идентификаторы - это те большие уродливые числа, похожие на числа, которые GitHub выделяет и сокращает и делает практически невозможными для чтения.На скриншоте показаны два следующих элемента: a89f1cc и 31a6a2d.

. Эти хэш-идентификаторы являются действительными именами объектов Git, то есть именами, которые сам Git использует для найти содержимое объектов.Эти хеш-идентификаторы сами создаются путем применения криптографического хеша к содержимому, так что хеш-идентификатор является коротким (ish) ключом для базы данных со значением ключа: с учетом ключа, который гарантированно будет уникальнымс этим конкретным содержимым, 2 Git может найти значение и получить все содержимое.Поскольку два хэша различны, два объекта также обязательно различаются.Если бы два объекта были одинаковыми, два хэша были бы одинаковыми.

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

git rev-parse a89f1cc^{}

например, будет искать объект a89f1cc, проверьте,это аннотированный объект тега, и если так, следуйте за ним к любому другому объекту, которому сам тег присвоит имена.Если a89f1cc - это объект другого типа, суффикс ^{} не имеет никакого эффекта.Мы также можем написать:

git rev-parse a89f1cc^{commit}

, который найдет объект commit , к которому a89f1cc разрешит или выдаст ошибку, и в данном конкретном случае это будет то, что мы хотим:это либо даст нам полный хэш-идентификатор самого a89f1cc, если он уже является коммитом, либо выдаст хэш-идентификатор коммита , в который разрешается a89f1cc, если он преобразуется в коммит, илииначе ошибка.

Более практично для вас, как человека, использующего систему, с учетом двух имен тегов, вы можете просто использовать names :

git rev-parse v0.1^{commit}

и:

git rev-parse v0.2^{commit}

, чтобы найти коммиты, на которые указывают теги.(Для некоторых оболочек могут потребоваться какие-то кавычки вокруг символов ^ и / или фигурных скобок {...}; это зависит от того, используете ли вы bash, tcsh, PowerShell или что-то подобное. Возможно, вам придется немного изменить эти команды командной строкичтобы ваша оболочка была довольна.)

Разрешение каждого из двух хэшей тегов в коммиты покажет вам, какой коммит или коммит имен двух разных тегов.Можно назначить несколько тегов одному коммиту, но вы этого не сделали, поэтому вы получите два разных хэша коммита.Это те коммиты, которые pip install будет проверять, собирать и устанавливать.


1 Альберт Эйнштейн часто перефразируется словами: "1072 * Всеследует сделать как можно более простым, но не более простым, , хотя Wikiquote говорит, что он действительно написал Едва ли можно отрицать, что высшая цель всей теории состоит в том, чтобы сделать неприводимые основные элементы такими, какпросто и как можно меньше, не отказываясь от адекватного представления единого источника опыта.

2 Это небольшое завышение, в зависимости от вашей версии Git,Подробности смотрите в Столкновение хэша в git .


Еще больше информации о том, являетесь ли вы пользователем Git: теги против веток и график фиксации

ЕслиВы только собираетесь установить, выше, пожалуй, все, что вам нужно.Однако, как тот, кто использует сам Git, есть кое-что, чему можно научиться.

Мы видели выше, что имя тега разрешается через git rev-parse (что большинство команд Git делают внутренне, когда это уместно) в хэш-идентификатор.Но то же самое верно - ну, в основном верно - для имени ветви , как master или develop.Мы можем запустить:

$ git rev-parse v2.16.0
e1c2c6b098dfb717a4a6ff7f3894d57343210a41

и получить хеш-идентификатор, подобный этому, но мы также можем запустить:

$ git rev-parse master
ccdcbd54c4475c2238b310f7113ab3075b5abc9c

и получить хеш-идентификатор.Этот хэш-идентификатор - это (один, один!) Коммит, на который указывает имя masterЭто верно для всех ссылок Git: имена ветвей, имена тегов, имена для удаленного отслеживания, такие как origin/master и т. Д., Все являются формами ссылок , а в Git: каждая ссылка преобразуется в один (1) хэш-идентификатор.

Что особенного в именах ветвей, так это то, что они меняются со временем.Теперь они хранят один хэш-идентификатор, а затем, после запуска git commit, в некотором имени ветви хранится новый, другой хэш-идентификатор.Это на самом деле, как растут ветви: вы говорите Git, что хотели бы быть на какой-то ветви, запустив, например:

git checkout master

, после чего git status говорит on branch master,Быть в ветви означает, что git commit изменит название этой ветви для вас: Git сделает новый коммит, который получит некотороеновый, случайный хеш-идентификатор, а затем Git сохранит этот новый хеш-идентификатор коммита в имени master.

Основным механизмом для этого является специальное имя HEAD (во всех столицах, хотя в системах Windows и Mac, в которых происходит сворачивание регистра, часто можно использовать строчные буквы).Git присоединяет слово HEAD к имени ветви , чтобы запомнить, в какой ветке вы указали Git.

Если бы у нас были заглавные буквы для имен ветвей, мы могли бывычеркните это так:

A <-B <-C   <-- master (HEAD)

, что означает, что HEAD присоединено к master, а имя master указывает на commit C - содержитидентификатор хеша для коммита C.Сам коммит C содержит идентификатор хеша для более раннего коммита B, а коммит B содержит идентификатор хеша для коммита A.

В нашем случае наш репозиторий очень маленький: он имеет толькоэти три коммита.Коммит A не имеет более раннего коммита - Git называет его корневым коммитом - поэтому он никуда не указывает.Это показывает, как работает Git: он использует name master, чтобы найти хеш-идентификатор для current commit C, а затем использует содержимое commit C, чтобы найтиC s parent commit B.Содержимое B позволяет Git найти родителя B A, а A не имеет родителя, поэтому действие прекращается: Git показывает, что вы фиксируете C, затем B, затем A,и останавливается.

Git, другими словами, работает в обратном направлении .

Когда вы делаете новый коммит D, Git создает этот коммит, записывая снимок всехваш код, записывая фактический хеш-идентификатор для более раннего коммита C, а затем записывая коммит и получая его фактический хеш-код (что бы это ни было).Затем Git использует HEAD для записи нового хеш-идентификатора в master, давая:

A <-B <-C <-D   <-- master (HEAD)

и теперь master имена (указывает на) commit D.

Опять же, именно так обычно двигаются и растут ветви.Различие между именем ветви master и именем тега v0.1 заключается в том, что имя ветви должно перемещаться - предполагается, что со временем оно изменится,назвать последний коммит для этой ветви - но имя тега не перемещается.После того, как вы присвоили имя тега, указывающее на какой-то конкретный коммит, он остается там: он продолжает указывать на этот коммит.

Связи коммита с коммитом образуют graph , и это таксделать граф, который действительно склеивает Git вместе.GitHub пытается скрыть граф коммитов от вас.Поскольку Git в основном относится к графику - просто files просто приходят для поездки - это ужасная медвежья услуга.Понимание графика коммитов крайне важно для использования Git.

0 голосов
/ 26 мая 2018

Это просто недоразумение, основанное на том, как github отображает теги в своем пользовательском интерфейсе.Когда git отображает тег в коммите, это не обязательно означает, что коммит помечен этой версией.Чтобы увидеть фактические теги в github, вы можете нажать на вкладку «Релизы».

...