James Moger
2013-01-15 93d506581010cdb6308ae3d282a8bc513966d70d
Support --baseFolder parameter and small data reorganization
1 files added
8 files renamed
32 files modified
793 ■■■■■ changed files
.gitignore 3 ●●●● patch | view | raw | blame | history
build.xml 210 ●●●● patch | view | raw | blame | history
distrib/authority.cmd 2 ●●● patch | view | raw | blame | history
distrib/gitblit 5 ●●●●● patch | view | raw | blame | history
distrib/gitblit-centos 5 ●●●●● patch | view | raw | blame | history
distrib/gitblit-stop.cmd 2 ●●● patch | view | raw | blame | history
distrib/gitblit-ubuntu 3 ●●●● patch | view | raw | blame | history
distrib/gitblit.cmd 2 ●●● patch | view | raw | blame | history
distrib/gitblit.properties 47 ●●●● patch | view | raw | blame | history
distrib/groovy/.gitignore patch | view | raw | blame | history
distrib/groovy/blockpush.groovy patch | view | raw | blame | history
distrib/groovy/jenkins.groovy patch | view | raw | blame | history
distrib/groovy/localclone.groovy patch | view | raw | blame | history
distrib/groovy/protect-refs.groovy patch | view | raw | blame | history
distrib/groovy/sendmail-html.groovy patch | view | raw | blame | history
distrib/groovy/sendmail.groovy patch | view | raw | blame | history
distrib/groovy/thebuggenie.groovy patch | view | raw | blame | history
distrib/installService.cmd 4 ●●●● patch | view | raw | blame | history
distrib/projects.conf 3 ●●●●● patch | view | raw | blame | history
docs/01_setup.mkd 134 ●●●●● patch | view | raw | blame | history
docs/04_releases.mkd 18 ●●●● patch | view | raw | blame | history
src/WEB-INF/web.xml 24 ●●●●● patch | view | raw | blame | history
src/com/gitblit/Constants.java 8 ●●●● patch | view | raw | blame | history
src/com/gitblit/FederationClient.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java 111 ●●●●● patch | view | raw | blame | history
src/com/gitblit/GitBlitServer.java 54 ●●●●● patch | view | raw | blame | history
src/com/gitblit/GitServlet.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/GitblitUserService.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/LdapUserService.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/RedmineUserService.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/RobotsTxtServlet.java 10 ●●●●● patch | view | raw | blame | history
src/com/gitblit/authority/GitblitAuthority.java 38 ●●●● patch | view | raw | blame | history
src/com/gitblit/build/Build.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/build/BuildWebXml.java 64 ●●●● patch | view | raw | blame | history
src/com/gitblit/utils/FileUtils.java 15 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/ChangePasswordPage.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/EditUserPage.java 2 ●●● patch | view | raw | blame | history
src/com/gitblit/wicket/pages/RepositoriesPage.java 2 ●●● patch | view | raw | blame | history
test-gitblit.properties 6 ●●●● patch | view | raw | blame | history
tests/com/gitblit/tests/GitBlitSuite.java 5 ●●●●● patch | view | raw | blame | history
tests/com/gitblit/tests/GitBlitTest.java 2 ●●● patch | view | raw | blame | history
.gitignore
@@ -31,4 +31,5 @@
/deploy
/*.jks
/x509test
/certs
/certs
/data
build.xml
@@ -12,10 +12,11 @@
    <property name="project.jar" value="gitblit.jar" />
    <property name="project.mainclass" value="com.gitblit.Launcher" />
    <property name="project.build.dir" value="${basedir}/build" />
    <property name="project.deploy.dir" value="${basedir}/deploy" />
    <property name="project.deploy.dir" value="${basedir}/deploy" />
    <property name="project.war.dir" value="${basedir}/war" />
    <property name="project.jar.dir" value="${basedir}/jar" />
    <property name="project.site.dir" value="${basedir}/site" />
    <property name="project.site.dir" value="${basedir}/target/site" />
    <property name="project.target.dir" value="${basedir}/target" />
    <property name="project.resources.dir" value="${basedir}/resources" />    
    <property name="project.express.dir" value="${basedir}/express" />
    <property name="project.maven.repo.url" value="enter here your Maven repo URL" />
@@ -106,22 +107,66 @@
    -->
    <target name="compile" depends="buildinfo" description="Retrieves dependencies and compiles Gitblit from source">
        <!-- copy required distribution files to project folder -->
        <copy todir="${basedir}" overwrite="false">
        <!-- cleanup old builds -->
        <delete dir="${project.target.dir}" />
        <mkdir dir="${project.target.dir}" />
        <!-- cleanup old builds -->
        <delete>
            <fileset dir="${basedir}">
                <include name="*.zip" />
                <include name="*.war" />
                <include name="*.jar" />
            </fileset>
        </delete>
        <!-- copy required distribution files to data folder -->
        <mkdir dir="${basedir}/data" />
        <copy todir="${basedir}/data" overwrite="false">
            <fileset dir="${basedir}/distrib">
                <include name="gitblit.properties" />
                <include name="users.conf" />
                <include name="projects.conf" />
            </fileset>
        </copy>
        
        <!-- copy required distribution files to project folder -->
        <mkdir dir="${basedir}/certs" />
        <copy todir="${basedir}/certs" overwrite="false">
        <mkdir dir="${basedir}/data/certs" />
        <copy todir="${basedir}/data/certs" overwrite="false">
            <fileset dir="${basedir}/distrib">
                <include name="authority.conf" />
                <include name="*.tmpl" />
            </fileset>
        </copy>
        <!-- copy required distribution files to project folder -->
        <mkdir dir="${basedir}/data/groovy" />
        <copy todir="${basedir}/data/groovy" overwrite="false">
            <fileset dir="${basedir}/distrib/groovy" />
        </copy>
        <!-- upgrade existing workspace to data folder -->
        <move todir="${basedir}/data" overwrite="true" failonerror="false">
            <fileset dir="${basedir}">
                <include name="users.conf" />
                <include name="projects.conf" />
                <include name="gitblit.properties" />
                <include name="serverKeyStore.jks" />
                <include name="serverTrustStore.jks" />
            </fileset>
        </move>
        <move todir="${basedir}/data/certs" overwrite="true" failonerror="false">
            <fileset dir="${basedir}/certs" />
        </move>
        <move todir="${basedir}/data/git" overwrite="true" failonerror="false">
            <fileset dir="${basedir}/git" />
        </move>
        <move todir="${basedir}/data/proposals" overwrite="true" failonerror="false">
            <fileset dir="${basedir}/proposals" />
        </move>
        <delete dir="${basedir}/javadoc" failonerror="false" />
        <delete dir="${basedir}/site" failonerror="false" />
        <delete dir="${basedir}/temp" failonerror="false" />
        <!-- copy gitblit.properties to the WEB-INF folder.
             this file is only used for parsing setting descriptions. -->
@@ -186,18 +231,45 @@
                <exclude name="federation.properties" />
                <exclude name="openshift.mkd" />
                <exclude name="authority.conf" />
                <exclude name="users.conf" />
                <exclude name="projects.conf" />
                <exclude name="gitblit.properties" />
                <exclude name="*.tmpl" />
                <exclude name="groovy/**" />
            </fileset>
            <fileset dir="${basedir}">
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>            
        </copy>
        <copy tofile="${project.deploy.dir}/authority.jar" file="${basedir}/authority-${gb.version}.jar" />
        
        <!-- Copy the supported Groovy hook scripts -->
        <mkdir dir="${project.deploy.dir}/data/groovy" />
        <copy todir="${project.deploy.dir}/data/groovy">
            <fileset dir="${basedir}/distrib/groovy">
                <include name="sendmail.groovy" />
                <include name="sendmail-html.groovy" />
                <include name="jenkins.groovy" />
                <include name="protect-refs.groovy" />
            </fileset>
        </copy>
        <copy tofile="${project.deploy.dir}/authority.jar" file="${project.target.dir}/authority-${gb.version}.jar" />
        <!-- Prepare the data folder -->
        <mkdir dir="${project.deploy.dir}/data"/>
        <copy todir="${project.deploy.dir}/data">
            <fileset dir="${basedir}/distrib">
                <include name="users.conf" />
                <include name="projects.conf" />
                <include name="gitblit.properties" />
            </fileset>
        </copy>
        <!-- Certificate templates -->
        <mkdir dir="${project.deploy.dir}/certs"/>
        <copy todir="${project.deploy.dir}/certs">
        <mkdir dir="${project.deploy.dir}/data/certs"/>
        <mkdir dir="${project.deploy.dir}/data/certs"/>
        <copy todir="${project.deploy.dir}/data/certs">
            <fileset dir="${basedir}/distrib">
                <include name="*.tmpl" />
                <include name="authority.conf" />
@@ -234,20 +306,8 @@
            <param name="docs.output.dir" value="${project.deploy.dir}/docs" />
        </antcall>
        
        <!-- Copy the supported Groovy hook scripts -->
        <mkdir dir="${project.deploy.dir}/groovy" />
        <copy todir="${project.deploy.dir}/groovy">
            <fileset dir="${basedir}/groovy">
                <include name="sendmail.groovy" />
                <include name="sendmail-html.groovy" />
                <include name="jenkins.groovy" />
                <include name="protect-refs.groovy" />
                <include name="localclone.groovy" />
            </fileset>
        </copy>
        <!-- Create Zip deployment -->        
        <zip destfile="${distribution.zipfile}">
        <zip destfile="${project.target.dir}/${distribution.zipfile}">
            <fileset dir="${project.deploy.dir}">
                <include name="**/*" />
            </fileset>
@@ -383,9 +443,6 @@
        <!-- Copy web.xml and users.conf to WEB-INF -->
        <copy todir="${project.war.dir}/WEB-INF">
            <fileset dir="${basedir}/distrib">
                 <include name="users.conf" />
            </fileset>
            <fileset dir="${basedir}/src/WEB-INF">
                 <include name="web.xml" />
            </fileset>
@@ -404,19 +461,28 @@
            <param name="docs.output.dir" value="${project.war.dir}/WEB-INF/docs" />
        </antcall>
        <!-- Copy users.conf to WEB-INF/data -->
        <mkdir dir="${project.war.dir}/WEB-INF/data" />
        <copy todir="${project.war.dir}/WEB-INF/data">
            <fileset dir="${basedir}/distrib">
                 <include name="users.conf" />
                <include name="projects.conf" />
                 <include name="gitblit.properties" />
            </fileset>
        </copy>
        <!-- Copy the supported Groovy hook scripts -->
        <mkdir dir="${project.war.dir}/WEB-INF/groovy" />
        <copy todir="${project.war.dir}/WEB-INF/groovy">
            <fileset dir="${basedir}/groovy">
        <mkdir dir="${project.war.dir}/WEB-INF/data/groovy" />
        <copy todir="${project.war.dir}/WEB-INF/data/groovy">
            <fileset dir="${basedir}/distrib/groovy">
                <include name="sendmail.groovy" />
                <include name="sendmail-html.groovy" />
                <include name="jenkins.groovy" />
                <include name="protect-refs.groovy" />
                <include name="localclone.groovy" />
            </fileset>
        </copy>
        <!-- Build the WAR web.xml from the prototype web.xml and gitblit.properties -->
        <!-- Build the WAR web.xml from the prototype web.xml -->
        <java classpath="${project.build.dir}" classname="com.gitblit.build.BuildWebXml">
            <classpath refid="master-classpath" />
            
@@ -426,8 +492,6 @@
            <arg value="--destinationFile" />
            <arg value="${project.war.dir}/WEB-INF/web.xml" />
            
            <arg value="--propertiesFile" />
            <arg value="${basedir}/distrib/gitblit.properties" />
        </java>
        <!-- Gitblit resources -->
@@ -467,7 +531,7 @@
        </copy>
        <!-- Build the WAR file -->
        <jar basedir="${project.war.dir}" destfile="${distribution.warfile}" compress="true" />
        <jar basedir="${project.war.dir}" destfile="${project.target.dir}/${distribution.warfile}" compress="true" />
    </target>
    
@@ -554,7 +618,7 @@
    <target name="buildFederationClient" depends="compile" description="Builds the stand-alone Gitblit federation client">
        <echo>Building Gitblit Federation Client ${gb.version}</echo>
    
        <genjar jarfile="fedclient.jar">
        <genjar jarfile="${project.target.dir}/fedclient.jar">
            <class name="com.gitblit.FederationClientLauncher" />
            <resource file="${project.build.dir}/log4j.properties" />
            <classfilter>
@@ -575,16 +639,21 @@
        </genjar>
        
        <!-- Build the federation client zip file -->
        <zip destfile="${fedclient.zipfile}">
        <zip destfile="${project.target.dir}/${fedclient.zipfile}">
            <fileset dir="${basedir}">
                <include name="fedclient.jar" />
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
            <fileset dir="${project.target.dir}">
                <include name="fedclient.jar" />
            </fileset>
            <fileset dir="${basedir}/distrib">
                <include name="federation.properties" />
            </fileset>
        </zip>
        <!-- Cleanup -->
        <delete file="${project.target.dir}/fedclient.jar" />
    </target>
@@ -619,10 +688,20 @@
        <copy tofile="${deployments.root}/WEB-INF/reference.properties" 
            file="${basedir}/distrib/gitblit.properties"/>
        <!-- Copy users.conf and gitblit.properties -->
        <mkdir dir="${deployments.root}/WEB-INF/data" />
        <copy todir="${deployments.root}/WEB-INF/data">
            <fileset dir="${basedir}/distrib">
                <include name="users.conf" />
                <include name="projects.conf" />
                <include name="gitblit.properties" />
            </fileset>
        </copy>
        <!-- Copy the supported Groovy hook scripts -->
        <mkdir dir="${deployments.root}/WEB-INF/groovy" />
        <copy todir="${deployments.root}/WEB-INF/groovy">
            <fileset dir="${basedir}/groovy">
        <mkdir dir="${deployments.root}/WEB-INF/data/groovy" />
        <copy todir="${deployments.root}/WEB-INF/data/groovy">
            <fileset dir="${basedir}/distrib/groovy">
                <include name="sendmail.groovy" />
                <include name="sendmail-html.groovy" />
                <include name="jenkins.groovy" />
@@ -663,6 +742,8 @@
                <exclude name="hamcrest*.jar" />
                <exclude name="servlet*.jar" />
                <exclude name="javax.servlet*.jar" />
                <exclude name="jsslutils*.jar" />
                <exclude name="jcalendar*.jar" />
            </fileset>
        </copy>
@@ -680,7 +761,7 @@
        </jar>
        <!-- Build Express Zip file -->
        <zip destfile="${express.zipfile}">
        <zip destfile="${project.target.dir}/${express.zipfile}">
            <fileset dir="${project.express.dir}" />
        </zip>
@@ -695,7 +776,7 @@
    <target name="buildManager" depends="compile" description="Builds the stand-alone Gitblit Manager">
        <echo>Building Gitblit Manager ${gb.version}</echo>
        <genjar jarfile="manager-${gb.version}.jar">
        <genjar jarfile="${project.target.dir}/manager-${gb.version}.jar">
            <resource file="${basedir}/src/com/gitblit/client/splash.png" />
            <resource file="${basedir}/resources/gitblt-favicon.png" />
            <resource file="${basedir}/resources/gitweb-favicon.png" />
@@ -747,13 +828,18 @@
        </genjar>
        <!-- Build Manager Zip file -->
        <zip destfile="${manager.zipfile}">
        <zip destfile="${project.target.dir}/${manager.zipfile}">
            <fileset dir="${basedir}">
                <include name="manager-${gb.version}.jar" />
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
            <fileset dir="${project.target.dir}">
                <include name="manager-${gb.version}.jar" />
            </fileset>
        </zip>
        <!-- Cleanup -->
        <delete file="${project.target.dir}/manager-${gb.version}.jar" />
    </target>
    
    
@@ -765,7 +851,7 @@
    <target name="buildAuthority" depends="compile" description="Builds the stand-alone Gitblit Authority">
        <echo>Building Gitblit Authority ${gb.version}</echo>
        <genjar jarfile="authority-${gb.version}.jar">
        <genjar jarfile="${project.target.dir}/authority-${gb.version}.jar">
            <resource file="${basedir}/src/com/gitblit/client/splash.png" />
            <resource file="${basedir}/resources/gitblt-favicon.png" />
            <resource file="${basedir}/resources/user_16x16.png" />
@@ -812,13 +898,15 @@
        </genjar>
        <!-- Build Authority Zip file -->
        <zip destfile="${authority.zipfile}">
        <zip destfile="${project.target.dir}/${authority.zipfile}">
            <fileset dir="${basedir}">
                <include name="authority-${gb.version}.jar" />
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
            <zipfileset dir="${basedir}/distrib" prefix="certs">
            <fileset dir="${project.target.dir}">
                <include name="authority-${gb.version}.jar" />
            </fileset>
            <zipfileset dir="${basedir}/distrib" prefix="data/certs">
                <include name="authority.conf" />
                <include name="mail.tmpl" />
                <include name="instructions.tmpl" />
@@ -835,7 +923,7 @@
        <echo>Building Gitblit API Library ${gb.version}</echo>
    
        <!-- Build API Library jar -->
        <genjar jarfile="gbapi-${gb.version}.jar">
        <genjar jarfile="${project.target.dir}/gbapi-${gb.version}.jar">
            <class name="com.gitblit.Keys" />
            <class name="com.gitblit.client.GitblitClient" />
            <classpath refid="master-classpath" />
@@ -850,7 +938,7 @@
        </genjar>
        
        <!-- Build API sources jar -->
        <zip destfile="gbapi-${gb.version}-sources.jar">
        <zip destfile="${project.target.dir}/gbapi-${gb.version}-sources.jar">
            <fileset dir="${basedir}/src" defaultexcludes="yes">
                <include name="com/gitblit/Constants.java"/>
                <include name="com/gitblit/GitBlitException.java"/>
@@ -862,7 +950,7 @@
        </zip>
        
        <!-- Build API JavaDoc jar -->
        <javadoc destdir="${basedir}/javadoc">
        <javadoc destdir="${project.target.dir}/javadoc">
            <fileset dir="${basedir}/src" defaultexcludes="yes">
                <include name="com/gitblit/Constants.java"/>
                <include name="com/gitblit/GitBlitException.java"/>
@@ -872,18 +960,20 @@
                  <include name="com/gitblit/utils/**/*.java"/>                      
            </fileset>
        </javadoc>
        <zip destfile="gbapi-${gb.version}-javadoc.jar">
            <fileset dir="${basedir}/javadoc" />
        <zip destfile="${project.target.dir}/gbapi-${gb.version}-javadoc.jar">
            <fileset dir="${project.target.dir}/javadoc" />
        </zip>
        
        <!-- Build the API library zip file -->
        <zip destfile="${gbapi.zipfile}">
        <zip destfile="${project.target.dir}/${gbapi.zipfile}">
            <fileset dir="${basedir}">
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
            <fileset dir="${project.target.dir}">
                <include name="gbapi-${gb.version}.jar" />
                <include name="gbapi-${gb.version}-sources.jar" />
                <include name="gbapi-${gb.version}-javadoc.jar" />
                <include name="LICENSE" />
                <include name="NOTICE" />
            </fileset>
            <fileset dir="${basedir}/ext">
                <exclude name="src/**" />
@@ -892,6 +982,16 @@
                <include name="jdom*.jar" />
            </fileset>
        </zip>
        <!-- Cleanup -->
        <delete>
            <fileset dir="${project.target.dir}">
                <include name="javadoc/**" />
                <include name="gbapi-${gb.version}.jar" />
                <include name="gbapi-${gb.version}-sources.jar" />
                <include name="gbapi-${gb.version}-javadoc.jar" />
        </fileset>
        </delete>
    </target>
        
        
distrib/authority.cmd
@@ -1 +1 @@
@java -jar authority.jar
@java -jar authority.jar --baseFolder data
distrib/gitblit
@@ -3,6 +3,7 @@
set -e
GITBLIT_PATH=/opt/gitblit
GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_HTTP_PORT=0
GITBLIT_HTTPS_PORT=8443
source ${GITBLIT_PATH}/java-proxy-config.sh
@@ -14,13 +15,13 @@
  start)
        log_action_begin_msg "Starting gitblit server"
        cd $GITBLIT_PATH
        $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT > /dev/null &
        $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER > /dev/null &
        log_action_end_msg $?
        ;;
  stop)
        log_action_begin_msg "Stopping gitblit server"
        cd $GITBLIT_PATH
        $JAVA $GITBLIT_PATH/gitblit.jar --stop > /dev/null &
        $JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
        log_action_end_msg $?
        ;;
  force-reload|restart)
distrib/gitblit-centos
@@ -6,6 +6,7 @@
# change theses values (default values)
GITBLIT_PATH=/opt/gitblit
GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_HTTP_PORT=0
GITBLIT_HTTPS_PORT=8443
source ${GITBLIT_PATH}/java-proxy-config.sh
@@ -19,7 +20,7 @@
      then
      echo $"Starting gitblit server"
      cd $GITBLIT_PATH
      $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT > /dev/null &
      $JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER > /dev/null &
      echo "."
      exit $RETVAL
    fi
@@ -30,7 +31,7 @@
      then
      echo $"Stopping gitblit server"
      cd $GITBLIT_PATH
      $JAVA $GITBLIT_PATH/gitblit.jar --stop > /dev/null &
      $JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
      echo "."
      exit $RETVAL
    fi
distrib/gitblit-stop.cmd
@@ -1 +1 @@
@java -jar gitblit.jar --stop
@java -jar gitblit.jar --stop --baseFolder data
distrib/gitblit-ubuntu
@@ -8,9 +8,10 @@
# change theses values (default values)
GITBLIT_PATH=/opt/gitblit
GITBLIT_BASE_FOLDER=/opt/gitblit/data
GITBLIT_USER="gitblit"
source ${GITBLIT_PATH}/java-proxy-config.sh
ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar"
ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER"
RETVAL=0
distrib/gitblit.cmd
@@ -1 +1 @@
@java -jar gitblit.jar
@java -jar gitblit.jar --baseFolder data
distrib/gitblit.properties
@@ -1,4 +1,19 @@
#
# Gitblit Settings
#
# This settings file supports parameterization from the command-line for the
# following command-line parameters:
#
#   --baseFolder    ${baseFolder}    SINCE 1.2.1
#
# Settings that support ${baseFolder} parameter substitution are indicated with the
# BASEFOLDER attribute.  If the --baseFolder argument is unspecified, ${baseFolder}
# and it's trailing / will be discarded from the setting value leaving a relative
# path that is equivalent to pre-1.2.1 releases.
#
# e.g. "${baseFolder}/git" becomes "git", if --baseFolder is unspecified
#
# Git Servlet Settings
#
@@ -10,7 +25,8 @@
#
# SINCE 0.5.0
# RESTART REQUIRED
git.repositoriesFolder = git
# BASEFOLDER
git.repositoriesFolder = ${baseFolder}/git
# Build the available repository list at startup and cache this list for reuse.
# This reduces disk io when presenting the repositories page, responding to rpcs,
@@ -299,14 +315,16 @@
#
# RESTART REQUIRED
# SINCE 0.8.0
groovy.scriptsFolder = groovy
# BASEFOLDER
groovy.scriptsFolder = ${baseFolder}/groovy
# Specify the directory Grape uses for downloading libraries.
# http://groovy.codehaus.org/Grape
#
# RESTART REQUIRED
# SINCE 1.0.0
groovy.grapeFolder = groovy/grape
# BASEFOLDER
groovy.grapeFolder = ${baseFolder}/groovy/grape
# Scripts to execute on Pre-Receive.
#
@@ -437,7 +455,8 @@
# Config file for storing project metadata
#
# SINCE 1.2.0
web.projectsFile = projects.conf
# BASEFOLDER
web.projectsFile = ${baseFolder}/projects.conf
# Either the full path to a user config file (users.conf)
# OR the full path to a simple user properties file (users.properties)
@@ -451,7 +470,8 @@
#
# SINCE 0.5.0
# RESTART REQUIRED
realm.userService = users.conf
# BASEFOLDER
realm.userService = ${baseFolder}/users.conf
# How to store passwords.
# Valid values are plain, md5, or combined-md5.  md5 is the hash of password.
@@ -510,7 +530,8 @@
# http://googlewebmastercentral.blogspot.com/2008/06/improving-on-robots-exclusion-protocol.html
#
# SINCE 1.0.0
web.robots.txt =
# BASEFOLDER
web.robots.txt = ${baseFolder}/robots.txt
# If true, the web ui layout will respond and adapt to the browser's dimensions.
# if false, the web ui will use a 940px fixed-width layout.
@@ -609,6 +630,7 @@
# Specifying "gitblit" uses the internal login message.
#
# SINCE 0.7.0
# BASEFOLDER
web.loginMessage = gitblit
# This is the message displayed above the repositories table.
@@ -616,6 +638,7 @@
# Specifying "gitblit" uses the internal welcome message.
#
# SINCE 0.5.0
# BASEFOLDER
web.repositoriesMessage = gitblit
# Ordered list of charsets/encodings to use when trying to display a blob.
@@ -925,7 +948,8 @@
# Use forward slashes even on Windows!!
#
# SINCE 0.6.0
federation.proposalsFolder = proposals
# BASEFOLDER
federation.proposalsFolder = ${baseFolder}/proposals
# The default pull frequency if frequency is unspecified on a registration
#
@@ -1027,7 +1051,8 @@
#
# SINCE 1.0.0
# RESTART REQUIRED
realm.ldap.backingUserService = users.conf
# BASEFOLDER
realm.ldap.backingUserService = ${baseFolder}/users.conf
# Delegate team membership control to LDAP.
#
@@ -1123,7 +1148,8 @@
# default: users.conf
#
# RESTART REQUIRED
realm.redmine.backingUserService = users.conf
# BASEFOLDER
realm.redmine.backingUserService = ${baseFolder}/users.conf
# URL of the Redmine.
realm.redmine.url = http://example.com/redmine
@@ -1136,7 +1162,8 @@
#
# SINCE 0.5.0
# RESTART REQUIRED
server.tempFolder = temp
# BASEFOLDER
server.tempFolder = ${baseFolder}/temp
# Use Jetty NIO connectors.  If false, Jetty Socket connectors will be used.
#
distrib/groovy/.gitignore
distrib/groovy/blockpush.groovy
distrib/groovy/jenkins.groovy
distrib/groovy/localclone.groovy
distrib/groovy/protect-refs.groovy
distrib/groovy/sendmail-html.groovy
distrib/groovy/sendmail.groovy
distrib/groovy/thebuggenie.groovy
distrib/installService.cmd
@@ -25,12 +25,12 @@
         --StartPath="%CD%" ^
         --StartClass=com.gitblit.Launcher ^
         --StartMethod=main ^
         --StartParams="--storePassword;gitblit" ^
         --StartParams="--storePassword;gitblit;--baseFolder;%CD%\data" ^
         --StartMode=jvm ^
         --StopPath="%CD%" ^
         --StopClass=com.gitblit.Launcher ^
         --StopMethod=main ^
         --StopParams="--stop" ^
         --StopParams="--stop;--baseFolder;%CD%\data" ^
         --StopMode=jvm ^
         --Classpath="%CD%\gitblit.jar" ^
         --Jvm=auto ^
distrib/projects.conf
New file
@@ -0,0 +1,3 @@
[project "main"]
    title = Main Repositories
    description = main group of repositories
docs/01_setup.mkd
@@ -1,53 +1,55 @@
## Gitblit WAR Setup
## Gitblit WAR Installation & Setup
1. Download [Gitblit WAR %VERSION%](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%) to the webapps folder of your servlet container.  
2. You may have to manually extract the WAR (zip file) to a folder within your webapps folder.
3. Copy the `WEB-INF/users.conf` file to a location outside the webapps folder that is accessible by your servlet container.
Optionally copy the example hook scripts in `WEB-INF/groovy` to a location outside the webapps folder that is accesible by your servlet container.
4. The Gitblit webapp is configured through its `web.xml` file.
Open `web.xml` in your favorite text editor and make sure to review and set:
    - &lt;context-parameter&gt; *git.repositoryFolder* (set the full path to your repositories folder)
    - &lt;context-parameter&gt; *groovy.scriptsFolder* (set the full path to your Groovy hook scripts folder)
    - &lt;context-parameter&gt; *groovy.grapeFolder* (set the full path to your Groovy Grape artifact cache)
    - &lt;context-parameter&gt; *web.projectsFile* (set the full path to your projects metadata file)
    - &lt;context-parameter&gt; *realm.userService* (set the full path to `users.conf`)
3. By default, the Gitblit webapp is configured through `WEB-INF/data/gitblit.properties`.<br/>
Open `WEB-INF/data/gitblit.properties` in your favorite text editor and make sure to review and set:
    - &lt;context-parameter&gt; *git.packedGitLimit* (set larger than the size of your largest repository)
    - &lt;context-parameter&gt; *git.streamFileThreshold* (set larger than the size of your largest committed file)
5. You may have to restart your servlet container.
6. Open your browser to <http://localhost/gitblit> or whatever the url should be.
7. Enter the default administrator credentials: **admin / admin** and click the *Login* button
4. You may have to restart your servlet container.
5. Open your browser to <http://localhost/gitblit> or whatever the url should be.
6. Enter the default administrator credentials: **admin / admin** and click the *Login* button
    **NOTE:** Make sure to change the administrator username and/or password!! 
## Gitblit GO Setup
### WAR Data Location
By default, Gitblit WAR stores all data (users, settings, repositories, etc) in `${contextFolder}/WEB-INF/data`.  This is fine for a quick setup, but there are many reasons why you don't want to keep your data within the webapps folder of your servlet container.  You may specify an external location for your data by editing `WEB-INF/web.xml` and manipulating the *baseFolder* context parameter.  Choose a location that is writeable by your servlet container.  Your servlet container may be smart enough to recognize the change and to restart Gitblit.
On the next restart of Gitblit, Gitblit will copy the contents of the `WEB-INF/data` folder to your specified *baseFolder* **IF** the file `${baseFolder}/gitblit.properties` does not already exist.  This allows you to get going with minimal fuss.
Specifying an alternate *baseFolder* also allows for simpler upgrades in the future.
## Gitblit GO Installation & Setup
1. Download and unzip [Gitblit GO %VERSION%](http://code.google.com/p/gitblit/downloads/detail?name=%GO%).  
*Its best to eliminate spaces in the path name.* 
2. The server itself is configured through a simple text file.
Open `gitblit.properties` in your favorite text editor and make sure to review and set:
    - *git.repositoryFolder* (path may be relative or absolute)
    - *groovy.scriptsFolder* (path may be relative or absolute)
    - *groovy.grapeFolder* (path may be relative or absolute)
    - *server.tempFolder* (path may be relative or absolute)
2. The server itself is configured through a simple text file.<br/>
Open `data/gitblit.properties` in your favorite text editor and make sure to review and set:
    - *server.httpPort* and *server.httpsPort*
    - *server.httpBindInterface* and *server.httpsBindInterface*  
    - *server.storePassword*
    **https** is strongly recommended because passwords are insecurely transmitted form your browser/git client using Basic authentication!
    - *git.packedGitLimit* (set larger than the size of your largest repository)
    - *git.streamFileThreshold* (set larger than the size of your largest committed file)
3. Execute `authority.cmd` or `java -jar authority.jar` from a command-line
3. Execute `authority.cmd` or `java -jar authority.jar --baseFolder data` from a command-line
    1. fill out the fields in the *new certificate defaults* dialog
    2. enter the store password used in *server.storePassword* when prompted.  This generates an SSL certificate for **localhost**.
    3. you may want to generate an SSL certificate for the hostname or ip address hostnames you are serving from<br/>**NOTE:** You can only have **one** SSL certificate specified for a port.
    5. exit the authority app
4. Execute `gitblit.cmd` or `java -jar gitblit.jar` from a command-line
4. Execute `gitblit.cmd` or `java -jar gitblit.jar --baseFolder data` from a command-line
5. Open your browser to <http://localhost:8080> or <https://localhost:8443> depending on your chosen configuration.
6. Enter the default administrator credentials: **admin / admin** and click the *Login* button    
    **NOTE:** Make sure to change the administrator username and/or password!! 
### GO Data Location
By default, Gitblit GO stores all data (users, settings, repositories, etc) in the `data` subfolder of your GO installation.  You may specify an external location for your data on the command-line by setting the *--baseFolder* argument.  If you relocate the data folder then you must supply the *--baseFolder* argument to both GO and the Certificate Authority.
If you are deploying Gitblit to a *nix platform, you might consider moving the data folder out of the GO installation folder and then creating a symlink named "data" that points to your moved folder.
### Creating your own Self-Signed SSL Certificate
Gitblit GO (and Gitblit Certificate Authority) automatically generates a Certificate Authority (CA) certificate and an ssl certificate signed by this CA certificate that is bound to *localhost*.
Remote Eclipse/EGit/JGit clients (<= 2.1.0) will fail to communicate using this certificate because JGit always verifies the hostname of the certificate, regardless of the *http.sslVerify=false* client-side setting.
Remote Eclipse/EGit/JGit clients (<= 2.2.0) will fail to communicate using this certificate because JGit always verifies the hostname of the certificate, regardless of the *http.sslVerify=false* client-side setting.
The EGit failure message is something like:
@@ -56,7 +58,7 @@
If you want to serve your repositories to another machine over https then you will want to generate a new certificate for the hostname or ip address you are serving from.
1. `authority.cmd` or `java -jar authority.jar`
1. `authority.cmd` or `java -jar authority.jar --baseFolder data`
2. Click the *new ssl certificate* button (red rosette in the toolbar in upper left of window)
3. Enter the hostname or ip address
4. Make sure the checkbox *serve https with this certificate* is checked
@@ -64,11 +66,11 @@
 
If you decide to change the value of *server.storePassword* (recommended) <u>after</u> you have already started Gitblit or Gitblit Certificate Authority, then you will have to delete the following files and then restart the Gitblit Certificate Authority app:
1. serverKeyStore.jks
2. serverTrustStore.jks
3. certs/caKeyStore.jks
4. certs/ca.crt
5. certs/caRevocationList.crl (optional)
1. data/serverKeyStore.jks
2. data/serverTrustStore.jks
3. data/certs/caKeyStore.jks
4. data/certs/ca.crt
5. data/certs/caRevocationList.crl (optional)
### Client SSL Certificates
SINCE 1.2.0
@@ -84,6 +86,7 @@
How do you make your servlet container trust a client certificate?
In the WAR variant, you will have to manually setup your servlet container to:
1. want/need client certificates
2. trust a CA certificate used to sign your client certificates
3. generate client certificates signed by your CA certificate
@@ -92,9 +95,9 @@
#### Creating SSL Certificates with Gitblit Certificate Authority
When you generate a new client certificate, a zip file bundle is created which includes a P12 keystore for browsers and a PEM keystore for Git.  Both of these are password-protected.  Additionally, a personalized README file is generated with setup instructions for popular browsers and Git.  The README is generated from `certs\instructions.tmpl` and can be modified to suit your needs.
When you generate a new client certificate, a zip file bundle is created which includes a P12 keystore for browsers and a PEM keystore for Git.  Both of these are password-protected.  Additionally, a personalized README file is generated with setup instructions for popular browsers and Git.  The README is generated from `data\certs\instructions.tmpl` and can be modified to suit your needs.
1. `authority.cmd` or `java -jar authority.jar`
1. `authority.cmd` or `java -jar authority.jar --baseFolder data`
2. Select the user for which to generate the certificate
3. Click the *new certificate* button and enter the expiration date of the certificate.  You must also enter a password for the generated keystore.  This password is *not* the same as the user's login password.  This password is used to protect the privatekey and public certificate you will generate for the selected user.  You must also enter a password hint for the user.
4. If your mail server settings are properly configured you will have a *send email* checkbox which you can use to immediately send the generated certificate bundle to the user.
@@ -130,6 +133,7 @@
#### Command-Line Parameters
Command-Line parameters override the values in `gitblit.properties` at runtime.
    --baseFolder           The default base folder for all relative file reference settings
    --repositoriesFolder   Git Repositories Folder
    --userService          Authentication and Authorization Service (filename or fully qualified classname)
    --useNio               Use NIO Connector else use Socket Connector.
@@ -143,7 +147,7 @@
    
**Example**
    java -jar gitblit.jar --userService c:\myrealm.config --storePassword something
    java -jar gitblit.jar --userService c:/myrealm.config --storePassword something --baseFolder c:/data
#### Overriding Gitblit GO's Log4j Configuration
@@ -221,9 +225,6 @@
    Alternatively, you can respecify *web.forwardSlashCharacter*.
## Upgrading Gitblit
Generally, upgrading is easy.
Since Gitblit does not use a database the only files you have to worry about are your configuration file (`gitblit.properties` or `web.xml`) and possibly your `users.conf` or `users.properties` file.
Any important changes to the setting keys or default values will always be mentioned in the [release log](releases.html).
@@ -231,26 +232,47 @@
`users.properties` and its user service implementation are deprecated as of v0.8.0.
### Upgrading Gitblit WAR
1. Backup your `web.xml` file
Backup your `web.properties` file (if you have one, these are the setting overrides from using the RPC administration service)
2. Delete currently deployed gitblit WAR
3. Deploy new WAR and overwrite the `web.xml` file with your backup
4. Review and optionally apply any new settings as indicated in the [release log](releases.html).
### Upgrading Gitblit WAR (1.2.1+)
1. Make sure your `WEB-INF/web.xml` *baseFolder* context parameter is not `${contextFolder}/WEB-INF/data`!<br/>
If it is, move your `WEB-INF/data` folder to a location writeable by your servlet container.
2. Deploy new WAR
3. Edit the new WAR's `WEB-INF/web.xml` file and set the *baseFolder* context parameter to your external baseFolder.
4. Review and optionally apply any new settings as indicated in the [release log](releases.html) to `${baseFolder}/gitblit.properties`.
 
### Upgrading Gitblit GO
### Upgrading Gitblit GO (1.2.1+)
 
1. Backup your `gitblit.properties` file
2. Backup your `users.properties` file *(if it is located in the Gitblit GO folder)*
OR
Backup your `users.conf` file *(if it is located in the Gitblit GO folder)*
3. Backup your Groovy hook scripts
4. Unzip Gitblit GO to a new folder
5. Overwrite the `gitblit.properties` file with your backup
6. Overwrite the `users.properties` file with your backup *(if it was located in the Gitblit GO folder)*
OR
Overwrite the `users.conf` file with your backup *(if it was located in the Gitblit GO folder)*
7. Review and optionally apply any new settings as indicated in the [release log](releases.html).
1. Unzip Gitblit GO to a new folder
2. Copy your `data` folder from your current Gitblit installation to the new folder and overwrite any conflicts
3. Review and optionally apply any new settings as indicated in the [release log](releases.html) to `data/gitblit.properties`.
In *nix systems, there are other tricks you can play like symlinking the `data` folder or symlinking the GO folder.
All platforms support the *--baseFolder* command-line argument.
### Upgrading Gitblit WAR (pre-1.2.1)
1. Create a `data` as outlined in step 1 of *Upgrading Gitblit GO (pre-1.2.1)*
2. Copy your existing web.xml to your data folder
3. Deploy new WAR
4. Copy the new WAR's `WEB-INF/data/gitblit.properties` file to your data folder
5. Manually apply any changes you made to your original web.xml file to the gitblit.properties file you copied to your data folder
6. Edit the new WAR's `WEB-INF/web.xml` file and set the *baseFolder* context parameter to your external baseFolder.
### Upgrading Gitblit GO (pre-1.2.1)
1. Create a `data` folder and copy the following files and folders to it:
    - users.conf
    - projects.conf *(if you have one)*
    - gitblit.properties
    - serverKeystore.jks
    - serverTrustStore.jks
    - certs folder
    - groovy folder
    - proposals folder
    - and any other custom files (robots.txt, welcome/login markdown files, etc)
2. Unzip Gitblit GO to a new folder
3. Copy your `data` folder and overwrite the folder of the same name in the just-unzipped version
4. Review and optionally apply any new settings as indicated in the [release log](releases.html) to `data/gitblit.properties`.
**NOTE:** You may need to adjust your service definitions to include the `--baseFolder data` argument.
#### Upgrading Windows Service
You may need to delete your old service definition and install a new one depending on what has changed in the release.
@@ -277,7 +299,7 @@
        federationSets = 
#### Repository Names
Repository names must be unique and are CASE-SENSITIVE ON CASE-SENSITIVE FILESYSTEMS.  The name must be composed of letters, digits, or `/ _ - . ~`<br/>
Repository names must be case-insensitive-unique but are CASE-SENSITIVE ON CASE-SENSITIVE FILESYSTEMS.  The name must be composed of letters, digits, or `/ _ - . ~`<br/>
Whitespace is illegal.
Repositories can be grouped within subfolders.  e.g. *libraries/mycoollib.git* and *libraries/myotherlib.git*
@@ -366,6 +388,10 @@
You can not use fast-forward merges on your client when using committer verification.  You must specify *--no-ff* to ensure that a merge commit is created with your identity as the committer.  Only the first parent chain is traversed when verifying commits.
#### Push Log
Gitblit v1.2.1 introduces an incomplete push mechanism.  All pushes are logged since 1.2.1, but the log has not yet been exposed through the web ui.  This will be a feature of an upcoming release.
### Teams
Since v0.8.0, Gitblit supports *teams* for the original `users.properties` user service and the current default user service `users.conf`.  Teams have assigned users and assigned repositories.  A user can be a member of multiple teams and a repository may belong to multiple teams.  This allows the administrator to quickly add a user to a team without having to keep track of all the appropriate repositories. 
docs/04_releases.mkd
@@ -2,6 +2,14 @@
### Current Release
<div class="alert alert-info">
<h4>Update Note 1.2.1</h4>
Because there are now several types of files and folders that must be considered Gitblit data, the default location for data has changed.
<p>You will need to move a few files around when upgrading.  Please see the Upgrading section of the <a href="setup.html">setup</a> page for details.</p>
<b>Express Users</b> make sure to update your web.xml file with the ${baseFolder} values!
</div>
**%VERSION%** ([go](http://code.google.com/p/gitblit/downloads/detail?name=%GO%) | [war](http://code.google.com/p/gitblit/downloads/detail?name=%WAR%) | [express](http://code.google.com/p/gitblit/downloads/detail?name=%EXPRESS%) | [fedclient](http://code.google.com/p/gitblit/downloads/detail?name=%FEDCLIENT%) | [manager](http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%) | [api](http://code.google.com/p/gitblit/downloads/detail?name=%API%)) based on [%JGIT%][jgit] &nbsp; *released %BUILDDATE%*
#### fixes
@@ -10,7 +18,7 @@
- Added nullchecking when concurrently forking a repository and trying to display it's fork network (issue-187)
- Fixed bug where permission changes were not visible in the web ui to a logged-in user until the user logged-out and then logged back in again (issue-186)
- Fixed nullpointer on creating a repository with mixed case (issue 185)
- Fixed nullpointer when using web.allowForking = true && git.cacheRepositoryList = false (issue 182)
- Fixed nullpointer when using *web.allowForking = true* && *git.cacheRepositoryList = false* (issue 182)
- Likely fix for commit and commitdiff page failures when a submodule reference changes (issue 178)
- Build project models from the repository model cache, when possible, to reduce page load time (issue 172)
- Fixed loading of Brazilian Portuguese translation from *nix server (github/inaiat)
@@ -30,6 +38,10 @@
#### changes
- Gitblit GO and Gitblit WAR are now both configured by `gitblit.properties`. WAR is no longer configured by `web.xml`.<br/>
However, Express for OpenShift continues to be configured by `web.xml`.
- Support for a *--baseFolder* command-line argument for Gitblit GO and Gitblit Certificate Authority
- Support for specifying a *${baseFolder}* parameter in `gitblit.properties` and `web.xml` for several settings
- Improve history display of a submodule link
- Updated Korean translation (github/ds5apn)
- Updated checkstyle definition (github/mystygage)
@@ -37,7 +49,7 @@
### Older Releases
<div class="alert alert-info">
<h4>Update Note</h4>
<h4>Update Note 1.2.0</h4>
The permissions model has changed in the 1.2.0 release.
<p>If you are updating your server, you must also update any Gitblit Manager and Federation Client installs to 1.2.0 as well.  The data model used by the RPC mechanism has changed slightly for the new permissions infrastructure.</p>
</div>
@@ -142,7 +154,7 @@
<hr/>
<div class="alert alert-error">
<h4>Update Note</h4>
<h4>Update Note 1.1.0</h4>
If you are updating from an earlier release AND you have indexed branches with the Lucene indexing feature, you need to be aware that this release will completely re-index your repositories.  Please be sure to provide ample heap resources as appropriate for your installation.
</div>
src/WEB-INF/web.xml
@@ -3,6 +3,30 @@
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <!-- The base folder is used to specify the root location of your Gitblit data.
            ${baseFolder}/gitblit.properties
            ${baseFolder}/users.conf
            ${baseFolder}/projects.conf
            ${baseFolder}/robots.txt
            ${baseFolder}/git
            ${baseFolder}/groovy
            ${baseFolder}/groovy/grape
            ${baseFolder}/proposals
        By default, this location is WEB-INF/data.  It is recommended to set this
        path to a location outside your webapps folder that is writable by your
        servlet container.  Gitblit will copy the WEB-INF/data files to that
        location for you when it restarts.  This approach makes upgrading simpler.
        All you have to do is set this parameter for the new release and then
        review the defaults for any new settings.  Settings are always versioned
        with a SINCE x.y.z attribute and also noted in the release changelog.
        -->
    <context-param>
        <param-name>baseFolder</param-name>
        <param-value>${contextFolder}/WEB-INF/data</param-value>
    </context-param>
    <!-- PARAMS --> 
     
    <!-- Gitblit Context Listener --><!-- STRIP     
src/com/gitblit/Constants.java
@@ -90,10 +90,16 @@
    
    public static final String R_GITBLIT = "refs/gitblit/";
    
    public static final String baseFolder = "baseFolder";
    public static final String baseFolder$ = "${" + baseFolder + "}";
    public static final String contextFolder$ = "${contextFolder}";
    public static String getGitBlitVersion() {
        return NAME + " v" + VERSION;
    }
    /**
     * Enumeration representing the four access restriction levels.
     */
src/com/gitblit/FederationClient.java
@@ -76,7 +76,7 @@
        }
        // configure the Gitblit singleton for minimal, non-server operation
        GitBlit.self().configureContext(settings, false);
        GitBlit.self().configureContext(settings, null, false);
        FederationPullExecutor executor = new FederationPullExecutor(registrations, params.isDaemon);
        executor.run();
        if (!params.isDaemon) {
src/com/gitblit/GitBlit.java
@@ -163,6 +163,8 @@
    private final ObjectCache<String> projectRepositoriesMarkdownCache = new ObjectCache<String>();
    private ServletContext servletContext;
    private File baseFolder;
    private File repositoriesFolder;
@@ -394,12 +396,8 @@
     * @return the file
     */
    public static File getFileOrFolder(String fileOrFolder) {
        String openShift = System.getenv("OPENSHIFT_DATA_DIR");
        if (!StringUtils.isEmpty(openShift)) {
            // running on RedHat OpenShift
            return new File(openShift, fileOrFolder);
        }
        return new File(fileOrFolder);
        return com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$,
                self().baseFolder, fileOrFolder);
    }
    /**
@@ -409,7 +407,7 @@
     * @return the repositories folder path
     */
    public static File getRepositoriesFolder() {
        return getFileOrFolder(Keys.git.repositoriesFolder, "git");
        return getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
    }
    /**
@@ -419,7 +417,7 @@
     * @return the proposals folder path
     */
    public static File getProposalsFolder() {
        return getFileOrFolder(Keys.federation.proposalsFolder, "proposals");
        return getFileOrFolder(Keys.federation.proposalsFolder, "${baseFolder}/proposals");
    }
    /**
@@ -429,9 +427,9 @@
     * @return the Groovy scripts folder path
     */
    public static File getGroovyScriptsFolder() {
        return getFileOrFolder(Keys.groovy.scriptsFolder, "groovy");
        return getFileOrFolder(Keys.groovy.scriptsFolder, "${baseFolder}/groovy");
    }
    /**
     * Updates the list of server settings.
     * 
@@ -1652,7 +1650,7 @@
        }
        RepositoryModel model = new RepositoryModel();
        model.isBare = r.isBare();
        File basePath = getFileOrFolder(Keys.git.repositoriesFolder, "git");
        File basePath = getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
        if (model.isBare) {
            model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory());
        } else {
@@ -3043,12 +3041,15 @@
     * 
     * @param settings
     */
    public void configureContext(IStoredSettings settings, boolean startFederation) {
        logger.info("Reading configuration from " + settings.toString());
    public void configureContext(IStoredSettings settings, File folder, boolean startFederation) {
        this.settings = settings;
        this.baseFolder = folder;
        repositoriesFolder = getRepositoriesFolder();
        logger.info("Git repositories folder " + repositoriesFolder.getAbsolutePath());
        logger.info("Gitblit base folder     = " + folder.getAbsolutePath());
        logger.info("Git repositories folder = " + repositoriesFolder.getAbsolutePath());
        logger.info("Gitblit settings        = " + settings.toString());
        // prepare service executors
        mailExecutor = new MailExecutor(settings);
@@ -3070,7 +3071,7 @@
        serverStatus = new ServerStatus(isGO());
        if (this.userService == null) {
            String realm = settings.getString(Keys.realm.userService, "users.properties");
            String realm = settings.getString(Keys.realm.userService, "${baseFolder}/users.properties");
            IUserService loginService = null;
            try {
                // check to see if this "file" is a login service class
@@ -3083,7 +3084,7 @@
        }
        
        // load and cache the project metadata
        projectConfigs = new FileBasedConfig(getFileOrFolder(Keys.web.projectsFile, "projects.conf"), FS.detect());
        projectConfigs = new FileBasedConfig(getFileOrFolder(Keys.web.projectsFile, "${baseFolder}/projects.conf"), FS.detect());
        getProjectConfigs();
        
        // schedule mail engine
@@ -3198,39 +3199,63 @@
    public void contextInitialized(ServletContextEvent contextEvent, InputStream referencePropertiesInputStream) {
        servletContext = contextEvent.getServletContext();
        if (settings == null) {
            // Gitblit WAR is running in a servlet container
            // Gitblit is running in a servlet container
            ServletContext context = contextEvent.getServletContext();
            WebXmlSettings webxmlSettings = new WebXmlSettings(context);
            // gitblit.properties file located within the webapp
            String webProps = context.getRealPath("/WEB-INF/gitblit.properties");
            if (!StringUtils.isEmpty(webProps)) {
                File overrideFile = new File(webProps);
                webxmlSettings.applyOverrides(overrideFile);
            }
            File contextFolder = new File(context.getRealPath("/"));
            String openShift = System.getenv("OPENSHIFT_DATA_DIR");
            
            // gitblit.properties file located outside the deployed war
            // folder lie, for example, on RedHat OpenShift.
            File overrideFile = getFileOrFolder("gitblit.properties");
            if (!overrideFile.getPath().equals("gitblit.properties")) {
                webxmlSettings.applyOverrides(overrideFile);
            }
            configureContext(webxmlSettings, true);
            if (!StringUtils.isEmpty(openShift)) {
                // Gitblit is running in OpenShift/JBoss
                File base = new File(openShift);
            // Copy the included scripts to the configured groovy folder
            File localScripts = getFileOrFolder(Keys.groovy.scriptsFolder, "groovy");
            if (!localScripts.exists()) {
                File includedScripts = new File(context.getRealPath("/WEB-INF/groovy"));
                if (!includedScripts.equals(localScripts)) {
                    try {
                        com.gitblit.utils.FileUtils.copy(localScripts, includedScripts.listFiles());
                    } catch (IOException e) {
                        logger.error(MessageFormat.format(
                                "Failed to copy included Groovy scripts from {0} to {1}",
                                includedScripts, localScripts));
                // gitblit.properties setting overrides
                File overrideFile = new File(base, "gitblit.properties");
                webxmlSettings.applyOverrides(overrideFile);
                // Copy the included scripts to the configured groovy folder
                File localScripts = new File(base, webxmlSettings.getString(Keys.groovy.scriptsFolder, "groovy"));
                if (!localScripts.exists()) {
                    File warScripts = new File(contextFolder, "/WEB-INF/data/groovy");
                    if (!warScripts.equals(localScripts)) {
                        try {
                            com.gitblit.utils.FileUtils.copy(localScripts, warScripts.listFiles());
                        } catch (IOException e) {
                            logger.error(MessageFormat.format(
                                    "Failed to copy included Groovy scripts from {0} to {1}",
                                    warScripts, localScripts));
                        }
                    }
                }
                // configure context using the web.xml
                configureContext(webxmlSettings, base, true);
            } else {
                // Gitblit is running in a standard servlet container
                logger.info("WAR contextFolder is " + contextFolder.getAbsolutePath());
                String path = webxmlSettings.getString(Constants.baseFolder, Constants.contextFolder$ + "/WEB-INF/data");
                File base = com.gitblit.utils.FileUtils.resolveParameter(Constants.contextFolder$, contextFolder, path);
                base.mkdirs();
                // try to copy the data folder contents to the baseFolder
                File localSettings = new File(base, "gitblit.properties");
                if (!localSettings.exists()) {
                    File contextData = new File(contextFolder, "/WEB-INF/data");
                    if (!base.equals(contextData)) {
                        try {
                            com.gitblit.utils.FileUtils.copy(base, contextData.listFiles());
                        } catch (IOException e) {
                            logger.error(MessageFormat.format(
                                    "Failed to copy included data from {0} to {1}",
                                contextData, base));
                        }
                    }
                }
                // delegate all config to baseFolder/gitblit.properties file
                FileSettings settings = new FileSettings(localSettings.getAbsolutePath());
                configureContext(settings, base, true);
            }
        }
        
src/com/gitblit/GitBlitServer.java
@@ -84,10 +84,29 @@
    private static Logger logger;
    public static void main(String... args) {
        // filter out the baseFolder parameter
        List<String> filtered = new ArrayList<String>();
        String folder = "data";
        for (int i = 0; i< args.length; i++) {
            String arg = args[i];
            if (arg.equals("--baseFolder")) {
                if (i + 1 == args.length) {
                    System.out.println("Invalid --baseFolder parameter!");
                    System.exit(-1);
                } else if (args[i + 1] != ".") {
                    folder = args[i + 1];
                }
                i = i + 1;
            } else {
                filtered.add(arg);
            }
        }
        Params.baseFolder = folder;
        Params params = new Params();
        JCommander jc = new JCommander(params);
        try {
            jc.parse(args);
            jc.parse(filtered.toArray(new String[filtered.size()]));
            if (params.help) {
                usage(jc, null);
            }
@@ -147,13 +166,13 @@
     * Start Gitblit GO.
     */
    private static void start(Params params) {
        FileSettings settings = Params.FILESETTINGS;
        final File baseFolder = new File(Params.baseFolder).getAbsoluteFile();
        FileSettings settings = params.FILESETTINGS;
        if (!StringUtils.isEmpty(params.settingsfile)) {
            if (new File(params.settingsfile).exists()) {
                settings = new FileSettings(params.settingsfile);                
            }
        }
        logger = LoggerFactory.getLogger(GitBlitServer.class);
        logger.info(Constants.BORDER);
        logger.info("            _____  _  _    _      _  _  _");
@@ -197,11 +216,10 @@
        // conditionally configure the https connector
        if (params.securePort > 0) {
            final File folder = new File(System.getProperty("user.dir"));
            File certificatesConf = new File(folder, X509Utils.CA_CONFIG);
            File serverKeyStore = new File(folder, X509Utils.SERVER_KEY_STORE);
            File serverTrustStore = new File(folder, X509Utils.SERVER_TRUST_STORE);
            File caRevocationList = new File(folder, X509Utils.CA_REVOCATION_LIST);
            File certificatesConf = new File(baseFolder, X509Utils.CA_CONFIG);
            File serverKeyStore = new File(baseFolder, X509Utils.SERVER_KEY_STORE);
            File serverTrustStore = new File(baseFolder, X509Utils.SERVER_TRUST_STORE);
            File caRevocationList = new File(baseFolder, X509Utils.CA_REVOCATION_LIST);
            // generate CA & web certificates, create certificate stores
            X509Metadata metadata = new X509Metadata("localhost", params.storePassword);
@@ -218,12 +236,12 @@
            }
            
            metadata.notAfter = new Date(System.currentTimeMillis() + 10*TimeUtils.ONEYEAR);
            X509Utils.prepareX509Infrastructure(metadata, folder, new X509Log() {
            X509Utils.prepareX509Infrastructure(metadata, baseFolder, new X509Log() {
                @Override
                public void log(String message) {
                    BufferedWriter writer = null;
                    try {
                        writer = new BufferedWriter(new FileWriter(new File(folder, X509Utils.CERTS + File.separator + "log.txt"), true));
                        writer = new BufferedWriter(new FileWriter(new File(baseFolder, X509Utils.CERTS + File.separator + "log.txt"), true));
                        writer.write(MessageFormat.format("{0,date,yyyy-MM-dd HH:mm}: {1}", new Date(), message));
                        writer.newLine();
                        writer.flush();
@@ -277,7 +295,7 @@
        // tempDir is where the embedded Gitblit web application is expanded and
        // where Jetty creates any necessary temporary files
        File tempDir = new File(params.temp);
        File tempDir = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.temp);
        if (tempDir.exists()) {
            try {
                FileUtils.delete(tempDir, FileUtils.RECURSIVE | FileUtils.RETRY);
@@ -361,7 +379,7 @@
        // Setup the GitBlit context
        GitBlit gitblit = GitBlit.self();
        gitblit.configureContext(settings, true);
        gitblit.configureContext(settings, baseFolder, true);
        rootContext.addEventListener(gitblit);
        try {
@@ -532,7 +550,9 @@
    @Parameters(separators = " ")
    private static class Params {
        private static final FileSettings FILESETTINGS = new FileSettings(Constants.PROPERTIES_FILE);
        public static String baseFolder;
        private final FileSettings FILESETTINGS = new FileSettings(new File(baseFolder, Constants.PROPERTIES_FILE).getAbsolutePath());
        /*
         * Server parameters
@@ -551,14 +571,14 @@
         */
        @Parameter(names = { "--repositoriesFolder" }, description = "Git Repositories Folder")
        public String repositoriesFolder = FILESETTINGS.getString(Keys.git.repositoriesFolder,
                "repos");
                "git");
        /*
         * Authentication Parameters
         */
        @Parameter(names = { "--userService" }, description = "Authentication and Authorization Service (filename or fully qualified classname)")
        public String userService = FILESETTINGS.getString(Keys.realm.userService,
                "users.properties");
                "users.conf");
        /*
         * JETTY Parameters
@@ -567,10 +587,10 @@
        public Boolean useNIO = FILESETTINGS.getBoolean(Keys.server.useNio, true);
        @Parameter(names = "--httpPort", description = "HTTP port for to serve. (port <= 0 will disable this connector)")
        public Integer port = FILESETTINGS.getInteger(Keys.server.httpPort, 80);
        public Integer port = FILESETTINGS.getInteger(Keys.server.httpPort, 0);
        @Parameter(names = "--httpsPort", description = "HTTPS port to serve.  (port <= 0 will disable this connector)")
        public Integer securePort = FILESETTINGS.getInteger(Keys.server.httpsPort, 443);
        public Integer securePort = FILESETTINGS.getInteger(Keys.server.httpsPort, 8443);
        @Parameter(names = "--ajpPort", description = "AJP port to serve.  (port <= 0 will disable this connector)")
        public Integer ajpPort = FILESETTINGS.getInteger(Keys.server.ajpPort, 0);
src/com/gitblit/GitServlet.java
@@ -86,7 +86,7 @@
        groovyDir = GitBlit.getGroovyScriptsFolder();
        try {
            // set Grape root
            File grapeRoot = new File(GitBlit.getString(Keys.groovy.grapeFolder, "groovy/grape")).getAbsoluteFile();
            File grapeRoot = GitBlit.getFileOrFolder(Keys.groovy.grapeFolder, "${baseFolder}/groovy/grape").getAbsoluteFile();
            grapeRoot.mkdirs();
            System.setProperty("grape.root", grapeRoot.getAbsolutePath());
            
src/com/gitblit/GitblitUserService.java
@@ -60,7 +60,7 @@
    @Override
    public void setup(IStoredSettings settings) {
        File realmFile = GitBlit.getFileOrFolder(Keys.realm.userService, "users.conf");
        File realmFile = GitBlit.getFileOrFolder(Keys.realm.userService, "${baseFolder}/users.conf");
        serviceImpl = createUserService(realmFile);
        logger.info("GUS delegating to " + serviceImpl.toString());
    }
src/com/gitblit/LdapUserService.java
@@ -61,7 +61,7 @@
    @Override
    public void setup(IStoredSettings settings) {
        this.settings = settings;
        String file = settings.getString(Keys.realm.ldap.backingUserService, "users.conf");
        String file = settings.getString(Keys.realm.ldap.backingUserService, "${baseFolder}/users.conf");
        File realmFile = GitBlit.getFileOrFolder(file);
        serviceImpl = createUserService(realmFile);
src/com/gitblit/RedmineUserService.java
@@ -47,7 +47,7 @@
    public void setup(IStoredSettings settings) {
        this.settings = settings;
        String file = settings.getString(Keys.realm.redmine.backingUserService, "users.conf");
        String file = settings.getString(Keys.realm.redmine.backingUserService, "${baseFolder}/users.conf");
        File realmFile = GitBlit.getFileOrFolder(file);
        serviceImpl = createUserService(realmFile);
src/com/gitblit/RobotsTxtServlet.java
@@ -24,7 +24,6 @@
import javax.servlet.http.HttpServletResponse;
import com.gitblit.utils.FileUtils;
import com.gitblit.utils.StringUtils;
/**
 * Handles requests for robots.txt
@@ -55,13 +54,10 @@
    protected void processRequest(javax.servlet.http.HttpServletRequest request,
            javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,
            java.io.IOException {
        String robotstxt = GitBlit.getString(Keys.web.robots.txt, null);
        File file = GitBlit.getFileOrFolder(Keys.web.robots.txt, null);
        String content = "";
        if (!StringUtils.isEmpty(robotstxt)) {
            File robotsfile = new File(robotstxt);
            if (robotsfile.exists()) {
                content = FileUtils.readContent(robotsfile, "\n");
            }
        if (file.exists()) {
            content = FileUtils.readContent(file, "\n");
        }
        response.getWriter().append(content);
    }
src/com/gitblit/authority/GitblitAuthority.java
@@ -138,6 +138,21 @@
    private JButton newSSLCertificate;
    public static void main(String... args) {
        // filter out the baseFolder parameter
        String folder = "data";
        for (int i = 0; i< args.length; i++) {
            String arg = args[i];
            if (arg.equals("--baseFolder")) {
                if (i + 1 == args.length) {
                    System.out.println("Invalid --baseFolder parameter!");
                    System.exit(-1);
                } else if (args[i + 1] != ".") {
                    folder = args[i+1];
                }
                break;
            }
        }
        final String baseFolder = folder;
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
@@ -145,7 +160,7 @@
                } catch (Exception e) {
                }
                GitblitAuthority authority = new GitblitAuthority();
                authority.initialize();
                authority.initialize(baseFolder);
                authority.setLocationRelativeTo(null);
                authority.setVisible(true);
            }
@@ -158,7 +173,7 @@
        defaultSorter = new TableRowSorter<UserCertificateTableModel>(tableModel);
    }
    
    public void initialize() {
    public void initialize(String baseFolder) {
        setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
        setTitle("Gitblit Certificate Authority v" + Constants.VERSION + " (" + Constants.VERSION_DATE + ")");
        setContentPane(getUI());
@@ -174,10 +189,10 @@
            }
        });        
        setSizeAndPosition();
        File folder = new File(System.getProperty("user.dir"));
        File folder = new File(baseFolder).getAbsoluteFile();
        load(folder);
        setSizeAndPosition();
    }
    
    private void setSizeAndPosition() {
@@ -230,7 +245,7 @@
    }
    
    private StoredConfig getConfig() throws IOException, ConfigInvalidException {
        File configFile  = new File(System.getProperty("user.dir"), X509Utils.CA_CONFIG);
        File configFile  = new File(folder, X509Utils.CA_CONFIG);
        FileBasedConfig config = new FileBasedConfig(configFile, FS.detect());
        config.load();
        return config;
@@ -243,30 +258,31 @@
        }
        gitblitSettings = new FileSettings(file.getAbsolutePath());
        mail = new MailExecutor(gitblitSettings);
        String us = gitblitSettings.getString(Keys.realm.userService, "users.conf");
        String us = gitblitSettings.getString(Keys.realm.userService, "${baseFolder}/users.conf");
        String ext = us.substring(us.lastIndexOf(".") + 1).toLowerCase();
        IUserService service = null;
        if (!ext.equals("conf") && !ext.equals("properties")) {
            if (us.equals("com.gitblit.LdapUserService")) {
                us = gitblitSettings.getString(Keys.realm.ldap.backingUserService, "users.conf");
                us = gitblitSettings.getString(Keys.realm.ldap.backingUserService, "${baseFolder}/users.conf");
            } else if (us.equals("com.gitblit.LdapUserService")) {
                us = gitblitSettings.getString(Keys.realm.redmine.backingUserService, "users.conf");
                us = gitblitSettings.getString(Keys.realm.redmine.backingUserService, "${baseFolder}/users.conf");
            }
        }
        if (us.endsWith(".conf")) {
            service = new ConfigUserService(new File(us));
            service = new ConfigUserService(FileUtils.resolveParameter(Constants.baseFolder$, folder, us));
        } else {
            throw new RuntimeException("Unsupported user service: " + us);
        }
        
        service = new ConfigUserService(new File(us));
        service = new ConfigUserService(FileUtils.resolveParameter(Constants.baseFolder$, folder, us));
        return service;
    }
    
    private void load(File folder) {
        this.folder = folder;
        this.userService = loadUsers(folder);
        System.out.println(Constants.baseFolder$ + " set to " + folder);
        if (userService == null) {
            JOptionPane.showMessageDialog(this, MessageFormat.format("Sorry, {0} doesn't look like a Gitblit GO installation.", folder));
        } else {
src/com/gitblit/build/Build.java
@@ -217,7 +217,7 @@
        Properties properties = new Properties();
        FileInputStream is = null;
        try {
            is = new FileInputStream(Constants.PROPERTIES_FILE);
            is = new FileInputStream(new File("distrib", Constants.PROPERTIES_FILE));
            properties.load(is);
        } catch (Throwable t) {
            t.printStackTrace();
src/com/gitblit/build/BuildWebXml.java
@@ -60,44 +60,44 @@
    }
    private static void generateWebXml(Params params) throws Exception {
        StringBuilder parameters = new StringBuilder();
        // Read the current Gitblit properties
        BufferedReader propertiesReader = new BufferedReader(new FileReader(new File(
                params.propertiesFile)));
        if (params.propertiesFile != null) {
            BufferedReader propertiesReader = new BufferedReader(new FileReader(new File(
                    params.propertiesFile)));
        Vector<Setting> settings = new Vector<Setting>();
        List<String> comments = new ArrayList<String>();
        String line = null;
        while ((line = propertiesReader.readLine()) != null) {
            if (line.length() == 0) {
                comments.clear();
            } else {
                if (line.charAt(0) == '#') {
                    if (line.length() > 1) {
                        comments.add(line.substring(1).trim());
                    }
                } else {
                    String[] kvp = line.split("=", 2);
                    String key = kvp[0].trim();
                    if (!skipKey(key)) {
                        Setting s = new Setting(key, kvp[1].trim(), comments);
                        settings.add(s);
                    }
            Vector<Setting> settings = new Vector<Setting>();
            List<String> comments = new ArrayList<String>();
            String line = null;
            while ((line = propertiesReader.readLine()) != null) {
                if (line.length() == 0) {
                    comments.clear();
                } else {
                    if (line.charAt(0) == '#') {
                        if (line.length() > 1) {
                            comments.add(line.substring(1).trim());
                        }
                    } else {
                        String[] kvp = line.split("=", 2);
                        String key = kvp[0].trim();
                        if (!skipKey(key)) {
                            Setting s = new Setting(key, kvp[1].trim(), comments);
                            settings.add(s);
                        }
                        comments.clear();
                    }
                }
            }
        }
        propertiesReader.close();
            propertiesReader.close();
        StringBuilder parameters = new StringBuilder();
        for (Setting setting : settings) {
            for (String comment : setting.comments) {
                parameters.append(MessageFormat.format(COMMENT_PATTERN, comment));
            for (Setting setting : settings) {
                for (String comment : setting.comments) {
                    parameters.append(MessageFormat.format(COMMENT_PATTERN, comment));
                }
                parameters.append(MessageFormat.format(PARAM_PATTERN, setting.name,
                        StringUtils.escapeForHtml(setting.value, false)));
            }
            parameters.append(MessageFormat.format(PARAM_PATTERN, setting.name,
                    StringUtils.escapeForHtml(setting.value, false)));
        }
        // Read the prototype web.xml file
        File webxml = new File(params.sourceFile);
        char[] buffer = new char[(int) webxml.length()];
@@ -150,11 +150,11 @@
        @Parameter(names = { "--sourceFile" }, description = "Source web.xml file", required = true)
        public String sourceFile;
        @Parameter(names = { "--propertiesFile" }, description = "Properties settings file", required = true)
        @Parameter(names = { "--propertiesFile" }, description = "Properties settings file")
        public String propertiesFile;
        @Parameter(names = { "--destinationFile" }, description = "Destination web.xml file", required = true)
        public String destinationFile;
    }
}
src/com/gitblit/utils/FileUtils.java
@@ -274,4 +274,19 @@
            return path.getAbsoluteFile();
        }
    }
    public static File resolveParameter(String parameter, File aFolder, String path) {
        if (aFolder == null) {
            // strip any parameter reference
            path = path.replace(parameter, "").trim();
            if (path.length() > 0 && path.charAt(0) == '/') {
                // strip leading /
                path = path.substring(1);
            }
        } else if (path.contains(parameter)) {
            // replace parameter with path
            path = path.replace(parameter, aFolder.getAbsolutePath());
        }
        return new File(path);
    }
}
src/com/gitblit/wicket/pages/ChangePasswordPage.java
@@ -54,7 +54,7 @@
        UserModel user = GitBlitWebSession.get().getUser();        
        if (!GitBlit.self().supportsCredentialChanges(user)) {
            error(MessageFormat.format(getString("gb.userServiceDoesNotPermitPasswordChanges"),
                    GitBlit.getString(Keys.realm.userService, "users.conf")), true);
                    GitBlit.getString(Keys.realm.userService, "${baseFolder}/users.conf")), true);
        }
        
        setupPage(getString("gb.changePassword"), user.username);
src/com/gitblit/wicket/pages/EditUserPage.java
@@ -57,7 +57,7 @@
        super();
        if (!GitBlit.self().supportsAddUser()) {
            error(MessageFormat.format(getString("gb.userServiceDoesNotPermitAddUser"),
                    GitBlit.getString(Keys.realm.userService, "users.conf")), true);
                    GitBlit.getString(Keys.realm.userService, "${baseFolder}/users.conf")), true);
        }
        isCreate = true;
        setupPage(new UserModel(""));
src/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -119,7 +119,7 @@
        } else {
            // Read user-supplied message
            if (!StringUtils.isEmpty(messageSource)) {
                File file = new File(messageSource);
                File file = GitBlit.getFileOrFolder(messageSource);
                if (file.exists()) {
                    try {
                        FileInputStream fis = new FileInputStream(file);
test-gitblit.properties
@@ -2,10 +2,10 @@
# Gitblit Unit Testing properties
#
git.repositoriesFolder = git
git.repositoriesFolder = ${baseFolder}/git
git.searchRepositoriesSubfolders = true
git.enableGitServlet = true
groovy.scriptsFolder = groovy
groovy.scriptsFolder = ${baseFolder}/groovy
groovy.preReceiveScripts = blockpush
groovy.postReceiveScripts = sendmail
web.authenticateViewPages = false
@@ -77,7 +77,7 @@
#federation.example1.mirror = true 
#federation.example1.mergeAccounts = true
server.tempFolder = temp
server.tempFolder = ${baseFolder}/temp
server.useNio = true
server.contextPath = /
server.httpPort = 0
tests/com/gitblit/tests/GitBlitSuite.java
@@ -63,7 +63,7 @@
        FanoutServiceTest.class })
public class GitBlitSuite {
    public static final File REPOSITORIES = new File("git");
    public static final File REPOSITORIES = new File("data/git");
    static int port = 8280;
    static int shutdownPort = 8281;
@@ -117,7 +117,8 @@
                GitBlitServer.main("--httpPort", "" + port, "--httpsPort", "0", "--shutdownPort",
                        "" + shutdownPort, "--repositoriesFolder",
                        "\"" + GitBlitSuite.REPOSITORIES.getAbsolutePath() + "\"", "--userService",
                        "test-users.conf", "--settings", "test-gitblit.properties");
                        "test-users.conf", "--settings", "test-gitblit.properties",
                        "--baseFolder", "data");
            }
        });
tests/com/gitblit/tests/GitBlitTest.java
@@ -138,7 +138,7 @@
        assertEquals(5, settings.getInteger("realm.realmFile", 5));
        assertTrue(settings.getBoolean("git.enableGitServlet", false));
        assertEquals("users.conf", settings.getString("realm.userService", null));
        assertEquals("${baseFolder}/users.conf", settings.getString("realm.userService", null));
        assertEquals(5, settings.getInteger("realm.minPasswordLength", 0));
        List<String> mdExtensions = settings.getStrings("web.markdownExtensions");
        assertTrue(mdExtensions.size() > 0);