Crlf conversion to support working with msys git
authorConstantine Plotnikov <Constantine.Plotnikov@jetbrains.com>
Wed, 7 Oct 2009 16:38:06 +0000 (20:38 +0400)
committerConstantine Plotnikov <Constantine.Plotnikov@jetbrains.com>
Wed, 7 Oct 2009 16:38:06 +0000 (20:38 +0400)
34 files changed:
build.properties.dist
build.xml
git-server/git-server.iml
git-server/resources/buildServerResources/gitSettings.jsp
git-server/src/META-INF/build-server-plugin-git.xml
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/Constants.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/GitUtils.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/Settings.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/ssh/HeadlessSshSessionFactory.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/ssh/PasswordSshSessionFactory.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/ssh/PrivateKeyFileSshSessionFactory.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/ssh/RefreshableSshConfigSessionFactory.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/ssh/SshUtils.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/ByteRange.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/DirectSubmoduleAwareTreeIterator.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/IndirectSubmoduleAwareTreeIterator.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/Submodule.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/SubmoduleAwareTreeIterator.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/SubmoduleResolver.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/SubmodulesConfig.java
git-server/src/jetbrains/buildServer/buildTriggers/vcs/git/submodules/TeamCitySubmoduleResolver.java
git-teamcity.ipr
git-teamcity.xml
git-tests/git-tests.iml
git-tests/src/jetbrains/buildServer/buildTriggers/vcs/git/tests/GitTestUtil.java
git-tests/src/jetbrains/buildServer/buildTriggers/vcs/git/tests/GitVcsSupportTest.java
git-tests/src/jetbrains/buildServer/buildTriggers/vcs/git/tests/SubmoduleTest.java
git-tests/src/testng.xml
lib/lib-compile/javac2/readme.txt
lib/src/jgit-0.5.0-SNAPSHOT-version.txt
license/jgit.LICENSE.txt
root.iml
teamcity-common.xml
teamcity-plugin.dist.xml

index 856af88c36167bebdf6f5a1a52ec5206bacd47ac..9ec1bf3b349fa6c182001c3c5f8138a1bcc944c9 100644 (file)
@@ -1,11 +1,11 @@
-# Copy the file to 'build.properties' to make it used by the build\r
-# Please specify the folowing properties. Remember to use Java string values escaping rules.\r
-\r
-# Path to unpacked .tar.gz distribution or installed .exe distribution of TeamCity\r
-# for example:\r
-#path.variable.teamcitydistribution=C\:/TeamCity4\r
-\r
-\r
-# Path to JDK 1.5\r
-# for example:\r
+# Copy the file to 'build.properties' to make it used by the build
+# Please specify the folowing properties. Remember to use Java string values escaping rules.
+
+# Path to unpacked .tar.gz distribution or installed .exe distribution of TeamCity
+# for example:
+#path.variable.teamcitydistribution=C\:/TeamCity4
+
+
+# Path to JDK 1.5
+# for example:
 #jdk.home.1.5=c:/Program Files/Java/jdk1.5.0_08
\ No newline at end of file
index f009397e1efcae23b776a9fc7871bbba1f4c9881..d945c175e4becc3f45c7aaf511737e6e06b38900 100755 (executable)
--- a/build.xml
+++ b/build.xml
@@ -1,77 +1,77 @@
-<project name="git-custom-build" default="dist" basedir=".">\r
-\r
-  <property file="build.properties"/>\r
-  <property name="plugin.name" value="jetbrains.git"/>\r
-\r
-  <property name="build.number" value="SNAPSHOT"/>\r
-  <property name="build.vcs.number" value=""/>\r
-\r
-  <property name="plugin.version" value="1.0.0.${build.number}-${build.vcs.number}"/>\r
-\r
-  <property name="javac2.home" value="${basedir}/lib/lib-compile/javac2"/>\r
-\r
-  <import file="teamcity-common.xml"/>\r
-  <import file="git-teamcity.xml"/>\r
-\r
-  <target name="package">\r
-    <package.teamcity.plugin name="${plugin.name}" server.output="${git-server.output.dir}"\r
-                             server.lib.dir="lib" server.lib.includes="*.jar"\r
-                             plugin.descriptor.file="teamcity-plugin.dist.xml"\r
-                             plugin.version="${plugin.version}">\r
-      <additional-files>\r
-        <fileset dir="${basedir}" includes="license/**"/>\r
-      </additional-files>\r
-    </package.teamcity.plugin>\r
-\r
-    <mkdir dir="${basedir}/dist/src"/>\r
-\r
-    <zip basedir="${basedir}" destfile="${basedir}/dist/src/${plugin.name}-src.zip">\r
-      <include name="git-server/**"/>\r
-      <include name="git-tests/**"/>\r
-      <include name="lib/**"/>\r
-      <include name="license/**"/>\r
-      <include name="*.iml"/>\r
-      <include name="*.ipr"/>\r
-      <include name="build.xml"/>\r
-      <include name="build.properties.dist"/>\r
-      <include name="git-teamcity.xml"/>\r
-      <include name="teamcity-common.xml"/>\r
-    </zip>\r
-  </target>\r
-\r
-  <target name="dist" depends="check.teamcitydistribution,all,package"/>\r
-\r
-  <target name="clean" depends="git-teamcity.clean">\r
-    <delete dir="dist" quiet="true"/>\r
-  </target>\r
-\r
-  <target name="deploy" depends="dist">\r
-    <deploy.teamcity.plugin name="${plugin.name}"/>\r
-  </target>\r
-\r
-  <taskdef name="testng" classname="org.testng.TestNGAntTask" classpath="${basedir}/git-tests/lib/testng-5.7-jdk15.jar"/>\r
-\r
-  <target name="run-tests" depends="clean, init, compile.module.git-tests.production">\r
-    <property name="suspend" value="n"/>\r
-\r
-    <testng haltonfailure="no" failureProperty="failure_found" listener="org.testng.reporters.TestHTMLReporter"\r
-            outputdir="${basedir}/test-output" classpathref="git-tests.runtime.module.classpath" dumpcommand="true">\r
-\r
-      <jvmarg value="-ea"/>\r
-      <!--<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=${suspend},address=5555"/>-->\r
-\r
-      <sysproperty key="java.awt.headless" value="true"/>\r
-\r
-      <xmlfileset dir="${basedir}/git-tests/src">\r
-        <include name="testng.xml"/>\r
-      </xmlfileset>\r
-    </testng>\r
-  </target>\r
-\r
-  <target name="check_for_failures">\r
-    <fail if="failure_found" message="Failures found."/>\r
-  </target>\r
-\r
-</project>\r
-\r
+<project name="git-custom-build" default="dist" basedir=".">
+
+  <property file="build.properties"/>
+  <property name="plugin.name" value="jetbrains.git"/>
+
+  <property name="build.number" value="SNAPSHOT"/>
+  <property name="build.vcs.number" value=""/>
+
+  <property name="plugin.version" value="1.0.0.${build.number}-${build.vcs.number}"/>
+
+  <property name="javac2.home" value="${basedir}/lib/lib-compile/javac2"/>
+
+  <import file="teamcity-common.xml"/>
+  <import file="git-teamcity.xml"/>
+
+  <target name="package">
+    <package.teamcity.plugin name="${plugin.name}" server.output="${git-server.output.dir}"
+                             server.lib.dir="lib" server.lib.includes="*.jar"
+                             plugin.descriptor.file="teamcity-plugin.dist.xml"
+                             plugin.version="${plugin.version}">
+      <additional-files>
+        <fileset dir="${basedir}" includes="license/**"/>
+      </additional-files>
+    </package.teamcity.plugin>
+
+    <mkdir dir="${basedir}/dist/src"/>
+
+    <zip basedir="${basedir}" destfile="${basedir}/dist/src/${plugin.name}-src.zip">
+      <include name="git-server/**"/>
+      <include name="git-tests/**"/>
+      <include name="lib/**"/>
+      <include name="license/**"/>
+      <include name="*.iml"/>
+      <include name="*.ipr"/>
+      <include name="build.xml"/>
+      <include name="build.properties.dist"/>
+      <include name="git-teamcity.xml"/>
+      <include name="teamcity-common.xml"/>
+    </zip>
+  </target>
+
+  <target name="dist" depends="check.teamcitydistribution,all,package"/>
+
+  <target name="clean" depends="git-teamcity.clean">
+    <delete dir="dist" quiet="true"/>
+  </target>
+
+  <target name="deploy" depends="dist">
+    <deploy.teamcity.plugin name="${plugin.name}"/>
+  </target>
+
+  <taskdef name="testng" classname="org.testng.TestNGAntTask" classpath="${basedir}/git-tests/lib/testng-5.7-jdk15.jar"/>
+
+  <target name="run-tests" depends="clean, init, compile.module.git-tests.production">
+    <property name="suspend" value="n"/>
+
+    <testng haltonfailure="no" failureProperty="failure_found" listener="org.testng.reporters.TestHTMLReporter"
+            outputdir="${basedir}/test-output" classpathref="git-tests.runtime.module.classpath" dumpcommand="true">
+
+      <jvmarg value="-ea"/>
+      <!--<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=${suspend},address=5555"/>-->
+
+      <sysproperty key="java.awt.headless" value="true"/>
+
+      <xmlfileset dir="${basedir}/git-tests/src">
+        <include name="testng.xml"/>
+      </xmlfileset>
+    </testng>
+  </target>
+
+  <target name="check_for_failures">
+    <fail if="failure_found" message="Failures found."/>
+  </target>
+
+</project>
+
         
\ No newline at end of file
index 9f76d8ad42fbdf9ba6dfb12594df3075fb8a0c84..5fc4f24aa29d64fe0438a20ff3c057a8a57cecc7 100755 (executable)
@@ -1,23 +1,23 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<module relativePaths="true" type="JAVA_MODULE" version="4">\r
-  <component name="FacetManager">\r
-    <facet type="Spring" name="Spring">\r
-      <configuration />\r
-    </facet>\r
-  </component>\r
-  <component name="NewModuleRootManager" inherit-compiler-output="true">\r
-    <exclude-output />\r
-    <content url="file://$MODULE_DIR$">\r
-      <sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />\r
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />\r
-    </content>\r
-    <orderEntry type="inheritedJdk" />\r
-    <orderEntry type="sourceFolder" forTests="false" />\r
-    <orderEntry type="library" name="TeamCity Open API common" level="project" />\r
-    <orderEntry type="library" name="TeamCity Open API server" level="project" />\r
-    <orderEntry type="library" name="TeamCity Third-Party" level="project" />\r
-    <orderEntry type="library" name="Tomcat" level="project" />\r
-    <orderEntry type="library" name="JGit" level="project" />\r
-  </component>\r
-</module>\r
-\r
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="TeamCity Open API common" level="project" />
+    <orderEntry type="library" name="TeamCity Open API server" level="project" />
+    <orderEntry type="library" name="TeamCity Third-Party" level="project" />
+    <orderEntry type="library" name="Tomcat" level="project" />
+    <orderEntry type="library" name="JGit" level="project" />
+  </component>
+</module>
+
index 0903fef9b649104fabdb82e16c7b0727180afd3a..3271b2a66668e2f795e1bd5e6f95bad980b056d4 100755 (executable)
-<%@ page import="java.io.File" %>\r
-<%@include file="/include.jsp" %>\r
-<%@ taglib prefix="props" tagdir="/WEB-INF/tags/props" %>\r
-<%--\r
-  ~ Copyright 2000-2009 JetBrains s.r.o.\r
-  ~\r
-  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
-  ~ you may not use this file except in compliance with the License.\r
-  ~ You may obtain a copy of the License at\r
-  ~\r
-  ~ http://www.apache.org/licenses/LICENSE-2.0\r
-  ~\r
-  ~ Unless required by applicable law or agreed to in writing, software\r
-  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-  ~ See the License for the specific language governing permissions and\r
-  ~ limitations under the License.\r
-  --%>\r
-\r
-<jsp:useBean id="propertiesBean" scope="request" type="jetbrains.buildServer.controllers.BasePropertiesBean"/>\r
-<table class="runnerFormTable">\r
-  <c:set var="userHome"\r
-         value='<%=new File(System.getProperty("user.home"), ".ssh"+File.separator+"config").getAbsolutePath() %>'/>\r
-  <l:settingsGroup title="General Settings">\r
-    <tr>\r
-      <th><label for="url">Clone URL: <l:star/></label></th>\r
-      <td><props:textProperty name="url" className="longField"/>\r
-        <span class="error" id="error_url"></span></td>\r
-    </tr>\r
-    <tr>\r
-      <th><label for="branch">Branch name: </label></th>\r
-      <td><props:textProperty name="branch"/></td>\r
-    </tr>\r
-    <tr>\r
-      <th><label for="path">Clone repository to: </label></th>\r
-      <td><props:textProperty name="path" className="longField"/>\r
-        <div class="smallNote" style="margin: 0;">Provide path to a directory on TeamCity server where a\r
-          bare cloned repository should be created. Leave blank to use default path.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-    <tr>\r
-      <th><label for="usernameStyle">User Name Style:</label></th>\r
-      <td><props:selectProperty name="usernameStyle">\r
-        <props:option value="USERID">UserId (jsmith)</props:option>\r
-        <props:option value="EMAIL">Email (jsmith@example.org)</props:option>\r
-        <props:option value="NAME">Name (John Smith)</props:option>\r
-        <props:option value="FULL">Full (John Smith &lt;jsmith@example.org&gt;)</props:option>\r
-      </props:selectProperty>\r
-        <div class="smallNote" style="margin: 0;">Changing user name style will affect only newly collected changes.\r
-          Old changes will continue to be stored with the style that was active at the time of collecting changes.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-    <tr>\r
-      <th><label for="submoduleCheckout">Submodules:</label></th>\r
-      <td><props:selectProperty name="submoduleCheckout">\r
-        <props:option value="IGNORE">Ignore</props:option>\r
-        <props:option value="CHECKOUT">Checkout</props:option>\r
-      </props:selectProperty>\r
-        <div class="smallNote" style="margin: 0">If the option "Checkout" is selected, the submodules are\r
-          treated as part of the source tree.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-  </l:settingsGroup>\r
-  <l:settingsGroup title="Authentication settings">\r
-    <tr>\r
-      <td colspan="2">Authorization settings can be required if the repository is password protected.</td>\r
-    </tr>\r
-    <tr>\r
-      <th><label for="authMethod">Authentication Method:</label></th>\r
-      <td><props:selectProperty name="authMethod" onchange="gitSelectAuthentication()">\r
-        <props:option value="ANONYMOUS">Anonymous</props:option>\r
-        <props:option value="PRIVATE_KEY_DEFAULT">Default Private Key</props:option>\r
-        <props:option value="PASSWORD">Password</props:option>\r
-        <props:option value="PRIVATE_KEY_FILE">Private Key</props:option>\r
-      </props:selectProperty>\r
-        <div id="sshPrivateKeyNote" class="smallNote" style="margin: 0">Valid only for SSH protocol.</div>\r
-        <div id="defaultPrivateKeyNote" class="smallNote" style="margin: 0">Uses mapping specified in the file\r
-          ${userHome} if that that file exists.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-    <tr id="gitUsername">\r
-      <th><label for="username">User name:</label></th>\r
-      <td><props:textProperty name="username"/>\r
-        <div class="smallNote" style="margin: 0">Username must be specified is there is no username in the clone URL.\r
-          The user name specified here overrides username from URL.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-    <tr id="gitKnownHosts">\r
-      <th>Known Hosts Database:</th>\r
-      <td><props:checkboxProperty name="ignoreKnownHosts"/>\r
-        <label for="ignoreKnownHosts">Do not check</label></td>\r
-    </tr>\r
-    <tr id="gitPasswordRow">\r
-      <th><label for="secure:password">Password:</label></th>\r
-      <td><props:passwordProperty name="secure:password"/></td>\r
-    </tr>\r
-    <tr id="gitPrivateKeyRow">\r
-      <th><label for="privateKeyPath">Private Key Path: <l:star/></label></th>\r
-      <td><props:textProperty name="privateKeyPath" className="longField"/>\r
-        <div class="smallNote" style="margin: 0;">Specify path to the private key\r
-          on the TeamCity server host.\r
-        </div>\r
-      </td>\r
-    </tr>\r
-    <tr id="gitPassphraseRow">\r
-      <th><label for="secure:passphrase">Passphrase:</label></th>\r
-      <td><props:passwordProperty name="secure:passphrase"/></td>\r
-    </tr>\r
-  </l:settingsGroup>\r
-</table>\r
-<script type="text/javascript">\r
-  window.gitSelectAuthentication = function() {\r
-    var c = $('authMethod');\r
-    switch (c.value) {\r
-      case 'PRIVATE_KEY_DEFAULT':\r
-        BS.Util.hide('gitPasswordRow', 'gitPrivateKeyRow', 'gitPassphraseRow');\r
-        BS.Util.show('gitUsername', 'gitKnownHosts');\r
-        BS.Util.show('sshPrivateKeyNote', 'defaultPrivateKeyNote');\r
-        break;\r
-      case 'PRIVATE_KEY_FILE':\r
-        BS.Util.hide('gitPasswordRow', 'gitKnownHosts');\r
-        BS.Util.show('gitUsername', 'gitPrivateKeyRow', 'gitPassphraseRow');\r
-        BS.Util.hide('defaultPrivateKeyNote');\r
-        BS.Util.show('sshPrivateKeyNote');\r
-        break;\r
-      case 'PASSWORD':\r
-        BS.Util.show('gitUsername', 'gitPasswordRow');\r
-        BS.Util.hide('gitPrivateKeyRow', 'gitPassphraseRow', 'gitKnownHosts');\r
-        BS.Util.hide('sshPrivateKeyNote', 'defaultPrivateKeyNote');\r
-        break;\r
-      case 'ANONYMOUS':\r
-        BS.Util.hide('gitUsername', 'gitPasswordRow', 'gitPrivateKeyRow', 'gitPassphraseRow', 'gitKnownHosts');\r
-        BS.Util.hide('sshPrivateKeyNote', 'defaultPrivateKeyNote');\r
-        break;\r
-      default:\r
-        alert('Unknown value: ' + c.value);\r
-        break;\r
-    }\r
-  }\r
-  gitSelectAuthentication();\r
-  if ($('url').value == "") {\r
-    $('submoduleCheckout').selectedIndex = 1;\r
-  }\r
-</script>\r
+<%@ page import="java.io.File" %>
+<%@include file="/include.jsp" %>
+<%@ taglib prefix="props" tagdir="/WEB-INF/tags/props" %>
+<%--
+  ~ Copyright 2000-2009 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  --%>
+
+<jsp:useBean id="propertiesBean" scope="request" type="jetbrains.buildServer.controllers.BasePropertiesBean"/>
+<table class="runnerFormTable">
+  <c:set var="userHome"
+         value='<%=new File(System.getProperty("user.home"), ".ssh"+File.separator+"config").getAbsolutePath() %>'/>
+  <l:settingsGroup title="General Settings">
+    <tr>
+      <th><label for="url">Clone URL: <l:star/></label></th>
+      <td><props:textProperty name="url" className="longField"/>
+        <span class="error" id="error_url"></span></td>
+    </tr>
+    <tr>
+      <th><label for="branch">Branch name: </label></th>
+      <td><props:textProperty name="branch"/></td>
+    </tr>
+    <tr>
+      <th><label for="path">Clone repository to: </label></th>
+      <td><props:textProperty name="path" className="longField"/>
+        <div class="smallNote" style="margin: 0;">Provide path to a directory on TeamCity server where a
+          bare cloned repository should be created. Leave blank to use default path.
+        </div>
+      </td>
+    </tr>
+    <tr>
+      <th><label for="usernameStyle">User Name Style:</label></th>
+      <td><props:selectProperty name="usernameStyle">
+        <props:option value="USERID">UserId (jsmith)</props:option>
+        <props:option value="EMAIL">Email (jsmith@example.org)</props:option>
+        <props:option value="NAME">Name (John Smith)</props:option>
+        <props:option value="FULL">Full (John Smith &lt;jsmith@example.org&gt;)</props:option>
+      </props:selectProperty>
+        <div class="smallNote" style="margin: 0;">Changing user name style will affect only newly collected changes.
+          Old changes will continue to be stored with the style that was active at the time of collecting changes.
+        </div>
+      </td>
+    </tr>
+    <tr>
+      <th><label for="submoduleCheckout">Submodules:</label></th>
+      <td><props:selectProperty name="submoduleCheckout">
+        <props:option value="IGNORE">Ignore</props:option>
+        <props:option value="CHECKOUT">Checkout</props:option>
+      </props:selectProperty>
+        <div class="smallNote" style="margin: 0">If the option "Checkout" is selected, the submodules are
+          treated as part of the source tree.
+        </div>
+      </td>
+    </tr>
+  </l:settingsGroup>
+  <l:settingsGroup title="Authentication settings">
+    <tr>
+      <td colspan="2">Authorization settings can be required if the repository is password protected.</td>
+    </tr>
+    <tr>
+      <th><label for="authMethod">Authentication Method:</label></th>
+      <td><props:selectProperty name="authMethod" onchange="gitSelectAuthentication()">
+        <props:option value="ANONYMOUS">Anonymous</props:option>
+        <props:option value="PRIVATE_KEY_DEFAULT">Default Private Key</props:option>
+        <props:option value="PASSWORD">Password</props:option>
+        <props:option value="PRIVATE_KEY_FILE">Private Key</props:option>
+      </props:selectProperty>
+        <div id="sshPrivateKeyNote" class="smallNote" style="margin: 0">Valid only for SSH protocol.</div>
+        <div id="defaultPrivateKeyNote" class="smallNote" style="margin: 0">Uses mapping specified in the file
+          ${userHome} if that that file exists.
+        </div>
+      </td>
+    </tr>
+    <tr id="gitUsername">
+      <th><label for="username">User name:</label></th>
+      <td><props:textProperty name="username"/>
+        <div class="smallNote" style="margin: 0">Username must be specified is there is no username in the clone URL.
+          The user name specified here overrides username from URL.
+        </div>
+      </td>
+    </tr>
+    <tr id="gitKnownHosts">
+      <th>Known Hosts Database:</th>
+      <td><props:checkboxProperty name="ignoreKnownHosts"/>
+        <label for="ignoreKnownHosts">Do not check</label></td>
+    </tr>
+    <tr id="gitPasswordRow">
+      <th><label for="secure:password">Password:</label></th>
+      <td><props:passwordProperty name="secure:password"/></td>
+    </tr>
+    <tr id="gitPrivateKeyRow">
+      <th><label for="privateKeyPath">Private Key Path: <l:star/></label></th>
+      <td><props:textProperty name="privateKeyPath" className="longField"/>
+        <div class="smallNote" style="margin: 0;">Specify path to the private key
+          on the TeamCity server host.
+        </div>
+      </td>
+    </tr>
+    <tr id="gitPassphraseRow">
+      <th><label for="secure:passphrase">Passphrase:</label></th>
+      <td><props:passwordProperty name="secure:passphrase"/></td>
+    </tr>
+  </l:settingsGroup>
+</table>
+<script type="text/javascript">
+  window.gitSelectAuthentication = function() {
+    var c = $('authMethod');
+    switch (c.value) {
+      case 'PRIVATE_KEY_DEFAULT':
+        BS.Util.hide('gitPasswordRow', 'gitPrivateKeyRow', 'gitPassphraseRow');
+        BS.Util.show('gitUsername', 'gitKnownHosts');
+        BS.Util.show('sshPrivateKeyNote', 'defaultPrivateKeyNote');
+        break;
+      case 'PRIVATE_KEY_FILE':
+        BS.Util.hide('gitPasswordRow', 'gitKnownHosts');
+        BS.Util.show('gitUsername', 'gitPrivateKeyRow', 'gitPassphraseRow');
+        BS.Util.hide('defaultPrivateKeyNote');
+        BS.Util.show('sshPrivateKeyNote');
+        break;
+      case 'PASSWORD':
+        BS.Util.show('gitUsername', 'gitPasswordRow');
+        BS.Util.hide('gitPrivateKeyRow', 'gitPassphraseRow', 'gitKnownHosts');
+        BS.Util.hide('sshPrivateKeyNote', 'defaultPrivateKeyNote');
+        break;
+      case 'ANONYMOUS':
+        BS.Util.hide('gitUsername', 'gitPasswordRow', 'gitPrivateKeyRow', 'gitPassphraseRow', 'gitKnownHosts');
+        BS.Util.hide('sshPrivateKeyNote', 'defaultPrivateKeyNote');
+        break;
+      default:
+        alert('Unknown value: ' + c.value);
+        break;
+    }
+  }
+  gitSelectAuthentication();
+  if ($('url').value == "") {
+    $('submoduleCheckout').selectedIndex = 1;
+  }
+</script>
index ff8250c4a118bd11f51fb16ea1cd249b5b011daa..9a731749cf1ce1bfc99f54df42ffb3e524252c7e 100755 (executable)
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-  ~ Copyright 2000-2009 JetBrains s.r.o.\r
-  ~\r
-  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
-  ~ you may not use this file except in compliance with the License.\r
-  ~ You may obtain a copy of the License at\r
-  ~\r
-  ~ http://www.apache.org/licenses/LICENSE-2.0\r
-  ~\r
-  ~ Unless required by applicable law or agreed to in writing, software\r
-  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-  ~ See the License for the specific language governing permissions and\r
-  ~ limitations under the License.\r
-  -->\r
-\r
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">\r
-\r
-<beans default-autowire="constructor">\r
-  <bean id="jetbrainsGitServer" class="jetbrains.buildServer.buildTriggers.vcs.git.GitVcsSupport"/>\r
-</beans>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2000-2009 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans default-autowire="constructor">
+  <bean id="jetbrainsGitServer" class="jetbrains.buildServer.buildTriggers.vcs.git.GitVcsSupport"/>
+</beans>
index b2d28e0cdc725b7f2336085d2af9f5c2471d42ca..15128d58df6c69e7a7550ff04a7ac0b8e7a8fb56 100755 (executable)
@@ -1,77 +1,77 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git;\r
-\r
-import jetbrains.buildServer.vcs.VcsRoot;\r
-\r
-/**\r
- * The configuration constants\r
- */\r
-public interface Constants {\r
-  /**\r
-   * The URL property\r
-   */\r
-  public static String URL = "url";\r
-  /**\r
-   * The path property\r
-   */\r
-  public static String PATH = "path";\r
-  /**\r
-   * The branch name property\r
-   */\r
-  public static String BRANCH_NAME = "branch";\r
-  /**\r
-   * The branch name property\r
-   */\r
-  public static String SUBMODULES_CHECKOUT = "submoduleCheckout";\r
-  /**\r
-   * The user name property\r
-   */\r
-  public static String AUTH_METHOD = "authMethod";\r
-  /**\r
-   * The user name property\r
-   */\r
-  public static String USERNAME = "username";\r
-  /**\r
-   * The user name property\r
-   */\r
-  public static String PRIVATE_KEY_PATH = "privateKeyPath";\r
-  /**\r
-   * The password property name\r
-   */\r
-  public static String PASSWORD = VcsRoot.SECURE_PROPERTY_PREFIX + "password";\r
-  /**\r
-   * The password property name\r
-   */\r
-  public static String PASSPHRASE = VcsRoot.SECURE_PROPERTY_PREFIX + "passphrase";\r
-  /**\r
-   * The vcs name\r
-   */\r
-  public static String VCS_NAME = "jetbrains.git";\r
-  /**\r
-   * The user name property\r
-   */\r
-  public static String USERNAME_STYLE = "usernameStyle";\r
-  /**\r
-   * The ignore known hosts property\r
-   */\r
-  public static String IGNORE_KNOWN_HOSTS = "ignoreKnownHosts";\r
-  /**\r
-   * The ignore known hosts property\r
-   */\r
-  public static String SUBMODULE_URLS = "submoduleUrls_TEST_ONLY";\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git;
+
+import jetbrains.buildServer.vcs.VcsRoot;
+
+/**
+ * The configuration constants
+ */
+public interface Constants {
+  /**
+   * The URL property
+   */
+  public static String URL = "url";
+  /**
+   * The path property
+   */
+  public static String PATH = "path";
+  /**
+   * The branch name property
+   */
+  public static String BRANCH_NAME = "branch";
+  /**
+   * The branch name property
+   */
+  public static String SUBMODULES_CHECKOUT = "submoduleCheckout";
+  /**
+   * The user name property
+   */
+  public static String AUTH_METHOD = "authMethod";
+  /**
+   * The user name property
+   */
+  public static String USERNAME = "username";
+  /**
+   * The user name property
+   */
+  public static String PRIVATE_KEY_PATH = "privateKeyPath";
+  /**
+   * The password property name
+   */
+  public static String PASSWORD = VcsRoot.SECURE_PROPERTY_PREFIX + "password";
+  /**
+   * The password property name
+   */
+  public static String PASSPHRASE = VcsRoot.SECURE_PROPERTY_PREFIX + "passphrase";
+  /**
+   * The vcs name
+   */
+  public static String VCS_NAME = "jetbrains.git";
+  /**
+   * The user name property
+   */
+  public static String USERNAME_STYLE = "usernameStyle";
+  /**
+   * The ignore known hosts property
+   */
+  public static String IGNORE_KNOWN_HOSTS = "ignoreKnownHosts";
+  /**
+   * The ignore known hosts property
+   */
+  public static String SUBMODULE_URLS = "submoduleUrls_TEST_ONLY";
+}
index b6b481f4b2ca7fe299d8a10668cda2b24bbbc78a..79361cc646faf281ba75afdf8085f21108053240 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git;\r
-\r
-import jetbrains.buildServer.vcs.VcsException;\r
-import org.jetbrains.annotations.NotNull;\r
-import org.spearce.jgit.lib.Commit;\r
-import org.spearce.jgit.lib.PersonIdent;\r
-import org.spearce.jgit.lib.Repository;\r
-import org.spearce.jgit.lib.RepositoryConfig;\r
-import org.spearce.jgit.transport.URIish;\r
-\r
-import java.io.File;\r
-import java.io.UnsupportedEncodingException;\r
-import java.nio.charset.Charset;\r
-import java.util.Comparator;\r
-\r
-/**\r
- * Commands that allows working with git repositories\r
- */\r
-public class GitUtils {\r
-  /**\r
-   * Amount of characters displayed for in the display version of revision number\r
-   */\r
-  public static final int DISPLAY_VERSION_AMOUNT = 40;\r
-  /**\r
-   * User name for the system user\r
-   */\r
-  public static final String SYSTEM_USER = "system@git-plugin.teamcity";\r
-  /**\r
-   * The UTF8 character set\r
-   */\r
-  public static final Charset UTF8 = Charset.forName("UTF-8");\r
-\r
-  /**\r
-   * Convert remote URL to JGIT form\r
-   *\r
-   * @param file the file to convert\r
-   * @return the file URL recognized by JGit\r
-   */\r
-  public static String toURL(File file) {\r
-    return "file:///" + file.getAbsolutePath().replace(File.separatorChar, '/');\r
-  }\r
-\r
-  /**\r
-   * The version comparator\r
-   */\r
-  public static final Comparator<String> VERSION_COMPARATOR = new Comparator<String>() {\r
-    public int compare(String o1, String o2) {\r
-      long r = versionTime(o1) - versionTime(o2);\r
-      return r < 0 ? -1 : r > 0 ? 1 : 0;\r
-    }\r
-  };\r
-\r
-  /**\r
-   * Make version string from revision hash and time\r
-   *\r
-   * @param revision the revision hash\r
-   * @param time     the time of revision\r
-   * @return the version string\r
-   */\r
-  @NotNull\r
-  public static String makeVersion(@NotNull String revision, long time) {\r
-    return revision + "@" + Long.toHexString(time);\r
-  }\r
-\r
-  /**\r
-   * Extract revision number from the version\r
-   *\r
-   * @param version string\r
-   * @return the revision number\r
-   */\r
-  @NotNull\r
-  public static String versionRevision(@NotNull String version) {\r
-    int i = version.indexOf('@');\r
-    if (i == -1) {\r
-      throw new IllegalArgumentException("Invalid format of version: " + version);\r
-    }\r
-    return version.substring(0, i);\r
-  }\r
-\r
-  /**\r
-   * Extract revision number from the version\r
-   *\r
-   * @param version string\r
-   * @return the revision number\r
-   */\r
-  public static long versionTime(@NotNull String version) {\r
-    int i = version.indexOf('@');\r
-    if (i == -1) {\r
-      throw new IllegalArgumentException("Invalid format of version: " + version);\r
-    }\r
-    return Long.parseLong(version.substring(i + 1), 16);\r
-  }\r
-\r
-  /**\r
-   * Ensures that a bare repository exists at the specified path.\r
-   * If it does not, the directory is attempted to be created.\r
-   *\r
-   * @param dir    the path to the directory to init\r
-   * @param remote the remote URL\r
-   * @return a connection to repository\r
-   * @throws VcsException if the there is a problem with accessing VCS\r
-   */\r
-  public static Repository getRepository(File dir, URIish remote) throws VcsException {\r
-    if (dir.exists() && !dir.isDirectory()) {\r
-      throw new VcsException("The specified path is not a directory: " + dir);\r
-    }\r
-    try {\r
-      Repository r = new Repository(dir);\r
-      if (!new File(dir, "config").exists()) {\r
-        r.create(true);\r
-        final RepositoryConfig config = r.getConfig();\r
-        config.setString("teamcity", null, "remote", remote.toString());\r
-        config.save();\r
-      } else {\r
-        final RepositoryConfig config = r.getConfig();\r
-        final String existingRemote = config.getString("teamcity", null, "remote");\r
-        if (existingRemote != null && !remote.toString().equals(existingRemote)) {\r
-          throw new VcsException(\r
-            "The specified directory " + dir + " is already used for another remote " + existingRemote +\r
-            " and cannot be used for others. Please specify the other directory explicitly.");\r
-        }\r
-      }\r
-      return r;\r
-    } catch (Exception ex) {\r
-      throw new VcsException("The repository at " + dir + " cannot be opened or created: " + ex, ex);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Create reference name from branch name\r
-   *\r
-   * @param branch the branch name\r
-   * @return the reference name\r
-   */\r
-  public static String branchRef(String branch) {\r
-    return "refs/heads/" + branch;\r
-  }\r
-\r
-\r
-  /**\r
-   * Make version from commit object\r
-   *\r
-   * @param c the commit object\r
-   * @return the version string\r
-   */\r
-  public static String makeVersion(Commit c) {\r
-    return makeVersion(c.getCommitId().name(), c.getCommitter().getWhen().getTime());\r
-  }\r
-\r
-  /**\r
-   * Get user for the commit\r
-   *\r
-   * @param s the vcs root settings\r
-   * @param c the commit\r
-   * @return the user name\r
-   */\r
-  public static String getUser(Settings s, Commit c) {\r
-    final PersonIdent a = c.getAuthor();\r
-    switch (s.getUsernameStyle()) {\r
-      case NAME:\r
-        return a.getName();\r
-      case EMAIL:\r
-        return a.getEmailAddress();\r
-      case FULL:\r
-        return a.getName() + " <" + a.getEmailAddress() + ">";\r
-      case USERID:\r
-        String email = a.getEmailAddress();\r
-        final int i = email.lastIndexOf("@");\r
-        return email.substring(0, i > 0 ? i : email.length());\r
-      default:\r
-        throw new IllegalStateException("Unsupported username style: " + s.getUsernameStyle());\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Create display version for the commit\r
-   *\r
-   * @param c the commit to examine\r
-   * @return the display version\r
-   */\r
-  public static String displayVersion(Commit c) {\r
-    return displayVersion(c.getCommitId().name());\r
-  }\r
-\r
-  /**\r
-   * Create display version for the commit\r
-   *\r
-   * @param version the version to examine\r
-   * @return the display version\r
-   */\r
-  public static String displayVersion(String version) {\r
-    return version.substring(0, DISPLAY_VERSION_AMOUNT);\r
-  }\r
-\r
-  /**\r
-   * Convert Git path to a relative File\r
-   *\r
-   * @param path the path to covert\r
-   * @return the {@link File} object\r
-   */\r
-  public static File toFile(String path) {\r
-    return new File(path.replace('/', File.separatorChar));\r
-  }\r
-\r
-  /**\r
-   * Ref name for the tag\r
-   *\r
-   * @param label the tag name\r
-   * @return the reference name\r
-   */\r
-  public static String tagName(String label) {\r
-    return "refs/tags/" + label;\r
-  }\r
-\r
-  /**\r
-   * Get UTF8 bytes\r
-   *\r
-   * @param s a string to convert\r
-   * @return a UTF8 bytes for the string\r
-   */\r
-  public static byte[] getUtf8(String s) {\r
-    try {\r
-      return s.getBytes(UTF8.name());\r
-    } catch (UnsupportedEncodingException e) {\r
-      throw new RuntimeException("UTF-8 encoding not found", e);\r
-    }\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git;
+
+import jetbrains.buildServer.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.PersonIdent;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.lib.RepositoryConfig;
+import org.spearce.jgit.transport.URIish;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Comparator;
+
+/**
+ * Commands that allows working with git repositories
+ */
+public class GitUtils {
+  /**
+   * Amount of characters displayed for in the display version of revision number
+   */
+  public static final int DISPLAY_VERSION_AMOUNT = 40;
+  /**
+   * User name for the system user
+   */
+  public static final String SYSTEM_USER = "system@git-plugin.teamcity";
+  /**
+   * The UTF8 character set
+   */
+  public static final Charset UTF8 = Charset.forName("UTF-8");
+
+  /**
+   * Convert remote URL to JGIT form
+   *
+   * @param file the file to convert
+   * @return the file URL recognized by JGit
+   */
+  public static String toURL(File file) {
+    return "file:///" + file.getAbsolutePath().replace(File.separatorChar, '/');
+  }
+
+  /**
+   * The version comparator
+   */
+  public static final Comparator<String> VERSION_COMPARATOR = new Comparator<String>() {
+    public int compare(String o1, String o2) {
+      long r = versionTime(o1) - versionTime(o2);
+      return r < 0 ? -1 : r > 0 ? 1 : 0;
+    }
+  };
+
+  /**
+   * Make version string from revision hash and time
+   *
+   * @param revision the revision hash
+   * @param time     the time of revision
+   * @return the version string
+   */
+  @NotNull
+  public static String makeVersion(@NotNull String revision, long time) {
+    return revision + "@" + Long.toHexString(time);
+  }
+
+  /**
+   * Extract revision number from the version
+   *
+   * @param version string
+   * @return the revision number
+   */
+  @NotNull
+  public static String versionRevision(@NotNull String version) {
+    int i = version.indexOf('@');
+    if (i == -1) {
+      throw new IllegalArgumentException("Invalid format of version: " + version);
+    }
+    return version.substring(0, i);
+  }
+
+  /**
+   * Extract revision number from the version
+   *
+   * @param version string
+   * @return the revision number
+   */
+  public static long versionTime(@NotNull String version) {
+    int i = version.indexOf('@');
+    if (i == -1) {
+      throw new IllegalArgumentException("Invalid format of version: " + version);
+    }
+    return Long.parseLong(version.substring(i + 1), 16);
+  }
+
+  /**
+   * Ensures that a bare repository exists at the specified path.
+   * If it does not, the directory is attempted to be created.
+   *
+   * @param dir    the path to the directory to init
+   * @param remote the remote URL
+   * @return a connection to repository
+   * @throws VcsException if the there is a problem with accessing VCS
+   */
+  public static Repository getRepository(File dir, URIish remote) throws VcsException {
+    if (dir.exists() && !dir.isDirectory()) {
+      throw new VcsException("The specified path is not a directory: " + dir);
+    }
+    try {
+      Repository r = new Repository(dir);
+      if (!new File(dir, "config").exists()) {
+        r.create(true);
+        final RepositoryConfig config = r.getConfig();
+        config.setString("teamcity", null, "remote", remote.toString());
+        config.save();
+      } else {
+        final RepositoryConfig config = r.getConfig();
+        final String existingRemote = config.getString("teamcity", null, "remote");
+        if (existingRemote != null && !remote.toString().equals(existingRemote)) {
+          throw new VcsException(
+            "The specified directory " + dir + " is already used for another remote " + existingRemote +
+            " and cannot be used for others. Please specify the other directory explicitly.");
+        }
+      }
+      return r;
+    } catch (Exception ex) {
+      throw new VcsException("The repository at " + dir + " cannot be opened or created: " + ex, ex);
+    }
+  }
+
+  /**
+   * Create reference name from branch name
+   *
+   * @param branch the branch name
+   * @return the reference name
+   */
+  public static String branchRef(String branch) {
+    return "refs/heads/" + branch;
+  }
+
+
+  /**
+   * Make version from commit object
+   *
+   * @param c the commit object
+   * @return the version string
+   */
+  public static String makeVersion(Commit c) {
+    return makeVersion(c.getCommitId().name(), c.getCommitter().getWhen().getTime());
+  }
+
+  /**
+   * Get user for the commit
+   *
+   * @param s the vcs root settings
+   * @param c the commit
+   * @return the user name
+   */
+  public static String getUser(Settings s, Commit c) {
+    final PersonIdent a = c.getAuthor();
+    switch (s.getUsernameStyle()) {
+      case NAME:
+        return a.getName();
+      case EMAIL:
+        return a.getEmailAddress();
+      case FULL:
+        return a.getName() + " <" + a.getEmailAddress() + ">";
+      case USERID:
+        String email = a.getEmailAddress();
+        final int i = email.lastIndexOf("@");
+        return email.substring(0, i > 0 ? i : email.length());
+      default:
+        throw new IllegalStateException("Unsupported username style: " + s.getUsernameStyle());
+    }
+  }
+
+  /**
+   * Create display version for the commit
+   *
+   * @param c the commit to examine
+   * @return the display version
+   */
+  public static String displayVersion(Commit c) {
+    return displayVersion(c.getCommitId().name());
+  }
+
+  /**
+   * Create display version for the commit
+   *
+   * @param version the version to examine
+   * @return the display version
+   */
+  public static String displayVersion(String version) {
+    return version.substring(0, DISPLAY_VERSION_AMOUNT);
+  }
+
+  /**
+   * Convert Git path to a relative File
+   *
+   * @param path the path to covert
+   * @return the {@link File} object
+   */
+  public static File toFile(String path) {
+    return new File(path.replace('/', File.separatorChar));
+  }
+
+  /**
+   * Ref name for the tag
+   *
+   * @param label the tag name
+   * @return the reference name
+   */
+  public static String tagName(String label) {
+    return "refs/tags/" + label;
+  }
+
+  /**
+   * Get UTF8 bytes
+   *
+   * @param s a string to convert
+   * @return a UTF8 bytes for the string
+   */
+  public static byte[] getUtf8(String s) {
+    try {
+      return s.getBytes(UTF8.name());
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 encoding not found", e);
+    }
+  }
+}
index 088daac0e771de7d03d5afd236575c2734ff4ee5..a8261814ba54825291d90b8ce10c62da40c66713 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git;\r
-\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import com.intellij.openapi.util.text.StringUtil;\r
-import jetbrains.buildServer.vcs.VcsException;\r
-import jetbrains.buildServer.vcs.VcsRoot;\r
-import org.spearce.jgit.transport.URIish;\r
-\r
-import java.io.File;\r
-import java.net.URISyntaxException;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-/**\r
- * Git Vcs Settings\r
- */\r
-public class Settings {\r
-  /**\r
-   * logger instance\r
-   */\r
-  private static Logger LOG = Logger.getInstance(Settings.class.getName());\r
-  /**\r
-   * The url for the repository\r
-   */\r
-  private URIish repositoryURL;\r
-  /**\r
-   * The public URL\r
-   */\r
-  private String publicURL;\r
-  /**\r
-   * The current branch\r
-   */\r
-  private String branch;\r
-  /**\r
-   * The repository path\r
-   */\r
-  private File repositoryPath;\r
-  /**\r
-   * The style for user name\r
-   */\r
-  private UserNameStyle usernameStyle;\r
-  /**\r
-   * The authentication method\r
-   */\r
-  private AuthenticationMethod authenticationMethod;\r
-  /**\r
-   * Submodule checkout policy\r
-   */\r
-  private SubmodulesCheckoutPolicy submodulePolicy;\r
-  /**\r
-   * The passphrase (used for {@link AuthenticationMethod#PRIVATE_KEY_FILE})\r
-   */\r
-  private String passphrase;\r
-  /**\r
-   * The private key file (used for {@link AuthenticationMethod#PRIVATE_KEY_FILE})\r
-   */\r
-  private String privateKeyFile;\r
-  /**\r
-   * If true, known hosts are ignored\r
-   */\r
-  private boolean ignoreKnownHosts;\r
-  /**\r
-   * The directory where internal roots are created\r
-   */\r
-  private String cachesDirectory;\r
-  /**\r
-   * The submodule URLs\r
-   */\r
-  private final Map<String, String> submoduleUrls = new HashMap<String, String>();\r
-  /**\r
-   * The submodule paths.\r
-   */\r
-  private final Map<String, String> submodulePaths = new HashMap<String, String>();\r
-\r
-  /**\r
-   * The constructor from the root object\r
-   *\r
-   * @param root the root\r
-   * @throws VcsException in case of incorrect configuration\r
-   */\r
-  public Settings(VcsRoot root) throws VcsException {\r
-    final String p = root.getProperty(Constants.PATH);\r
-    repositoryPath = p == null ? null : new File(p);\r
-    branch = root.getProperty(Constants.BRANCH_NAME);\r
-    final String style = root.getProperty(Constants.USERNAME_STYLE);\r
-    usernameStyle = style == null ? UserNameStyle.USERID : Enum.valueOf(UserNameStyle.class, style);\r
-    String submoduleCheckout = root.getProperty(Constants.SUBMODULES_CHECKOUT);\r
-    submodulePolicy =\r
-      submoduleCheckout != null ? Enum.valueOf(SubmodulesCheckoutPolicy.class, submoduleCheckout) : SubmodulesCheckoutPolicy.IGNORE;\r
-    final String authMethod = root.getProperty(Constants.AUTH_METHOD);\r
-    authenticationMethod = authMethod == null ? AuthenticationMethod.ANONYMOUS : Enum.valueOf(AuthenticationMethod.class, authMethod);\r
-    String username = authenticationMethod == AuthenticationMethod.ANONYMOUS ? null : root.getProperty(Constants.USERNAME);\r
-    String password = authenticationMethod != AuthenticationMethod.PASSWORD ? null : root.getProperty(Constants.PASSWORD);\r
-    ignoreKnownHosts = "true".equals(root.getProperty(Constants.IGNORE_KNOWN_HOSTS));\r
-    final String remote = root.getProperty(Constants.URL);\r
-    URIish uri;\r
-    try {\r
-      uri = new URIish(remote);\r
-    } catch (URISyntaxException e) {\r
-      throw new VcsException("Invalid URI: " + remote);\r
-    }\r
-    if (!StringUtil.isEmptyOrSpaces(username)) {\r
-      uri = uri.setUser(username);\r
-    }\r
-    if (!StringUtil.isEmpty(password)) {\r
-      uri = uri.setPass(password);\r
-    }\r
-    if (authenticationMethod == AuthenticationMethod.PRIVATE_KEY_FILE) {\r
-      passphrase = root.getProperty(Constants.PASSPHRASE);\r
-      privateKeyFile = root.getProperty(Constants.PRIVATE_KEY_PATH);\r
-    }\r
-    publicURL = uri.toString();\r
-    repositoryURL = uri;\r
-    String urls = root.getProperty(Constants.SUBMODULE_URLS);\r
-    if (urls != null) {\r
-      final String[] pairs = urls.split("\n");\r
-      final int n = pairs.length / 2;\r
-      for (int i = 0; i < n; i++) {\r
-        setSubmoduleUrl(pairs[i * 2], pairs[i * 2 + 1]);\r
-      }\r
-    }\r
-  }\r
-\r
-\r
-  /**\r
-   * Set submodule path\r
-   *\r
-   * @param submodule the local path of submodule within vcs root\r
-   * @param path      the path to set\r
-   */\r
-  public void setSubmodulePath(String submodule, String path) {\r
-    submodulePaths.put(submodule, path);\r
-  }\r
-\r
-  /**\r
-   * Get submodule path\r
-   *\r
-   * @param submodule the local path of submodule within vcs root\r
-   * @param url       the url used to construct a default path\r
-   * @return the path on file system or null if path is not set\r
-   */\r
-  public String getSubmodulePath(String submodule, String url) {\r
-    String path = submodulePaths.get(submodule);\r
-    if (path == null) {\r
-      path = getPathForUrl(url).getPath();\r
-    }\r
-    return path;\r
-  }\r
-\r
-  /**\r
-   * Set submodule url\r
-   *\r
-   * @param submodule the local path of submodule within vcs root\r
-   * @param url       the url to set\r
-   */\r
-  public void setSubmoduleUrl(String submodule, String url) {\r
-    submoduleUrls.put(submodule, url);\r
-  }\r
-\r
-  /**\r
-   * Get submodule url\r
-   *\r
-   * @param submodule the local path of submodule within vcs root\r
-   * @return the url or null if url is not set\r
-   */\r
-  public String getSubmoduleUrl(String submodule) {\r
-    return submoduleUrls.get(submodule);\r
-  }\r
-\r
-  /**\r
-   * @return true if submodules should be checked out\r
-   */\r
-  public boolean areSubmodulesCheckedOut() {\r
-    return submodulePolicy == SubmodulesCheckoutPolicy.CHECKOUT;\r
-  }\r
-\r
-  /**\r
-   * @return username style\r
-   */\r
-  public UserNameStyle getUsernameStyle() {\r
-    return usernameStyle;\r
-  }\r
-\r
-  /**\r
-   * @return the URL with password removed\r
-   */\r
-  public String getPublicURL() {\r
-    return publicURL;\r
-  }\r
-\r
-  /**\r
-   * @return the local repository path\r
-   */\r
-  public File getRepositoryPath() {\r
-    if (repositoryPath == null) {\r
-      if (LOG.isDebugEnabled()) {\r
-        LOG.debug("Using internal directory for (" + getPublicURL() + "#" + getBranch() + ")");\r
-      }\r
-      repositoryPath = getPathForUrl(getRepositoryURL().toString());\r
-    }\r
-    return repositoryPath;\r
-  }\r
-\r
-  /**\r
-   * Set repository path\r
-   *\r
-   * @param file the path to set\r
-   */\r
-  public void setRepositoryPath(File file) {\r
-    repositoryPath = file;\r
-  }\r
-\r
-  /**\r
-   * @return the URL for the repository\r
-   */\r
-  public URIish getRepositoryURL() {\r
-    return repositoryURL;\r
-  }\r
-\r
-  /**\r
-   * @return the branch name\r
-   */\r
-  public String getBranch() {\r
-    return branch == null || branch.length() == 0 ? "master" : branch;\r
-  }\r
-\r
-  /**\r
-   * @return debug information that allows identify repository operation context\r
-   */\r
-  public String debugInfo() {\r
-    return " (" + getRepositoryPath() + ", " + getPublicURL() + "#" + getBranch() + ")";\r
-  }\r
-\r
-  /**\r
-   * Authentication method to use\r
-   *\r
-   * @return the authentication method\r
-   */\r
-  public AuthenticationMethod getAuthenticationMethod() {\r
-    return authenticationMethod;\r
-  }\r
-\r
-\r
-  /**\r
-   * @return the passphrase for private key\r
-   */\r
-  public String getPassphrase() {\r
-    return passphrase;\r
-  }\r
-\r
-  /**\r
-   * @return the path to private key file\r
-   */\r
-  public String getPrivateKeyFile() {\r
-    return privateKeyFile;\r
-  }\r
-\r
-  /**\r
-   * @return true if the result of checking in known hosts database should be ignored\r
-   */\r
-  public boolean isKnownHostsIgnored() {\r
-    return ignoreKnownHosts;\r
-  }\r
-\r
-  /**\r
-   * Get server paths for the URL\r
-   *\r
-   * @param url the URL to get path for\r
-   * @return the internal directory name for the URL\r
-   */\r
-  public File getPathForUrl(String url) {\r
-    File dir = new File(cachesDirectory);\r
-    // TODO the directory needs to be cleaned up\r
-    // TODO consider using a better hash in order to reduce a chance for conflict\r
-    String name = String.format("git-%08X.git", url.hashCode() & 0xFFFFFFFFL);\r
-    return new File(dir, "git" + File.separatorChar + name);\r
-  }\r
-\r
-  /**\r
-   * Set caches directory for the settings\r
-   *\r
-   * @param cachesDirectory caches directory\r
-   */\r
-  public void setCachesDirectory(String cachesDirectory) {\r
-    this.cachesDirectory = cachesDirectory;\r
-  }\r
-\r
-\r
-  /**\r
-   * Authentication method\r
-   */\r
-  enum AuthenticationMethod {\r
-    /**\r
-     * Anonymous access (or password is a part of URL)\r
-     */\r
-    ANONYMOUS,\r
-    /**\r
-     * The default SSH private key\r
-     */\r
-    PRIVATE_KEY_DEFAULT,\r
-    /**\r
-     * The private key is specified in the file\r
-     */\r
-    PRIVATE_KEY_FILE,\r
-    /**\r
-     * The password is used\r
-     */\r
-    PASSWORD\r
-  }\r
-\r
-  /**\r
-   * Submodule checkout policy\r
-   */\r
-  public enum SubmodulesCheckoutPolicy {\r
-    /**\r
-     * Ignore submodules\r
-     */\r
-    IGNORE,\r
-    /**\r
-     * Checkout submodules\r
-     */\r
-    CHECKOUT,\r
-  }\r
-\r
-  /**\r
-   * The style for user names\r
-   */\r
-  enum UserNameStyle {\r
-    /**\r
-     * Name (John Smith)\r
-     */\r
-    NAME,\r
-    /**\r
-     * User id based on email (jsmith)\r
-     */\r
-    USERID,\r
-    /**\r
-     * Email (jsmith@example.org)\r
-     */\r
-    EMAIL,\r
-    /**\r
-     * Name and Email (John Smith &ltjsmith@example.org&gt)\r
-     */\r
-    FULL\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import jetbrains.buildServer.vcs.VcsException;
+import jetbrains.buildServer.vcs.VcsRoot;
+import org.spearce.jgit.transport.URIish;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Git Vcs Settings
+ */
+public class Settings {
+  /**
+   * logger instance
+   */
+  private static Logger LOG = Logger.getInstance(Settings.class.getName());
+  /**
+   * The url for the repository
+   */
+  private URIish repositoryURL;
+  /**
+   * The public URL
+   */
+  private String publicURL;
+  /**
+   * The current branch
+   */
+  private String branch;
+  /**
+   * The repository path
+   */
+  private File repositoryPath;
+  /**
+   * The style for user name
+   */
+  private UserNameStyle usernameStyle;
+  /**
+   * The authentication method
+   */
+  private AuthenticationMethod authenticationMethod;
+  /**
+   * Submodule checkout policy
+   */
+  private SubmodulesCheckoutPolicy submodulePolicy;
+  /**
+   * The passphrase (used for {@link AuthenticationMethod#PRIVATE_KEY_FILE})
+   */
+  private String passphrase;
+  /**
+   * The private key file (used for {@link AuthenticationMethod#PRIVATE_KEY_FILE})
+   */
+  private String privateKeyFile;
+  /**
+   * If true, known hosts are ignored
+   */
+  private boolean ignoreKnownHosts;
+  /**
+   * The directory where internal roots are created
+   */
+  private String cachesDirectory;
+  /**
+   * The submodule URLs
+   */
+  private final Map<String, String> submoduleUrls = new HashMap<String, String>();
+  /**
+   * The submodule paths.
+   */
+  private final Map<String, String> submodulePaths = new HashMap<String, String>();
+
+  /**
+   * The constructor from the root object
+   *
+   * @param root the root
+   * @throws VcsException in case of incorrect configuration
+   */
+  public Settings(VcsRoot root) throws VcsException {
+    final String p = root.getProperty(Constants.PATH);
+    repositoryPath = p == null ? null : new File(p);
+    branch = root.getProperty(Constants.BRANCH_NAME);
+    final String style = root.getProperty(Constants.USERNAME_STYLE);
+    usernameStyle = style == null ? UserNameStyle.USERID : Enum.valueOf(UserNameStyle.class, style);
+    String submoduleCheckout = root.getProperty(Constants.SUBMODULES_CHECKOUT);
+    submodulePolicy =
+      submoduleCheckout != null ? Enum.valueOf(SubmodulesCheckoutPolicy.class, submoduleCheckout) : SubmodulesCheckoutPolicy.IGNORE;
+    final String authMethod = root.getProperty(Constants.AUTH_METHOD);
+    authenticationMethod = authMethod == null ? AuthenticationMethod.ANONYMOUS : Enum.valueOf(AuthenticationMethod.class, authMethod);
+    String username = authenticationMethod == AuthenticationMethod.ANONYMOUS ? null : root.getProperty(Constants.USERNAME);
+    String password = authenticationMethod != AuthenticationMethod.PASSWORD ? null : root.getProperty(Constants.PASSWORD);
+    ignoreKnownHosts = "true".equals(root.getProperty(Constants.IGNORE_KNOWN_HOSTS));
+    final String remote = root.getProperty(Constants.URL);
+    URIish uri;
+    try {
+      uri = new URIish(remote);
+    } catch (URISyntaxException e) {
+      throw new VcsException("Invalid URI: " + remote);
+    }
+    if (!StringUtil.isEmptyOrSpaces(username)) {
+      uri = uri.setUser(username);
+    }
+    if (!StringUtil.isEmpty(password)) {
+      uri = uri.setPass(password);
+    }
+    if (authenticationMethod == AuthenticationMethod.PRIVATE_KEY_FILE) {
+      passphrase = root.getProperty(Constants.PASSPHRASE);
+      privateKeyFile = root.getProperty(Constants.PRIVATE_KEY_PATH);
+    }
+    publicURL = uri.toString();
+    repositoryURL = uri;
+    String urls = root.getProperty(Constants.SUBMODULE_URLS);
+    if (urls != null) {
+      final String[] pairs = urls.split("\n");
+      final int n = pairs.length / 2;
+      for (int i = 0; i < n; i++) {
+        setSubmoduleUrl(pairs[i * 2], pairs[i * 2 + 1]);
+      }
+    }
+  }
+
+
+  /**
+   * Set submodule path
+   *
+   * @param submodule the local path of submodule within vcs root
+   * @param path      the path to set
+   */
+  public void setSubmodulePath(String submodule, String path) {
+    submodulePaths.put(submodule, path);
+  }
+
+  /**
+   * Get submodule path
+   *
+   * @param submodule the local path of submodule within vcs root
+   * @param url       the url used to construct a default path
+   * @return the path on file system or null if path is not set
+   */
+  public String getSubmodulePath(String submodule, String url) {
+    String path = submodulePaths.get(submodule);
+    if (path == null) {
+      path = getPathForUrl(url).getPath();
+    }
+    return path;
+  }
+
+  /**
+   * Set submodule url
+   *
+   * @param submodule the local path of submodule within vcs root
+   * @param url       the url to set
+   */
+  public void setSubmoduleUrl(String submodule, String url) {
+    submoduleUrls.put(submodule, url);
+  }
+
+  /**
+   * Get submodule url
+   *
+   * @param submodule the local path of submodule within vcs root
+   * @return the url or null if url is not set
+   */
+  public String getSubmoduleUrl(String submodule) {
+    return submoduleUrls.get(submodule);
+  }
+
+  /**
+   * @return true if submodules should be checked out
+   */
+  public boolean areSubmodulesCheckedOut() {
+    return submodulePolicy == SubmodulesCheckoutPolicy.CHECKOUT;
+  }
+
+  /**
+   * @return username style
+   */
+  public UserNameStyle getUsernameStyle() {
+    return usernameStyle;
+  }
+
+  /**
+   * @return the URL with password removed
+   */
+  public String getPublicURL() {
+    return publicURL;
+  }
+
+  /**
+   * @return the local repository path
+   */
+  public File getRepositoryPath() {
+    if (repositoryPath == null) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Using internal directory for (" + getPublicURL() + "#" + getBranch() + ")");
+      }
+      repositoryPath = getPathForUrl(getRepositoryURL().toString());
+    }
+    return repositoryPath;
+  }
+
+  /**
+   * Set repository path
+   *
+   * @param file the path to set
+   */
+  public void setRepositoryPath(File file) {
+    repositoryPath = file;
+  }
+
+  /**
+   * @return the URL for the repository
+   */
+  public URIish getRepositoryURL() {
+    return repositoryURL;
+  }
+
+  /**
+   * @return the branch name
+   */
+  public String getBranch() {
+    return branch == null || branch.length() == 0 ? "master" : branch;
+  }
+
+  /**
+   * @return debug information that allows identify repository operation context
+   */
+  public String debugInfo() {
+    return " (" + getRepositoryPath() + ", " + getPublicURL() + "#" + getBranch() + ")";
+  }
+
+  /**
+   * Authentication method to use
+   *
+   * @return the authentication method
+   */
+  public AuthenticationMethod getAuthenticationMethod() {
+    return authenticationMethod;
+  }
+
+
+  /**
+   * @return the passphrase for private key
+   */
+  public String getPassphrase() {
+    return passphrase;
+  }
+
+  /**
+   * @return the path to private key file
+   */
+  public String getPrivateKeyFile() {
+    return privateKeyFile;
+  }
+
+  /**
+   * @return true if the result of checking in known hosts database should be ignored
+   */
+  public boolean isKnownHostsIgnored() {
+    return ignoreKnownHosts;
+  }
+
+  /**
+   * Get server paths for the URL
+   *
+   * @param url the URL to get path for
+   * @return the internal directory name for the URL
+   */
+  public File getPathForUrl(String url) {
+    File dir = new File(cachesDirectory);
+    // TODO the directory needs to be cleaned up
+    // TODO consider using a better hash in order to reduce a chance for conflict
+    String name = String.format("git-%08X.git", url.hashCode() & 0xFFFFFFFFL);
+    return new File(dir, "git" + File.separatorChar + name);
+  }
+
+  /**
+   * Set caches directory for the settings
+   *
+   * @param cachesDirectory caches directory
+   */
+  public void setCachesDirectory(String cachesDirectory) {
+    this.cachesDirectory = cachesDirectory;
+  }
+
+
+  /**
+   * Authentication method
+   */
+  enum AuthenticationMethod {
+    /**
+     * Anonymous access (or password is a part of URL)
+     */
+    ANONYMOUS,
+    /**
+     * The default SSH private key
+     */
+    PRIVATE_KEY_DEFAULT,
+    /**
+     * The private key is specified in the file
+     */
+    PRIVATE_KEY_FILE,
+    /**
+     * The password is used
+     */
+    PASSWORD
+  }
+
+  /**
+   * Submodule checkout policy
+   */
+  public enum SubmodulesCheckoutPolicy {
+    /**
+     * Ignore submodules
+     */
+    IGNORE,
+    /**
+     * Checkout submodules
+     */
+    CHECKOUT,
+  }
+
+  /**
+   * The style for user names
+   */
+  enum UserNameStyle {
+    /**
+     * Name (John Smith)
+     */
+    NAME,
+    /**
+     * User id based on email (jsmith)
+     */
+    USERID,
+    /**
+     * Email (jsmith@example.org)
+     */
+    EMAIL,
+    /**
+     * Name and Email (John Smith &ltjsmith@example.org&gt)
+     */
+    FULL
+  }
+}
index 6763996a9e02fc5aab10f35b4c7d8fd87f51829a..b8b81e7da5999eff231bcfbb0535667fd6bca864 100755 (executable)
@@ -1,35 +1,35 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.ssh;\r
-\r
-import com.jcraft.jsch.Session;\r
-import org.spearce.jgit.transport.OpenSshConfig;\r
-import org.spearce.jgit.transport.SshConfigSessionFactory;\r
-\r
-/**\r
- * A headless SSH session factory that is based on ~/.ssh/config settings.\r
- * It is used in case when the default host specific configuration\r
- * should be used.\r
- */\r
-public class HeadlessSshSessionFactory extends SshConfigSessionFactory {\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  protected void configure(OpenSshConfig.Host hc, Session session) {\r
-    // do nothing, UserInfo will not be set and opening connection will fail\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.ssh;
+
+import com.jcraft.jsch.Session;
+import org.spearce.jgit.transport.OpenSshConfig;
+import org.spearce.jgit.transport.SshConfigSessionFactory;
+
+/**
+ * A headless SSH session factory that is based on ~/.ssh/config settings.
+ * It is used in case when the default host specific configuration
+ * should be used.
+ */
+public class HeadlessSshSessionFactory extends SshConfigSessionFactory {
+  /**
+   * {@inheritDoc}
+   */
+  protected void configure(OpenSshConfig.Host hc, Session session) {
+    // do nothing, UserInfo will not be set and opening connection will fail
+  }
+}
index a8eb49413c4ecdca35ba10d9f9a3b6360ee0808f..fa3ef2943008254314db2bc09eabc3dfe58a51f1 100755 (executable)
@@ -1,53 +1,53 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.ssh;\r
-\r
-import com.jcraft.jsch.JSch;\r
-import com.jcraft.jsch.JSchException;\r
-import com.jcraft.jsch.Session;\r
-import org.spearce.jgit.transport.SshSessionFactory;\r
-\r
-/**\r
- * A simple session factory used for password authentication.\r
- * It assume that password was passed in URL to ssh.\r
- */\r
-public class PasswordSshSessionFactory extends SshSessionFactory {\r
-  /**\r
-   * An instance of the session factory\r
-   */\r
-  public static final SshSessionFactory INSTANCE = new PasswordSshSessionFactory();\r
-  /**\r
-   * An ssh instance with no keys registered\r
-   */\r
-  private final JSch sch;\r
-\r
-  /**\r
-   * A private constructor to ensure that only one instance is created\r
-   */\r
-  private PasswordSshSessionFactory() {\r
-    sch = new JSch();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public Session getSession(String user, String pass, String host, int port) throws JSchException {\r
-    final Session session = SshUtils.createSession(sch, user, host, port);\r
-    session.setPassword(pass);\r
-    return session;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.ssh;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import org.spearce.jgit.transport.SshSessionFactory;
+
+/**
+ * A simple session factory used for password authentication.
+ * It assume that password was passed in URL to ssh.
+ */
+public class PasswordSshSessionFactory extends SshSessionFactory {
+  /**
+   * An instance of the session factory
+   */
+  public static final SshSessionFactory INSTANCE = new PasswordSshSessionFactory();
+  /**
+   * An ssh instance with no keys registered
+   */
+  private final JSch sch;
+
+  /**
+   * A private constructor to ensure that only one instance is created
+   */
+  private PasswordSshSessionFactory() {
+    sch = new JSch();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Session getSession(String user, String pass, String host, int port) throws JSchException {
+    final Session session = SshUtils.createSession(sch, user, host, port);
+    session.setPassword(pass);
+    return session;
+  }
+}
index 3437016de691d139b8853f2b3dc063893a4f6654..bb9feb30290614bffb1b60a8462265e468db5c3a 100755 (executable)
@@ -1,68 +1,68 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.ssh;\r
-\r
-import com.jcraft.jsch.JSch;\r
-import com.jcraft.jsch.JSchException;\r
-import com.jcraft.jsch.Session;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.Settings;\r
-import jetbrains.buildServer.vcs.VcsException;\r
-import org.spearce.jgit.transport.SshSessionFactory;\r
-\r
-/**\r
- * The SSH session factory that uses explicitly specified private key file\r
- * for authentication.\r
- */\r
-public class PrivateKeyFileSshSessionFactory extends SshSessionFactory {\r
-  /**\r
-   * SSH instance with registered identity\r
-   */\r
-  private final JSch sch;\r
-\r
-  /**\r
-   * A construction\r
-   *\r
-   * @param privateKeyPath a path to the key\r
-   * @param passphrase     a passphrase for the key\r
-   * @throws VcsException if private key could not be read\r
-   */\r
-  public PrivateKeyFileSshSessionFactory(String privateKeyPath, String passphrase) throws VcsException {\r
-    this.sch = new JSch();\r
-    try {\r
-      sch.addIdentity(privateKeyPath, passphrase);\r
-    } catch (JSchException e) {\r
-      throw new VcsException("Unable to load identity file: " + privateKeyPath + (passphrase != null ? " (passphrase protected)" : ""), e);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * A constructor from vcs root settings\r
-   *\r
-   * @param s a settings object\r
-   * @throws VcsException if private key could not be read\r
-   */\r
-  public PrivateKeyFileSshSessionFactory(Settings s) throws VcsException {\r
-    this(s.getPrivateKeyFile(), s.getPassphrase());\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public Session getSession(String user, String pass, String host, int port) throws JSchException {\r
-    return SshUtils.createSession(sch, user, host, port);\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.ssh;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import jetbrains.buildServer.buildTriggers.vcs.git.Settings;
+import jetbrains.buildServer.vcs.VcsException;
+import org.spearce.jgit.transport.SshSessionFactory;
+
+/**
+ * The SSH session factory that uses explicitly specified private key file
+ * for authentication.
+ */
+public class PrivateKeyFileSshSessionFactory extends SshSessionFactory {
+  /**
+   * SSH instance with registered identity
+   */
+  private final JSch sch;
+
+  /**
+   * A construction
+   *
+   * @param privateKeyPath a path to the key
+   * @param passphrase     a passphrase for the key
+   * @throws VcsException if private key could not be read
+   */
+  public PrivateKeyFileSshSessionFactory(String privateKeyPath, String passphrase) throws VcsException {
+    this.sch = new JSch();
+    try {
+      sch.addIdentity(privateKeyPath, passphrase);
+    } catch (JSchException e) {
+      throw new VcsException("Unable to load identity file: " + privateKeyPath + (passphrase != null ? " (passphrase protected)" : ""), e);
+    }
+  }
+
+  /**
+   * A constructor from vcs root settings
+   *
+   * @param s a settings object
+   * @throws VcsException if private key could not be read
+   */
+  public PrivateKeyFileSshSessionFactory(Settings s) throws VcsException {
+    this(s.getPrivateKeyFile(), s.getPassphrase());
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Session getSession(String user, String pass, String host, int port) throws JSchException {
+    return SshUtils.createSession(sch, user, host, port);
+  }
+}
index f06248c5206697f2e1db252a6ba4388b25e7d5eb..afc71073d971c028815523ab64246d9137b54aa4 100755 (executable)
@@ -1,99 +1,99 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.ssh;\r
-\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import com.jcraft.jsch.JSchException;\r
-import com.jcraft.jsch.Session;\r
-import jetbrains.buildServer.configuration.ChangeListener;\r
-import jetbrains.buildServer.configuration.FilesWatcher;\r
-import org.jetbrains.annotations.NotNull;\r
-import org.spearce.jgit.transport.SshSessionFactory;\r
-\r
-import java.io.File;\r
-\r
-/**\r
- * A {@link SshSessionFactory} that refreshes it states when the content of ~/.ssh directory changes. The factory delegates its work to {@link HeadlessSshSessionFactory}.\r
- */\r
-public class RefreshableSshConfigSessionFactory extends SshSessionFactory {\r
-  /**\r
-   * logger instance\r
-   */\r
-  private static Logger LOG = Logger.getInstance(RefreshableSshConfigSessionFactory.class.getName());\r
-\r
-  /**\r
-   * The delegate factory\r
-   */\r
-  private SshSessionFactory myDelegate;\r
-  /**\r
-   * The lock that guards {@link #myDelegate}\r
-   */\r
-  private final Object delegateLock = new Object();\r
-\r
-  /**\r
-   * A constructor\r
-   */\r
-  public RefreshableSshConfigSessionFactory() {\r
-    FilesWatcher watcher = new FilesWatcher(new FilesWatcher.WatchedFilesProvider() {\r
-      public File[] getWatchedFiles() {\r
-        File sshDir = new File(System.getProperty("user.home"), ".ssh");\r
-        if (sshDir.exists() && sshDir.isDirectory()) {\r
-          final File[] files = sshDir.listFiles();\r
-          if (files != null) {\r
-            return files;\r
-          }\r
-        }\r
-        return new File[0];\r
-      }\r
-    });\r
-    watcher.registerListener(new ChangeListener() {\r
-      public void changeOccured(String requestor) {\r
-        expireDelegate();\r
-      }\r
-    });\r
-  }\r
-\r
-  /**\r
-   * @return the delegate session factory\r
-   */\r
-  @NotNull\r
-  private SshSessionFactory delegate() {\r
-    synchronized (delegateLock) {\r
-      if (myDelegate == null) {\r
-        LOG.info("Reloading SSH configuration information for Git plugin");\r
-        myDelegate = new HeadlessSshSessionFactory();\r
-      }\r
-      return myDelegate;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Expire the delegate\r
-   */\r
-  private void expireDelegate() {\r
-    synchronized (delegateLock) {\r
-      myDelegate = null;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public Session getSession(String user, String pass, String host, int port) throws JSchException {\r
-    return delegate().getSession(user, pass, host, port);\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.ssh;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import jetbrains.buildServer.configuration.ChangeListener;
+import jetbrains.buildServer.configuration.FilesWatcher;
+import org.jetbrains.annotations.NotNull;
+import org.spearce.jgit.transport.SshSessionFactory;
+
+import java.io.File;
+
+/**
+ * A {@link SshSessionFactory} that refreshes it states when the content of ~/.ssh directory changes. The factory delegates its work to {@link HeadlessSshSessionFactory}.
+ */
+public class RefreshableSshConfigSessionFactory extends SshSessionFactory {
+  /**
+   * logger instance
+   */
+  private static Logger LOG = Logger.getInstance(RefreshableSshConfigSessionFactory.class.getName());
+
+  /**
+   * The delegate factory
+   */
+  private SshSessionFactory myDelegate;
+  /**
+   * The lock that guards {@link #myDelegate}
+   */
+  private final Object delegateLock = new Object();
+
+  /**
+   * A constructor
+   */
+  public RefreshableSshConfigSessionFactory() {
+    FilesWatcher watcher = new FilesWatcher(new FilesWatcher.WatchedFilesProvider() {
+      public File[] getWatchedFiles() {
+        File sshDir = new File(System.getProperty("user.home"), ".ssh");
+        if (sshDir.exists() && sshDir.isDirectory()) {
+          final File[] files = sshDir.listFiles();
+          if (files != null) {
+            return files;
+          }
+        }
+        return new File[0];
+      }
+    });
+    watcher.registerListener(new ChangeListener() {
+      public void changeOccured(String requestor) {
+        expireDelegate();
+      }
+    });
+  }
+
+  /**
+   * @return the delegate session factory
+   */
+  @NotNull
+  private SshSessionFactory delegate() {
+    synchronized (delegateLock) {
+      if (myDelegate == null) {
+        LOG.info("Reloading SSH configuration information for Git plugin");
+        myDelegate = new HeadlessSshSessionFactory();
+      }
+      return myDelegate;
+    }
+  }
+
+  /**
+   * Expire the delegate
+   */
+  private void expireDelegate() {
+    synchronized (delegateLock) {
+      myDelegate = null;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Session getSession(String user, String pass, String host, int port) throws JSchException {
+    return delegate().getSession(user, pass, host, port);
+  }
+}
index 6482726e29b9ce7fa54af0be60fe303881c89578..347999df03a59bb2350bdf5cf0878cf5aeb595a5 100755 (executable)
@@ -1,50 +1,50 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.ssh;\r
-\r
-import com.jcraft.jsch.JSch;\r
-import com.jcraft.jsch.JSchException;\r
-import com.jcraft.jsch.Session;\r
-\r
-/**\r
- * Some common functionality for SSH\r
- */\r
-public class SshUtils {\r
-  /**\r
-   * Default SSH port\r
-   */\r
-  static final int SSH_PORT = 22;\r
-\r
-  /**\r
-   * Create SSH session\r
-   *\r
-   * @param sch  SSH instance to use\r
-   * @param user the user\r
-   * @param host the host\r
-   * @param port the port to use\r
-   * @return the configured session\r
-   * @throws JSchException if session could not be created\r
-   */\r
-  static Session createSession(JSch sch, String user, String host, int port) throws JSchException {\r
-    if (port <= 0) {\r
-      port = SSH_PORT;\r
-    }\r
-    final Session session = sch.getSession(user, host, port);\r
-    session.setConfig("StrictHostKeyChecking", "no");\r
-    return session;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.ssh;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Some common functionality for SSH
+ */
+public class SshUtils {
+  /**
+   * Default SSH port
+   */
+  static final int SSH_PORT = 22;
+
+  /**
+   * Create SSH session
+   *
+   * @param sch  SSH instance to use
+   * @param user the user
+   * @param host the host
+   * @param port the port to use
+   * @return the configured session
+   * @throws JSchException if session could not be created
+   */
+  static Session createSession(JSch sch, String user, String host, int port) throws JSchException {
+    if (port <= 0) {
+      port = SSH_PORT;
+    }
+    final Session session = sch.getSession(user, host, port);
+    session.setConfig("StrictHostKeyChecking", "no");
+    return session;
+  }
+}
index b5d8eb70eb106ccb20ce867b81804984e683fe49..02feb6a86b0e38559b182e89a9f8b6c8709082dc 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-/**\r
- * The range of bytes. Contains methods suitable for checking membership in a hash set.\r
- * The class assumes that byte array does not changes after the construction.\r
- */\r
-public class ByteRange implements Comparable<ByteRange> {\r
-  /**\r
-   * The data for the range\r
-   */\r
-  private final byte[] myData;\r
-  /**\r
-   * The start of the range\r
-   */\r
-  private final int myStart;\r
-  /**\r
-   * The position after the last byte\r
-   */\r
-  private final int myLength;\r
-  /**\r
-   * The hash code\r
-   */\r
-  private int myHash;\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param data   the bytes for the range\r
-   * @param start  the start of the range\r
-   * @param length the length of the range\r
-   */\r
-  public ByteRange(byte[] data, int start, int length) {\r
-    assert start >= 0;\r
-    assert length >= 0;\r
-    assert start + length <= data.length;\r
-    myData = data;\r
-    myStart = start;\r
-    myLength = length;\r
-    int hash = 0;\r
-    for (int i = myStart; i < start + length; i++) {\r
-      hash += hash * 19 + data[i];\r
-    }\r
-    myHash = hash;\r
-\r
-  }\r
-\r
-  /**\r
-   * A constructor from the entire array\r
-   *\r
-   * @param bytes the array with characters\r
-   */\r
-  public ByteRange(byte[] bytes) {\r
-    this(bytes, 0, bytes.length);\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  @Override\r
-  public int hashCode() {\r
-    return myHash;\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  @Override\r
-  public boolean equals(Object obj) {\r
-    if (!(obj instanceof ByteRange)) {\r
-      return false;\r
-    }\r
-    final ByteRange r = (ByteRange)obj;\r
-    if (myHash != r.myHash || myLength != r.myLength) {\r
-      return false;\r
-    }\r
-    for (int i = 0; i < myLength; i++) {\r
-      if (myData[myStart + i] != r.myData[r.myStart + i]) {\r
-        return false;\r
-      }\r
-    }\r
-    return true;\r
-  }\r
-\r
-  /**\r
-   * Compare byte ranges treating bytes by absolute values\r
-   * {@inheritDoc}\r
-   */\r
-  public int compareTo(ByteRange o) {\r
-    int n = Math.min(myLength, o.myLength);\r
-    for (int i = 0; i < n; i++) {\r
-      int d = myData[myStart + i] - o.myData[o.myStart + i];\r
-      if (d != 0) {\r
-        return d;\r
-      }\r
-    }\r
-    return myLength - o.myLength;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+/**
+ * The range of bytes. Contains methods suitable for checking membership in a hash set.
+ * The class assumes that byte array does not changes after the construction.
+ */
+public class ByteRange implements Comparable<ByteRange> {
+  /**
+   * The data for the range
+   */
+  private final byte[] myData;
+  /**
+   * The start of the range
+   */
+  private final int myStart;
+  /**
+   * The position after the last byte
+   */
+  private final int myLength;
+  /**
+   * The hash code
+   */
+  private int myHash;
+
+  /**
+   * The constructor
+   *
+   * @param data   the bytes for the range
+   * @param start  the start of the range
+   * @param length the length of the range
+   */
+  public ByteRange(byte[] data, int start, int length) {
+    assert start >= 0;
+    assert length >= 0;
+    assert start + length <= data.length;
+    myData = data;
+    myStart = start;
+    myLength = length;
+    int hash = 0;
+    for (int i = myStart; i < start + length; i++) {
+      hash += hash * 19 + data[i];
+    }
+    myHash = hash;
+
+  }
+
+  /**
+   * A constructor from the entire array
+   *
+   * @param bytes the array with characters
+   */
+  public ByteRange(byte[] bytes) {
+    this(bytes, 0, bytes.length);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public int hashCode() {
+    return myHash;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof ByteRange)) {
+      return false;
+    }
+    final ByteRange r = (ByteRange)obj;
+    if (myHash != r.myHash || myLength != r.myLength) {
+      return false;
+    }
+    for (int i = 0; i < myLength; i++) {
+      if (myData[myStart + i] != r.myData[r.myStart + i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Compare byte ranges treating bytes by absolute values
+   * {@inheritDoc}
+   */
+  public int compareTo(ByteRange o) {
+    int n = Math.min(myLength, o.myLength);
+    for (int i = 0; i < n; i++) {
+      int d = myData[myStart + i] - o.myData[o.myStart + i];
+      if (d != 0) {
+        return d;
+      }
+    }
+    return myLength - o.myLength;
+  }
+}
index 854db4528d68879a572de4a3b1460d71dbfbfe24..afadf82bb8769569dc30e4c59da4eb0192c478a1 100755 (executable)
@@ -1,81 +1,81 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import org.spearce.jgit.errors.CorruptObjectException;\r
-import org.spearce.jgit.treewalk.AbstractTreeIterator;\r
-\r
-import java.io.IOException;\r
-\r
-/**\r
- * Direct submodule-aware tree iterator. This iterator for the cases when no directory entry reordering is needed.\r
- */\r
-public class DirectSubmoduleAwareTreeIterator extends SubmoduleAwareTreeIterator {\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws IOException in case of submodule processing problem\r
-   */\r
-  public DirectSubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver) throws IOException {\r
-    super(wrappedIterator, submoduleResolver);\r
-  }\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param parent            the parent iterator\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws IOException in case of submodule processing problem\r
-   */\r
-  public DirectSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,\r
-                                          AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver) throws IOException {\r
-    super(parent, wrappedIterator, submoduleResolver);\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public boolean first() {\r
-    return myWrappedIterator.first();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public boolean eof() {\r
-    return myWrappedIterator.eof();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public void next(int delta) throws CorruptObjectException {\r
-    myWrappedIterator.next(delta);\r
-    movedToEntry();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public void back(int delta) throws CorruptObjectException {\r
-    myWrappedIterator.back(delta);\r
-    movedToEntry();\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import org.spearce.jgit.errors.CorruptObjectException;
+import org.spearce.jgit.treewalk.AbstractTreeIterator;
+
+import java.io.IOException;
+
+/**
+ * Direct submodule-aware tree iterator. This iterator for the cases when no directory entry reordering is needed.
+ */
+public class DirectSubmoduleAwareTreeIterator extends SubmoduleAwareTreeIterator {
+  /**
+   * The constructor
+   *
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @throws IOException in case of submodule processing problem
+   */
+  public DirectSubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver) throws IOException {
+    super(wrappedIterator, submoduleResolver);
+  }
+
+  /**
+   * The constructor
+   *
+   * @param parent            the parent iterator
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @throws IOException in case of submodule processing problem
+   */
+  public DirectSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,
+                                          AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver) throws IOException {
+    super(parent, wrappedIterator, submoduleResolver);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean first() {
+    return myWrappedIterator.first();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean eof() {
+    return myWrappedIterator.eof();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void next(int delta) throws CorruptObjectException {
+    myWrappedIterator.next(delta);
+    movedToEntry();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void back(int delta) throws CorruptObjectException {
+    myWrappedIterator.back(delta);
+    movedToEntry();
+  }
+}
index 5b03430ba142899dae339452464fce04fdf1d3d7..ec7a6e996e519c6fb3e9092dc1191ece110a08fe 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import org.spearce.jgit.errors.CorruptObjectException;\r
-import org.spearce.jgit.treewalk.AbstractTreeIterator;\r
-\r
-import java.io.IOException;\r
-\r
-/**\r
- * Indirect submodule-aware tree iterator. This iterator for the cases when directory entry reordering is needed.\r
- * This is caused by the fact that submodules are directories are treated differently with respect to the sorting.\r
- * The submodules are ordered like the following:\r
- * <ul>\r
- * <li>a</li>\r
- * <li>a.c</li>\r
- * <li>a0c</li>\r
- * </ul>\r
- * And the directories are ordered as the following:\r
- * <ul>\r
- * <li>a.c</li>\r
- * <li>a/c</li>\r
- * <li>a0c</li>\r
- * </ul>\r
- * Because of this, when interpreting submodules are directories an reordering is needed.\r
- */\r
-public class IndirectSubmoduleAwareTreeIterator extends SubmoduleAwareTreeIterator {\r
-  /**\r
-   * The current position\r
-   */\r
-  private int myPosition = 0;\r
-  /**\r
-   * The offset mapping\r
-   */\r
-  private final int[] myMapping;\r
-\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @param mapping           the mapping of positions\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  public IndirectSubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver, int[] mapping)\r
-    throws IOException {\r
-    super(wrappedIterator, submoduleResolver);\r
-    myMapping = mapping;\r
-    adjustStartPosition();\r
-  }\r
-\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param parent            the parent iterator\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @param mapping           the mapping of positions\r
-   * @throws CorruptObjectException in case of navigation error\r
-   */\r
-  public IndirectSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,\r
-                                            AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver, int[] mapping)\r
-    throws CorruptObjectException {\r
-    super(parent, wrappedIterator, submoduleResolver);\r
-    myMapping = mapping;\r
-    adjustStartPosition();\r
-  }\r
-\r
-  /**\r
-   * Adjust start position for the mapping\r
-   *\r
-   * @throws CorruptObjectException in case of navigation error\r
-   */\r
-  private void adjustStartPosition() throws CorruptObjectException {\r
-    if (myMapping[0] != 0) {\r
-      for (int i = 0; i < myMapping.length; i++) {\r
-        if (myMapping[i] == 0) {\r
-          myPosition = i;\r
-          break;\r
-        }\r
-      }\r
-      assert myPosition != 0;\r
-      back(myPosition);\r
-    }\r
-  }\r
-\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public boolean first() {\r
-    return myPosition == 0;\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public boolean eof() {\r
-    return myMapping == null ? myWrappedIterator.eof() : myPosition == myMapping.length;\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public void next(int delta) throws CorruptObjectException {\r
-    if (delta <= 0) {\r
-      throw new IllegalArgumentException("Delta must be positive: " + delta);\r
-    }\r
-    if (myPosition + delta > myMapping.length) {\r
-      delta = myMapping.length - myPosition;\r
-    }\r
-    if (delta == 0) {\r
-      return;\r
-    }\r
-    move(delta);\r
-  }\r
-\r
-  /**\r
-   * Move to the position specified by the offset in array\r
-   *\r
-   * @param offset the positive or negative offset to move by\r
-   * @throws CorruptObjectException in case of navigation problems\r
-   */\r
-  private void move(int offset) throws CorruptObjectException {\r
-    int newPosition = myPosition + offset;\r
-    int actualDelta = translatePosition(newPosition) - translatePosition(myPosition);\r
-    assert actualDelta != 0;\r
-    if (actualDelta < 0) {\r
-      myWrappedIterator.back(-actualDelta);\r
-    } else {\r
-      myWrappedIterator.next(actualDelta);\r
-    }\r
-    myPosition = newPosition;\r
-    movedToEntry();\r
-  }\r
-\r
-  /**\r
-   * Translate position using mapping\r
-   *\r
-   * @param position a position to translate\r
-   * @return the translated positions\r
-   */\r
-  private int translatePosition(int position) {\r
-    return position >= myMapping.length ? position : myMapping[position];\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public void back(int delta) throws CorruptObjectException {\r
-    if (delta <= 0) {\r
-      throw new IllegalArgumentException("Delta must be positive: " + delta);\r
-    }\r
-    if (myPosition - delta < 0) {\r
-      delta = myPosition;\r
-    }\r
-    if (delta == 0) {\r
-      return;\r
-    }\r
-    move(-delta);\r
-  }\r
-\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import org.spearce.jgit.errors.CorruptObjectException;
+import org.spearce.jgit.treewalk.AbstractTreeIterator;
+
+import java.io.IOException;
+
+/**
+ * Indirect submodule-aware tree iterator. This iterator for the cases when directory entry reordering is needed.
+ * This is caused by the fact that submodules are directories are treated differently with respect to the sorting.
+ * The submodules are ordered like the following:
+ * <ul>
+ * <li>a</li>
+ * <li>a.c</li>
+ * <li>a0c</li>
+ * </ul>
+ * And the directories are ordered as the following:
+ * <ul>
+ * <li>a.c</li>
+ * <li>a/c</li>
+ * <li>a0c</li>
+ * </ul>
+ * Because of this, when interpreting submodules are directories an reordering is needed.
+ */
+public class IndirectSubmoduleAwareTreeIterator extends SubmoduleAwareTreeIterator {
+  /**
+   * The current position
+   */
+  private int myPosition = 0;
+  /**
+   * The offset mapping
+   */
+  private final int[] myMapping;
+
+
+  /**
+   * The constructor
+   *
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @param mapping           the mapping of positions
+   * @throws IOException in case of IO problem
+   */
+  public IndirectSubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver, int[] mapping)
+    throws IOException {
+    super(wrappedIterator, submoduleResolver);
+    myMapping = mapping;
+    adjustStartPosition();
+  }
+
+
+  /**
+   * The constructor
+   *
+   * @param parent            the parent iterator
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @param mapping           the mapping of positions
+   * @throws CorruptObjectException in case of navigation error
+   */
+  public IndirectSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,
+                                            AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver, int[] mapping)
+    throws CorruptObjectException {
+    super(parent, wrappedIterator, submoduleResolver);
+    myMapping = mapping;
+    adjustStartPosition();
+  }
+
+  /**
+   * Adjust start position for the mapping
+   *
+   * @throws CorruptObjectException in case of navigation error
+   */
+  private void adjustStartPosition() throws CorruptObjectException {
+    if (myMapping[0] != 0) {
+      for (int i = 0; i < myMapping.length; i++) {
+        if (myMapping[i] == 0) {
+          myPosition = i;
+          break;
+        }
+      }
+      assert myPosition != 0;
+      back(myPosition);
+    }
+  }
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean first() {
+    return myPosition == 0;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean eof() {
+    return myMapping == null ? myWrappedIterator.eof() : myPosition == myMapping.length;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void next(int delta) throws CorruptObjectException {
+    if (delta <= 0) {
+      throw new IllegalArgumentException("Delta must be positive: " + delta);
+    }
+    if (myPosition + delta > myMapping.length) {
+      delta = myMapping.length - myPosition;
+    }
+    if (delta == 0) {
+      return;
+    }
+    move(delta);
+  }
+
+  /**
+   * Move to the position specified by the offset in array
+   *
+   * @param offset the positive or negative offset to move by
+   * @throws CorruptObjectException in case of navigation problems
+   */
+  private void move(int offset) throws CorruptObjectException {
+    int newPosition = myPosition + offset;
+    int actualDelta = translatePosition(newPosition) - translatePosition(myPosition);
+    assert actualDelta != 0;
+    if (actualDelta < 0) {
+      myWrappedIterator.back(-actualDelta);
+    } else {
+      myWrappedIterator.next(actualDelta);
+    }
+    myPosition = newPosition;
+    movedToEntry();
+  }
+
+  /**
+   * Translate position using mapping
+   *
+   * @param position a position to translate
+   * @return the translated positions
+   */
+  private int translatePosition(int position) {
+    return position >= myMapping.length ? position : myMapping[position];
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void back(int delta) throws CorruptObjectException {
+    if (delta <= 0) {
+      throw new IllegalArgumentException("Delta must be positive: " + delta);
+    }
+    if (myPosition - delta < 0) {
+      delta = myPosition;
+    }
+    if (delta == 0) {
+      return;
+    }
+    move(-delta);
+  }
+
 }
\ No newline at end of file
index 5f83e4ce689c610772323665ef5cc19d8268a380..92cdcc451144769de5227b45c010adf548df882b 100755 (executable)
@@ -1,69 +1,69 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-/**\r
- * The entry in submodule configuration\r
- */\r
-public class Submodule {\r
-  /**\r
-   * The name of submodule name. It is usually a lowercase path.\r
-   */\r
-  private final String myName;\r
-  /**\r
-   * The path where submodule is mapped\r
-   */\r
-  private final String myPath;\r
-  /**\r
-   * The submodule URL.\r
-   */\r
-  private final String myUrl;\r
-\r
-  /**\r
-   * The entry constructor\r
-   *\r
-   * @param name the name of submodule\r
-   * @param path the path in repository\r
-   * @param url  the URL which is submodule is mapped to\r
-   */\r
-  Submodule(String name, String path, String url) {\r
-    myName = name;\r
-    myUrl = url;\r
-    myPath = path;\r
-  }\r
-\r
-  /**\r
-   * @return the submodule name\r
-   */\r
-  public String getName() {\r
-    return myName;\r
-  }\r
-\r
-  /**\r
-   * @return the submodule path\r
-   */\r
-  public String getPath() {\r
-    return myPath;\r
-  }\r
-\r
-  /**\r
-   * @return the submodule URL\r
-   */\r
-  public String getUrl() {\r
-    return myUrl;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+/**
+ * The entry in submodule configuration
+ */
+public class Submodule {
+  /**
+   * The name of submodule name. It is usually a lowercase path.
+   */
+  private final String myName;
+  /**
+   * The path where submodule is mapped
+   */
+  private final String myPath;
+  /**
+   * The submodule URL.
+   */
+  private final String myUrl;
+
+  /**
+   * The entry constructor
+   *
+   * @param name the name of submodule
+   * @param path the path in repository
+   * @param url  the URL which is submodule is mapped to
+   */
+  Submodule(String name, String path, String url) {
+    myName = name;
+    myUrl = url;
+    myPath = path;
+  }
+
+  /**
+   * @return the submodule name
+   */
+  public String getName() {
+    return myName;
+  }
+
+  /**
+   * @return the submodule path
+   */
+  public String getPath() {
+    return myPath;
+  }
+
+  /**
+   * @return the submodule URL
+   */
+  public String getUrl() {
+    return myUrl;
+  }
+}
index 39eefbbc4d2e30e5401ac1e9d83e35c4b496de57..85481709d7f6a1e2749b4bf010ef2f1aa7f90e34 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import com.intellij.util.containers.IntArrayList;\r
-import org.spearce.jgit.errors.CorruptObjectException;\r
-import org.spearce.jgit.lib.*;\r
-import org.spearce.jgit.treewalk.AbstractTreeIterator;\r
-import org.spearce.jgit.treewalk.CanonicalTreeParser;\r
-\r
-import java.io.IOException;\r
-import java.util.LinkedList;\r
-\r
-/**\r
- * The tree iterator that aware of the submodules. If submodule entry\r
- * is encountered, it is replaced with referenced tree.\r
- */\r
-public abstract class SubmoduleAwareTreeIterator extends AbstractTreeIterator {\r
-  /**\r
-   * The iterator wrapped by this iterator\r
-   */\r
-  protected final AbstractTreeIterator myWrappedIterator;\r
-  /**\r
-   * The resolver for submodules\r
-   */\r
-  protected final SubmoduleResolver mySubmoduleResolver;\r
-  /**\r
-   * The local id buffer (for submodules)\r
-   */\r
-  protected byte[] myIdBuffer;\r
-  /**\r
-   * If true the current entry is as submodule entry\r
-   */\r
-  protected boolean myIsOnSubmodule;\r
-  /**\r
-   * If true, the iterator is on EOF\r
-   */\r
-  protected boolean myIsEof;\r
-  /**\r
-   * The referenced commit for the submodule, the commit is in other repository.\r
-   */\r
-  protected Commit mySubmoduleCommit;\r
-  /**\r
-   * Submodule reference mode bits\r
-   */\r
-  protected static final int GITLINK_MODE_BITS = FileMode.GITLINK.getBits();\r
-  /**\r
-   * Tree mode bits\r
-   */\r
-  protected static final int TREE_MODE_BITS = FileMode.TREE.getBits();\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws CorruptObjectException in case of submodule processing problem\r
-   */\r
-  public SubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver)\r
-    throws CorruptObjectException {\r
-    myWrappedIterator = wrappedIterator;\r
-    mySubmoduleResolver = submoduleResolver;\r
-    movedToEntry();\r
-  }\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param commit            the commit that is starting point for iteration\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  public SubmoduleAwareTreeIterator(Commit commit, SubmoduleResolver submoduleResolver) throws IOException {\r
-    this(createTreeParser(commit), submoduleResolver);\r
-  }\r
-\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param parent            the parent iterator\r
-   * @param wrappedIterator   the wrapped iterator\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws CorruptObjectException in case of submodule processing problem\r
-   */\r
-  public SubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,\r
-                                    AbstractTreeIterator wrappedIterator,\r
-                                    SubmoduleResolver submoduleResolver)\r
-    throws CorruptObjectException {\r
-    super(parent);\r
-    myWrappedIterator = wrappedIterator;\r
-    mySubmoduleResolver = submoduleResolver;\r
-    movedToEntry();\r
-  }\r
-\r
-  /**\r
-   * The constructor\r
-   *\r
-   * @param parent            the parent iterator\r
-   * @param commit            the commit that is starting point for iteration\r
-   * @param submoduleResolver the resolver for submodules\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  public SubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent, Commit commit, SubmoduleResolver submoduleResolver)\r
-    throws IOException {\r
-    this(parent, createTreeParser(commit), submoduleResolver);\r
-  }\r
-\r
-  /**\r
-   * @return the current repository for the submodule\r
-   */\r
-  public Repository getRepository() {\r
-    return mySubmoduleResolver.getRepository();\r
-  }\r
-\r
-\r
-  /**\r
-   * Move iterator to the specific entry.\r
-   *\r
-   * @throws CorruptObjectException in case of submodule processing problem\r
-   */\r
-  protected void movedToEntry() throws CorruptObjectException {\r
-    myIsEof = eof();\r
-    if (myIsEof) {\r
-      return;\r
-    }\r
-    int wrappedMode = myWrappedIterator.getEntryRawMode();\r
-    myIsOnSubmodule = GITLINK_MODE_BITS == wrappedMode;\r
-    mode = myIsOnSubmodule ? TREE_MODE_BITS : wrappedMode;\r
-    if (myIsOnSubmodule) {\r
-      try {\r
-        mySubmoduleCommit = mySubmoduleResolver.getSubmodule(myWrappedIterator.getEntryPathString(), myWrappedIterator.getEntryObjectId());\r
-      } catch (IOException e) {\r
-        final CorruptObjectException ex = new CorruptObjectException(myWrappedIterator.getEntryObjectId(), "Commit could not be resolved");\r
-        ex.initCause(e);\r
-        throw ex;\r
-      }\r
-      if (myIdBuffer == null) {\r
-        myIdBuffer = new byte[Constants.OBJECT_ID_LENGTH];\r
-      }\r
-      mySubmoduleCommit.getTreeId().copyRawTo(myIdBuffer, 0);\r
-    } else {\r
-      mySubmoduleCommit = null;\r
-    }\r
-    // copy name\r
-    final int nameLength = myWrappedIterator.getNameLength();\r
-    final int pathLength = nameLength + pathOffset;\r
-    ensurePathCapacity(pathLength, pathOffset);\r
-    myWrappedIterator.getName(path, pathOffset);\r
-    pathLen = pathLength;\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public byte[] idBuffer() {\r
-    if (myIsOnSubmodule) {\r
-      return myIdBuffer;\r
-    } else {\r
-      return myWrappedIterator.idBuffer();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public int idOffset() {\r
-    return myIsOnSubmodule ? 0 : myWrappedIterator.idOffset();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  @Override\r
-  public AbstractTreeIterator createSubtreeIterator(Repository repo, MutableObjectId idBuffer, WindowCursor curs)\r
-    throws IOException {\r
-    String path = myWrappedIterator.getEntryPathString();\r
-    if (myIsOnSubmodule) {\r
-      CanonicalTreeParser p = createTreeParser(curs, mySubmoduleCommit);\r
-      return createSubmoduleAwareTreeIterator(this, p, mySubmoduleResolver.getSubResolver(mySubmoduleCommit, path), "");\r
-    } else {\r
-      return createSubmoduleAwareTreeIterator(this, myWrappedIterator.createSubtreeIterator(getRepository(), idBuffer, curs),\r
-                                              mySubmoduleResolver,\r
-                                              path);\r
-    }\r
-  }\r
-\r
-\r
-  /**\r
-   * Create a tree iterator from commit\r
-   *\r
-   * @param commit      a start commit\r
-   * @param subResolver a submodule resolver\r
-   * @return an iterator for tree that considers submodules\r
-   * @throws IOException in the case if IO error occurs\r
-   */\r
-  public static SubmoduleAwareTreeIterator create(Commit commit, SubmoduleResolver subResolver)\r
-    throws IOException {\r
-    return createSubmoduleAwareTreeIterator(null, createTreeParser(commit), subResolver, "");\r
-  }\r
-\r
-\r
-  /**\r
-   * Create a tree iterator from commit\r
-   *\r
-   * @param parent      the parent iterator (or null)\r
-   * @param wrapped     the wrapped iterator\r
-   * @param subResolver a submodule resolver\r
-   * @param path        the path the submodule is referenced in the local repository\r
-   * @return an iterator for tree that considers submodules\r
-   * @throws IOException in the case if IO error occurs\r
-   */\r
-  private static SubmoduleAwareTreeIterator createSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,\r
-                                                                             AbstractTreeIterator wrapped,\r
-                                                                             SubmoduleResolver subResolver, String path)\r
-    throws IOException {\r
-    if (subResolver.containsSubmodule(path)) {\r
-      int[] mapping = buildMapping(wrapped);\r
-      if (mapping == null) {\r
-        return parent == null\r
-               ? new DirectSubmoduleAwareTreeIterator(wrapped, subResolver)\r
-               : new DirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver);\r
-      } else {\r
-        return parent == null\r
-               ? new IndirectSubmoduleAwareTreeIterator(wrapped, subResolver, mapping)\r
-               : new IndirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver, mapping);\r
-      }\r
-    }\r
-    return parent == null\r
-           ? new DirectSubmoduleAwareTreeIterator(wrapped, subResolver)\r
-           : new DirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver);\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public AbstractTreeIterator createSubtreeIterator(Repository repo) throws IOException {\r
-    String path = myWrappedIterator.getEntryPathString();\r
-    if (myIsOnSubmodule) {\r
-      WindowCursor curs = new WindowCursor();\r
-      try {\r
-        CanonicalTreeParser p = createTreeParser(curs, mySubmoduleCommit);\r
-        return createSubmoduleAwareTreeIterator(this, p, mySubmoduleResolver.getSubResolver(mySubmoduleCommit, path), "");\r
-      } finally {\r
-        curs.release();\r
-      }\r
-    } else {\r
-      return createSubmoduleAwareTreeIterator(this, myWrappedIterator.createSubtreeIterator(getRepository()), mySubmoduleResolver,\r
-                                              path);\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Create tree parser\r
-   *\r
-   * @param curs   the window cursor for loading objects\r
-   * @param commit the commit\r
-   * @return the tree parser for tree in the commit\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  private static CanonicalTreeParser createTreeParser(WindowCursor curs, final Commit commit) throws IOException {\r
-    CanonicalTreeParser p = new CanonicalTreeParser();\r
-    p.reset(commit.getRepository(), commit.getTreeId(), curs);\r
-    return p;\r
-  }\r
-\r
-\r
-  /**\r
-   * Create tree parser\r
-   *\r
-   * @param commit the commit that contains point ot the tree\r
-   * @return the tree parser\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  public static CanonicalTreeParser createTreeParser(final Commit commit) throws IOException {\r
-    WindowCursor curs = new WindowCursor();\r
-    try {\r
-      return createTreeParser(curs, commit);\r
-    } finally {\r
-      curs.release();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Scan current tree and build mapping that reorders submodule entries if needed.\r
-   *\r
-   * @param w wrapped tree iterator\r
-   * @return a mapping or null if the mapping is not needed\r
-   * @throws CorruptObjectException in case if navigation fails\r
-   */\r
-  static int[] buildMapping(final AbstractTreeIterator w) throws CorruptObjectException {\r
-    class SubmoduleEntry {\r
-      final ByteRange name;\r
-      final int position;\r
-\r
-      public SubmoduleEntry(int position) {\r
-        this.position = position;\r
-        byte[] n = new byte[w.getNameLength() + 1];\r
-        w.getName(n, 0);\r
-        n[n.length - 1] = '/';\r
-        name = new ByteRange(n);\r
-      }\r
-    }\r
-    IntArrayList rc = new IntArrayList();\r
-    boolean reordered = false;\r
-    LinkedList<SubmoduleEntry> stack = new LinkedList<SubmoduleEntry>();\r
-    int actual = 0;\r
-    assert w.first();\r
-    if (w.eof()) {\r
-      return null;\r
-    }\r
-    final int INITIAL_NAME_SIZE = 32;\r
-    byte[] name = new byte[INITIAL_NAME_SIZE];\r
-    while (!w.eof()) {\r
-      if (!stack.isEmpty()) {\r
-        int l = w.getNameLength();\r
-        if (l > name.length) {\r
-          int nl = name.length;\r
-          while (nl < l) {\r
-            nl <<= 1;\r
-          }\r
-          name = new byte[nl];\r
-        }\r
-        w.getName(name, 0);\r
-        ByteRange currentName = new ByteRange(name, 0, l);\r
-        while (!stack.isEmpty()) {\r
-          final SubmoduleEntry top = stack.getLast();\r
-          final int result = top.name.compareTo(currentName);\r
-          assert result != 0;\r
-          if (result < 0) {\r
-            if (top.position != rc.size()) {\r
-              reordered = true;\r
-            }\r
-            rc.add(top.position);\r
-            stack.removeLast();\r
-          } else {\r
-            break;\r
-          }\r
-        }\r
-      }\r
-      if (w.getEntryRawMode() == GITLINK_MODE_BITS) {\r
-        stack.add(new SubmoduleEntry(actual));\r
-      } else {\r
-        rc.add(actual);\r
-      }\r
-      w.next(1);\r
-      actual++;\r
-    }\r
-    while (!stack.isEmpty()) {\r
-      final SubmoduleEntry top = stack.removeLast();\r
-      if (top.position != rc.size()) {\r
-        reordered = true;\r
-      }\r
-      rc.add(top.position);\r
-    }\r
-    w.back(actual);\r
-    assert w.first();\r
-    return reordered ? rc.toArray() : null;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import com.intellij.util.containers.IntArrayList;
+import org.spearce.jgit.errors.CorruptObjectException;
+import org.spearce.jgit.lib.*;
+import org.spearce.jgit.treewalk.AbstractTreeIterator;
+import org.spearce.jgit.treewalk.CanonicalTreeParser;
+
+import java.io.IOException;
+import java.util.LinkedList;
+
+/**
+ * The tree iterator that aware of the submodules. If submodule entry
+ * is encountered, it is replaced with referenced tree.
+ */
+public abstract class SubmoduleAwareTreeIterator extends AbstractTreeIterator {
+  /**
+   * The iterator wrapped by this iterator
+   */
+  protected final AbstractTreeIterator myWrappedIterator;
+  /**
+   * The resolver for submodules
+   */
+  protected final SubmoduleResolver mySubmoduleResolver;
+  /**
+   * The local id buffer (for submodules)
+   */
+  protected byte[] myIdBuffer;
+  /**
+   * If true the current entry is as submodule entry
+   */
+  protected boolean myIsOnSubmodule;
+  /**
+   * If true, the iterator is on EOF
+   */
+  protected boolean myIsEof;
+  /**
+   * The referenced commit for the submodule, the commit is in other repository.
+   */
+  protected Commit mySubmoduleCommit;
+  /**
+   * Submodule reference mode bits
+   */
+  protected static final int GITLINK_MODE_BITS = FileMode.GITLINK.getBits();
+  /**
+   * Tree mode bits
+   */
+  protected static final int TREE_MODE_BITS = FileMode.TREE.getBits();
+
+  /**
+   * The constructor
+   *
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @throws CorruptObjectException in case of submodule processing problem
+   */
+  public SubmoduleAwareTreeIterator(AbstractTreeIterator wrappedIterator, SubmoduleResolver submoduleResolver)
+    throws CorruptObjectException {
+    myWrappedIterator = wrappedIterator;
+    mySubmoduleResolver = submoduleResolver;
+    movedToEntry();
+  }
+
+  /**
+   * The constructor
+   *
+   * @param commit            the commit that is starting point for iteration
+   * @param submoduleResolver the resolver for submodules
+   * @throws IOException in case of IO problem
+   */
+  public SubmoduleAwareTreeIterator(Commit commit, SubmoduleResolver submoduleResolver) throws IOException {
+    this(createTreeParser(commit), submoduleResolver);
+  }
+
+
+  /**
+   * The constructor
+   *
+   * @param parent            the parent iterator
+   * @param wrappedIterator   the wrapped iterator
+   * @param submoduleResolver the resolver for submodules
+   * @throws CorruptObjectException in case of submodule processing problem
+   */
+  public SubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,
+                                    AbstractTreeIterator wrappedIterator,
+                                    SubmoduleResolver submoduleResolver)
+    throws CorruptObjectException {
+    super(parent);
+    myWrappedIterator = wrappedIterator;
+    mySubmoduleResolver = submoduleResolver;
+    movedToEntry();
+  }
+
+  /**
+   * The constructor
+   *
+   * @param parent            the parent iterator
+   * @param commit            the commit that is starting point for iteration
+   * @param submoduleResolver the resolver for submodules
+   * @throws IOException in case of IO problem
+   */
+  public SubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent, Commit commit, SubmoduleResolver submoduleResolver)
+    throws IOException {
+    this(parent, createTreeParser(commit), submoduleResolver);
+  }
+
+  /**
+   * @return the current repository for the submodule
+   */
+  public Repository getRepository() {
+    return mySubmoduleResolver.getRepository();
+  }
+
+
+  /**
+   * Move iterator to the specific entry.
+   *
+   * @throws CorruptObjectException in case of submodule processing problem
+   */
+  protected void movedToEntry() throws CorruptObjectException {
+    myIsEof = eof();
+    if (myIsEof) {
+      return;
+    }
+    int wrappedMode = myWrappedIterator.getEntryRawMode();
+    myIsOnSubmodule = GITLINK_MODE_BITS == wrappedMode;
+    mode = myIsOnSubmodule ? TREE_MODE_BITS : wrappedMode;
+    if (myIsOnSubmodule) {
+      try {
+        mySubmoduleCommit = mySubmoduleResolver.getSubmodule(myWrappedIterator.getEntryPathString(), myWrappedIterator.getEntryObjectId());
+      } catch (IOException e) {
+        final CorruptObjectException ex = new CorruptObjectException(myWrappedIterator.getEntryObjectId(), "Commit could not be resolved");
+        ex.initCause(e);
+        throw ex;
+      }
+      if (myIdBuffer == null) {
+        myIdBuffer = new byte[Constants.OBJECT_ID_LENGTH];
+      }
+      mySubmoduleCommit.getTreeId().copyRawTo(myIdBuffer, 0);
+    } else {
+      mySubmoduleCommit = null;
+    }
+    // copy name
+    final int nameLength = myWrappedIterator.getNameLength();
+    final int pathLength = nameLength + pathOffset;
+    ensurePathCapacity(pathLength, pathOffset);
+    myWrappedIterator.getName(path, pathOffset);
+    pathLen = pathLength;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public byte[] idBuffer() {
+    if (myIsOnSubmodule) {
+      return myIdBuffer;
+    } else {
+      return myWrappedIterator.idBuffer();
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public int idOffset() {
+    return myIsOnSubmodule ? 0 : myWrappedIterator.idOffset();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AbstractTreeIterator createSubtreeIterator(Repository repo, MutableObjectId idBuffer, WindowCursor curs)
+    throws IOException {
+    String path = myWrappedIterator.getEntryPathString();
+    if (myIsOnSubmodule) {
+      CanonicalTreeParser p = createTreeParser(curs, mySubmoduleCommit);
+      return createSubmoduleAwareTreeIterator(this, p, mySubmoduleResolver.getSubResolver(mySubmoduleCommit, path), "");
+    } else {
+      return createSubmoduleAwareTreeIterator(this, myWrappedIterator.createSubtreeIterator(getRepository(), idBuffer, curs),
+                                              mySubmoduleResolver,
+                                              path);
+    }
+  }
+
+
+  /**
+   * Create a tree iterator from commit
+   *
+   * @param commit      a start commit
+   * @param subResolver a submodule resolver
+   * @return an iterator for tree that considers submodules
+   * @throws IOException in the case if IO error occurs
+   */
+  public static SubmoduleAwareTreeIterator create(Commit commit, SubmoduleResolver subResolver)
+    throws IOException {
+    return createSubmoduleAwareTreeIterator(null, createTreeParser(commit), subResolver, "");
+  }
+
+
+  /**
+   * Create a tree iterator from commit
+   *
+   * @param parent      the parent iterator (or null)
+   * @param wrapped     the wrapped iterator
+   * @param subResolver a submodule resolver
+   * @param path        the path the submodule is referenced in the local repository
+   * @return an iterator for tree that considers submodules
+   * @throws IOException in the case if IO error occurs
+   */
+  private static SubmoduleAwareTreeIterator createSubmoduleAwareTreeIterator(SubmoduleAwareTreeIterator parent,
+                                                                             AbstractTreeIterator wrapped,
+                                                                             SubmoduleResolver subResolver, String path)
+    throws IOException {
+    if (subResolver.containsSubmodule(path)) {
+      int[] mapping = buildMapping(wrapped);
+      if (mapping == null) {
+        return parent == null
+               ? new DirectSubmoduleAwareTreeIterator(wrapped, subResolver)
+               : new DirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver);
+      } else {
+        return parent == null
+               ? new IndirectSubmoduleAwareTreeIterator(wrapped, subResolver, mapping)
+               : new IndirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver, mapping);
+      }
+    }
+    return parent == null
+           ? new DirectSubmoduleAwareTreeIterator(wrapped, subResolver)
+           : new DirectSubmoduleAwareTreeIterator(parent, wrapped, subResolver);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public AbstractTreeIterator createSubtreeIterator(Repository repo) throws IOException {
+    String path = myWrappedIterator.getEntryPathString();
+    if (myIsOnSubmodule) {
+      WindowCursor curs = new WindowCursor();
+      try {
+        CanonicalTreeParser p = createTreeParser(curs, mySubmoduleCommit);
+        return createSubmoduleAwareTreeIterator(this, p, mySubmoduleResolver.getSubResolver(mySubmoduleCommit, path), "");
+      } finally {
+        curs.release();
+      }
+    } else {
+      return createSubmoduleAwareTreeIterator(this, myWrappedIterator.createSubtreeIterator(getRepository()), mySubmoduleResolver,
+                                              path);
+    }
+  }
+
+  /**
+   * Create tree parser
+   *
+   * @param curs   the window cursor for loading objects
+   * @param commit the commit
+   * @return the tree parser for tree in the commit
+   * @throws IOException in case of IO problem
+   */
+  private static CanonicalTreeParser createTreeParser(WindowCursor curs, final Commit commit) throws IOException {
+    CanonicalTreeParser p = new CanonicalTreeParser();
+    p.reset(commit.getRepository(), commit.getTreeId(), curs);
+    return p;
+  }
+
+
+  /**
+   * Create tree parser
+   *
+   * @param commit the commit that contains point ot the tree
+   * @return the tree parser
+   * @throws IOException in case of IO problem
+   */
+  public static CanonicalTreeParser createTreeParser(final Commit commit) throws IOException {
+    WindowCursor curs = new WindowCursor();
+    try {
+      return createTreeParser(curs, commit);
+    } finally {
+      curs.release();
+    }
+  }
+
+  /**
+   * Scan current tree and build mapping that reorders submodule entries if needed.
+   *
+   * @param w wrapped tree iterator
+   * @return a mapping or null if the mapping is not needed
+   * @throws CorruptObjectException in case if navigation fails
+   */
+  static int[] buildMapping(final AbstractTreeIterator w) throws CorruptObjectException {
+    class SubmoduleEntry {
+      final ByteRange name;
+      final int position;
+
+      public SubmoduleEntry(int position) {
+        this.position = position;
+        byte[] n = new byte[w.getNameLength() + 1];
+        w.getName(n, 0);
+        n[n.length - 1] = '/';
+        name = new ByteRange(n);
+      }
+    }
+    IntArrayList rc = new IntArrayList();
+    boolean reordered = false;
+    LinkedList<SubmoduleEntry> stack = new LinkedList<SubmoduleEntry>();
+    int actual = 0;
+    assert w.first();
+    if (w.eof()) {
+      return null;
+    }
+    final int INITIAL_NAME_SIZE = 32;
+    byte[] name = new byte[INITIAL_NAME_SIZE];
+    while (!w.eof()) {
+      if (!stack.isEmpty()) {
+        int l = w.getNameLength();
+        if (l > name.length) {
+          int nl = name.length;
+          while (nl < l) {
+            nl <<= 1;
+          }
+          name = new byte[nl];
+        }
+        w.getName(name, 0);
+        ByteRange currentName = new ByteRange(name, 0, l);
+        while (!stack.isEmpty()) {
+          final SubmoduleEntry top = stack.getLast();
+          final int result = top.name.compareTo(currentName);
+          assert result != 0;
+          if (result < 0) {
+            if (top.position != rc.size()) {
+              reordered = true;
+            }
+            rc.add(top.position);
+            stack.removeLast();
+          } else {
+            break;
+          }
+        }
+      }
+      if (w.getEntryRawMode() == GITLINK_MODE_BITS) {
+        stack.add(new SubmoduleEntry(actual));
+      } else {
+        rc.add(actual);
+      }
+      w.next(1);
+      actual++;
+    }
+    while (!stack.isEmpty()) {
+      final SubmoduleEntry top = stack.removeLast();
+      if (top.position != rc.size()) {
+        reordered = true;
+      }
+      rc.add(top.position);
+    }
+    w.back(actual);
+    assert w.first();
+    return reordered ? rc.toArray() : null;
+  }
+}
index 8d40d72d81db49e8c033ab59b23b34e8d358ff71..5af3e572c2d8c0ea88aea6823297822b236ab782 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import org.spearce.jgit.lib.BlobBasedConfig;\r
-import org.spearce.jgit.lib.Commit;\r
-import org.spearce.jgit.lib.ObjectId;\r
-import org.spearce.jgit.lib.Repository;\r
-\r
-import java.io.FileNotFoundException;\r
-import java.io.IOException;\r
-\r
-/**\r
- * The resolver for submodules\r
- */\r
-public abstract class SubmoduleResolver {\r
-  /**\r
-   * logger instance\r
-   */\r
-  private static Logger LOG = Logger.getInstance(SubmoduleResolver.class.getName());\r
-  /**\r
-   * The base for submodule configuration\r
-   */\r
-  final Commit myCommit;\r
-  /**\r
-   * The submodule configuration\r
-   */\r
-  SubmodulesConfig myConfig;\r
-\r
-  /**\r
-   * The commit for that contains submodule reference\r
-   *\r
-   * @param commit the submodule commit\r
-   */\r
-  public SubmoduleResolver(Commit commit) {\r
-    myCommit = commit;\r
-  }\r
-\r
-  /**\r
-   * Resolve the commit for submodule\r
-   *\r
-   * @param path   the within repository path\r
-   * @param commit the commit identifier\r
-   * @return the the resoled commit in other repository\r
-   * @throws IOException if there is an IO problem during resolving repository or mapping commit\r
-   */\r
-  public Commit getSubmodule(String path, ObjectId commit) throws IOException {\r
-    ensureConfigLoaded();\r
-    if (myConfig == null) {\r
-      throw new IOException("No submodule configuration for commit: " + myCommit.getCommitId().name());\r
-    }\r
-    final Submodule submodule = myConfig.findEntry(path);\r
-    if (submodule == null) {\r
-      throw new IOException("No valid submodule configuration entry is found for the path: " + path + " in commit " + commit.name());\r
-    }\r
-    Repository r = resolveRepository(path, submodule.getUrl());\r
-    final Commit c = r.mapCommit(commit);\r
-    if (c == null) {\r
-      throw new IOException("The commit " + commit + " (referenced by " + path + ") is not found in repository: " + r);\r
-    }\r
-    return c;\r
-  }\r
-\r
-  /**\r
-   * Ensure that submodule configuration has been loaded.\r
-   */\r
-  private void ensureConfigLoaded() {\r
-    if (myConfig == null) {\r
-      try {\r
-        myConfig = new SubmodulesConfig(myCommit.getRepository().getConfig(), new BlobBasedConfig(null, myCommit, ".gitmodules"));\r
-      } catch (FileNotFoundException e) {\r
-        // do nothing\r
-      } catch (Exception e) {\r
-        LOG.error("Unable to load or parse submodule configuration at: " + myCommit.getCommitId().name(), e);\r
-      }\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Get repository by the URL. Note that the repository is retrieved but not cleaned up. This should be done by implementer of this component at later time.\r
-   *\r
-   * @param path the local path within repository\r
-   * @param url  the URL to resolve  @return the resolved repository\r
-   * @return the resolved repository\r
-   * @throws IOException if repository could not be resolved\r
-   */\r
-  protected abstract Repository resolveRepository(String path, String url) throws IOException;\r
-\r
-  /**\r
-   * Get submodule resolver for the path\r
-   *\r
-   * @param commit the start commit\r
-   * @param path   the local path within repository\r
-   * @return the submodule resolver that handles submodules inside the specified commit\r
-   */\r
-  public abstract SubmoduleResolver getSubResolver(Commit commit, String path);\r
-\r
-  /**\r
-   * Check if the specified directory is a submodule prefix\r
-   *\r
-   * @param path the path to check\r
-   * @return true if the path contains submodules\r
-   */\r
-  public boolean containsSubmodule(String path) {\r
-    ensureConfigLoaded();\r
-    return myConfig != null && myConfig.isSubmodulePrefix(path);\r
-  }\r
-\r
-  /**\r
-   * @return the current repository\r
-   */\r
-  public Repository getRepository() {\r
-    return myCommit.getRepository();\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import com.intellij.openapi.diagnostic.Logger;
+import org.spearce.jgit.lib.BlobBasedConfig;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.ObjectId;
+import org.spearce.jgit.lib.Repository;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * The resolver for submodules
+ */
+public abstract class SubmoduleResolver {
+  /**
+   * logger instance
+   */
+  private static Logger LOG = Logger.getInstance(SubmoduleResolver.class.getName());
+  /**
+   * The base for submodule configuration
+   */
+  final Commit myCommit;
+  /**
+   * The submodule configuration
+   */
+  SubmodulesConfig myConfig;
+
+  /**
+   * The commit for that contains submodule reference
+   *
+   * @param commit the submodule commit
+   */
+  public SubmoduleResolver(Commit commit) {
+    myCommit = commit;
+  }
+
+  /**
+   * Resolve the commit for submodule
+   *
+   * @param path   the within repository path
+   * @param commit the commit identifier
+   * @return the the resoled commit in other repository
+   * @throws IOException if there is an IO problem during resolving repository or mapping commit
+   */
+  public Commit getSubmodule(String path, ObjectId commit) throws IOException {
+    ensureConfigLoaded();
+    if (myConfig == null) {
+      throw new IOException("No submodule configuration for commit: " + myCommit.getCommitId().name());
+    }
+    final Submodule submodule = myConfig.findEntry(path);
+    if (submodule == null) {
+      throw new IOException("No valid submodule configuration entry is found for the path: " + path + " in commit " + commit.name());
+    }
+    Repository r = resolveRepository(path, submodule.getUrl());
+    final Commit c = r.mapCommit(commit);
+    if (c == null) {
+      throw new IOException("The commit " + commit + " (referenced by " + path + ") is not found in repository: " + r);
+    }
+    return c;
+  }
+
+  /**
+   * Ensure that submodule configuration has been loaded.
+   */
+  private void ensureConfigLoaded() {
+    if (myConfig == null) {
+      try {
+        myConfig = new SubmodulesConfig(myCommit.getRepository().getConfig(), new BlobBasedConfig(null, myCommit, ".gitmodules"));
+      } catch (FileNotFoundException e) {
+        // do nothing
+      } catch (Exception e) {
+        LOG.error("Unable to load or parse submodule configuration at: " + myCommit.getCommitId().name(), e);
+      }
+    }
+  }
+
+  /**
+   * Get repository by the URL. Note that the repository is retrieved but not cleaned up. This should be done by implementer of this component at later time.
+   *
+   * @param path the local path within repository
+   * @param url  the URL to resolve  @return the resolved repository
+   * @return the resolved repository
+   * @throws IOException if repository could not be resolved
+   */
+  protected abstract Repository resolveRepository(String path, String url) throws IOException;
+
+  /**
+   * Get submodule resolver for the path
+   *
+   * @param commit the start commit
+   * @param path   the local path within repository
+   * @return the submodule resolver that handles submodules inside the specified commit
+   */
+  public abstract SubmoduleResolver getSubResolver(Commit commit, String path);
+
+  /**
+   * Check if the specified directory is a submodule prefix
+   *
+   * @param path the path to check
+   * @return true if the path contains submodules
+   */
+  public boolean containsSubmodule(String path) {
+    ensureConfigLoaded();
+    return myConfig != null && myConfig.isSubmodulePrefix(path);
+  }
+
+  /**
+   * @return the current repository
+   */
+  public Repository getRepository() {
+    return myCommit.getRepository();
+  }
+}
index 0cb435155caa26f923c910199be9974dca3d8971..88f4da19aef31572cb88d954267b900f7af4631f 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import org.spearce.jgit.lib.Config;\r
-import org.spearce.jgit.lib.RepositoryConfig;\r
-\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Map;\r
-\r
-/**\r
- * Utility that allows working with submodules configuration file\r
- */\r
-public class SubmodulesConfig {\r
-  /**\r
-   * logger instance\r
-   */\r
-  private static Logger LOG = Logger.getInstance(SubmodulesConfig.class.getName());\r
-  /**\r
-   * Repository configuration\r
-   */\r
-  private final RepositoryConfig myRepositoryConfig;\r
-  /**\r
-   * Module configuration\r
-   */\r
-  private final Config myModulesConfig;\r
-  /**\r
-   * Loaded entries\r
-   */\r
-  private final Map<String, Submodule> myPathToEntry = new HashMap<String, Submodule>();\r
-  /**\r
-   * The set of direct parents for submodules\r
-   */\r
-  private final HashSet<String> mySubmoduleDirectParents = new HashSet<String>();\r
-  /**\r
-   * If true the configuration is loaded\r
-   */\r
-  private boolean myIsLoaded = false;\r
-\r
-  /**\r
-   * A constructor from configuration files\r
-   *\r
-   * @param repositoryConfig repository configuration\r
-   * @param modulesConfig    modules configuration\r
-   */\r
-  public SubmodulesConfig(RepositoryConfig repositoryConfig, Config modulesConfig) {\r
-    myRepositoryConfig = repositoryConfig;\r
-    myModulesConfig = modulesConfig;\r
-  }\r
-\r
-  /**\r
-   * Get entry for the path\r
-   *\r
-   * @param path the entry path\r
-   * @return the entry or null if the entry is not found for the path\r
-   */\r
-  public Submodule findEntry(String path) {\r
-    ensureLoaded();\r
-    return myPathToEntry.get(path);\r
-  }\r
-\r
-  /**\r
-   * Ensure that submodule configuration is loaded from database\r
-   */\r
-  private void ensureLoaded() {\r
-    if (myIsLoaded) {\r
-      return;\r
-    }\r
-    for (String name : myModulesConfig.getSubsections("submodule")) {\r
-      final String path = myModulesConfig.getString("submodule", name, "path");\r
-      String url = myRepositoryConfig.getString("submodule", name, "url");\r
-      if (url == null) {\r
-        url = myModulesConfig.getString("submodule", name, "url");\r
-      }\r
-      if (url == null || path == null) {\r
-        // if url or path might be missing in the case of leftover sections\r
-        // in configuration file.\r
-        LOG.warn("Invalid submodule entry: " + name + " path: " + path + " url :" + url);\r
-        continue;\r
-      }\r
-      myPathToEntry.put(path, new Submodule(name, path, url));\r
-      int p = path.lastIndexOf('/');\r
-      if (p == -1) {\r
-        p = 0;\r
-      }\r
-      mySubmoduleDirectParents.add(path.substring(0, p));\r
-    }\r
-    myIsLoaded = true;\r
-  }\r
-\r
-  /**\r
-   * Check if the specified prefix is a direct submodule parent. This check is used to detect\r
-   * situation when the directory might be reordered due to the submodules.\r
-   *\r
-   * @param path the path to be checked if it is a submodule parent.\r
-   * @return true if the path can directly contain submodules\r
-   */\r
-  public boolean isSubmodulePrefix(String path) {\r
-    ensureLoaded();\r
-    return mySubmoduleDirectParents.contains(path);\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import com.intellij.openapi.diagnostic.Logger;
+import org.spearce.jgit.lib.Config;
+import org.spearce.jgit.lib.RepositoryConfig;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Utility that allows working with submodules configuration file
+ */
+public class SubmodulesConfig {
+  /**
+   * logger instance
+   */
+  private static Logger LOG = Logger.getInstance(SubmodulesConfig.class.getName());
+  /**
+   * Repository configuration
+   */
+  private final RepositoryConfig myRepositoryConfig;
+  /**
+   * Module configuration
+   */
+  private final Config myModulesConfig;
+  /**
+   * Loaded entries
+   */
+  private final Map<String, Submodule> myPathToEntry = new HashMap<String, Submodule>();
+  /**
+   * The set of direct parents for submodules
+   */
+  private final HashSet<String> mySubmoduleDirectParents = new HashSet<String>();
+  /**
+   * If true the configuration is loaded
+   */
+  private boolean myIsLoaded = false;
+
+  /**
+   * A constructor from configuration files
+   *
+   * @param repositoryConfig repository configuration
+   * @param modulesConfig    modules configuration
+   */
+  public SubmodulesConfig(RepositoryConfig repositoryConfig, Config modulesConfig) {
+    myRepositoryConfig = repositoryConfig;
+    myModulesConfig = modulesConfig;
+  }
+
+  /**
+   * Get entry for the path
+   *
+   * @param path the entry path
+   * @return the entry or null if the entry is not found for the path
+   */
+  public Submodule findEntry(String path) {
+    ensureLoaded();
+    return myPathToEntry.get(path);
+  }
+
+  /**
+   * Ensure that submodule configuration is loaded from database
+   */
+  private void ensureLoaded() {
+    if (myIsLoaded) {
+      return;
+    }
+    for (String name : myModulesConfig.getSubsections("submodule")) {
+      final String path = myModulesConfig.getString("submodule", name, "path");
+      String url = myRepositoryConfig.getString("submodule", name, "url");
+      if (url == null) {
+        url = myModulesConfig.getString("submodule", name, "url");
+      }
+      if (url == null || path == null) {
+        // if url or path might be missing in the case of leftover sections
+        // in configuration file.
+        LOG.warn("Invalid submodule entry: " + name + " path: " + path + " url :" + url);
+        continue;
+      }
+      myPathToEntry.put(path, new Submodule(name, path, url));
+      int p = path.lastIndexOf('/');
+      if (p == -1) {
+        p = 0;
+      }
+      mySubmoduleDirectParents.add(path.substring(0, p));
+    }
+    myIsLoaded = true;
+  }
+
+  /**
+   * Check if the specified prefix is a direct submodule parent. This check is used to detect
+   * situation when the directory might be reordered due to the submodules.
+   *
+   * @param path the path to be checked if it is a submodule parent.
+   * @return true if the path can directly contain submodules
+   */
+  public boolean isSubmodulePrefix(String path) {
+    ensureLoaded();
+    return mySubmoduleDirectParents.contains(path);
+  }
+}
index e9857e885a045b4ed316b329643c4e8745f7ead7..7182e93a8f837792beb8536746953e6a21971e06 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.submodules;\r
-\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.GitUtils;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.GitVcsSupport;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.Settings;\r
-import jetbrains.buildServer.vcs.VcsException;\r
-import org.spearce.jgit.lib.Commit;\r
-import org.spearce.jgit.lib.NullProgressMonitor;\r
-import org.spearce.jgit.lib.Repository;\r
-import org.spearce.jgit.transport.RefSpec;\r
-import org.spearce.jgit.transport.Transport;\r
-import org.spearce.jgit.transport.URIish;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.net.URISyntaxException;\r
-import java.net.URL;\r
-import java.util.Collections;\r
-import java.util.Map;\r
-\r
-/**\r
- * The resolver for submodules that uses TeamCity repository mapping.\r
- */\r
-public class TeamCitySubmoduleResolver extends SubmoduleResolver {\r
-  /**\r
-   * logger instance\r
-   */\r
-  private static Logger LOG = Logger.getInstance(TeamCitySubmoduleResolver.class.getName());\r
-  /**\r
-   * Base path within root for the resolver\r
-   */\r
-  final String myBasePath;\r
-  /**\r
-   * The settings object\r
-   */\r
-  final Settings mySettings;\r
-  /**\r
-   * The vcs support\r
-   */\r
-  private final GitVcsSupport myVcs;\r
-  /**\r
-   * Repositories created for submodules\r
-   */\r
-  private final Map<String, Repository> mySubmoduleRepositories;\r
-\r
-  /**\r
-   * The resolver constructor\r
-   *\r
-   * @param submoduleRepositories the collection to accumulate submodule repositories\r
-   * @param vcs                   the Git vcs service\r
-   * @param settings              the settings object\r
-   * @param commit                the commit this resolves handles\r
-   */\r
-  public TeamCitySubmoduleResolver(Map<String, Repository> submoduleRepositories, GitVcsSupport vcs, Settings settings, Commit commit) {\r
-    this(submoduleRepositories, vcs, settings, "", commit);\r
-  }\r
-\r
-  /**\r
-   * The resolver constructor\r
-   *\r
-   * @param submoduleRepositories the collection to accumulate submodule repositories\r
-   * @param vcs                   the Git vcs service\r
-   * @param settings              the settings object\r
-   * @param basePath              the base path\r
-   * @param commit                the commit this resolves handles\r
-   */\r
-  private TeamCitySubmoduleResolver(Map<String, Repository> submoduleRepositories,\r
-                                    GitVcsSupport vcs,\r
-                                    Settings settings,\r
-                                    String basePath,\r
-                                    Commit commit) {\r
-    super(commit);\r
-    mySubmoduleRepositories = submoduleRepositories;\r
-    myBasePath = basePath;\r
-    mySettings = settings;\r
-    myVcs = vcs;\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  protected Repository resolveRepository(String path, String url) throws IOException {\r
-    String overrideUrl = mySettings.getSubmoduleUrl(path);\r
-    if (overrideUrl != null) {\r
-      url = overrideUrl;\r
-    }\r
-    if (url.startsWith(".")) {\r
-      String baseUrl = myCommit.getRepository().getConfig().getString("teamcity", null, "remote");\r
-      URL u = new URL(new URL(baseUrl), url);\r
-      url = u.toString();\r
-    }\r
-    String dir = mySettings.getSubmodulePath(path, url);\r
-    if (mySubmoduleRepositories.containsKey(dir)) {\r
-      return mySubmoduleRepositories.get(dir);\r
-    }\r
-    try {\r
-      final URIish uri = new URIish(url);\r
-      final Repository r = GitUtils.getRepository(new File(dir), uri);\r
-      mySubmoduleRepositories.put(dir, r);\r
-      final Transport tn = myVcs.openTransport(mySettings, r, uri);\r
-      if (LOG.isDebugEnabled()) {\r
-        LOG.debug("Fetching submodule " + path + " data for " + mySettings.debugInfo());\r
-      }\r
-      try {\r
-        String refName = GitUtils.branchRef("*");\r
-        RefSpec spec = new RefSpec("+" + refName + ":" + refName);\r
-        tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(spec));\r
-      } finally {\r
-        tn.close();\r
-      }\r
-      return r;\r
-    } catch (VcsException e) {\r
-      if (e.getCause() instanceof IOException) {\r
-        throw (IOException)e.getCause();\r
-      }\r
-      final IOException ex = new IOException(e.getMessage());\r
-      ex.initCause(e);\r
-      throw ex;\r
-    } catch (URISyntaxException e) {\r
-      final IOException ex = new IOException(e.getMessage());\r
-      ex.initCause(e);\r
-      throw ex;\r
-    }\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  public SubmoduleResolver getSubResolver(Commit commit, String path) {\r
-    return new TeamCitySubmoduleResolver(mySubmoduleRepositories, myVcs, mySettings, fullPath(path), commit);\r
-  }\r
-\r
-  /**\r
-   * Get full path using from local path\r
-   *\r
-   * @param path the path to examine\r
-   * @return the full including the base path\r
-   */\r
-  private String fullPath(String path) {\r
-    return myBasePath.length() == 0 ? path : myBasePath + "/" + path;\r
-  }\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.submodules;
+
+import com.intellij.openapi.diagnostic.Logger;
+import jetbrains.buildServer.buildTriggers.vcs.git.GitUtils;
+import jetbrains.buildServer.buildTriggers.vcs.git.GitVcsSupport;
+import jetbrains.buildServer.buildTriggers.vcs.git.Settings;
+import jetbrains.buildServer.vcs.VcsException;
+import org.spearce.jgit.lib.Commit;
+import org.spearce.jgit.lib.NullProgressMonitor;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.transport.RefSpec;
+import org.spearce.jgit.transport.Transport;
+import org.spearce.jgit.transport.URIish;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * The resolver for submodules that uses TeamCity repository mapping.
+ */
+public class TeamCitySubmoduleResolver extends SubmoduleResolver {
+  /**
+   * logger instance
+   */
+  private static Logger LOG = Logger.getInstance(TeamCitySubmoduleResolver.class.getName());
+  /**
+   * Base path within root for the resolver
+   */
+  final String myBasePath;
+  /**
+   * The settings object
+   */
+  final Settings mySettings;
+  /**
+   * The vcs support
+   */
+  private final GitVcsSupport myVcs;
+  /**
+   * Repositories created for submodules
+   */
+  private final Map<String, Repository> mySubmoduleRepositories;
+
+  /**
+   * The resolver constructor
+   *
+   * @param submoduleRepositories the collection to accumulate submodule repositories
+   * @param vcs                   the Git vcs service
+   * @param settings              the settings object
+   * @param commit                the commit this resolves handles
+   */
+  public TeamCitySubmoduleResolver(Map<String, Repository> submoduleRepositories, GitVcsSupport vcs, Settings settings, Commit commit) {
+    this(submoduleRepositories, vcs, settings, "", commit);
+  }
+
+  /**
+   * The resolver constructor
+   *
+   * @param submoduleRepositories the collection to accumulate submodule repositories
+   * @param vcs                   the Git vcs service
+   * @param settings              the settings object
+   * @param basePath              the base path
+   * @param commit                the commit this resolves handles
+   */
+  private TeamCitySubmoduleResolver(Map<String, Repository> submoduleRepositories,
+                                    GitVcsSupport vcs,
+                                    Settings settings,
+                                    String basePath,
+                                    Commit commit) {
+    super(commit);
+    mySubmoduleRepositories = submoduleRepositories;
+    myBasePath = basePath;
+    mySettings = settings;
+    myVcs = vcs;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Repository resolveRepository(String path, String url) throws IOException {
+    String overrideUrl = mySettings.getSubmoduleUrl(path);
+    if (overrideUrl != null) {
+      url = overrideUrl;
+    }
+    if (url.startsWith(".")) {
+      String baseUrl = myCommit.getRepository().getConfig().getString("teamcity", null, "remote");
+      URL u = new URL(new URL(baseUrl), url);
+      url = u.toString();
+    }
+    String dir = mySettings.getSubmodulePath(path, url);
+    if (mySubmoduleRepositories.containsKey(dir)) {
+      return mySubmoduleRepositories.get(dir);
+    }
+    try {
+      final URIish uri = new URIish(url);
+      final Repository r = GitUtils.getRepository(new File(dir), uri);
+      mySubmoduleRepositories.put(dir, r);
+      final Transport tn = myVcs.openTransport(mySettings, r, uri);
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Fetching submodule " + path + " data for " + mySettings.debugInfo());
+      }
+      try {
+        String refName = GitUtils.branchRef("*");
+        RefSpec spec = new RefSpec("+" + refName + ":" + refName);
+        tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(spec));
+      } finally {
+        tn.close();
+      }
+      return r;
+    } catch (VcsException e) {
+      if (e.getCause() instanceof IOException) {
+        throw (IOException)e.getCause();
+      }
+      final IOException ex = new IOException(e.getMessage());
+      ex.initCause(e);
+      throw ex;
+    } catch (URISyntaxException e) {
+      final IOException ex = new IOException(e.getMessage());
+      ex.initCause(e);
+      throw ex;
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public SubmoduleResolver getSubResolver(Commit commit, String path) {
+    return new TeamCitySubmoduleResolver(mySubmoduleRepositories, myVcs, mySettings, fullPath(path), commit);
+  }
+
+  /**
+   * Get full path using from local path
+   *
+   * @param path the path to examine
+   * @return the full including the base path
+   */
+  private String fullPath(String path) {
+    return myBasePath.length() == 0 ? path : myBasePath + "/" + path;
+  }
+}
index 2f22bd55eac9be8805585d0580bf0d30286db3df..48b11e0352822416acd9bf10141a039da9880ae2 100755 (executable)
-<?xml version="1.0" encoding="UTF-8"?>\r
-<project relativePaths="false" version="4">\r
-  <component name="AntConfiguration">\r
-    <defaultAnt bundledAnt="true" />\r
-    <buildFile url="file://$PROJECT_DIR$/build.xml">\r
-      <additionalClassPath />\r
-      <antReference projectDefault="true" />\r
-      <customJdkName value="" />\r
-      <maximumHeapSize value="128" />\r
-      <maximumStackSize value="32" />\r
-      <properties />\r
-    </buildFile>\r
-  </component>\r
-  <component name="BuildJarProjectSettings">\r
-    <option name="BUILD_JARS_ON_MAKE" value="false" />\r
-  </component>\r
-  <component name="CodeStyleSettingsManager">\r
-    <option name="PER_PROJECT_SETTINGS">\r
-      <value>\r
-        <option name="OTHER_INDENT_OPTIONS">\r
-          <value>\r
-            <option name="INDENT_SIZE" value="2" />\r
-            <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
-            <option name="TAB_SIZE" value="4" />\r
-            <option name="USE_TAB_CHARACTER" value="false" />\r
-            <option name="SMART_TABS" value="false" />\r
-            <option name="LABEL_INDENT_SIZE" value="0" />\r
-            <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-          </value>\r
-        </option>\r
-        <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />\r
-        <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />\r
-        <option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />\r
-        <option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />\r
-        <option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />\r
-        <option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />\r
-        <option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />\r
-        <option name="SPACE_AFTER_TYPE_CAST" value="false" />\r
-        <option name="RIGHT_MARGIN" value="140" />\r
-        <option name="CALL_PARAMETERS_WRAP" value="1" />\r
-        <option name="METHOD_PARAMETERS_WRAP" value="5" />\r
-        <option name="EXTENDS_LIST_WRAP" value="1" />\r
-        <option name="THROWS_LIST_WRAP" value="5" />\r
-        <option name="EXTENDS_KEYWORD_WRAP" value="1" />\r
-        <option name="THROWS_KEYWORD_WRAP" value="1" />\r
-        <option name="METHOD_CALL_CHAIN_WRAP" value="1" />\r
-        <option name="BINARY_OPERATION_WRAP" value="1" />\r
-        <option name="TERNARY_OPERATION_WRAP" value="5" />\r
-        <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />\r
-        <option name="FOR_STATEMENT_WRAP" value="5" />\r
-        <option name="ARRAY_INITIALIZER_WRAP" value="1" />\r
-        <option name="ASSIGNMENT_WRAP" value="1" />\r
-        <option name="IF_BRACE_FORCE" value="1" />\r
-        <option name="DOWHILE_BRACE_FORCE" value="1" />\r
-        <option name="WHILE_BRACE_FORCE" value="1" />\r
-        <option name="FOR_BRACE_FORCE" value="1" />\r
-        <option name="FIELD_ANNOTATION_WRAP" value="0" />\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="groovy">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="gsp">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="java">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="2" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="js">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="4" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="jsp">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="4" />\r
-          <option name="TAB_SIZE" value="8" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="sql">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="xml">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="4" />\r
-          <option name="TAB_SIZE" value="8" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-        <ADDITIONAL_INDENT_OPTIONS fileType="yml">\r
-          <option name="INDENT_SIZE" value="2" />\r
-          <option name="CONTINUATION_INDENT_SIZE" value="8" />\r
-          <option name="TAB_SIZE" value="4" />\r
-          <option name="USE_TAB_CHARACTER" value="false" />\r
-          <option name="SMART_TABS" value="false" />\r
-          <option name="LABEL_INDENT_SIZE" value="0" />\r
-          <option name="LABEL_INDENT_ABSOLUTE" value="false" />\r
-        </ADDITIONAL_INDENT_OPTIONS>\r
-      </value>\r
-    </option>\r
-    <option name="USE_PER_PROJECT_SETTINGS" value="true" />\r
-  </component>\r
-  <component name="CompilerAPISettings">\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="false" />\r
-    <option name="DEPRECATION" value="true" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />\r
-  </component>\r
-  <component name="CompilerConfiguration">\r
-    <option name="DEFAULT_COMPILER" value="Javac" />\r
-    <option name="DEPLOY_AFTER_MAKE" value="0" />\r
-    <resourceExtensions>\r
-      <entry name=".+\.(properties|xml|html|dtd|tld)" />\r
-      <entry name=".+\.(gif|png|jpeg|jpg)" />\r
-    </resourceExtensions>\r
-    <wildcardResourcePatterns>\r
-      <entry name="?*.properties" />\r
-      <entry name="?*.xml" />\r
-      <entry name="?*.gif" />\r
-      <entry name="?*.png" />\r
-      <entry name="?*.jpeg" />\r
-      <entry name="?*.jpg" />\r
-      <entry name="?*.html" />\r
-      <entry name="?*.dtd" />\r
-      <entry name="?*.tld" />\r
-      <entry name="?*.ftl" />\r
-      <entry name="?*.jsp" />\r
-    </wildcardResourcePatterns>\r
-  </component>\r
-  <component name="CopyrightManager" default="">\r
-    <copyright>\r
-      <option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />\r
-      <option name="keyword" value="Copyright" />\r
-      <option name="myName" value="open.source" />\r
-      <option name="myLocal" value="true" />\r
-    </copyright>\r
-    <module2copyright>\r
-      <element module="All" copyright="open.source" />\r
-    </module2copyright>\r
-    <LanguageOptions name="JAVA">\r
-      <option name="fileTypeOverride" value="2" />\r
-      <option name="relativeBefore" value="true" />\r
-      <option name="addBlankAfter" value="false" />\r
-      <option name="fileLocation" value="1" />\r
-      <option name="block" value="true" />\r
-      <option name="separateBefore" value="false" />\r
-      <option name="separateAfter" value="false" />\r
-      <option name="prefixLines" value="true" />\r
-      <option name="lenBefore" value="80" />\r
-      <option name="lenAfter" value="80" />\r
-      <option name="box" value="false" />\r
-      <option name="filler" value=" " />\r
-    </LanguageOptions>\r
-    <LanguageOptions name="JSP">\r
-      <option name="fileTypeOverride" value="1" />\r
-      <option name="relativeBefore" value="true" />\r
-      <option name="addBlankAfter" value="true" />\r
-      <option name="fileLocation" value="1" />\r
-      <option name="block" value="true" />\r
-      <option name="separateBefore" value="false" />\r
-      <option name="separateAfter" value="false" />\r
-      <option name="prefixLines" value="true" />\r
-      <option name="lenBefore" value="80" />\r
-      <option name="lenAfter" value="80" />\r
-      <option name="box" value="false" />\r
-      <option name="filler" value=" " />\r
-    </LanguageOptions>\r
-    <LanguageOptions name="JSPX">\r
-      <option name="fileTypeOverride" value="1" />\r
-      <option name="relativeBefore" value="true" />\r
-      <option name="addBlankAfter" value="true" />\r
-      <option name="fileLocation" value="1" />\r
-      <option name="block" value="true" />\r
-      <option name="separateBefore" value="false" />\r
-      <option name="separateAfter" value="false" />\r
-      <option name="prefixLines" value="true" />\r
-      <option name="lenBefore" value="80" />\r
-      <option name="lenAfter" value="80" />\r
-      <option name="box" value="false" />\r
-      <option name="filler" value=" " />\r
-    </LanguageOptions>\r
-    <LanguageOptions name="Properties">\r
-      <option name="fileTypeOverride" value="1" />\r
-      <option name="relativeBefore" value="true" />\r
-      <option name="addBlankAfter" value="true" />\r
-      <option name="fileLocation" value="1" />\r
-      <option name="block" value="true" />\r
-      <option name="separateBefore" value="false" />\r
-      <option name="separateAfter" value="false" />\r
-      <option name="prefixLines" value="true" />\r
-      <option name="lenBefore" value="80" />\r
-      <option name="lenAfter" value="80" />\r
-      <option name="box" value="false" />\r
-      <option name="filler" value=" " />\r
-    </LanguageOptions>\r
-    <LanguageOptions name="XML">\r
-      <option name="fileTypeOverride" value="1" />\r
-      <option name="relativeBefore" value="true" />\r
-      <option name="addBlankAfter" value="true" />\r
-      <option name="fileLocation" value="1" />\r
-      <option name="block" value="true" />\r
-      <option name="separateBefore" value="false" />\r
-      <option name="separateAfter" value="false" />\r
-      <option name="prefixLines" value="true" />\r
-      <option name="lenBefore" value="80" />\r
-      <option name="lenAfter" value="80" />\r
-      <option name="box" value="false" />\r
-      <option name="filler" value=" " />\r
-    </LanguageOptions>\r
-  </component>\r
-  <component name="DependencyValidationManager">\r
-    <option name="SKIP_IMPORT_STATEMENTS" value="false" />\r
-  </component>\r
-  <component name="EclipseCompilerSettings">\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="true" />\r
-    <option name="DEPRECATION" value="false" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />\r
-  </component>\r
-  <component name="EclipseEmbeddedCompilerSettings">\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="true" />\r
-    <option name="DEPRECATION" value="false" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />\r
-  </component>\r
-  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />\r
-  <component name="FacetAutodetectingManager">\r
-    <autodetection-disabled>\r
-      <facet-type id="web">\r
-        <modules>\r
-          <module name="git-server">\r
-            <files>\r
-              <file url="file://$PROJECT_DIR$/git-server/web/WEB-INF/web.xml" />\r
-            </files>\r
-          </module>\r
-        </modules>\r
-      </facet-type>\r
-    </autodetection-disabled>\r
-  </component>\r
-  <component name="IdProvider" IDEtalkID="5D3DF039F2986C172BD95D6A6F8754EF" />\r
-  <component name="InspectionProjectProfileManager">\r
-    <option name="PROJECT_PROFILE" value="Project Default" />\r
-    <option name="USE_PROJECT_PROFILE" value="true" />\r
-    <version value="1.0" />\r
-    <profiles>\r
-      <profile version="1.0" is_locked="false">\r
-        <option name="myName" value="Project Default" />\r
-        <option name="myLocal" value="false" />\r
-        <inspection_tool class="UnnecessaryFullyQualifiedName" enabled="true" level="WARNING" enabled_by_default="true">\r
-          <option name="m_ignoreJavadoc" value="false" />\r
-        </inspection_tool>\r
-      </profile>\r
-    </profiles>\r
-    <list size="5">\r
-      <item index="0" class="java.lang.String" itemvalue="INFO" />\r
-      <item index="1" class="java.lang.String" itemvalue="WARNING" />\r
-      <item index="2" class="java.lang.String" itemvalue="ERROR" />\r
-      <item index="3" class="java.lang.String" itemvalue="TYPO" />\r
-      <item index="4" class="java.lang.String" itemvalue="SERVER PROBLEM" />\r
-    </list>\r
-  </component>\r
-  <component name="JavacSettings">\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="false" />\r
-    <option name="DEPRECATION" value="true" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-    <option name="MAXIMUM_HEAP_SIZE" value="128" />\r
-  </component>\r
-  <component name="JavadocGenerationManager">\r
-    <option name="OUTPUT_DIRECTORY" />\r
-    <option name="OPTION_SCOPE" value="protected" />\r
-    <option name="OPTION_HIERARCHY" value="true" />\r
-    <option name="OPTION_NAVIGATOR" value="true" />\r
-    <option name="OPTION_INDEX" value="true" />\r
-    <option name="OPTION_SEPARATE_INDEX" value="true" />\r
-    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />\r
-    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />\r
-    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />\r
-    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />\r
-    <option name="OPTION_DEPRECATED_LIST" value="true" />\r
-    <option name="OTHER_OPTIONS" value="" />\r
-    <option name="HEAP_SIZE" />\r
-    <option name="LOCALE" />\r
-    <option name="OPEN_IN_BROWSER" value="true" />\r
-  </component>\r
-  <component name="JikesSettings">\r
-    <option name="JIKES_PATH" value="" />\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="DEPRECATION" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="false" />\r
-    <option name="IS_EMACS_ERRORS_MODE" value="true" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-  </component>\r
-  <component name="Palette2">\r
-    <group name="Swing">\r
-      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />\r
-      </item>\r
-      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />\r
-      </item>\r
-      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />\r
-      </item>\r
-      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">\r
-        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />\r
-      </item>\r
-      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />\r
-        <initial-values>\r
-          <property name="text" value="Button" />\r
-        </initial-values>\r
-      </item>\r
-      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />\r
-        <initial-values>\r
-          <property name="text" value="RadioButton" />\r
-        </initial-values>\r
-      </item>\r
-      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />\r
-        <initial-values>\r
-          <property name="text" value="CheckBox" />\r
-        </initial-values>\r
-      </item>\r
-      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />\r
-        <initial-values>\r
-          <property name="text" value="Label" />\r
-        </initial-values>\r
-      </item>\r
-      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">\r
-          <preferred-size width="150" height="-1" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">\r
-          <preferred-size width="150" height="-1" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">\r
-          <preferred-size width="150" height="-1" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />\r
-      </item>\r
-      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">\r
-          <preferred-size width="150" height="50" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">\r
-          <preferred-size width="200" height="200" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">\r
-          <preferred-size width="200" height="200" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />\r
-      </item>\r
-      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />\r
-      </item>\r
-      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />\r
-      </item>\r
-      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />\r
-      </item>\r
-      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">\r
-          <preferred-size width="-1" height="20" />\r
-        </default-constraints>\r
-      </item>\r
-      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">\r
-        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />\r
-      </item>\r
-      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">\r
-        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />\r
-      </item>\r
-    </group>\r
-  </component>\r
-  <component name="ProjectDetails">\r
-    <option name="projectName" value="git-teamcity" />\r
-  </component>\r
-  <component name="ProjectFileVersion" converted="true" />\r
-  <component name="ProjectKey">\r
-    <option name="state" value="project://60c230e5-1bc8-46d2-9235-d195b9ba9c04" />\r
-  </component>\r
-  <component name="ProjectModuleManager">\r
-    <modules>\r
-      <module fileurl="file://$PROJECT_DIR$/git-server/git-server.iml" filepath="$PROJECT_DIR$/git-server/git-server.iml" />\r
-      <module fileurl="file://$PROJECT_DIR$/git-tests/git-tests.iml" filepath="$PROJECT_DIR$/git-tests/git-tests.iml" />\r
-      <module fileurl="file://$PROJECT_DIR$/root.iml" filepath="$PROJECT_DIR$/root.iml" />\r
-    </modules>\r
-  </component>\r
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">\r
-    <output url="file://$PROJECT_DIR$/out" />\r
-  </component>\r
-  <component name="ResourceManagerContainer">\r
-    <option name="myResourceBundles">\r
-      <value>\r
-        <list size="0" />\r
-      </value>\r
-    </option>\r
-  </component>\r
-  <component name="RmicSettings">\r
-    <option name="IS_EANABLED" value="false" />\r
-    <option name="DEBUGGING_INFO" value="true" />\r
-    <option name="GENERATE_NO_WARNINGS" value="false" />\r
-    <option name="GENERATE_IIOP_STUBS" value="false" />\r
-    <option name="ADDITIONAL_OPTIONS_STRING" value="" />\r
-  </component>\r
-  <component name="SvnBranchConfigurationManager">\r
-    <option name="mySupportsUserInfoFilter" value="true" />\r
-  </component>\r
-  <component name="VcsDirectoryMappings">\r
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />\r
-  </component>\r
-  <component name="WebServicesPlugin" addRequiredLibraries="true" />\r
-  <component name="libraryTable">\r
-    <library name="TeamCity Open API agent">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/agent-api.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />\r
-      </JAVADOC>\r
-      <SOURCES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />\r
-      </SOURCES>\r
-    </library>\r
-    <library name="TeamCity Open API server">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/server-api.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />\r
-      </JAVADOC>\r
-      <SOURCES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />\r
-      </SOURCES>\r
-    </library>\r
-    <library name="TeamCity Open API common">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/runtime-util.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/devPackage/common-api.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/log4j-1.2.12.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />\r
-      </JAVADOC>\r
-      <SOURCES>\r
-        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />\r
-      </SOURCES>\r
-    </library>\r
-    <library name="TeamCity Third-Party">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/annotations.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/spring.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/openapi.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/util.jar!/" />\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/spring-webmvc.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC />\r
-      <SOURCES />\r
-    </library>\r
-    <library name="Tomcat">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/lib/servlet-api.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC />\r
-      <SOURCES />\r
-    </library>\r
-    <library name="JGit">\r
-      <CLASSES>\r
-        <root url="jar://$PROJECT_DIR$/lib/jsch-0.1.37.jar!/" />\r
-        <root url="jar://$PROJECT_DIR$/lib/jgit-0.5.0-SNAPSHOT.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC />\r
-      <SOURCES>\r
-        <root url="jar://$PROJECT_DIR$/lib/src/jsch-0.1.37.zip!/jsch-0.1.37/src" />\r
-        <root url="jar://$PROJECT_DIR$/lib/src/jgit-0.5.0-SNAPSHOT-sources.jar!/" />\r
-      </SOURCES>\r
-    </library>\r
-    <library name="TestLibs">\r
-      <CLASSES>\r
-        <root url="file://$PROJECT_DIR$/git-tests/lib" />\r
-      </CLASSES>\r
-      <JAVADOC />\r
-      <SOURCES />\r
-      <jarDirectory url="file://$PROJECT_DIR$/git-tests/lib" recursive="false" />\r
-    </library>\r
-    <library name="TeamCity Tests">\r
-      <CLASSES>\r
-        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/patches-impl.jar!/" />\r
-      </CLASSES>\r
-      <JAVADOC />\r
-      <SOURCES />\r
-    </library>\r
-  </component>\r
-  <UsedPathMacros>\r
-    <macro name="TeamCityDistribution" />\r
-  </UsedPathMacros>\r
-</project>\r
-\r
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AntConfiguration">
+    <defaultAnt bundledAnt="true" />
+    <buildFile url="file://$PROJECT_DIR$/build.xml">
+      <additionalClassPath />
+      <antReference projectDefault="true" />
+      <customJdkName value="" />
+      <maximumHeapSize value="128" />
+      <maximumStackSize value="32" />
+      <properties />
+    </buildFile>
+  </component>
+  <component name="BuildJarProjectSettings">
+    <option name="BUILD_JARS_ON_MAKE" value="false" />
+  </component>
+  <component name="CodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="OTHER_INDENT_OPTIONS">
+          <value>
+            <option name="INDENT_SIZE" value="2" />
+            <option name="CONTINUATION_INDENT_SIZE" value="8" />
+            <option name="TAB_SIZE" value="4" />
+            <option name="USE_TAB_CHARACTER" value="false" />
+            <option name="SMART_TABS" value="false" />
+            <option name="LABEL_INDENT_SIZE" value="0" />
+            <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+          </value>
+        </option>
+        <option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
+        <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
+        <option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
+        <option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
+        <option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
+        <option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
+        <option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
+        <option name="SPACE_AFTER_TYPE_CAST" value="false" />
+        <option name="RIGHT_MARGIN" value="140" />
+        <option name="CALL_PARAMETERS_WRAP" value="1" />
+        <option name="METHOD_PARAMETERS_WRAP" value="5" />
+        <option name="EXTENDS_LIST_WRAP" value="1" />
+        <option name="THROWS_LIST_WRAP" value="5" />
+        <option name="EXTENDS_KEYWORD_WRAP" value="1" />
+        <option name="THROWS_KEYWORD_WRAP" value="1" />
+        <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
+        <option name="BINARY_OPERATION_WRAP" value="1" />
+        <option name="TERNARY_OPERATION_WRAP" value="5" />
+        <option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
+        <option name="FOR_STATEMENT_WRAP" value="5" />
+        <option name="ARRAY_INITIALIZER_WRAP" value="1" />
+        <option name="ASSIGNMENT_WRAP" value="1" />
+        <option name="IF_BRACE_FORCE" value="1" />
+        <option name="DOWHILE_BRACE_FORCE" value="1" />
+        <option name="WHILE_BRACE_FORCE" value="1" />
+        <option name="FOR_BRACE_FORCE" value="1" />
+        <option name="FIELD_ANNOTATION_WRAP" value="0" />
+        <ADDITIONAL_INDENT_OPTIONS fileType="groovy">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="gsp">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="java">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="2" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="js">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="4" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="jsp">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="4" />
+          <option name="TAB_SIZE" value="8" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="sql">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="xml">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="4" />
+          <option name="TAB_SIZE" value="8" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="yml">
+          <option name="INDENT_SIZE" value="2" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+  <component name="CompilerAPISettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="DEPRECATION" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <option name="DEPLOY_AFTER_MAKE" value="0" />
+    <resourceExtensions>
+      <entry name=".+\.(properties|xml|html|dtd|tld)" />
+      <entry name=".+\.(gif|png|jpeg|jpg)" />
+    </resourceExtensions>
+    <wildcardResourcePatterns>
+      <entry name="?*.properties" />
+      <entry name="?*.xml" />
+      <entry name="?*.gif" />
+      <entry name="?*.png" />
+      <entry name="?*.jpeg" />
+      <entry name="?*.jpg" />
+      <entry name="?*.html" />
+      <entry name="?*.dtd" />
+      <entry name="?*.tld" />
+      <entry name="?*.ftl" />
+      <entry name="?*.jsp" />
+    </wildcardResourcePatterns>
+  </component>
+  <component name="CopyrightManager" default="">
+    <copyright>
+      <option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
+      <option name="keyword" value="Copyright" />
+      <option name="myName" value="open.source" />
+      <option name="myLocal" value="true" />
+    </copyright>
+    <module2copyright>
+      <element module="All" copyright="open.source" />
+    </module2copyright>
+    <LanguageOptions name="JAVA">
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="false" />
+      <option name="fileLocation" value="1" />
+      <option name="block" value="true" />
+      <option name="separateBefore" value="false" />
+      <option name="separateAfter" value="false" />
+      <option name="prefixLines" value="true" />
+      <option name="lenBefore" value="80" />
+      <option name="lenAfter" value="80" />
+      <option name="box" value="false" />
+      <option name="filler" value=" " />
+    </LanguageOptions>
+    <LanguageOptions name="JSP">
+      <option name="fileTypeOverride" value="1" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="block" value="true" />
+      <option name="separateBefore" value="false" />
+      <option name="separateAfter" value="false" />
+      <option name="prefixLines" value="true" />
+      <option name="lenBefore" value="80" />
+      <option name="lenAfter" value="80" />
+      <option name="box" value="false" />
+      <option name="filler" value=" " />
+    </LanguageOptions>
+    <LanguageOptions name="JSPX">
+      <option name="fileTypeOverride" value="1" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="block" value="true" />
+      <option name="separateBefore" value="false" />
+      <option name="separateAfter" value="false" />
+      <option name="prefixLines" value="true" />
+      <option name="lenBefore" value="80" />
+      <option name="lenAfter" value="80" />
+      <option name="box" value="false" />
+      <option name="filler" value=" " />
+    </LanguageOptions>
+    <LanguageOptions name="Properties">
+      <option name="fileTypeOverride" value="1" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="block" value="true" />
+      <option name="separateBefore" value="false" />
+      <option name="separateAfter" value="false" />
+      <option name="prefixLines" value="true" />
+      <option name="lenBefore" value="80" />
+      <option name="lenAfter" value="80" />
+      <option name="box" value="false" />
+      <option name="filler" value=" " />
+    </LanguageOptions>
+    <LanguageOptions name="XML">
+      <option name="fileTypeOverride" value="1" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="block" value="true" />
+      <option name="separateBefore" value="false" />
+      <option name="separateAfter" value="false" />
+      <option name="prefixLines" value="true" />
+      <option name="lenBefore" value="80" />
+      <option name="lenAfter" value="80" />
+      <option name="box" value="false" />
+      <option name="filler" value=" " />
+    </LanguageOptions>
+  </component>
+  <component name="DependencyValidationManager">
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </component>
+  <component name="EclipseCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EclipseEmbeddedCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+  <component name="FacetAutodetectingManager">
+    <autodetection-disabled>
+      <facet-type id="web">
+        <modules>
+          <module name="git-server">
+            <files>
+              <file url="file://$PROJECT_DIR$/git-server/web/WEB-INF/web.xml" />
+            </files>
+          </module>
+        </modules>
+      </facet-type>
+    </autodetection-disabled>
+  </component>
+  <component name="IdProvider" IDEtalkID="5D3DF039F2986C172BD95D6A6F8754EF" />
+  <component name="InspectionProjectProfileManager">
+    <profiles>
+      <profile version="1.0" is_locked="false">
+        <option name="myName" value="Project Default" />
+        <option name="myLocal" value="false" />
+        <inspection_tool class="UnnecessaryFullyQualifiedName" enabled="true" level="WARNING" enabled_by_default="true">
+          <option name="m_ignoreJavadoc" value="false" />
+        </inspection_tool>
+      </profile>
+    </profiles>
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_PROFILE" value="true" />
+    <version value="1.0" />
+    <list size="5">
+      <item index="0" class="java.lang.String" itemvalue="INFO" />
+      <item index="1" class="java.lang.String" itemvalue="WARNING" />
+      <item index="2" class="java.lang.String" itemvalue="ERROR" />
+      <item index="3" class="java.lang.String" itemvalue="TYPO" />
+      <item index="4" class="java.lang.String" itemvalue="SERVER PROBLEM" />
+    </list>
+  </component>
+  <component name="JavacSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="DEPRECATION" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="JavadocGenerationManager">
+    <option name="OUTPUT_DIRECTORY" />
+    <option name="OPTION_SCOPE" value="protected" />
+    <option name="OPTION_HIERARCHY" value="true" />
+    <option name="OPTION_NAVIGATOR" value="true" />
+    <option name="OPTION_INDEX" value="true" />
+    <option name="OPTION_SEPARATE_INDEX" value="true" />
+    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
+    <option name="OPTION_DEPRECATED_LIST" value="true" />
+    <option name="OTHER_OPTIONS" value="" />
+    <option name="HEAP_SIZE" />
+    <option name="LOCALE" />
+    <option name="OPEN_IN_BROWSER" value="true" />
+  </component>
+  <component name="JikesSettings">
+    <option name="JIKES_PATH" value="" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="DEPRECATION" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="IS_EMACS_ERRORS_MODE" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+  <component name="ProjectDetails">
+    <option name="projectName" value="git-teamcity" />
+  </component>
+  <component name="ProjectDictionaryState">
+    <dictionary name="Constantin.Plotnikov" />
+  </component>
+  <component name="ProjectKey">
+    <option name="state" value="project://60c230e5-1bc8-46d2-9235-d195b9ba9c04" />
+  </component>
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/git-server/git-server.iml" filepath="$PROJECT_DIR$/git-server/git-server.iml" />
+      <module fileurl="file://$PROJECT_DIR$/git-tests/git-tests.iml" filepath="$PROJECT_DIR$/git-tests/git-tests.iml" />
+      <module fileurl="file://$PROJECT_DIR$/root.iml" filepath="$PROJECT_DIR$/root.iml" />
+    </modules>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+  <component name="ResourceManagerContainer">
+    <option name="myResourceBundles">
+      <value>
+        <list size="0" />
+      </value>
+    </option>
+  </component>
+  <component name="RmicSettings">
+    <option name="IS_EANABLED" value="false" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="GENERATE_IIOP_STUBS" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="SvnBranchConfigurationManager">
+    <option name="mySupportsUserInfoFilter" value="true" />
+  </component>
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+  <component name="WebServicesPlugin" addRequiredLibraries="true" />
+  <component name="libraryTable">
+    <library name="TeamCity Open API agent">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/devPackage/agent-api.jar!/" />
+      </CLASSES>
+      <JAVADOC>
+        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />
+      </JAVADOC>
+      <SOURCES>
+        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />
+      </SOURCES>
+    </library>
+    <library name="TeamCity Open API server">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/devPackage/server-api.jar!/" />
+      </CLASSES>
+      <JAVADOC>
+        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />
+      </JAVADOC>
+      <SOURCES>
+        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />
+      </SOURCES>
+    </library>
+    <library name="TeamCity Open API common">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/devPackage/runtime-util.jar!/" />
+        <root url="jar://$TeamCityDistribution$/devPackage/common-api.jar!/" />
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/log4j-1.2.12.jar!/" />
+      </CLASSES>
+      <JAVADOC>
+        <root url="jar://$TeamCityDistribution$/devPackage/javadoc/openApi-help.jar!/" />
+      </JAVADOC>
+      <SOURCES>
+        <root url="jar://$TeamCityDistribution$/devPackage/src/openApi-source.jar!/" />
+      </SOURCES>
+    </library>
+    <library name="TeamCity Third-Party">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/annotations.jar!/" />
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/spring.jar!/" />
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/openapi.jar!/" />
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/util.jar!/" />
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/spring-webmvc.jar!/" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES />
+    </library>
+    <library name="Tomcat">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/lib/servlet-api.jar!/" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES />
+    </library>
+    <library name="JGit">
+      <CLASSES>
+        <root url="jar://$PROJECT_DIR$/lib/jsch-0.1.37.jar!/" />
+        <root url="jar://$PROJECT_DIR$/lib/jgit-0.5.0-SNAPSHOT.jar!/" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES>
+        <root url="jar://$PROJECT_DIR$/lib/src/jsch-0.1.37.zip!/jsch-0.1.37/src" />
+        <root url="jar://$PROJECT_DIR$/lib/src/jgit-0.5.0-SNAPSHOT-sources.jar!/" />
+      </SOURCES>
+    </library>
+    <library name="TestLibs">
+      <CLASSES>
+        <root url="file://$PROJECT_DIR$/git-tests/lib" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES />
+      <jarDirectory url="file://$PROJECT_DIR$/git-tests/lib" recursive="false" />
+    </library>
+    <library name="TeamCity Tests">
+      <CLASSES>
+        <root url="jar://$TeamCityDistribution$/webapps/ROOT/WEB-INF/lib/patches-impl.jar!/" />
+      </CLASSES>
+      <JAVADOC />
+      <SOURCES />
+    </library>
+  </component>
+</project>
+
index 83bb8b06cb5fc0a70fa10aaa4436becbc9b5c5b9..95427c69e26df0c04e54014995b0ba496ea22e4b 100755 (executable)
-<?xml version="1.0" encoding="UTF-8"?>\r
-<project name="git-teamcity" default="all">\r
-\r
-\r
-  <property file="git-teamcity.properties"/>\r
-  <!-- Uncomment the following property if no tests compilation is needed -->\r
-  <!-- \r
-  <property name="skip.tests" value="true"/>\r
-   -->\r
-  <property name="javac2.home" value="${idea.home}/lib"/>\r
-  <path id="javac2.classpath">\r
-    <pathelement location="${javac2.home}/javac2.jar"/>\r
-    <pathelement location="${javac2.home}/jdom.jar"/>\r
-    <pathelement location="${javac2.home}/asm.jar"/>\r
-    <pathelement location="${javac2.home}/asm-commons.jar"/>\r
-  </path>\r
-  <taskdef name="javac2" classname="com.intellij.ant.Javac2" classpathref="javac2.classpath"/>\r
-  <taskdef name="instrumentIdeaExtensions" classname="com.intellij.ant.InstrumentIdeaExtensions" classpathref="javac2.classpath"/>\r
-\r
-  <!-- Compiler options -->\r
-\r
-  <property name="compiler.debug" value="on"/>\r
-  <property name="compiler.generate.no.warnings" value="off"/>\r
-  <property name="compiler.args" value=""/>\r
-  <property name="compiler.max.memory" value="128m"/>\r
-  <patternset id="ignored.files">\r
-    <exclude name="**/CVS/**"/>\r
-    <exclude name="**/SCCS/**"/>\r
-    <exclude name="**/RCS/**"/>\r
-    <exclude name="**/rcs/**"/>\r
-    <exclude name="**/.DS_Store/**"/>\r
-    <exclude name="**/.svn/**"/>\r
-    <exclude name="**/.pyc/**"/>\r
-    <exclude name="**/.pyo/**"/>\r
-    <exclude name="**/*.pyc/**"/>\r
-    <exclude name="**/*.pyo/**"/>\r
-    <exclude name="**/.git/**"/>\r
-  </patternset>\r
-  <patternset id="library.patterns">\r
-    <include name="*.zip"/>\r
-    <include name="*.war"/>\r
-    <include name="*.egg"/>\r
-    <include name="*.ear"/>\r
-    <include name="*.swc"/>\r
-    <include name="*.jar"/>\r
-  </patternset>\r
-  <patternset id="compiler.resources">\r
-    <include name="**/?*.properties"/>\r
-    <include name="**/?*.xml"/>\r
-    <include name="**/?*.gif"/>\r
-    <include name="**/?*.png"/>\r
-    <include name="**/?*.jpeg"/>\r
-    <include name="**/?*.jpg"/>\r
-    <include name="**/?*.html"/>\r
-    <include name="**/?*.dtd"/>\r
-    <include name="**/?*.tld"/>\r
-    <include name="**/?*.ftl"/>\r
-    <include name="**/?*.jsp"/>\r
-  </patternset>\r
-\r
-  <!-- JDK definitions -->\r
-\r
-  <property name="jdk.bin.1.5" value="${jdk.home.1.5}/bin"/>\r
-  <path id="jdk.classpath.1.5">\r
-    <fileset dir="${jdk.home.1.5}">\r
-      <include name="jre/lib/charsets.jar"/>\r
-      <include name="jre/lib/deploy.jar"/>\r
-      <include name="jre/lib/javaws.jar"/>\r
-      <include name="jre/lib/jce.jar"/>\r
-      <include name="jre/lib/jsse.jar"/>\r
-      <include name="jre/lib/management-agent.jar"/>\r
-      <include name="jre/lib/plugin.jar"/>\r
-      <include name="jre/lib/resources.jar"/>\r
-      <include name="jre/lib/rt.jar"/>\r
-      <include name="jre/lib/ext/dnsns.jar"/>\r
-      <include name="jre/lib/ext/localedata.jar"/>\r
-      <include name="jre/lib/ext/sunjce_provider.jar"/>\r
-      <include name="jre/lib/ext/sunmscapi.jar"/>\r
-      <include name="jre/lib/ext/sunpkcs11.jar"/>\r
-    </fileset>\r
-  </path>\r
-\r
-  <property name="project.jdk.home" value="${jdk.home.1.5}"/>\r
-  <property name="project.jdk.bin" value="${jdk.bin.1.5}"/>\r
-  <property name="project.jdk.classpath" value="jdk.classpath.1.5"/>\r
-\r
-\r
-  <!-- Project Libraries -->\r
-\r
-  <path id="library.jgit.classpath">\r
-    <pathelement location="${basedir}/lib/jgit-0.5.0-SNAPSHOT.jar"/>\r
-    <pathelement location="${basedir}/lib/jsch-0.1.37.jar"/>\r
-  </path>\r
-\r
-  <path id="library.teamcity_open_api_agent.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/devPackage/agent-api.jar"/>\r
-  </path>\r
-\r
-  <path id="library.teamcity_open_api_common.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/devPackage/common-api.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/devPackage/runtime-util.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/log4j-1.2.12.jar"/>\r
-  </path>\r
-\r
-  <path id="library.teamcity_open_api_server.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/devPackage/server-api.jar"/>\r
-  </path>\r
-\r
-  <path id="library.teamcity_tests.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/patches-impl.jar"/>\r
-  </path>\r
-\r
-  <path id="library.teamcity_third-party.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/annotations.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/openapi.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/spring-webmvc.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/spring.jar"/>\r
-    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/util.jar"/>\r
-  </path>\r
-\r
-  <path id="library.testlibs.classpath">\r
-    <fileset dir="${basedir}/git-tests/lib">\r
-      <patternset refid="library.patterns"/>\r
-    </fileset>\r
-  </path>\r
-\r
-  <path id="library.tomcat.classpath">\r
-    <pathelement location="${path.variable.teamcitydistribution}/lib/servlet-api.jar"/>\r
-  </path>\r
-\r
-\r
-  <!-- Global Libraries -->\r
-\r
-  <!-- Modules -->\r
-\r
-\r
-  <!-- Module git-server -->\r
-\r
-  <dirname property="module.git-server.basedir" file="${ant.file}"/>\r
-\r
-\r
-  <property name="module.jdk.home.git-server" value="${project.jdk.home}"/>\r
-  <property name="module.jdk.bin.git-server" value="${project.jdk.bin}"/>\r
-  <property name="module.jdk.classpath.git-server" value="${project.jdk.classpath}"/>\r
-\r
-  <property name="compiler.args.git-server" value="${compiler.args}"/>\r
-\r
-  <property name="git-server.output.dir" value="${module.git-server.basedir}/out/production/git-server"/>\r
-  <property name="git-server.testoutput.dir" value="${module.git-server.basedir}/out/test/git-server"/>\r
-\r
-  <path id="git-server.module.bootclasspath">\r
-    <!-- Paths to be included in compilation bootclasspath -->\r
-  </path>\r
-\r
-  <path id="git-server.module.classpath">\r
-    <path refid="${module.jdk.classpath.git-server}"/>\r
-    <path refid="library.teamcity_open_api_common.classpath"/>\r
-    <path refid="library.teamcity_open_api_server.classpath"/>\r
-    <path refid="library.teamcity_third-party.classpath"/>\r
-    <path refid="library.tomcat.classpath"/>\r
-    <path refid="library.jgit.classpath"/>\r
-  </path>\r
-\r
-  <path id="git-server.runtime.module.classpath">\r
-    <pathelement location="${git-server.output.dir}"/>\r
-    <pathelement location="${git-server.testoutput.dir}"/>\r
-    <path refid="library.teamcity_open_api_common.classpath"/>\r
-    <path refid="library.teamcity_open_api_server.classpath"/>\r
-    <path refid="library.teamcity_third-party.classpath"/>\r
-    <path refid="library.tomcat.classpath"/>\r
-    <path refid="library.jgit.classpath"/>\r
-  </path>\r
-\r
-\r
-  <patternset id="excluded.from.module.git-server">\r
-    <patternset refid="ignored.files"/>\r
-  </patternset>\r
-\r
-  <patternset id="excluded.from.compilation.git-server">\r
-    <patternset refid="excluded.from.module.git-server"/>\r
-  </patternset>\r
-\r
-  <path id="git-server.module.sourcepath">\r
-    <dirset dir="${module.git-server.basedir}/git-server">\r
-      <include name="resources"/>\r
-      <include name="src"/>\r
-    </dirset>\r
-  </path>\r
-\r
-\r
-  <target name="compile.module.git-server" depends="compile.module.git-server.production,compile.module.git-server.tests"\r
-          description="Compile module git-server"/>\r
-\r
-  <target name="compile.module.git-server.production" description="Compile module git-server; production classes">\r
-    <mkdir dir="${git-server.output.dir}"/>\r
-    <javac2 destdir="${git-server.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}"\r
-            memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.git-server}/javac">\r
-      <compilerarg line="${compiler.args.git-server}"/>\r
-      <bootclasspath refid="git-server.module.bootclasspath"/>\r
-      <classpath refid="git-server.module.classpath"/>\r
-      <src refid="git-server.module.sourcepath"/>\r
-      <patternset refid="excluded.from.compilation.git-server"/>\r
-    </javac2>\r
-\r
-    <copy todir="${git-server.output.dir}">\r
-      <fileset dir="${module.git-server.basedir}/git-server/resources">\r
-        <patternset refid="compiler.resources"/>\r
-        <type type="file"/>\r
-      </fileset>\r
-      <fileset dir="${module.git-server.basedir}/git-server/src">\r
-        <patternset refid="compiler.resources"/>\r
-        <type type="file"/>\r
-      </fileset>\r
-    </copy>\r
-  </target>\r
-\r
-  <target name="compile.module.git-server.tests" depends="compile.module.git-server.production"\r
-          description="compile module git-server; test classes" unless="skip.tests"/>\r
-\r
-  <target name="clean.module.git-server" description="cleanup module">\r
-    <delete dir="${git-server.output.dir}"/>\r
-    <delete dir="${git-server.testoutput.dir}"/>\r
-  </target>\r
-\r
-\r
-  <!-- Module root -->\r
-\r
-  <dirname property="module.root.basedir" file="${ant.file}"/>\r
-\r
-\r
-  <property name="module.jdk.home.root" value="${project.jdk.home}"/>\r
-  <property name="module.jdk.bin.root" value="${project.jdk.bin}"/>\r
-  <property name="module.jdk.classpath.root" value="${project.jdk.classpath}"/>\r
-\r
-  <property name="compiler.args.root" value="${compiler.args}"/>\r
-\r
-  <property name="root.output.dir" value="${module.root.basedir}/out/production/root"/>\r
-  <property name="root.testoutput.dir" value="${module.root.basedir}/out/test/root"/>\r
-\r
-  <path id="root.module.bootclasspath">\r
-    <!-- Paths to be included in compilation bootclasspath -->\r
-  </path>\r
-\r
-  <path id="root.module.classpath">\r
-    <path refid="${module.jdk.classpath.root}"/>\r
-  </path>\r
-\r
-  <path id="root.runtime.module.classpath">\r
-    <pathelement location="${root.output.dir}"/>\r
-    <pathelement location="${root.testoutput.dir}"/>\r
-  </path>\r
-\r
-\r
-  <patternset id="excluded.from.module.root">\r
-    <patternset refid="ignored.files"/>\r
-  </patternset>\r
-\r
-  <patternset id="excluded.from.compilation.root">\r
-    <patternset refid="excluded.from.module.root"/>\r
-  </patternset>\r
-\r
-\r
-  <target name="compile.module.root" depends="compile.module.root.production,compile.module.root.tests" description="Compile module root"/>\r
-\r
-  <target name="compile.module.root.production" description="Compile module root; production classes"/>\r
-\r
-  <target name="compile.module.root.tests" depends="compile.module.root.production" description="compile module root; test classes"\r
-          unless="skip.tests"/>\r
-\r
-  <target name="clean.module.root" description="cleanup module">\r
-    <delete dir="${root.output.dir}"/>\r
-    <delete dir="${root.testoutput.dir}"/>\r
-  </target>\r
-\r
-\r
-  <!-- Module git-tests -->\r
-\r
-  <dirname property="module.git-tests.basedir" file="${ant.file}"/>\r
-\r
-\r
-  <property name="module.jdk.home.git-tests" value="${project.jdk.home}"/>\r
-  <property name="module.jdk.bin.git-tests" value="${project.jdk.bin}"/>\r
-  <property name="module.jdk.classpath.git-tests" value="${project.jdk.classpath}"/>\r
-\r
-  <property name="compiler.args.git-tests" value="${compiler.args}"/>\r
-\r
-  <property name="git-tests.output.dir" value="${module.git-tests.basedir}/out/production/git-tests"/>\r
-  <property name="git-tests.testoutput.dir" value="${module.git-tests.basedir}/out/test/git-tests"/>\r
-\r
-  <path id="git-tests.module.bootclasspath">\r
-    <!-- Paths to be included in compilation bootclasspath -->\r
-  </path>\r
-\r
-  <path id="git-tests.module.classpath">\r
-    <path refid="${module.jdk.classpath.git-tests}"/>\r
-    <path refid="library.teamcity_open_api_common.classpath"/>\r
-    <path refid="library.testlibs.classpath"/>\r
-    <pathelement location="${git-server.output.dir}"/>\r
-    <pathelement location="${git-server.testoutput.dir}"/>\r
-    <path refid="library.jgit.classpath"/>\r
-    <path refid="library.teamcity_open_api_agent.classpath"/>\r
-    <path refid="library.teamcity_open_api_server.classpath"/>\r
-    <path refid="library.teamcity_third-party.classpath"/>\r
-    <path refid="library.tomcat.classpath"/>\r
-    <path refid="library.teamcity_tests.classpath"/>\r
-  </path>\r
-\r
-  <path id="git-tests.runtime.module.classpath">\r
-    <pathelement location="${git-tests.output.dir}"/>\r
-    <pathelement location="${git-tests.testoutput.dir}"/>\r
-    <path refid="library.teamcity_open_api_common.classpath"/>\r
-    <path refid="library.testlibs.classpath"/>\r
-    <path refid="git-server.runtime.module.classpath"/>\r
-    <path refid="library.jgit.classpath"/>\r
-    <path refid="library.teamcity_open_api_agent.classpath"/>\r
-    <path refid="library.teamcity_open_api_server.classpath"/>\r
-    <path refid="library.teamcity_third-party.classpath"/>\r
-    <path refid="library.tomcat.classpath"/>\r
-    <path refid="library.teamcity_tests.classpath"/>\r
-  </path>\r
-\r
-\r
-  <patternset id="excluded.from.module.git-tests">\r
-    <patternset refid="ignored.files"/>\r
-  </patternset>\r
-\r
-  <patternset id="excluded.from.compilation.git-tests">\r
-    <patternset refid="excluded.from.module.git-tests"/>\r
-  </patternset>\r
-\r
-  <path id="git-tests.module.sourcepath">\r
-    <dirset dir="${module.git-tests.basedir}/git-tests">\r
-      <include name="src"/>\r
-    </dirset>\r
-  </path>\r
-\r
-\r
-  <target name="compile.module.git-tests" depends="compile.module.git-tests.production,compile.module.git-tests.tests"\r
-          description="Compile module git-tests"/>\r
-\r
-  <target name="compile.module.git-tests.production" depends="compile.module.git-server"\r
-          description="Compile module git-tests; production classes">\r
-    <mkdir dir="${git-tests.output.dir}"/>\r
-    <javac2 destdir="${git-tests.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}"\r
-            memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.git-tests}/javac">\r
-      <compilerarg line="${compiler.args.git-tests}"/>\r
-      <bootclasspath refid="git-tests.module.bootclasspath"/>\r
-      <classpath refid="git-tests.module.classpath"/>\r
-      <src refid="git-tests.module.sourcepath"/>\r
-      <patternset refid="excluded.from.compilation.git-tests"/>\r
-    </javac2>\r
-\r
-    <copy todir="${git-tests.output.dir}">\r
-      <fileset dir="${module.git-tests.basedir}/git-tests/src">\r
-        <patternset refid="compiler.resources"/>\r
-        <type type="file"/>\r
-      </fileset>\r
-    </copy>\r
-  </target>\r
-\r
-  <target name="compile.module.git-tests.tests" depends="compile.module.git-tests.production"\r
-          description="compile module git-tests; test classes" unless="skip.tests"/>\r
-\r
-  <target name="clean.module.git-tests" description="cleanup module">\r
-    <delete dir="${git-tests.output.dir}"/>\r
-    <delete dir="${git-tests.testoutput.dir}"/>\r
-  </target>\r
-\r
-  <target name="init" description="Build initialization">\r
-    <!-- Perform any build initialization in this target -->\r
-  </target>\r
-\r
-  <target name="clean" depends="clean.module.git-server, clean.module.root, clean.module.git-tests" description="cleanup all"/>\r
-\r
-  <target name="all" depends="init, clean, compile.module.git-server, compile.module.root, compile.module.git-tests"\r
-          description="build all"/>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="git-teamcity" default="all">
+
+
+  <property file="git-teamcity.properties"/>
+  <!-- Uncomment the following property if no tests compilation is needed -->
+  <!-- 
+  <property name="skip.tests" value="true"/>
+   -->
+  <property name="javac2.home" value="${idea.home}/lib"/>
+  <path id="javac2.classpath">
+    <pathelement location="${javac2.home}/javac2.jar"/>
+    <pathelement location="${javac2.home}/jdom.jar"/>
+    <pathelement location="${javac2.home}/asm.jar"/>
+    <pathelement location="${javac2.home}/asm-commons.jar"/>
+  </path>
+  <taskdef name="javac2" classname="com.intellij.ant.Javac2" classpathref="javac2.classpath"/>
+  <taskdef name="instrumentIdeaExtensions" classname="com.intellij.ant.InstrumentIdeaExtensions" classpathref="javac2.classpath"/>
+
+  <!-- Compiler options -->
+
+  <property name="compiler.debug" value="on"/>
+  <property name="compiler.generate.no.warnings" value="off"/>
+  <property name="compiler.args" value=""/>
+  <property name="compiler.max.memory" value="128m"/>
+  <patternset id="ignored.files">
+    <exclude name="**/CVS/**"/>
+    <exclude name="**/SCCS/**"/>
+    <exclude name="**/RCS/**"/>
+    <exclude name="**/rcs/**"/>
+    <exclude name="**/.DS_Store/**"/>
+    <exclude name="**/.svn/**"/>
+    <exclude name="**/.pyc/**"/>
+    <exclude name="**/.pyo/**"/>
+    <exclude name="**/*.pyc/**"/>
+    <exclude name="**/*.pyo/**"/>
+    <exclude name="**/.git/**"/>
+  </patternset>
+  <patternset id="library.patterns">
+    <include name="*.zip"/>
+    <include name="*.war"/>
+    <include name="*.egg"/>
+    <include name="*.ear"/>
+    <include name="*.swc"/>
+    <include name="*.jar"/>
+  </patternset>
+  <patternset id="compiler.resources">
+    <include name="**/?*.properties"/>
+    <include name="**/?*.xml"/>
+    <include name="**/?*.gif"/>
+    <include name="**/?*.png"/>
+    <include name="**/?*.jpeg"/>
+    <include name="**/?*.jpg"/>
+    <include name="**/?*.html"/>
+    <include name="**/?*.dtd"/>
+    <include name="**/?*.tld"/>
+    <include name="**/?*.ftl"/>
+    <include name="**/?*.jsp"/>
+  </patternset>
+
+  <!-- JDK definitions -->
+
+  <property name="jdk.bin.1.5" value="${jdk.home.1.5}/bin"/>
+  <path id="jdk.classpath.1.5">
+    <fileset dir="${jdk.home.1.5}">
+      <include name="jre/lib/charsets.jar"/>
+      <include name="jre/lib/deploy.jar"/>
+      <include name="jre/lib/javaws.jar"/>
+      <include name="jre/lib/jce.jar"/>
+      <include name="jre/lib/jsse.jar"/>
+      <include name="jre/lib/management-agent.jar"/>
+      <include name="jre/lib/plugin.jar"/>
+      <include name="jre/lib/resources.jar"/>
+      <include name="jre/lib/rt.jar"/>
+      <include name="jre/lib/ext/dnsns.jar"/>
+      <include name="jre/lib/ext/localedata.jar"/>
+      <include name="jre/lib/ext/sunjce_provider.jar"/>
+      <include name="jre/lib/ext/sunmscapi.jar"/>
+      <include name="jre/lib/ext/sunpkcs11.jar"/>
+    </fileset>
+  </path>
+
+  <property name="project.jdk.home" value="${jdk.home.1.5}"/>
+  <property name="project.jdk.bin" value="${jdk.bin.1.5}"/>
+  <property name="project.jdk.classpath" value="jdk.classpath.1.5"/>
+
+
+  <!-- Project Libraries -->
+
+  <path id="library.jgit.classpath">
+    <pathelement location="${basedir}/lib/jgit-0.5.0-SNAPSHOT.jar"/>
+    <pathelement location="${basedir}/lib/jsch-0.1.37.jar"/>
+  </path>
+
+  <path id="library.teamcity_open_api_agent.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/devPackage/agent-api.jar"/>
+  </path>
+
+  <path id="library.teamcity_open_api_common.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/devPackage/common-api.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/devPackage/runtime-util.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/log4j-1.2.12.jar"/>
+  </path>
+
+  <path id="library.teamcity_open_api_server.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/devPackage/server-api.jar"/>
+  </path>
+
+  <path id="library.teamcity_tests.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/patches-impl.jar"/>
+  </path>
+
+  <path id="library.teamcity_third-party.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/annotations.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/openapi.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/spring-webmvc.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/spring.jar"/>
+    <pathelement location="${path.variable.teamcitydistribution}/webapps/ROOT/WEB-INF/lib/util.jar"/>
+  </path>
+
+  <path id="library.testlibs.classpath">
+    <fileset dir="${basedir}/git-tests/lib">
+      <patternset refid="library.patterns"/>
+    </fileset>
+  </path>
+
+  <path id="library.tomcat.classpath">
+    <pathelement location="${path.variable.teamcitydistribution}/lib/servlet-api.jar"/>
+  </path>
+
+
+  <!-- Global Libraries -->
+
+  <!-- Modules -->
+
+
+  <!-- Module git-server -->
+
+  <dirname property="module.git-server.basedir" file="${ant.file}"/>
+
+
+  <property name="module.jdk.home.git-server" value="${project.jdk.home}"/>
+  <property name="module.jdk.bin.git-server" value="${project.jdk.bin}"/>
+  <property name="module.jdk.classpath.git-server" value="${project.jdk.classpath}"/>
+
+  <property name="compiler.args.git-server" value="${compiler.args}"/>
+
+  <property name="git-server.output.dir" value="${module.git-server.basedir}/out/production/git-server"/>
+  <property name="git-server.testoutput.dir" value="${module.git-server.basedir}/out/test/git-server"/>
+
+  <path id="git-server.module.bootclasspath">
+    <!-- Paths to be included in compilation bootclasspath -->
+  </path>
+
+  <path id="git-server.module.classpath">
+    <path refid="${module.jdk.classpath.git-server}"/>
+    <path refid="library.teamcity_open_api_common.classpath"/>
+    <path refid="library.teamcity_open_api_server.classpath"/>
+    <path refid="library.teamcity_third-party.classpath"/>
+    <path refid="library.tomcat.classpath"/>
+    <path refid="library.jgit.classpath"/>
+  </path>
+
+  <path id="git-server.runtime.module.classpath">
+    <pathelement location="${git-server.output.dir}"/>
+    <pathelement location="${git-server.testoutput.dir}"/>
+    <path refid="library.teamcity_open_api_common.classpath"/>
+    <path refid="library.teamcity_open_api_server.classpath"/>
+    <path refid="library.teamcity_third-party.classpath"/>
+    <path refid="library.tomcat.classpath"/>
+    <path refid="library.jgit.classpath"/>
+  </path>
+
+
+  <patternset id="excluded.from.module.git-server">
+    <patternset refid="ignored.files"/>
+  </patternset>
+
+  <patternset id="excluded.from.compilation.git-server">
+    <patternset refid="excluded.from.module.git-server"/>
+  </patternset>
+
+  <path id="git-server.module.sourcepath">
+    <dirset dir="${module.git-server.basedir}/git-server">
+      <include name="resources"/>
+      <include name="src"/>
+    </dirset>
+  </path>
+
+
+  <target name="compile.module.git-server" depends="compile.module.git-server.production,compile.module.git-server.tests"
+          description="Compile module git-server"/>
+
+  <target name="compile.module.git-server.production" description="Compile module git-server; production classes">
+    <mkdir dir="${git-server.output.dir}"/>
+    <javac2 destdir="${git-server.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}"
+            memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.git-server}/javac">
+      <compilerarg line="${compiler.args.git-server}"/>
+      <bootclasspath refid="git-server.module.bootclasspath"/>
+      <classpath refid="git-server.module.classpath"/>
+      <src refid="git-server.module.sourcepath"/>
+      <patternset refid="excluded.from.compilation.git-server"/>
+    </javac2>
+
+    <copy todir="${git-server.output.dir}">
+      <fileset dir="${module.git-server.basedir}/git-server/resources">
+        <patternset refid="compiler.resources"/>
+        <type type="file"/>
+      </fileset>
+      <fileset dir="${module.git-server.basedir}/git-server/src">
+        <patternset refid="compiler.resources"/>
+        <type type="file"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="compile.module.git-server.tests" depends="compile.module.git-server.production"
+          description="compile module git-server; test classes" unless="skip.tests"/>
+
+  <target name="clean.module.git-server" description="cleanup module">
+    <delete dir="${git-server.output.dir}"/>
+    <delete dir="${git-server.testoutput.dir}"/>
+  </target>
+
+
+  <!-- Module root -->
+
+  <dirname property="module.root.basedir" file="${ant.file}"/>
+
+
+  <property name="module.jdk.home.root" value="${project.jdk.home}"/>
+  <property name="module.jdk.bin.root" value="${project.jdk.bin}"/>
+  <property name="module.jdk.classpath.root" value="${project.jdk.classpath}"/>
+
+  <property name="compiler.args.root" value="${compiler.args}"/>
+
+  <property name="root.output.dir" value="${module.root.basedir}/out/production/root"/>
+  <property name="root.testoutput.dir" value="${module.root.basedir}/out/test/root"/>
+
+  <path id="root.module.bootclasspath">
+    <!-- Paths to be included in compilation bootclasspath -->
+  </path>
+
+  <path id="root.module.classpath">
+    <path refid="${module.jdk.classpath.root}"/>
+  </path>
+
+  <path id="root.runtime.module.classpath">
+    <pathelement location="${root.output.dir}"/>
+    <pathelement location="${root.testoutput.dir}"/>
+  </path>
+
+
+  <patternset id="excluded.from.module.root">
+    <patternset refid="ignored.files"/>
+  </patternset>
+
+  <patternset id="excluded.from.compilation.root">
+    <patternset refid="excluded.from.module.root"/>
+  </patternset>
+
+
+  <target name="compile.module.root" depends="compile.module.root.production,compile.module.root.tests" description="Compile module root"/>
+
+  <target name="compile.module.root.production" description="Compile module root; production classes"/>
+
+  <target name="compile.module.root.tests" depends="compile.module.root.production" description="compile module root; test classes"
+          unless="skip.tests"/>
+
+  <target name="clean.module.root" description="cleanup module">
+    <delete dir="${root.output.dir}"/>
+    <delete dir="${root.testoutput.dir}"/>
+  </target>
+
+
+  <!-- Module git-tests -->
+
+  <dirname property="module.git-tests.basedir" file="${ant.file}"/>
+
+
+  <property name="module.jdk.home.git-tests" value="${project.jdk.home}"/>
+  <property name="module.jdk.bin.git-tests" value="${project.jdk.bin}"/>
+  <property name="module.jdk.classpath.git-tests" value="${project.jdk.classpath}"/>
+
+  <property name="compiler.args.git-tests" value="${compiler.args}"/>
+
+  <property name="git-tests.output.dir" value="${module.git-tests.basedir}/out/production/git-tests"/>
+  <property name="git-tests.testoutput.dir" value="${module.git-tests.basedir}/out/test/git-tests"/>
+
+  <path id="git-tests.module.bootclasspath">
+    <!-- Paths to be included in compilation bootclasspath -->
+  </path>
+
+  <path id="git-tests.module.classpath">
+    <path refid="${module.jdk.classpath.git-tests}"/>
+    <path refid="library.teamcity_open_api_common.classpath"/>
+    <path refid="library.testlibs.classpath"/>
+    <pathelement location="${git-server.output.dir}"/>
+    <pathelement location="${git-server.testoutput.dir}"/>
+    <path refid="library.jgit.classpath"/>
+    <path refid="library.teamcity_open_api_agent.classpath"/>
+    <path refid="library.teamcity_open_api_server.classpath"/>
+    <path refid="library.teamcity_third-party.classpath"/>
+    <path refid="library.tomcat.classpath"/>
+    <path refid="library.teamcity_tests.classpath"/>
+  </path>
+
+  <path id="git-tests.runtime.module.classpath">
+    <pathelement location="${git-tests.output.dir}"/>
+    <pathelement location="${git-tests.testoutput.dir}"/>
+    <path refid="library.teamcity_open_api_common.classpath"/>
+    <path refid="library.testlibs.classpath"/>
+    <path refid="git-server.runtime.module.classpath"/>
+    <path refid="library.jgit.classpath"/>
+    <path refid="library.teamcity_open_api_agent.classpath"/>
+    <path refid="library.teamcity_open_api_server.classpath"/>
+    <path refid="library.teamcity_third-party.classpath"/>
+    <path refid="library.tomcat.classpath"/>
+    <path refid="library.teamcity_tests.classpath"/>
+  </path>
+
+
+  <patternset id="excluded.from.module.git-tests">
+    <patternset refid="ignored.files"/>
+  </patternset>
+
+  <patternset id="excluded.from.compilation.git-tests">
+    <patternset refid="excluded.from.module.git-tests"/>
+  </patternset>
+
+  <path id="git-tests.module.sourcepath">
+    <dirset dir="${module.git-tests.basedir}/git-tests">
+      <include name="src"/>
+    </dirset>
+  </path>
+
+
+  <target name="compile.module.git-tests" depends="compile.module.git-tests.production,compile.module.git-tests.tests"
+          description="Compile module git-tests"/>
+
+  <target name="compile.module.git-tests.production" depends="compile.module.git-server"
+          description="Compile module git-tests; production classes">
+    <mkdir dir="${git-tests.output.dir}"/>
+    <javac2 destdir="${git-tests.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}"
+            memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.git-tests}/javac">
+      <compilerarg line="${compiler.args.git-tests}"/>
+      <bootclasspath refid="git-tests.module.bootclasspath"/>
+      <classpath refid="git-tests.module.classpath"/>
+      <src refid="git-tests.module.sourcepath"/>
+      <patternset refid="excluded.from.compilation.git-tests"/>
+    </javac2>
+
+    <copy todir="${git-tests.output.dir}">
+      <fileset dir="${module.git-tests.basedir}/git-tests/src">
+        <patternset refid="compiler.resources"/>
+        <type type="file"/>
+      </fileset>
+    </copy>
+  </target>
+
+  <target name="compile.module.git-tests.tests" depends="compile.module.git-tests.production"
+          description="compile module git-tests; test classes" unless="skip.tests"/>
+
+  <target name="clean.module.git-tests" description="cleanup module">
+    <delete dir="${git-tests.output.dir}"/>
+    <delete dir="${git-tests.testoutput.dir}"/>
+  </target>
+
+  <target name="init" description="Build initialization">
+    <!-- Perform any build initialization in this target -->
+  </target>
+
+  <target name="clean" depends="clean.module.git-server, clean.module.root, clean.module.git-tests" description="cleanup all"/>
+
+  <target name="all" depends="init, clean, compile.module.git-server, compile.module.root, compile.module.git-tests"
+          description="build all"/>
 </project>
\ No newline at end of file
index 6a6d4b6f3961d00982a9811a9a65864a67ba20ce..e746e14a95b729190b59b832d83544c8caa2799c 100755 (executable)
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8"?>\r
-<module relativePaths="true" type="JAVA_MODULE" version="4">\r
-  <component name="NewModuleRootManager" inherit-compiler-output="true">\r
-    <exclude-output />\r
-    <content url="file://$MODULE_DIR$">\r
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />\r
-    </content>\r
-    <orderEntry type="inheritedJdk" />\r
-    <orderEntry type="sourceFolder" forTests="false" />\r
-    <orderEntry type="library" name="TeamCity Open API common" level="project" />\r
-    <orderEntry type="library" name="TestLibs" level="project" />\r
-    <orderEntry type="module" module-name="git-server" />\r
-    <orderEntry type="library" name="JGit" level="project" />\r
-    <orderEntry type="library" name="TeamCity Open API agent" level="project" />\r
-    <orderEntry type="library" name="TeamCity Open API server" level="project" />\r
-    <orderEntry type="library" name="TeamCity Third-Party" level="project" />\r
-    <orderEntry type="library" name="Tomcat" level="project" />\r
-    <orderEntry type="library" name="TeamCity Tests" level="project" />\r
-  </component>\r
-</module>\r
-\r
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="TeamCity Open API common" level="project" />
+    <orderEntry type="library" name="TestLibs" level="project" />
+    <orderEntry type="module" module-name="git-server" />
+    <orderEntry type="library" name="JGit" level="project" />
+    <orderEntry type="library" name="TeamCity Open API agent" level="project" />
+    <orderEntry type="library" name="TeamCity Open API server" level="project" />
+    <orderEntry type="library" name="TeamCity Third-Party" level="project" />
+    <orderEntry type="library" name="Tomcat" level="project" />
+    <orderEntry type="library" name="TeamCity Tests" level="project" />
+  </component>
+</module>
+
index b5f365df042dade355bd6b45d390684e8e6a584f..aa1f9f867658baa6e118e5f3a47986906d046bb9 100755 (executable)
@@ -1,46 +1,46 @@
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.tests;\r
-\r
-import java.io.File;\r
-\r
-/**\r
- * Utilities for th testing\r
- */\r
-public class GitTestUtil {\r
-  /**\r
-   * The private constructor for the test class\r
-   */\r
-  private GitTestUtil() {\r
-\r
-  }\r
-\r
-  /**\r
-   * Test data file\r
-   *\r
-   * @param path the file path relatively to data directory\r
-   * @return the IO file object (the file is absolute)\r
-   */\r
-  public static File dataFile(String... path) {\r
-    File f = new File("git-tests", "data");\r
-    for (String p : path) {\r
-      f = new File(f, p);\r
-    }\r
-    return f.getAbsoluteFile();\r
-  }\r
-\r
-}\r
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jetbrains.buildServer.buildTriggers.vcs.git.tests;
+
+import java.io.File;
+
+/**
+ * Utilities for th testing
+ */
+public class GitTestUtil {
+  /**
+   * The private constructor for the test class
+   */
+  private GitTestUtil() {
+
+  }
+
+  /**
+   * Test data file
+   *
+   * @param path the file path relatively to data directory
+   * @return the IO file object (the file is absolute)
+   */
+  public static File dataFile(String... path) {
+    File f = new File("git-tests", "data");
+    for (String p : path) {
+      f = new File(f, p);
+    }
+    return f.getAbsoluteFile();
+  }
+
+}
index f523cf20848686e1c8b577dadef2d5ba41c8961d..8bc49435f1754d5fb98500c520f0df3a83134440 100755 (executable)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package jetbrains.buildServer.buildTriggers.vcs.git.tests;\r
-\r
-import jetbrains.buildServer.TempFiles;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.Constants;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.GitUtils;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.GitVcsSupport;\r
-import jetbrains.buildServer.buildTriggers.vcs.git.Settings;\r
-import static jetbrains.buildServer.buildTriggers.vcs.git.tests.GitTestUtil.dataFile;\r
-import jetbrains.buildServer.util.FileUtil;\r
-import jetbrains.buildServer.vcs.*;\r
-import jetbrains.buildServer.vcs.impl.VcsRootImpl;\r
-import jetbrains.buildServer.vcs.patches.PatchBuilderImpl;\r
-import jetbrains.buildServer.vcs.patches.PatchTestCase;\r
-import org.spearce.jgit.lib.Repository;\r
-import org.spearce.jgit.lib.Tag;\r
-import org.spearce.jgit.transport.URIish;\r
-import org.testng.Assert;\r
-import org.testng.annotations.AfterMethod;\r
-import org.testng.annotations.BeforeMethod;\r
-import org.testng.annotations.Test;\r
-\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.net.URISyntaxException;\r
-import java.util.List;\r
-\r
-/**\r
- * The tests for version detection functionality\r
- */\r
-public class GitVcsSupportTest extends PatchTestCase {\r
-  /**\r
-   * The version of "version-test" HEAD\r
-   */\r
-  private static final String VERSION_TEST_HEAD = GitUtils.makeVersion("2276eaf76a658f96b5cf3eb25f3e1fda90f6b653", 1237391915000L);\r
-  /**\r
-   * The version that contains add/remove/update changes\r
-   */\r
-  private static final String CUD1_VERSION = GitUtils.makeVersion("ad4528ed5c84092fdbe9e0502163cf8d6e6141e7", 1238072086000L);\r
-  /**\r
-   * The merge head version\r
-   */\r
-  private static final String MERGE_VERSION = GitUtils.makeVersion("f3f826ce85d6dad25156b2d7550cedeb1a422f4c", 1238086450000L);\r
-  /**\r
-   * The merge branch version\r
-   */\r
-  private static final String MERGE_BRANCH_VERSION = GitUtils.makeVersion("ee886e4adb70fbe3bdc6f3f6393598b3f02e8009", 1238085489000L);\r
-  /**\r
-   * The merge branch version\r
-   */\r
-  public static final String SUBMODULE_MODIFIED_VERSION = GitUtils.makeVersion("37c371a6db0acefc77e3be99d16a44413e746591", 1245773817000L);\r
-  /**\r
-   * The merge branch version\r
-   */\r
-  public static final String SUBMODULE_ADDED_VERSION = GitUtils.makeVersion("b5d65401a4e8a09b80b8d73ca4392f1913e99ff5", 1245766034000L);\r
-  /**\r
-   * The merge branch version\r
-   */\r
-  public static final String SUBMODULE_TXT_ADDED_VERSION = GitUtils.makeVersion("d1a88fd33c516c1b607db75eb62244b2ea495c42", 1246534153000L);\r
-  /**\r
-   * The merge branch version\r
-   */\r
-  public static final String BEFORE_SUBMODULE_ADDED_VERSION =\r
-    GitUtils.makeVersion("592c5bcee6d906482177a62a6a44efa0cff9bbc7", 1238421437000L);\r
-  /**\r
-   * The source directory\r
-   */\r
-  protected File mySourceRep;\r
-  /**\r
-   * The caches directory\r
-   */\r
-  private File myCachesDir;\r
-  /**\r
-   * Temporary files\r
-   */\r
-  protected static TempFiles myTempFiles = new TempFiles();\r
-\r
-  static {\r
-    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {\r
-      public void run() {\r
-        myTempFiles.cleanup();\r
-      }\r
-    }));\r
-  }\r
-\r
-\r
-  /**\r
-   * Create a VCS root for the current parameters and specified branch\r
-   *\r
-   * @param branchName the branch name\r
-   * @return a created vcs root object\r
-   * @throws IOException if the root could not be created\r
-   */\r
-  protected VcsRoot getRoot(String branchName) throws IOException {\r
-    return getRoot(branchName, false);\r
-  }\r
-\r
-  /**\r
-   * Create a VCS root for the current parameters and specified branch\r
-   *\r
-   * @param branchName       the branch name\r
-   * @param enableSubmodules if true, submodules are enabled\r
-   * @return a created vcs root object\r
-   * @throws IOException if the root could not be created\r
-   */\r
-  protected VcsRoot getRoot(String branchName, boolean enableSubmodules) throws IOException {\r
-    VcsRootImpl myRoot = new VcsRootImpl(1, Constants.VCS_NAME);\r
-    myRoot.addProperty(Constants.URL, GitUtils.toURL(mySourceRep));\r
-    if (branchName != null) {\r
-      myRoot.addProperty(Constants.BRANCH_NAME, branchName);\r
-      myRoot.addProperty(Constants.SUBMODULE_URLS, "submodule\n" + GitUtils.toURL(dataFile("submodule.git")));\r
-    }\r
-    if (enableSubmodules) {\r
-      myRoot.addProperty(Constants.SUBMODULES_CHECKOUT, Settings.SubmodulesCheckoutPolicy.CHECKOUT.name());\r
-    }\r
-    return myRoot;\r
-  }\r
-\r
-  /**\r
-   * @return a created vcs support object\r
-   */\r
-  protected GitVcsSupport getSupport() {\r
-    return new GitVcsSupport(null) {\r
-      @Override\r
-      protected Settings createSettings(VcsRoot vcsRoot) throws VcsException {\r
-        final Settings s = super.createSettings(vcsRoot);\r
-        s.setCachesDirectory(myCachesDir.getPath());\r
-        return s;\r
-      }\r
-    };\r
-  }\r
-\r
-  /**\r
-   * Setup test environment\r
-   *\r
-   * @throws IOException in case of IO problem\r
-   */\r
-  @BeforeMethod\r
-  public void setUp() throws IOException {\r
-    File masterRep = dataFile("repo.git");\r
-    mySourceRep = myTempFiles.createTempDir();\r
-    FileUtil.copyDir(masterRep, mySourceRep);\r
-    myCachesDir = myTempFiles.createTempDir();\r
-  }\r
-\r
-  /**\r
-   * {@inheritDoc}\r
-   */\r
-  protected String getTestDataPath() {\r
-    return dataFile().getPath();\r
-  }\r
-\r
-\r
-  /**\r
-   * Tear down test environment\r
-   */\r
-  @AfterMethod\r
-  public void tearDown() {\r
-    // clear root\r
-    myTempFiles.cleanup();\r
-  }\r
-\r
-  /**\r
-   * The connection test\r
-   *\r
-   * @throws Exception in case of IO problem\r
-   */\r
-  @Test\r
-  public void testConnection() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("version-test");\r
-    support.testConnection(root);\r
-    try {\r
-      root = getRoot("no-such-branch");\r
-      support.testConnection(root);\r
-      Assert.fail("The connection should have failed");\r
-    } catch (VcsException ex) {\r
-      // test successful\r
-    }\r
-  }\r
-\r
-  /**\r
-   * The current version test\r
-   *\r
-   * @throws Exception in case of IO problem\r
-   */\r
-  @Test\r
-  public void testCurrentVersion() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("version-test");\r
-    String version = support.getCurrentVersion(root);\r
-    Assert.assertEquals(VERSION_TEST_HEAD, version);\r
-  }\r
-\r
-  /**\r
-   * Test get content for the file\r
-   *\r
-   * @throws Exception in case of bug\r
-   */\r
-  @Test\r
-  public void testGetContent() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("version-test");\r
-    String version = support.getCurrentVersion(root);\r
-    byte[] data1 = support.getContent("readme.txt", root, version);\r
-    byte[] data2 = FileUtil.loadFileBytes(dataFile("content", "readme.txt"));\r
-    Assert.assertEquals(data1, data2);\r
-  }\r
-\r
-  /**\r
-   * Test get content for the file\r
-   *\r
-   * @throws Exception in case of bug\r
-   */\r
-  @Test\r
-  public void testGetContentSubmodules() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("patch-tests", true);\r
-    String version = support.getCurrentVersion(root);\r
-    byte[] data1 = support.getContent("submodule/file.txt", root, version);\r
-    byte[] data2 = FileUtil.loadFileBytes(dataFile("content", "submodule file.txt"));\r
-    Assert.assertEquals(data1, data2);\r
-  }\r
-\r
-\r
-  /**\r
-   * Test getting changes for the build\r
-   *\r
-   * @throws Exception in case of IO problem\r
-   */\r
-  @Test\r
-  public void testCollectBuildChanges() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("master");\r
-    // ensure that all revisions reachable from master are fetched\r
-    final List<ModificationData> ms = support.collectChanges(root, VERSION_TEST_HEAD, CUD1_VERSION, new CheckoutRules(""));\r
-    assertEquals(2, ms.size());\r
-    ModificationData m2 = ms.get(1);\r
-    assertEquals("The second commit\n", m2.getDescription());\r
-    assertEquals(3, m2.getChanges().size());\r
-    for (VcsChange ch : m2.getChanges()) {\r
-      assertEquals(VcsChange.Type.ADDED, ch.getType());\r
-      assertEquals("dir/", ch.getFileName().substring(0, 4));\r
-    }\r
-    ModificationData m1 = ms.get(0);\r
-    assertEquals("more changes\n", m1.getDescription());\r
-    assertEquals(CUD1_VERSION, m1.getVersion());\r
-    assertEquals(3, m1.getChanges().size());\r
-    VcsChange ch10 = m1.getChanges().get(0);\r
-    assertEquals("dir/a.txt", ch10.getFileName());\r
-    assertEquals(CUD1_VERSION, ch10.getAfterChangeRevisionNumber());\r
-    assertEquals(m2.getVersion(), ch10.getBeforeChangeRevisionNumber());\r
-    assertEquals(VcsChange.Type.CHANGED, ch10.getType());\r
-    VcsChange ch11 = m1.getChanges().get(1);\r
-    assertEquals("dir/c.txt", ch11.getFileName());\r
-    assertEquals(VcsChange.Type.ADDED, ch11.getType());\r
-    VcsChange ch12 = m1.getChanges().get(2);\r
-    assertEquals("dir/tr.txt", ch12.getFileName());\r
-    assertEquals(VcsChange.Type.REMOVED, ch12.getType());\r
-    // now check merge commit relatively to the branch\r
-    final List<ModificationData> mms0 = support.collectChanges(root, MERGE_BRANCH_VERSION, MERGE_VERSION, new CheckoutRules(""));\r
-    assertEquals(2, mms0.size());\r
-    // no check the merge commit relatively to the fork\r
-    final List<ModificationData> mms1 = support.collectChanges(root, CUD1_VERSION, MERGE_VERSION, new CheckoutRules(""));\r
-    assertEquals(3, mms1.size());\r
-    ModificationData md1 = mms1.get(0);\r
-    assertFalse(md1.isCanBeIgnored());\r
-    assertEquals("merge commit\n", md1.getDescription());\r
-    assertEquals(MERGE_VERSION, md1.getVersion());\r
-    assertEquals(3, md1.getChanges().size());\r
-    VcsChange ch20 = md1.getChanges().get(0);\r
-    assertEquals("dir/a.txt", ch20.getFileName());\r
-    assertEquals(VcsChange.Type.REMOVED, ch20.getType());\r
-    VcsChange ch21 = md1.getChanges().get(1);\r
-    assertEquals("dir/b.txt", ch21.getFileName());\r
-    assertEquals(VcsChange.Type.CHANGED, ch21.getType());\r
-    VcsChange ch22 = md1.getChanges().get(2);\r
-    assertEquals("dir/q.txt", ch22.getFileName());\r
-    assertEquals(VcsChange.Type.ADDED, ch22.getType());\r
-    ModificationData md2 = mms1.get(1);\r
-    assertTrue(md2.isCanBeIgnored());\r
-    assertEquals("b-mod, d-add\n", md2.getDescription());\r
-    assertEquals(MERGE_BRANCH_VERSION, md2.getVersion());\r
-    assertEquals(2, md2.getChanges().size());\r
-    ModificationData md3 = mms1.get(2);\r
-    assertEquals("a-mod, c-rm\n", md3.getDescription());\r
-    assertEquals(2, md3.getChanges().size());\r
-    // check the case with broken commit\r
-    String missing = GitUtils.makeVersion(GitUtils.versionRevision(CUD1_VERSION).replace('0', 'f'), GitUtils.versionTime(CUD1_VERSION));\r
-    final List<ModificationData> mms2 = support.collectChanges(root, missing, MERGE_VERSION, new CheckoutRules(""));\r
-    assertEquals(4, mms2.size());\r
-    ModificationData mb3 = mms2.get(3);\r
-    assertEquals(GitUtils.SYSTEM_USER, mb3.getUserName());\r
-    assertEquals(0, mb3.getChanges().size());\r
-  }\r
-\r
-  /**\r
-   * Test getting changes for the build with submodules ignored\r
-   *\r
-   * @throws Exception in case of IO problem\r
-   */\r
-  @Test\r
-  public void testCollectBuildChangesSubmodulesIgnored() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("patch-tests");\r
-    final List<ModificationData> ms =\r
-      support.collectChanges(root, BEFORE_SUBMODULE_ADDED_VERSION, SUBMODULE_ADDED_VERSION, new CheckoutRules(""));\r
-    assertEquals(1, ms.size());\r
-    ModificationData m1 = ms.get(0);\r
-    assertEquals("added submodule\n", m1.getDescription());\r
-    assertEquals(2, m1.getChanges().size());\r
-    VcsChange ch11 = m1.getChanges().get(0);\r
-    assertEquals(VcsChange.Type.ADDED, ch11.getType());\r
-    assertEquals(".gitmodules", ch11.getFileName());\r
-    VcsChange ch12 = m1.getChanges().get(1);\r
-    assertEquals("submodule", ch12.getFileName());\r
-    assertEquals(VcsChange.Type.ADDED, ch12.getType());\r
-    final List<ModificationData> ms2 =\r
-      support.collectChanges(root, SUBMODULE_ADDED_VERSION, SUBMODULE_MODIFIED_VERSION, new CheckoutRules(""));\r
-    assertEquals(1, ms.size());\r
-    ModificationData m2 = ms2.get(0);\r
-    assertEquals("submodule updated\n", m2.getDescription());\r
-    assertEquals(1, m2.getChanges().size());\r
-    VcsChange ch21 = m2.getChanges().get(0);\r
-    assertEquals("submodule", ch21.getFileName());\r
-    assertEquals(VcsChange.Type.CHANGED, ch21.getType());\r
-  }\r
-\r
-  /**\r
-   * Test getting changes for the build\r
-   *\r
-   * @throws Exception in case of IO problem\r
-   */\r
-  @Test\r
-  public void testCollectBuildChangesSubmodules() throws Exception {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("patch-tests", true);\r
-    final List<ModificationData> ms =\r
-      support.collectChanges(root, BEFORE_SUBMODULE_ADDED_VERSION, SUBMODULE_ADDED_VERSION, new CheckoutRules(""));\r
-    assertEquals(1, ms.size());\r
-    ModificationData m1 = ms.get(0);\r
-    assertEquals("added submodule\n", m1.getDescription());\r
-    assertEquals(2, m1.getChanges().size());\r
-    VcsChange ch11 = m1.getChanges().get(0);\r
-    assertEquals(VcsChange.Type.ADDED, ch11.getType());\r
-    assertEquals(".gitmodules", ch11.getFileName());\r
-    VcsChange ch12 = m1.getChanges().get(1);\r
-    assertEquals("submodule/file.txt", ch12.getFileName());\r
-    assertEquals(VcsChange.Type.ADDED, ch12.getType());\r
-    final List<ModificationData> ms2 =\r
-      support.collectChanges(root, SUBMODULE_ADDED_VERSION, SUBMODULE_MODIFIED_VERSION, new CheckoutRules(""));\r
-    assertEquals(1, ms.size());\r
-    ModificationData m2 = ms2.get(0);\r
-    assertEquals("submodule updated\n", m2.getDescription());\r
-    assertEquals(1, m2.getChanges().size());\r
-    VcsChange ch21 = m2.getChanges().get(0);\r
-    assertEquals("submodule/new file.txt", ch21.getFileName());\r
-    assertEquals(VcsChange.Type.ADDED, ch21.getType());\r
-  }\r
-\r
-\r
-  /**\r
-   * Test patches\r
-   *\r
-   * @throws IOException  in case of test failure\r
-   * @throws VcsException in case of test failure\r
-   */\r
-  @Test\r
-  public void testPatches() throws IOException, VcsException {\r
-    checkPatch("cleanPatch1", null, GitUtils.makeVersion("a894d7d58ffde625019a9ecf8267f5f1d1e5c341", 1237391915000L));\r
-    checkPatch("patch1", GitUtils.makeVersion("70dbcf426232f7a33c7e5ebdfbfb26fc8c467a46", 1238420977000L),\r
-               GitUtils.makeVersion("0dd03338d20d2e8068fbac9f24899d45d443df38", 1238421020000L));\r
-    checkPatch("patch2", GitUtils.makeVersion("7e916b0edd394d0fca76456af89f4ff7f7f65049", 1238421159000L),\r
-               GitUtils.makeVersion("049a98762a29677da352405b27b3d910cb94eb3b", 1238421214000L));\r
-    checkPatch("patch3", null, GitUtils.makeVersion("1837cf38309496165054af8bf7d62a9fe8997202", 1238421349000L));\r
-    checkPatch("patch4", GitUtils.makeVersion("1837cf38309496165054af8bf7d62a9fe8997202", 1238421349000L),\r
-               GitUtils.makeVersion("592c5bcee6d906482177a62a6a44efa0cff9bbc7", 1238421437000L));\r
-    checkPatch("patch-case", "rename-test", GitUtils.makeVersion("cbf1073bd3f938e7d7d85718dbc6c3bee10360d9", 1247581634000L),\r
-               GitUtils.makeVersion("2eed4ae6732536f76a65136a606f635e8ada63b9", 1247581803000L), true);\r
-  }\r
-\r
-  /**\r
-   * Test patches\r
-   *\r
-   * @throws IOException  in case of test failure\r
-   * @throws VcsException in case of test failure\r
-   */\r
-  @Test\r
-  public void testSubmodulePatches() throws IOException, VcsException {\r
-    checkPatch("submodule-added-ignore", BEFORE_SUBMODULE_ADDED_VERSION, SUBMODULE_ADDED_VERSION);\r
-    checkPatch("submodule-removed-ignore", SUBMODULE_ADDED_VERSION, BEFORE_SUBMODULE_ADDED_VERSION);\r
-    checkPatch("submodule-modified-ignore", SUBMODULE_ADDED_VERSION, SUBMODULE_MODIFIED_VERSION);\r
-    checkPatch("submodule-added", "patch-tests", BEFORE_SUBMODULE_ADDED_VERSION, SUBMODULE_ADDED_VERSION, true);\r
-    checkPatch("submodule-removed", "patch-tests", SUBMODULE_ADDED_VERSION, BEFORE_SUBMODULE_ADDED_VERSION, true);\r
-    checkPatch("submodule-modified", "patch-tests", SUBMODULE_ADDED_VERSION, SUBMODULE_MODIFIED_VERSION, true);\r
-  }\r
-\r
-\r
-  /**\r
-   * Check single patch\r
-   *\r
-   * @param name        the name of patch\r
-   * @param fromVersion from version\r
-   * @param toVersion   to version\r
-   * @throws IOException  in case of test failure\r
-   * @throws VcsException in case of test failure\r
-   */\r
-  private void checkPatch(final String name, final String fromVersion, final String toVersion) throws IOException, VcsException {\r
-    checkPatch(name, "patch-tests", fromVersion, toVersion, false);\r
-  }\r
-\r
-  /**\r
-   * Check single patch\r
-   *\r
-   * @param name             the name of patch\r
-   * @param branchName       the name of branch to use\r
-   * @param fromVersion      from version\r
-   * @param toVersion        to version\r
-   * @param enableSubmodules if true, submodules are enabled\r
-   * @throws IOException  in case of test failure\r
-   * @throws VcsException in case of test failure\r
-   */\r
-  private void checkPatch(final String name,\r
-                          final String branchName, final String fromVersion,\r
-                          final String toVersion,\r
-                          boolean enableSubmodules\r
-  )\r
-    throws IOException, VcsException {\r
-    setName(name);\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot(branchName, enableSubmodules);\r
-    final ByteArrayOutputStream output = new ByteArrayOutputStream();\r
-    final PatchBuilderImpl builder = new PatchBuilderImpl(output);\r
-    support.buildPatch(root, fromVersion, toVersion, builder, new CheckoutRules(""));\r
-    builder.close();\r
-    checkPatchResult(output.toByteArray());\r
-  }\r
-\r
-  /**\r
-   * Test label implementation\r
-   *\r
-   * @throws IOException        in case of test failure\r
-   * @throws VcsException       in case of test failure\r
-   * @throws URISyntaxException in case of test failure\r
-   */\r
-  @Test\r
-  public void testLabels() throws IOException, VcsException, URISyntaxException {\r
-    GitVcsSupport support = getSupport();\r
-    VcsRoot root = getRoot("master");\r
-    // ensure that all revisions reachable from master are fetched\r
-    support.label("test_label", VERSION_TEST_HEAD, root, new CheckoutRules(""));\r
-    Repository r = new Repository(new File(new URIish(root.getProperty(Constants.URL)).getPath()));\r
-    try {\r
-      Tag t = r.mapTag("test_label");\r
-      assertEquals(t.getObjId().name(), GitUtils.versionRevision(VERSION_TEST_HEAD));\r
-    } finally {\r
-      r.close();\r