summaryrefslogtreecommitdiff
path: root/scripts/setlocalversion
blob: 8922669cd142708759b81316eeb9cd59725bd760 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/sh
#
# This scripts adds local version information from the version
# control systems git, mercurial (hg) and subversion (svn).
# <nico-linuxsetlocalversion -at- schottelius.org>.
#
# This script comes from linux kernel


usage() {
	echo "Usage: $0 [--save-scmversion] [srctree]" >&2
	exit 1
}

scmversion_print() {
	scm_only=false
	srctree=.
	if test "$1" = "--save-scmversion"; then
		scm_only=true
		shift
	fi
	if test $# -gt 0; then
		srctree=$1
		shift
	fi
	if test $# -gt 0 -o ! -d "$srctree"; then
		usage
	fi

	local short
	short=false

	cd "$srctree"
	if test -e .scmversion; then
		cat .scmversion
		return
	fi
	if test "$1" = "--short"; then
		short=true
	fi

	# Check for git and a git repo.
	if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then

		# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
		# it, because this version is defined in the top level Makefile.
		if [ -z "`git describe --exact-match 2>/dev/null`" ]; then

			# If only the short version is requested, don't bother
			# running further git commands
			if $short; then
				echo "+"
				return
			fi
			# If we are past a tagged commit (like
			# "v2.6.30-rc5-302-g72357d5"), we pretty print it.
			if atag="`git describe 2>/dev/null`"; then
				echo "$atag" | awk -F- '{printf("%05d-%s", $(NF-1),$(NF))}'

			# If we don't have a tag at all we print -g{commitish}.
			else
				printf '%s%s' -g $head
			fi
		fi

		# Is this git on svn?
		if git config --get svn-remote.svn.url >/dev/null; then
			printf -- '-svn%s' "`git svn find-rev $head`"
		fi

		# Update index only on r/w media
		[ -w . ] && git update-index --refresh --unmerged > /dev/null

		# Check for uncommitted changes
		if git diff-index --name-only HEAD | grep -v "^scripts/package" \
		    | read dummy; then
			printf '%s' -dirty
		fi

		# All done with git
		return
	fi

	# Check for mercurial and a mercurial repo.
	if test -d .hg && hgid=`hg id 2>/dev/null`; then
		tag=`printf '%s' "$hgid" | cut -s -d' ' -f2`

		# Do we have an untagged version?
		if [ -z "$tag" -o "$tag" = tip ]; then
			id=`printf '%s' "$hgid" | sed 's/[+ ].*//'`
			printf '%s%s' -hg "$id"
		fi

		# Are there uncommitted changes?
		# These are represented by + after the changeset id.
		case "$hgid" in
			*+|*+\ *) printf '%s' -dirty ;;
		esac

		# All done with mercurial
		return
	fi

	# Check for svn and a svn repo.
	if rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then
		rev=`echo $rev | awk '{print $NF}'`
		printf -- 'svn%s' "$rev"

		# All done with svn
		return
	fi
}
cd "${1:-.}" || usage
scmversion_print