1*53ee8cc1Swenshuai.xi#!/bin/sh 2*53ee8cc1Swenshuai.xi# 3*53ee8cc1Swenshuai.xi# This scripts adds local version information from the version 4*53ee8cc1Swenshuai.xi# control systems git, mercurial (hg) and subversion (svn). 5*53ee8cc1Swenshuai.xi# 6*53ee8cc1Swenshuai.xi# If something goes wrong, send a mail the kernel build mailinglist 7*53ee8cc1Swenshuai.xi# (see MAINTAINERS) and CC Nico Schottelius 8*53ee8cc1Swenshuai.xi# <nico-linuxsetlocalversion -at- schottelius.org>. 9*53ee8cc1Swenshuai.xi# 10*53ee8cc1Swenshuai.xi# 11*53ee8cc1Swenshuai.xi 12*53ee8cc1Swenshuai.xiusage() { 13*53ee8cc1Swenshuai.xi echo "Usage: $0 [--save-scmversion] [srctree]" >&2 14*53ee8cc1Swenshuai.xi exit 1 15*53ee8cc1Swenshuai.xi} 16*53ee8cc1Swenshuai.xi 17*53ee8cc1Swenshuai.xiscm_only=false 18*53ee8cc1Swenshuai.xisrctree=. 19*53ee8cc1Swenshuai.xiif test "$1" = "--save-scmversion"; then 20*53ee8cc1Swenshuai.xi scm_only=true 21*53ee8cc1Swenshuai.xi shift 22*53ee8cc1Swenshuai.xifi 23*53ee8cc1Swenshuai.xiif test $# -gt 0; then 24*53ee8cc1Swenshuai.xi srctree=$1 25*53ee8cc1Swenshuai.xi shift 26*53ee8cc1Swenshuai.xifi 27*53ee8cc1Swenshuai.xiif test $# -gt 0 -o ! -d "$srctree"; then 28*53ee8cc1Swenshuai.xi usage 29*53ee8cc1Swenshuai.xifi 30*53ee8cc1Swenshuai.xi 31*53ee8cc1Swenshuai.xiscm_version() 32*53ee8cc1Swenshuai.xi{ 33*53ee8cc1Swenshuai.xi local short 34*53ee8cc1Swenshuai.xi short=false 35*53ee8cc1Swenshuai.xi 36*53ee8cc1Swenshuai.xi cd "$srctree" 37*53ee8cc1Swenshuai.xi if test -e .scmversion; then 38*53ee8cc1Swenshuai.xi cat .scmversion 39*53ee8cc1Swenshuai.xi return 40*53ee8cc1Swenshuai.xi fi 41*53ee8cc1Swenshuai.xi if test "$1" = "--short"; then 42*53ee8cc1Swenshuai.xi short=true 43*53ee8cc1Swenshuai.xi fi 44*53ee8cc1Swenshuai.xi 45*53ee8cc1Swenshuai.xi # Check for git and a git repo. 46*53ee8cc1Swenshuai.xi if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then 47*53ee8cc1Swenshuai.xi 48*53ee8cc1Swenshuai.xi # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore 49*53ee8cc1Swenshuai.xi # it, because this version is defined in the top level Makefile. 50*53ee8cc1Swenshuai.xi if [ -z "`git describe --exact-match 2>/dev/null`" ]; then 51*53ee8cc1Swenshuai.xi 52*53ee8cc1Swenshuai.xi # If only the short version is requested, don't bother 53*53ee8cc1Swenshuai.xi # running further git commands 54*53ee8cc1Swenshuai.xi if $short; then 55*53ee8cc1Swenshuai.xi echo "+" 56*53ee8cc1Swenshuai.xi return 57*53ee8cc1Swenshuai.xi fi 58*53ee8cc1Swenshuai.xi # If we are past a tagged commit (like 59*53ee8cc1Swenshuai.xi # "v2.6.30-rc5-302-g72357d5"), we pretty print it. 60*53ee8cc1Swenshuai.xi if atag="`git describe 2>/dev/null`"; then 61*53ee8cc1Swenshuai.xi echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' 62*53ee8cc1Swenshuai.xi 63*53ee8cc1Swenshuai.xi # If we don't have a tag at all we print -g{commitish}. 64*53ee8cc1Swenshuai.xi else 65*53ee8cc1Swenshuai.xi printf '%s%s' -g $head 66*53ee8cc1Swenshuai.xi fi 67*53ee8cc1Swenshuai.xi fi 68*53ee8cc1Swenshuai.xi 69*53ee8cc1Swenshuai.xi # Is this git on svn? 70*53ee8cc1Swenshuai.xi if git config --get svn-remote.svn.url >/dev/null; then 71*53ee8cc1Swenshuai.xi printf -- '-svn%s' "`git svn find-rev $head`" 72*53ee8cc1Swenshuai.xi fi 73*53ee8cc1Swenshuai.xi 74*53ee8cc1Swenshuai.xi # Update index only on r/w media 75*53ee8cc1Swenshuai.xi [ -w . ] && git update-index --refresh --unmerged > /dev/null 76*53ee8cc1Swenshuai.xi 77*53ee8cc1Swenshuai.xi # Check for uncommitted changes 78*53ee8cc1Swenshuai.xi if git diff-index --name-only HEAD | grep -v "^scripts/package" \ 79*53ee8cc1Swenshuai.xi | read dummy; then 80*53ee8cc1Swenshuai.xi printf '%s' -dirty 81*53ee8cc1Swenshuai.xi fi 82*53ee8cc1Swenshuai.xi 83*53ee8cc1Swenshuai.xi # All done with git 84*53ee8cc1Swenshuai.xi return 85*53ee8cc1Swenshuai.xi fi 86*53ee8cc1Swenshuai.xi 87*53ee8cc1Swenshuai.xi # Check for mercurial and a mercurial repo. 88*53ee8cc1Swenshuai.xi if test -d .hg && hgid=`hg id 2>/dev/null`; then 89*53ee8cc1Swenshuai.xi # Do we have an tagged version? If so, latesttagdistance == 1 90*53ee8cc1Swenshuai.xi if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then 91*53ee8cc1Swenshuai.xi id=`hg log -r . --template '{latesttag}'` 92*53ee8cc1Swenshuai.xi printf '%s%s' -hg "$id" 93*53ee8cc1Swenshuai.xi else 94*53ee8cc1Swenshuai.xi tag=`printf '%s' "$hgid" | cut -d' ' -f2` 95*53ee8cc1Swenshuai.xi if [ -z "$tag" -o "$tag" = tip ]; then 96*53ee8cc1Swenshuai.xi id=`printf '%s' "$hgid" | sed 's/[+ ].*//'` 97*53ee8cc1Swenshuai.xi printf '%s%s' -hg "$id" 98*53ee8cc1Swenshuai.xi fi 99*53ee8cc1Swenshuai.xi fi 100*53ee8cc1Swenshuai.xi 101*53ee8cc1Swenshuai.xi # Are there uncommitted changes? 102*53ee8cc1Swenshuai.xi # These are represented by + after the changeset id. 103*53ee8cc1Swenshuai.xi case "$hgid" in 104*53ee8cc1Swenshuai.xi *+|*+\ *) printf '%s' -dirty ;; 105*53ee8cc1Swenshuai.xi esac 106*53ee8cc1Swenshuai.xi 107*53ee8cc1Swenshuai.xi # All done with mercurial 108*53ee8cc1Swenshuai.xi return 109*53ee8cc1Swenshuai.xi fi 110*53ee8cc1Swenshuai.xi 111*53ee8cc1Swenshuai.xi # Check for svn and a svn repo. 112*53ee8cc1Swenshuai.xi if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then 113*53ee8cc1Swenshuai.xi rev=`echo $rev | awk '{print $NF}'` 114*53ee8cc1Swenshuai.xi printf -- '-svn%s' "$rev" 115*53ee8cc1Swenshuai.xi 116*53ee8cc1Swenshuai.xi # All done with svn 117*53ee8cc1Swenshuai.xi return 118*53ee8cc1Swenshuai.xi fi 119*53ee8cc1Swenshuai.xi} 120*53ee8cc1Swenshuai.xi 121*53ee8cc1Swenshuai.xicollect_files() 122*53ee8cc1Swenshuai.xi{ 123*53ee8cc1Swenshuai.xi local file res 124*53ee8cc1Swenshuai.xi 125*53ee8cc1Swenshuai.xi for file; do 126*53ee8cc1Swenshuai.xi case "$file" in 127*53ee8cc1Swenshuai.xi *\~*) 128*53ee8cc1Swenshuai.xi continue 129*53ee8cc1Swenshuai.xi ;; 130*53ee8cc1Swenshuai.xi esac 131*53ee8cc1Swenshuai.xi if test -e "$file"; then 132*53ee8cc1Swenshuai.xi res="$res$(cat "$file")" 133*53ee8cc1Swenshuai.xi fi 134*53ee8cc1Swenshuai.xi done 135*53ee8cc1Swenshuai.xi echo "$res" 136*53ee8cc1Swenshuai.xi} 137*53ee8cc1Swenshuai.xi 138*53ee8cc1Swenshuai.xiif $scm_only; then 139*53ee8cc1Swenshuai.xi if test ! -e .scmversion; then 140*53ee8cc1Swenshuai.xi res=$(scm_version) 141*53ee8cc1Swenshuai.xi echo "$res" >.scmversion 142*53ee8cc1Swenshuai.xi fi 143*53ee8cc1Swenshuai.xi exit 144*53ee8cc1Swenshuai.xifi 145*53ee8cc1Swenshuai.xi 146*53ee8cc1Swenshuai.xiif test -e include/config/auto.conf; then 147*53ee8cc1Swenshuai.xi . include/config/auto.conf 148*53ee8cc1Swenshuai.xielse 149*53ee8cc1Swenshuai.xi echo "Error: kernelrelease not valid - run 'make prepare' to update it" 150*53ee8cc1Swenshuai.xi exit 1 151*53ee8cc1Swenshuai.xifi 152*53ee8cc1Swenshuai.xi 153*53ee8cc1Swenshuai.xi# localversion* files in the build and source directory 154*53ee8cc1Swenshuai.xires="$(collect_files localversion*)" 155*53ee8cc1Swenshuai.xiif test ! "$srctree" -ef .; then 156*53ee8cc1Swenshuai.xi res="$res$(collect_files "$srctree"/localversion*)" 157*53ee8cc1Swenshuai.xifi 158*53ee8cc1Swenshuai.xi 159*53ee8cc1Swenshuai.xi# CONFIG_LOCALVERSION and LOCALVERSION (if set) 160*53ee8cc1Swenshuai.xires="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}" 161*53ee8cc1Swenshuai.xi 162*53ee8cc1Swenshuai.xi# scm version string if not at a tagged commit 163*53ee8cc1Swenshuai.xiif test "$CONFIG_LOCALVERSION_AUTO" = "y"; then 164*53ee8cc1Swenshuai.xi # full scm version string 165*53ee8cc1Swenshuai.xi res="$res$(scm_version)" 166*53ee8cc1Swenshuai.xielse 167*53ee8cc1Swenshuai.xi # append a plus sign if the repository is not in a clean 168*53ee8cc1Swenshuai.xi # annotated or signed tagged state (as git describe only 169*53ee8cc1Swenshuai.xi # looks at signed or annotated tags - git tag -a/-s) and 170*53ee8cc1Swenshuai.xi # LOCALVERSION= is not specified 171*53ee8cc1Swenshuai.xi if test "${LOCALVERSION+set}" != "set"; then 172*53ee8cc1Swenshuai.xi scm=$(scm_version --short) 173*53ee8cc1Swenshuai.xi res="$res${scm:++}" 174*53ee8cc1Swenshuai.xi fi 175*53ee8cc1Swenshuai.xifi 176*53ee8cc1Swenshuai.xi 177*53ee8cc1Swenshuai.xiecho "$res" 178