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

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

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

Ответы [ 18 ]

4 голосов
/ 24 августа 2012

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

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

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

3 голосов
/ 22 апреля 2013

Я просто хотел бы отметить другой возможный подход - это использование git git-notes (1) , существующего с версии 1.6.6 ( Примечание для Self -Git ) (я использую git версия 1.7.9.5).

По сути, я использовал git svn для клонирования SVN-репозитория с линейной историей (без стандартной компоновки, без ветвей, без тегов), и я хотел сравнить номера ревизий в клонированном репозитории git.Этот git-клон не имеет тегов по умолчанию, поэтому я не могу использовать git describe.Стратегия здесь, вероятно, будет работать только для линейной истории - не знаю, как это получится с объединениями и т. Д .;но вот основная стратегия:

  • Запросить git rev-list список всей истории изменений
    • Поскольку rev-list по умолчанию в «обратном хронологическом порядке», мы будем использоватьего переключатель --reverse для получения списка коммитов, отсортированных по старым первым
  • Использование оболочки bash для
    • увеличения переменной счетчика для каждого коммита в качестве счетчика ревизий,
    • сгенерируйте и добавьте «временную» заметку git для каждого коммита
  • Затем просмотрите журнал, используя git log с --notes, который также выведет дамппримечание коммита, которое в данном случае будет «номером ревизии»
  • Когда закончите, удалите временные заметки ( Примечание: я не уверен, зафиксированы ли эти заметки или нет;действительно показывать в git status)

Во-первых, давайте заметим, что git имеет расположение заметок по умолчанию - но вы также можете указать ref (erence) для заметок - чтобудет хранить их в другом каталоге под .git;например, находясь в папке репо git, вы можете позвонить по номеру git notes get-ref и узнать, какой это будет каталог:

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

Следует отметить, что если вы notes add с --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 с другим контекстом, хотя ...

Надеюсь, это кому-нибудь поможет,
Приветствия!


РЕДАКТИРОВАТЬ: Хорошо, здесь это немного проще, с псевдонимами 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 голосов
/ 20 марта 2015

Для людей, у которых есть процесс сборки Ant , вы можете сгенерировать номер версии для проекта на 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 голос
/ 19 августа 2013

Наряду с идентификатором SHA-1 фиксации, дата и время сервера помогли бы?

Примерно так:

коммит произошел в 11:30:25 19 августа 2013 г. 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025

1 голос
/ 24 октября 2013

В руководстве по Git теги - блестящий ответ на этот вопрос:

Создать аннотированный тег в Git просто. Самый простой способ это укажите -a при запуске команды tag:

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

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

Check 2.6 Основы Git - Tagging

0 голосов
/ 10 сентября 2018

Событие после сборки для Visual Studio

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }
0 голосов
/ 18 марта 2016

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...