Как бы вы включили текущий идентификатор фиксации в файлы проекта Git?

У меня есть статическое JavaScript + HTML-приложение с открытым исходным кодом, которое развертывается примерно в трех разных местах прямо сейчас, один на моем локальном компьютере, один на внутреннем сервере и один на стабильном внешнем сервере.

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

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

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

Какой самый чистый способ сделать это?

Ответ 1

Добавьте его в автоматическую систему развертывания.

Если ваше развертывание не автоматизировано, автоматизируйте его и добавьте туда. Затем вы удалили шаг.

Сделайте его более полезным "это было развернуто по дате x в y время из z репозитория". Хеш фиксации на самом деле не означает значительную часть не-разработчиков.

Ответ 2

В этом есть несколько тонкостей из-за природы 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", а commit sha1 начинается с ee47184 (я не уверен, почему они включают в себя ведущий "g" ).

Разработчики Git делают это еще на один шаг и также включают дополнительный бит, если рабочая копия изменена (незафиксирована). Для этого требуется еще несколько шагов, поэтому все они завернуты в script, они называют VERSION-GEN. При запуске он выводит строку версии на стандартный вывод, а также создает файл VERSION-FILE (при этом script осторожно не касается этого файла, если версия не изменилась, поэтому он подходит для построения). Затем вы можете включить этот VERSION-FILE файл в исходный код, файлы справки и т.д.

Используя мой пример VERSION-GEN script (ниже), моя строка версии для приведенного выше примера:

$ 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)"
}