Git fork

GIT-VERSION-GEN: fix overriding GIT_VERSION

GIT-VERSION-GEN tries to derive the version that Git is being built from
via multiple different sources in the following order:

1. A file called "version" in the source tree's root directory, if it
exists.

2. The current commit in case Git is built from a Git repository.

3. Otherwise, we use a fallback version stored in a variable which is
bumped whenever a new Git version is getting tagged.

It used to be possible to override the version by overriding the
`GIT_VERSION` Makefile variable (e.g. `make GIT_VERSION=foo`). This
worked somewhat by chance, only: `GIT-VERSION-GEN` would write the
actual Git version into `GIT-VERSION-FILE`, not the overridden value,
but when including the file into our Makefile we would not override the
`GIT_VERSION` variable because it has already been set by the user. And
because our Makefile used the variable to propagate the version to our
build tools instead of using `GIT-VERSION-FILE` the resulting build
artifacts used the overridden version.

But that subtle mechanism broke with 4838deab65 (Makefile: refactor
GIT-VERSION-GEN to be reusable, 2024-12-06) and subsequent commits
because the version information is not propagated via the Makefile
variable anymore, but instead via the files that `GIT-VERSION-GEN`
started to write. And as the script never knew about the `GIT_VERSION`
environment variable in the first place it uses one of the values listed
above instead of the overridden value.

Fix this issue by making `GIT-VERSION-GEN` handle the case where
`GIT_VERSION` has been set via the environment.

Note that this requires us to introduce a new GIT_VERSION_OVERRIDE
variable that stores a potential user-provided value, either via the
environment or via "config.mak". Ideally we wouldn't need it and could
just continue to use GIT_VERSION for this. But unfortunately, Makefiles
will first include all sub-Makefiles before figuring out whether it
needs to re-make any of them [1]. Consequently, if there already is a
GIT-VERSION-FILE, we would have slurped in its value of GIT_VERSION
before we call GIT-VERSION-GEN, and because GIT-VERSION-GEN now uses
that value as an override it would mean that the first generated value
for GIT_VERSION will remain unchanged.

Furthermore we have to move the include for "GIT-VERSION-FILE" after the
includes for "config.mak" and related so that GIT_VERSION_OVERRIDE can
be set to the value provided by "config.mak".

[1]: https://www.gnu.org/software/make/manual/html_node/Remaking-Makefiles.html

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
992bc561 114494ae

+43 -29
+4
Documentation/Makefile
··· 181 181 -include ../config.mak.autogen 182 182 -include ../config.mak 183 183 184 + # Set GIT_VERSION_OVERRIDE such that version_gen knows to substitute 185 + # GIT_VERSION in case it was set by the user. 186 + GIT_VERSION_OVERRIDE := $(GIT_VERSION) 187 + 184 188 ifndef NO_MAN_BOLD_LITERAL 185 189 XMLTO_EXTRA += -m manpage-bold-literal.xsl 186 190 endif
+26 -22
GIT-VERSION-GEN
··· 27 27 GIT_CEILING_DIRECTORIES="$SOURCE_DIR/.." 28 28 export GIT_CEILING_DIRECTORIES 29 29 30 - # First see if there is a version file (included in release tarballs), 31 - # then try git-describe, then default. 32 - if test -f "$SOURCE_DIR"/version 33 - then 34 - VN=$(cat "$SOURCE_DIR"/version) || VN="$DEF_VER" 35 - elif { 36 - test -d "$SOURCE_DIR/.git" || 37 - test -d "${GIT_DIR:-.git}" || 38 - test -f "$SOURCE_DIR"/.git; 39 - } && 40 - VN=$(git -C "$SOURCE_DIR" describe --match "v[0-9]*" HEAD 2>/dev/null) && 41 - case "$VN" in 42 - *$LF*) (exit 1) ;; 43 - v[0-9]*) 44 - git -C "$SOURCE_DIR" update-index -q --refresh 45 - test -z "$(git -C "$SOURCE_DIR" diff-index --name-only HEAD --)" || 46 - VN="$VN-dirty" ;; 47 - esac 30 + if test -z "$GIT_VERSION" 48 31 then 49 - VN=$(echo "$VN" | sed -e 's/-/./g'); 50 - else 51 - VN="$DEF_VER" 32 + # First see if there is a version file (included in release tarballs), 33 + # then try git-describe, then default. 34 + if test -f "$SOURCE_DIR"/version 35 + then 36 + VN=$(cat "$SOURCE_DIR"/version) || VN="$DEF_VER" 37 + elif { 38 + test -d "$SOURCE_DIR/.git" || 39 + test -d "${GIT_DIR:-.git}" || 40 + test -f "$SOURCE_DIR"/.git; 41 + } && 42 + VN=$(git -C "$SOURCE_DIR" describe --match "v[0-9]*" HEAD 2>/dev/null) && 43 + case "$VN" in 44 + *$LF*) (exit 1) ;; 45 + v[0-9]*) 46 + git -C "$SOURCE_DIR" update-index -q --refresh 47 + test -z "$(git -C "$SOURCE_DIR" diff-index --name-only HEAD --)" || 48 + VN="$VN-dirty" ;; 49 + esac 50 + then 51 + VN=$(echo "$VN" | sed -e 's/-/./g'); 52 + else 53 + VN="$DEF_VER" 54 + fi 55 + 56 + GIT_VERSION=$(expr "$VN" : v*'\(.*\)') 52 57 fi 53 58 54 - GIT_VERSION=$(expr "$VN" : v*'\(.*\)') 55 59 GIT_BUILT_FROM_COMMIT=$(git -C "$SOURCE_DIR" rev-parse -q --verify HEAD 2>/dev/null) 56 60 GIT_DATE=$(git -C "$SOURCE_DIR" show --quiet --format='%as' 2>/dev/null) 57 61 if test -z "$GIT_USER_AGENT"
+12 -7
Makefile
··· 591 591 # 592 592 # Disable -pedantic compilation. 593 593 594 - GIT-VERSION-FILE: FORCE 595 - @OLD=$$(cat $@ 2>/dev/null || :) && \ 596 - $(call version_gen,"$(shell pwd)",GIT-VERSION-FILE.in,$@) && \ 597 - NEW=$$(cat $@ 2>/dev/null || :) && \ 598 - if test "$$OLD" != "$$NEW"; then echo "$$NEW" >&2; fi 599 - -include GIT-VERSION-FILE 600 - 601 594 # Set our default configuration. 602 595 # 603 596 # Among the variables below, these: ··· 1464 1457 ifdef DEVELOPER 1465 1458 include config.mak.dev 1466 1459 endif 1460 + 1461 + GIT-VERSION-FILE: FORCE 1462 + @OLD=$$(cat $@ 2>/dev/null || :) && \ 1463 + $(call version_gen,"$(shell pwd)",GIT-VERSION-FILE.in,$@) && \ 1464 + NEW=$$(cat $@ 2>/dev/null || :) && \ 1465 + if test "$$OLD" != "$$NEW"; then echo "$$NEW" >&2; fi 1466 + 1467 + # We need to set GIT_VERSION_OVERRIDE before including the version file as 1468 + # otherwise any user-provided value for GIT_VERSION would have been overridden 1469 + # already. 1470 + GIT_VERSION_OVERRIDE := $(GIT_VERSION) 1471 + -include GIT-VERSION-FILE 1467 1472 1468 1473 # what 'all' will build and 'install' will install in gitexecdir, 1469 1474 # excluding programs for built-in commands
+1
shared.mak
··· 122 122 # as arguments, in that order. 123 123 define version_gen 124 124 GIT_USER_AGENT="$(GIT_USER_AGENT)" \ 125 + GIT_VERSION="$(GIT_VERSION_OVERRIDE)" \ 125 126 $(SHELL_PATH) "$(1)/GIT-VERSION-GEN" "$(1)" "$(2)" "$(3)" 126 127 endef