Skip to content

Commit 548b8b5

Browse files
Villemoesmasahir0y
authored andcommitted
scripts/setlocalversion: make git describe output more reliable
When building for an embedded target using Yocto, we're sometimes observing that the version string that gets built into vmlinux (and thus what uname -a reports) differs from the path under /lib/modules/ where modules get installed in the rootfs, but only in the length of the -gabc123def suffix. Hence modprobe always fails. The problem is that Yocto has the concept of "sstate" (shared state), which allows different developers/buildbots/etc. to share build artifacts, based on a hash of all the metadata that went into building that artifact - and that metadata includes all dependencies (e.g. the compiler used etc.). That normally works quite well; usually a clean build (without using any sstate cache) done by one developer ends up being binary identical to a build done on another host. However, one thing that can cause two developers to end up with different builds [and thus make one's vmlinux package incompatible with the other's kernel-dev package], which is not captured by the metadata hashing, is this `git describe`: The output of that can be affected by (1) git version: before 2.11 git defaulted to a minimum of 7, since 2.11 (git.git commit e6c587) the default is dynamic based on the number of objects in the repo (2) hence even if both run the same git version, the output can differ based on how many remotes are being tracked (or just lots of local development branches or plain old garbage) (3) and of course somebody could have a core.abbrev config setting in ~/.gitconfig So in order to avoid `uname -a` output relying on such random details of the build environment which are rather hard to ensure are consistent between developers and buildbots, make sure the abbreviated sha1 always consists of exactly 12 hex characters. That is consistent with the current rule for -stable patches, and is almost always enough to identify the head commit unambigously - in the few cases where it does not, the v5.4.3-00021- prefix would certainly nail it down. Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
1 parent 87de84c commit 548b8b5

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

scripts/setlocalversion

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ scm_version()
4545

4646
# Check for git and a git repo.
4747
if test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
48-
head=$(git rev-parse --verify --short HEAD 2>/dev/null); then
48+
head=$(git rev-parse --verify HEAD 2>/dev/null); then
4949

5050
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
5151
# it, because this version is defined in the top level Makefile.
@@ -59,11 +59,22 @@ scm_version()
5959
fi
6060
# If we are past a tagged commit (like
6161
# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
62-
if atag="$(git describe 2>/dev/null)"; then
63-
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}'
64-
65-
# If we don't have a tag at all we print -g{commitish}.
62+
#
63+
# Ensure the abbreviated sha1 has exactly 12
64+
# hex characters, to make the output
65+
# independent of git version, local
66+
# core.abbrev settings and/or total number of
67+
# objects in the current repository - passing
68+
# --abbrev=12 ensures a minimum of 12, and the
69+
# awk substr() then picks the 'g' and first 12
70+
# hex chars.
71+
if atag="$(git describe --abbrev=12 2>/dev/null)"; then
72+
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}'
73+
74+
# If we don't have a tag at all we print -g{commitish},
75+
# again using exactly 12 hex chars.
6676
else
77+
head="$(echo $head | cut -c1-12)"
6778
printf '%s%s' -g $head
6879
fi
6980
fi

0 commit comments

Comments
 (0)