diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php
index fd1f6db67e2d5422b8b397ef3ba1aaf13a6acfdb..66999944b3a537a9543de9cf4f5e68fe68f25c7a 100644
--- a/public_html/deployment/classes/vcs.git.class.php
+++ b/public_html/deployment/classes/vcs.git.class.php
@@ -44,7 +44,7 @@ class vcs implements iVcs {
     private $_aRemoteBranches = array();
 
     /**
-     * name of the remote branch to access
+     * name of the default remote branch to access
      * @var type 
      */
     private $_sCurrentBranch = "origin/master";
@@ -55,6 +55,7 @@ class vcs implements iVcs {
      */
     public function __construct($aRepoConfig = array()) {
         $this->setConfig($aRepoConfig);
+        $this->getRemoteBranches(); // to fill the cache
     }
 
     /**
@@ -82,21 +83,38 @@ class vcs implements iVcs {
         $this->_aCfg = $aRepoConfig;
 
         // define temp dir
-        $this->_sTempDir = $this->_aCfg["url"];
-        $this->_sTempDir = preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir);
-        $this->_sTempDir = (getenv("temp") ? getenv("temp") : "/tmp") . '/checkout_vcsgit_' . $this->_sTempDir . "/";
+        $this->_setTempdir();
         $this->_sKeyfile = $this->_aCfg["dataDir"] . "/sshkeys/" . $this->_aCfg["auth"];
         $this->_sWrapper = $this->_aCfg["appRootDir"] . "/shellscripts/gitsshwrapper.sh";
 
         return $this->_aCfg = $aRepoConfig;
     }
 
+    private function _setTempdir() {
+        $this->_sTempDir = $this->_aCfg["url"];
+        $this->_sTempDir = preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir);
+        $this->_sTempDir = (getenv("temp") ? getenv("temp") : "/tmp") . '/checkout_vcsgit_' . $this->_sTempDir . '/';
+        $this->_sTempDir .= preg_replace('/[\@\.\:\/]/', '_', $this->_sCurrentBranch) . '/';
+
+        if (!file_exists($this->_sTempDir . ".git") || true) {
+            $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+            $sGitCmd.='mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
+            $sGitCmd.='git init >/dev/null && ';
+            $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 && ';
+            // $sGitCmd='time ('.$sGitCmd.')';
+            exec($sGitCmd, $aOutput, $iRc);
+        }
+        return $this->_sTempDir;
+    }
+
     /**
      * set the current branch
      * @param string $sBranchname  name of the branch
      */
     public function setCurrentBranch($sBranchname) {
-        return $this->_sCurrentBranch = $sBranchname;
+        $this->_sCurrentBranch = $sBranchname;
+        $this->_setTempdir();
+        return $this->_sCurrentBranch;
     }
 
     /**
@@ -140,24 +158,23 @@ class vcs implements iVcs {
         return $this->_aCfg["type"];
     }
 
-    
-    private function _getNameOfCacheModule(){
-        $sReturn="git".$this->getUrl();
-        $sReturn=preg_replace('/([^0-9a-z])/i', "", $sReturn);
-        // echo "DEBUG: getNameOfCacheModule $sReturn<br>";
-        return $sReturn;
+    /**
+     * get a nice name for a cache module based on repo url
+     * @return type
+     */
+    private function _getNameOfCacheModule() {
+        return preg_replace('/([^0-9a-z])/i', "", $this->getUrl());
     }
+
     /**
      * cleanup cache data for this project (revisions, list of branches+tags)
      * @return bool
      */
-    private function _cleanupCache(){
+    private function _cleanupCache($iAge) {
         require_once 'cache.class.php';
-        $oCache=new AhCache($this->_getNameOfCacheModule());
-        return $oCache->cleanup();
+        $oCache = new AhCache($this->_getNameOfCacheModule());
+        return $oCache->cleanup((int)$iAge);
     }
-            
-
 
     /**
      * read remote repository and get an array with names and revisions of 
@@ -166,61 +183,68 @@ class vcs implements iVcs {
      * @param bool $bForceNoCache  flag to overrde cache
      * @return array
      */
-    private function _fetchRemoteBranches($bForceNoCache=false) {
+    private function _fetchRemoteBranches($bForceNoCache = false) {
         $aReturn = array();
-        
-        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+
         if (!$this->getUrl()) {
             return false;
         }
-        $iTtl=300; // cache for 5 min
+
+        $iTtl = 300; // cache for 5 min
         require_once 'cache.class.php';
-        $oCache=new AhCache($this->_getNameOfCacheModule(), "RemoteBranches");
-        if ($oCache->isExpired() || $bForceNoCache){
-            if (!file_exists($this->_sTempDir . ".git")) {
-                $sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
+        $oCache = new AhCache($this->_getNameOfCacheModule(), "RemoteBranches");
+
+        // list of cached branch keys
+        $aKeysToDelete = array();
+        if ($oCache->isExpired() || $bForceNoCache) {
+            $sWorkdir = dirname($this->_sTempDir) . '/fetchRemoteBranches/';
+            $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+            if (!file_exists($sWorkdir . ".git")) {
+                $sGitCmd.='mkdir -p "' . $sWorkdir . '" && cd "' . $sWorkdir . '" && ';
                 $sGitCmd.='git init >/dev/null && ';
                 $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 && ';
             } else {
-                $sGitCmd.='cd "' . $this->_sTempDir . '" 2>&1 && ';
+                $sGitCmd.='cd "' . $sWorkdir . '" 2>&1 && ';
             }
-            // $sGitCmd.='git branch -r ; ';
-            $sGitCmd.='git ls-remote --heads origin 2>&1 ; git ls-remote --tags origin 2>&1 ';
+            $sGitCmd.='git ls-remote --heads --tags origin 2>&1 ;';
             exec($sGitCmd, $aOutput, $iRc);
             if ($iRc == 0) {
-                foreach ($aOutput as $sBranch) {
-                    $aTmp = explode("\t", $sBranch);
 
-                    $aBranch = explode("/", $aTmp[1]);
+                // use cache that getCommitmessageByBranch can access it
+                $this->_aRemoteBranches = $oCache->read();
+
+                foreach ($aOutput as $sBranchLine) {
+                    $aTmp = explode("\t", $sBranchLine);
 
+                    $aBranch = explode("/", $aTmp[1]);
                     $sBranch = array_pop($aBranch);
-                    
+                    $sRevision = $aTmp[0];
+
                     // skip dereferences
                     // http://stackoverflow.com/questions/15472107/when-listing-git-ls-remote-why-theres-after-the-tag-name
-                    if (!preg_match('/\^\{\}$/', $sBranch)){
+                    if (!preg_match('/\^\{\}$/', $sBranch)) {
                         $sType = array_pop($aBranch);
-                        if ($sType == "heads") {
-                            $sBranch = "origin/" . $sBranch;
-                        }
+                        $sName = ($sType == "heads") ? "origin/" . $sBranch : $sBranch;
+                        $sBranchKey = $sName;
 
-                        $aReturn[] = array(
+                        $sMessage = $this->getCommitmessageByBranch($sName, $sRevision);
+                        $aReturn[$sBranchKey] = array(
                             // 'debug'=> $aTmp,
-                            'revision' => $aTmp[0],
-                            'name' => $sBranch,
+                            'revision' => $sRevision,
+                            'name' => $sName,
                             'label' => $sType . ': ' . $sBranch,
-                            'type' => $sType
+                            'type' => $sType,
+                            'message' => $sMessage
                         );
                     }
                 }
-                // echo "DEBUG: refresh cache for branches and tags <br>";
-                $oCache->write($aReturn, $iTtl); 
+                $this->_aRemoteBranches = $aReturn;
+                $oCache->write($aReturn, $iTtl);
             }
         } else {
-            // echo "DEBUG: using cache for branches and tags <br>";
-            $aReturn=$oCache->read(); 
+            $this->_aRemoteBranches = $oCache->read();
         }
-        $this->_aRemoteBranches = $aReturn;
-        return $aReturn;
+        return $this->_aRemoteBranches;
     }
 
     /**
@@ -229,27 +253,70 @@ class vcs implements iVcs {
      */
     public function getRemoteBranches() {
         if (!$this->_aRemoteBranches) {
-            $this->_aRemoteBranches = $this->_fetchRemoteBranches();
+            $this->_fetchRemoteBranches();
         }
         return $this->_aRemoteBranches;
     }
 
     /**
-     * get current revision and log message from remote repository
+     * get current revision and commit message from remote repository
      * @see $this::getRevision
      * @return array
      */
     public function getRepoRevision() {
-        return $this->getRevision(false);
+        $sMessage = $this->getCommitmessageByBranch();
+        if ($sMessage) {
+            $aReturn = array(
+                'branch' => $this->_sCurrentBranch,
+                'revision' => $this->_aRemoteBranches[$this->_sCurrentBranch]['revision'],
+                'message' => $sMessage,
+            );
+        } else {
+            $aReturn = $this->getRevision(false);
+        }
+        return $aReturn;
     }
 
     /**
-     * get current revision and log message from an existing directory or a
+     * get a commit message of a given branch
+     * @param string  $sBranch          name of a branch
+     * @param string  $sVerifyRevision  optional: verify if this revision is the newsest
+     * @return string
+     */
+    public function getCommitmessageByBranch($sBranch = false, $sVerifyRevision = false) {
+        if (!$sBranch) {
+            $sBranch = $this->_sCurrentBranch;
+        }
+        // try to get infos from the cache
+        if (
+                (array_key_exists($sBranch, $this->_aRemoteBranches) && $sVerifyRevision && $this->_aRemoteBranches[$sBranch]['revision'] == $sVerifyRevision
+                ) ||
+                (array_key_exists($sBranch, $this->_aRemoteBranches) && !$sVerifyRevision
+                )
+        ) {
+            // it is up to date - doing nothing
+            return $this->_aRemoteBranches[$sBranch]['message'];
+        }
+        // ok, then I need to read it
+        if ($this->_sCurrentBranch != $sBranch) {
+            $sSaveBranch = $this->_sCurrentBranch;
+            $this->setCurrentBranch($sBranch);
+            $a = $this->getRevision(false);
+            $this->setCurrentBranch($sSaveBranch);
+        } else {
+            $a = $this->getRevision(false);
+        }
+        return $a['message'];
+    }
+
+    /**
+     * get current revision and commit message from an existing directory or a
      * remote repository
      * the return will fill $this->_aData["phases"]["source"] in project class
      * (array keys are revision, message or error)
      *    if ok:
      *       array(
+     *          "branch" => $sRevision,
      *          "revision" => $sRevision,
      *          "message" => $sCommitmessage
      *      );
@@ -258,68 +325,80 @@ class vcs implements iVcs {
      *      array(
      *          "error" => $sErrormessage,
      *      );
+     * @param string  $sWorkDir  optional: local directory with initialized git repo
      * @return array
      */
     public function getRevision($sWorkDir = false) {
         $aReturn = array();
-        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
         if (!$this->getUrl()) {
             return false;
         }
-        
-        $iTtl=300; // cache for 5 min
-        require_once 'cache.class.php';
-        $oCache=new AhCache($this->_getNameOfCacheModule(), "Revision-".$this->_sCurrentBranch ."-". $sWorkDir);
-        
-        if ($oCache->isExpired()){
 
-            if ($sWorkDir) {
-                $sGitCmd.='cd "' . $sWorkDir . '" && ';
+        $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
+        if ($sWorkDir) {
+            $sGitCmd.='cd "' . $sWorkDir . '" && ';
+        } else {
+            if (!file_exists($this->_sTempDir . ".git")) {
+                $sGitCmd.='mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
+                $sGitCmd.='git init >/dev/null 2>&1 && ';
+                $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 && ';
             } else {
-                if (!file_exists($this->_sTempDir . ".git")) {
-                    $sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
-                    $sGitCmd.='git init >/dev/null 2>&1 && ';
-                    $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 && ';
-                } else {
-                    $sGitCmd.='cd "' . $this->_sTempDir . '" && ';
-                }
-
-                // TODO: git 1.9 does needs only the line with --tags
-                $sGitCmd.=' ( '
-                        . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; '
-                        . 'git fetch --update-head-ok --depth 1 2>&1 '
-                        . ') && ';
+                $sGitCmd.='cd "' . $this->_sTempDir . '" && ';
             }
 
-            $sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" 2>&1 ; ';
-            $sLoginfo = shell_exec($sGitCmd);
+            // TODO: git 1.9 does needs only the line with --tags
+            $sGitCmd.=' ( '
+                    . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; ' // 1.5 s
+                    . 'git fetch --update-head-ok --depth 1 2>&1 '          // 1.5 s
+                    . ') && ';
+        }
 
-            $sRevision = false;
-            if (preg_match('#commit\ (.*)#', $sLoginfo, $aRev)) {
-                $sRevision = $aRev[1];
-            }
-            
-
-            if ($sRevision) {
-                $aReturn = array(
-                    "branch" => $this->_sCurrentBranch,
-                    "revision" => $sRevision,
-                    "message" => $sLoginfo
-                );
-                // echo "DEBUG: refresh cache for git revision<br>";
-                $oCache->write($aReturn, $iTtl);
-            } else {
-                if (!$sLoginfo) {
-                    $sLoginfo = $sGitCmd;
-                }
-                // echo "DEBUG: error on reading git revision<br>";
-                $aReturn = array(
-                    "error" => '<pre>' . $sLoginfo . '<hr>' . $sGitCmd . '</pre>'
-                );
-            }
+        $sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" 2>&1 ; '; // 0.0 s
+        $sLoginfo = shell_exec($sGitCmd);
+        /*
+         * 
+         * example output:
+          From gitlab.iml.unibe.ch:admins/imldeployment
+           * [new branch]      master     -> origin/master
+          commit 0b0dbe0dee80ca71ff43a54641d616c131e6fd8a
+          Author: Axel Hahn
+          Date:   Fri Dec 12 16:35:38 2014 +0100
+
+             - added: skip dereferenced tags in git (tags ending ^{} )
+             - added: modal infobox in build page if you switch the branch
+             - added: git uses a cache for taglist and revision infos (ttl is 5 min)
+         * 
+         */
+
+        // parse revision
+        $sRevision = false;
+        if (preg_match('#commit\ (.*)#', $sLoginfo, $aRev)) {
+            $sRevision = $aRev[1];
+        }
+
+
+        if ($sRevision) {
+            $sCommitMsg = $sLoginfo;
+            $sCommitMsg = preg_replace('/From\ .*\n/', '', $sCommitMsg);
+            $sCommitMsg = preg_replace('/\ \*.*\n/', '', $sCommitMsg);
+            $sCommitMsg = preg_replace('/commit.*\n/', '', $sCommitMsg);
+            // keep these to see them in the output:
+            // $sCommitMsg=preg_replace('/Author:\ .*\n/', '', $sCommitMsg);
+            // $sCommitMsg=preg_replace('/Date:\ .*\n/', '', $sCommitMsg);
+
+            $aReturn = array(
+                "branch" => $this->_sCurrentBranch,
+                "revision" => $sRevision,
+                "message" => $sCommitMsg
+            );
         } else {
-            // echo "DEBUG: use cache for git revision<br>";
-            $aReturn=$oCache->read();
+            if (!$sLoginfo) {
+                $sLoginfo = $sGitCmd;
+            }
+            // echo "DEBUG: error on reading git revision<br>";
+            $aReturn = array(
+                "error" => '<pre>' . $sLoginfo . '<hr>' . $sGitCmd . '</pre>'
+            );
         }
         return $aReturn;
     }