Как бы вы включили текущий идентификатор фиксации в файлы проекта Git?
У меня есть статическое JavaScript + HTML-приложение с открытым исходным кодом, которое сейчас развернуто примерно в трех разных местах: одно на моем локальном компьютере, одно на внутреннем сервере и одно на стабильном внешнем сервере.
Я хотел бы иметь возможность сразу сказать, какая версия развернута в каком месте, и я бы хотел, чтобы репортеры ошибок имели легкий доступ к версии, о которой они сообщают об ошибке.
В идеале, я бы хотел, чтобы как часть процесса фиксации был записан файл с хешем фиксации. Конечно, из того, что я знаю о Git, это невозможно, так как включение вычисленного хеша как части файла в коммит изменило бы вычисленный хеш этого коммита.
С другой стороны, я мог бы включить сборку как часть процесса сборки. У меня пока нет процесса сборки, и я хотел бы избежать добавления шага, если это возможно.
Какой самый чистый способ сделать это?
2 ответа
Добавьте его в свою автоматизированную систему развертывания.
Если ваше развертывание не автоматизировано, то автоматизируйте его и добавьте туда. Тогда вы удалили шаг.
Сделайте его более полезным "это было развернуто в x date в y раз из z репозитория". Хеш коммита не очень много значит для не-разработчиков.
Есть некоторые тонкости в этом из-за природы Git. Я сделал это, скопировав то, что делают сами разработчики Git. Во-первых, вы захотите использовать аннотированные теги, что, в любом случае, является хорошей идеей. Чтобы просмотреть, вы можете создать новый тег, как это:
$ git tag -a -m "Version 0.2" v0.2 HEAD
Тогда (как предложено в посте Отто) вы можете использовать git describe
для полезной строки "version", которая будет включать число коммитов с момента тега и первые цифры sha1 текущего коммита. Вот пример из одного из моих проектов:
$ git describe
v1.0-3-gee47184
То есть эта копия на 3 коммита выше тега "v1.0", а коммит sha1 начинается с ee47184 (я не уверен, почему они включают этот ведущий 'g').
Разработчики Git делают еще один шаг вперед, а также включают дополнительный бит, если рабочая копия изменена (незафиксирована). Это требует еще нескольких шагов, так что все это в сценарии, который они называют VERSION-GEN
, При запуске он выводит строку версии на стандартный вывод, а также создает VERSION-FILE
файл (сценарий старается не касаться этого файла, если версия не изменилась, поэтому он удобен для инструментов сборки). Затем вы можете включить это VERSION-FILE
файл в исходном коде, файлы справки и т. д.
Используя мой пример VERSION-GEN
скрипт (ниже), моя версия строки для приведенного выше примера:
$ VERSION-GEN
version: 1.0-3-gee47
Если я изменю любой из отслеживаемых файлов, он будет выглядеть так:
$ VERSION-GEN
version: 1.0-3-gee47-mod
Вот моя слегка подправленная версия VERSION-GEN
, Обратите внимание, что ожидается, что теги, обозначающие версии, имеют вид v[0-9]* (например, v1.0 или v0.2 или v12.3.4 или v12.2-4feb2009 и т. Д.)
#!/bin/sh
# Tag revisions like this:
# $ git tag -a -m "Version 0.2" v0.2 HEAD
VF=VERSION-FILE
DEFAULT_VERSION=UKNOWN
LF='
'
# First see if there is a version file (included in release tarballs),
# then try git-describe, then default.
if test -d .git -o -f .git &&
VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
case "$VN" in
*$LF*) (exit 1) ;;
v[0-9]*)
git update-index -q --refresh
test -z "$(git diff-index --name-only HEAD --)" ||
VN="$VN-mod" ;;
esac
then
continue
#VN=$(echo "$VN" | sed -e 's/-/./g');
else
VN="$DEFAULT_VERSION"
fi
VN=$(expr "$VN" : v*'\(.*\)')
# Show the version to the user via stderr
echo >&2 "version: $VN"
# Parse the existing VERSION-FILE
if test -r $VF
then
VC=$(sed -e 's/^version: //' <$VF)
else
VC=unset
fi
# If version has changed, update VERSION-FILE
test "$VN" = "$VC" || {
echo "version: $VN" >$VF
echo >&2 "($VF updated)"
}