diff --git a/App/tools/driver.makefile b/App/tools/driver.makefile
index a009e5f902439828d4bc48216e6871e5a86a2d14..4c834e3996c99070657cab56330c81948b5676df 100644
--- a/App/tools/driver.makefile
+++ b/App/tools/driver.makefile
@@ -1,6 +1,6 @@
 # driver.makefile
 #
-# $Header: /cvs/G/DRV/misc/App/tools/driver.makefile,v 1.100 2014/12/10 14:15:29 zimoch Exp $
+# $Header: /cvs/G/DRV/misc/App/tools/driver.makefile,v 1.101 2015/06/22 07:42:01 zimoch Exp $
 #
 # This generic makefile compiles EPICS code (drivers, records, snl, ...)
 # for all installed EPICS versions in parallel.
@@ -83,7 +83,7 @@ DOCUEXT = txt html htm doc pdf ps tex dvi gif jpg png
 DOCUEXT += TXT HTML HTM DOC PDF PS TEX DVI GIF JPG PNG
 DOCUEXT += template db dbt subs subst substitutions script
 
-GLOBALPROJECTS = /PROJECTS/drivers/ /DRV/ /IOCMON/ /CRLOGIC/
+LOCALPROJECTS = /X/ /A/ /F/ /P/ /S/ /Z/
 
 #override config here
 -include ${MAKEHOME}/config
@@ -102,8 +102,9 @@ GLOBALPROJECTS = /PROJECTS/drivers/ /DRV/ /IOCMON/ /CRLOGIC/
 # User can overwrite USE_LIBVERSION in the Makefile.
 
 # Where are we in CVS (or in PWD if no CVS is around)?
-THISDIR := $(if $(wildcard CVS/Repository),$(shell cat CVS/Repository),${PWD})
-USE_LIBVERSION = $(if $(strip $(foreach d,${GLOBALPROJECTS},$(findstring $d,${THISDIR}))),YES,NO)
+THISDIR := $(if $(wildcard CVS/Repository),/$(shell cat CVS/Repository),${PWD})
+# Do not use versions on known local projects (IOC projects)
+USE_LIBVERSION := $(if $(strip $(foreach d,${LOCALPROJECTS},$(findstring $d,${THISDIR}))),NO,YES)
 
 # Some shortcuts
 MAKEVERSION = ${MAKE} -f ${USERMAKEFILE} LIBVERSION=${LIBVERSION}
@@ -121,6 +122,14 @@ REGISTRYFILE = ${PRJ}_registerRecordDeviceDriver.cpp
 EXPORTFILE = ${PRJ}_exportAddress.c
 SUBFUNCFILE = ${PRJ}_subRecordFunctions.dbd
 
+# Default target is "build" for all versions.
+# Don't install anything (different from default EPICS make rules)
+default: build
+
+IGNOREFILES = .cvsignore .gitignore
+${IGNOREFILES}:
+	@echo -e "O.*\n.cvsignore\n.gitignore" > $@
+        
 ifndef EPICSVERSION
 ## RUN 1
 # in source directory, first run
@@ -134,12 +143,14 @@ EPICS_VERSIONS_3.13 = $(filter 3.13.%,${BUILD_EPICS_VERSIONS})
 EPICS_VERSIONS_3.14 = $(filter 3.14.%,${BUILD_EPICS_VERSIONS})
 EPICS_VERSIONS_3.15 = $(filter 3.15.%,${BUILD_EPICS_VERSIONS})
 
+#check only what is needed to build the lib? But what is that?
 VERSIONCHECKFILES = ${SOURCES} ${DBDS} $(foreach v,3.13 3.14 3.15, ${SOURCES_$v} ${DBDS_$v})
-VERSIONCHECKCMD = ${MAKEHOME}/getVersion.tcl ${VERSIONCHECKFILES}
+VERSIONCHECKCMD = ${MAKEHOME}/getVersion.tcl ${VERSIONDEBUGFLAG} ${VERSIONCHECKFILES}
 LIBVERSION_YES = $(or $(filter-out test,$(shell ${VERSIONCHECKCMD} 2>/dev/null)),${USER},test)
 LIBVERSION_Yes = $(LIBVERSION_YES)
 LIBVERSION_yes = $(LIBVERSION_YES)
 LIBVERSION = ${LIBVERSION_${USE_LIBVERSION}}
+VERSIONDEBUGFLAG = $(if ${VERSIONDEBUG}, -d)
 
 # Default project name is name of current directory.
 # But don't use "src" or "snl", go up directory tree instead.
@@ -153,10 +164,6 @@ export OS_CLASS_LIST
 export ARCH_FILTER
 export EXCLUDE_ARCHS
 
-# Default target is "build" for all versions.
-# Don't install anything (different from default EPICS make rules)
-build::
-
 clean::
 	$(RMDIR) O.*
 #	find . -name "*~" -exec $(RM) {} \;
@@ -181,11 +188,12 @@ help:
 	@echo "  TEMPLATES        ()"
 	@echo "  DBDS             (*.dbd)"
 	@echo "  EXCLUDE_VERSIONS () [versions not to build, e.g. 3.14]"
-	@echo "  EXCLUDE_ARCHS    () [target architectures not to build, e.g. embeddedlinux]"
+	@echo "  EXCLUDE_ARCHS    () [target architectures not to build, e.g. eldk]"
+	@echo "  ARCH_FILTER      () [target architectures to build, e.g. eldk-%]"
 	@echo "  BUILDCLASSES     (vxWorks) [other choices: Linux]"
 
 # "make version" shows the version and why it is how it is.       
-version:
+version: ${IGNOREFILES}
 	@${VERSIONCHECKCMD}
 
 debug::
@@ -201,7 +209,7 @@ debug::
 	@echo "ARCH_FILTER = ${ARCH_FILTER}"
 
 # Loop over all EPICS versions for second run.
-build install uninstall install-headers install-doc install-templates debug::
+build install uninstall install-headers install-doc install-templates debug:: ${IGNOREFILES}
 	for VERSION in ${BUILD_EPICS_VERSIONS}; do \
 	${MAKEVERSION} EPICSVERSION=$$VERSION $@ || exit; done
 
@@ -405,16 +413,13 @@ endef
 
 $(foreach a,${CROSS_COMPILER_TARGET_ARCHS},$(foreach l,$(LINK_$a),$(eval $(call MAKELINKDIRS,$l,$a))))
 
-install build install-headers debug:: .cvsignore ${BUILDDIRS} ${LINKDIRS}
+install build install-headers debug:: ${BUILDDIRS} ${LINKDIRS}
 # Delete old build if INSTBASE has changed.
 	@for ARCH in ${CROSS_COMPILER_TARGET_ARCHS}; do \
             echo ${INSTBASE} | cmp -s O.${EPICSVERSION}_$$ARCH/INSTBASE - || $(RM) O.${EPICSVERSION}_$$ARCH/*; \
 	    ${MAKE} -C O.${EPICSVERSION}_$$ARCH -f ../${USERMAKEFILE} T_A=$$ARCH $@; \
 	done
 
-.cvsignore:
-	echo "O.* .cvsignore" > .cvsignore
-
 # No need to create O.${T_A} subdirectory here:
 uninstall install-doc install-templates::
 	@echo "MAKING EPICS VERSION R${EPICSVERSION}"
@@ -453,7 +458,7 @@ CFLAGS += ${EXTRA_CFLAGS}
 
 LIBVERSIONSTR = $(if ${LIBVERSION},-${LIBVERSION})
 TESTVERSION := $(shell echo "${LIBVERSION}" | grep -v -E "^[0-9]+\.[0-9]+\.[0-9]+\$$")
-PROJECTDBD=${if ${DBDFILES},${PRJ}${LIBVERSIONSTR}.dbd}
+PROJECTDBD=${if $(strip ${DBDFILES}),${PRJ}${LIBVERSIONSTR}.dbd}
 DEPFILE = ${PRJ}${LIBVERSIONSTR}.dep
 
 INSTALL_BIN = ${INSTALL_LOCATION}/${T_A}
@@ -632,9 +637,7 @@ LIBRARY_OBJS = ${LIBOBJS}
 
 # Handle registry stuff automagically if we have a dbd file.
 # See ${REGISTRYFILE} and ${EXPORTFILE} rules below.
-ifdef PROJECTDBD
-LIBOBJS += $(addsuffix $(OBJ),$(basename ${REGISTRYFILE} ${EXPORTFILE}))
-endif # PROJECTDBD
+LIBOBJS += $(if $(PROJECTDBD),$(addsuffix $(OBJ),$(basename ${REGISTRYFILE} ${EXPORTFILE})))
 
 endif # both, 3.13 and 3.14 from here
 
@@ -699,9 +702,20 @@ SRC_INCLUDES = $(addprefix -I, $(sort $(dir ${SRCS:%=../%} ${HDRS:%=../%})))
 GENERIC_SRC_INCLUDES = $(SRC_INCLUDES)
 
 EXPANDARG = -3.14
-ifneq ($(words $(filter %.c %.cc %.C %.cpp, $(SRCS))),0)
-DBDFILES+=${SUBFUNCFILE}
-endif
+
+# Create dbd file with references to all subRecord functions
+# Problem: functions may be commented out. Better preprocess, but then generate headers first.
+
+#define maksubfuncfile
+#/static/ {static=1} \
+#/\([\t ]*(struct)?[\t ]*(genSub|sub|aSub)Record[\t ]*\*[\t ]*\w+[\t ]*\)/ { \
+#    match ($$0,/(\w+)[\t ]*\([\t ]*(struct)?[\t ]*\w+Record[\t ]*\*[\t ]*\w+[\t ]*\)/, a); \
+#    n=a[1];if(!static && !f[n]){f[n]=1;print "function (" n ")"}} \
+#/[;{}]/ {static=0}
+#endef 
+#
+#$(shell awk '$(maksubfuncfile)' $(addprefix ../,$(filter %.c %.cc %.C %.cpp, $(SRCS))) > ${SUBFUNCFILE})
+#DBDFILES += $(if $(shell cat ${SUBFUNCFILE}),${SUBFUNCFILE})
 
 # snc location in 3.14
 #-include ${SNCSEQ}/configure/RULES_BUILD # incompatible to 3.15
@@ -835,14 +849,6 @@ SNCFLAGS += -r
 	${LN} $< $(*F).gt
 	gdc $(*F).gt
 
-# Create dbd file with references to all subRecord functions
-${SUBFUNCFILE}: $(filter %.c %.cc %.C %.cpp, $(SRCS))
-	awk '/static/ {static=1} \
-                /\([\t ]*(struct)?[\t ]*(genSub|sub|aSub)Record[\t ]*\*[\t ]*\w+[\t ]*\)/ {\
-		match ($$0,/(\w+)[\t ]*\([\t ]*(struct)?[\t ]*\w+Record[\t ]*\*[\t ]*\w+[\t ]*\)/, a);\
-		n=a[1];if(!static && !f[n]){f[n]=1;print "function (" n ")"}}\
-                /[;{}]/ {static=0}' $^ > $@
-
 # The original 3.13 munching rule does not really work well
 ifeq (${EPICS_BASETYPE},3.13)
 MUNCH=tclsh $(VX_DIR)/host/src/hutils/munch.tcl
diff --git a/App/tools/getVersion.tcl b/App/tools/getVersion.tcl
index f24fc11f06df9f4363a996de4a74e496e166f8dc..a263058379ad99ea4afed8bcdcb5875c6523fe9c 100755
--- a/App/tools/getVersion.tcl
+++ b/App/tools/getVersion.tcl
@@ -2,34 +2,45 @@
 
 package require Tclx
 
+set debug 0
+
 set global_context [scancontext create]
 set file_context [scancontext create]
 set skip_context [scancontext create]
 
+scanmatch $global_context {there is no version here} {
+    return
+}
+
+scanmatch $global_context {cvs status: failed} {
+    puts stderr "Error: $matchInfo(line)"
+    return
+}
+
 scanmatch $global_context {no such directory `(.*)'} {
-    puts stderr "checking directory $matchInfo(submatch0): so such directory  => version test"
+    puts stderr "checking directory $matchInfo(submatch0): so such directory"
     return
 }
 
-scanmatch $global_context {there is no version here} {
-    puts stderr "checking current directory: not in cvs => version test"
+scanmatch $global_context {cvs [status aborted]: there is no version here} {
     return
 }
 
 scanmatch $global_context {^File: .*Up-to-date} {
     set file [lindex $matchInfo(line) 1]
     puts -nonewline stderr "checking $file: "
+    catch {unset major minor patch}
     scanfile $file_context $matchInfo(handle)
-    if {![info exists major($file)]} {
+    if {![info exists major]} {
         puts stderr "revision $rev($file) not tagged => version test"
         set version test
         continue
     }
-    puts stderr "revision $rev($file) tag $tag($file) => version $major($file).$minor($file).$patch($file)"
+    puts stderr "revision $rev($file) tag $tag($file) => version $major.$minor.$patch"
     if {![info exists version]} {
-        set version $major($file).$minor($file).$patch($file)
+        set version $major.$minor.$patch
     } else {
-        if ![cequal $major($file).$minor($file).$patch($file) $version] {
+        if ![cequal $major.$minor.$patch $version] {
             set version test
             continue
         }
@@ -56,18 +67,18 @@ scanmatch $file_context {Working revision:} {
 }
 
 scanmatch $file_context {Sticky Tag:.*_([0-9]+)_([0-9]+)_([0-9]+)[ \t]+\(revision: } {
-    set major($file) $matchInfo(submatch0)
-    set minor($file) $matchInfo(submatch1)
-    set patch($file) $matchInfo(submatch2)
+    set major $matchInfo(submatch0)
+    set minor $matchInfo(submatch1)
+    set patch $matchInfo(submatch2)
     set tag($file) "[lindex $matchInfo(line) 2] (sticky)"
     scanfile $skip_context $matchInfo(handle)
     return
 }
 
 scanmatch $file_context {Sticky Tag:.*_([0-9]+)_([0-9]+)[ \t]+\(revision: } {
-    set major($file) $matchInfo(submatch0)
-    set minor($file) $matchInfo(submatch1)
-    set patch($file) 0
+    set major $matchInfo(submatch0)
+    set minor $matchInfo(submatch1)
+    set patch 0
     set tag($file) "[lindex $matchInfo(line) 2] (sticky)"
     scanfile $skip_context $matchInfo(handle)
     return
@@ -78,13 +89,13 @@ scanmatch $file_context {_([0-9]+)_([0-9]+)(_([0-9]+))?[ \t]+\(revision: ([\.0-9
         set Major $matchInfo(submatch0)
         set Minor $matchInfo(submatch1)
         set Patch [expr $matchInfo(submatch3) + 0]
-        if {![info exists major($file)] ||
-            $Major>$major($file) ||
-            ($Major==$major($file) && ($Minor>$minor($file)
-                || ($Minor==$minor($file) && $Patch>$patch($file))))} {
-            set major($file) $Major
-            set minor($file) $Minor
-            set patch($file) $Patch
+        if {![info exists major] ||
+            $Major>$major ||
+            ($Major==$major && ($Minor>$minor
+                || ($Minor==$minor && $Patch>$patch)))} {
+            set major $Major
+            set minor $Minor
+            set patch $Patch
             set tag($file) [lindex $matchInfo(line) 0]
         }
     }
@@ -98,26 +109,132 @@ scanmatch $file_context {=================} {
     return
 }
 
-# cvs bug: calling cvs status for files in other directories spoils status
-# information for local files.
-# fix: check local and non local files separately
+set git_context [scancontext create]
 
-set cvsstatus [open "|cvs status -l -v 2>@ stdout"]
-scanfile $global_context $cvsstatus
-if [catch {close $cvsstatus}] {set version test}
+scanmatch $git_context {fatal: Not a git repository} {
+    return
+}
 
-set files {}
-foreach file $argv {
-    if {[file tail $file] != $file} {
-        lappend files $file
-    }
+scanmatch $git_context {^\?\? .*} {
+    set file [lindex $matchInfo(line) 1]
+    puts stderr "$file: not in git => version test"
+    set version test
+    continue
+}     
+
+scanmatch $git_context {^ M .*} {
+    set file [lindex $matchInfo(line) 1]
+    puts stderr "$file: locally modified => version test"
+    set version test
+    continue
+}     
+
+scanmatch $git_context {^D  .*} {
+    set file [lindex $matchInfo(line) 1]
+    puts stderr "$file: deleted (or renamed) but not committed => version test"
+    set version test
+    continue
+}     
+
+scanmatch $git_context {^ D .*} {
+    set file [lindex $matchInfo(line) 1]
+    puts stderr "$file: locally deleted => version test"
+    set version test
+    continue
+}     
+
+scanmatch $git_context {^([ MADRCU][ MADRCU]) .*} {
+    set file [lindex $matchInfo(line) 1]
+    puts stderr "$file: $matchInfo(submatch0) (whatever that means) => version test"
+    set version test
+    continue
+}     
+
+scanmatch $git_context {fatal: No names found} {
+    puts stderr "no tag on this version => version test"
+    set version test
+}
+
+scanmatch $git_context {([0-9]+)[_.]([0-9]+)([_.]([0-9]+))?$} {
+    set major $matchInfo(submatch0)
+    set minor $matchInfo(submatch1)
+    set patch [expr $matchInfo(submatch3) + 0]
+    set version $major.$minor.$patch
+    puts stderr "checking tag $matchInfo(line) => version $version"
+}
+
+scanmatch $git_context {(.*[0-9]+[_.][0-9]+([_.][0-9]+)?)-([0-9]+)-g} {
+    set version test
+    puts stderr "tag $matchInfo(submatch0) is $matchInfo(submatch2) commits old => version test"
+}
+
+if {[lindex $argv 0] == "-d"} {
+    set debug 1
+    set argv [lrange $argv 1 end]
 }
-if [llength $files] {
-    set cvsstatus [open "|cvs status -l -v $files 2>@ stdout"]
-    scanfile $global_context $cvsstatus
-    if [catch {close $cvsstatus}] {set version test}
+
+# Check all files in top directory and all files specified explicitly in subdirectories
+
+set topfiles [glob -nocomplain GNUmakefile makefile Makefile *.c *.cc *.cpp *.h *.dbd *.st *.stt *.gt]
+
+if {$debug} {
+    puts stderr "checking $topfiles $argv"
 }
-if {![info exists version]} {set version test}
-puts $version
 
-# $Header: /cvs/G/DRV/misc/App/tools/getVersion.tcl,v 1.3 2010/08/03 08:42:40 zimoch Exp $
+
+if {[catch {
+    # fails if we have no git:
+    set statusinfo [open "|git status --porcelain $topfiles $argv 2>@ stdout"]
+    scanfile $git_context $statusinfo
+    # fails if this is no git repo
+    close $statusinfo
+    
+    if [info exists version] {
+        puts $version
+        exit
+    }   
+    
+    set statusinfo [open "|git describe --tags HEAD 2>@ stdout"]
+    scanfile $git_context $statusinfo
+    catch {close $statusinfo}
+
+    if ![info exists version] {
+        puts stderr "Could not find out version tag => version test"
+        set version test
+    }
+    puts $version
+    exit
+}] && $debug} { puts stderr "git: $errorInfo" }
+
+
+if {[catch {
+# cvs bug: calling cvs status for files in other directories spoils status
+# information for local files.
+# fix: check local and non local files separately
+
+    # fails if we have no cvs or server has a problem
+    set statusinfo [open "|cvs status -l -v $topfiles $argv 2>@ stdout"]
+    scanfile $global_context $statusinfo
+    # fails if this is no cvs repo
+    close $statusinfo
+
+#    set files {}
+#    foreach file $argv {
+#        if {[file tail $file] != $file} {
+#            lappend files $file
+#        }
+#    }
+#    if [llength $files] {
+#        set statusinfo [open "|cvs status -l -v $files 2>@ stdout"]
+#        scanfile $global_context $statusinfo
+#        close $statusinfo
+#    }
+
+    puts $version
+    exit
+}] && $debug} { puts stderr "cvs: $errorInfo" }
+
+puts stderr "No repository found => version test"
+puts "test"
+
+# $Header: /cvs/G/DRV/misc/App/tools/getVersion.tcl,v 1.4 2015/06/22 07:42:01 zimoch Exp $