I've used the following ant details to retrieve the checked out branch's latest commit ID, what caveats should I be concerned about using this method?
Are there edge cases where I wouldn't retrieve the expected values?
<scriptdef name="substring" language="javascript">
<attribute name="text" />
<attribute name="start" />
<attribute name="end" />
<attribute name="property" />
<![CDATA[
var text = attributes.get("text");
var start = attributes.get("start");
var end = attributes.get("end") || (text.length() - 1);
project.setProperty(attributes.get("property"), text.substring(start, end));
]]>
</scriptdef>
<loadfile property="head.branch" srcfile="${basedir}/.git/HEAD" />
<substring text="${head.branch}" start="5" property="branch" />
<loadfile property="head.commitId" srcfile="${basedir}/.git/${branch}"/>
you can read the contents of .git/HEAD
, then read the contents of the file that you get from that.
The caveat that you will run into is that the SHA-1 that you get from the above steps may be in a pack file (the way git compresses multiple changes together to save space). I would recommend using git instead of trying to manipulate the .git folder contents yourself.
JGIT can be used to provide a git client within your build
Example
$ ant clone print-latest-commit-id
..
..
clone-repo:
[git-clone] Cloning repository https://github.com/myproj/myrepo.git
resolve:
get-commit-id:
print-commit-id:
[echo] head.commitId = 9e3e8358f2b31507b13f5def69627da422e1656b
build.xml
<project name="build" default="clone" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="resolve" description="Resolve 3rd party dependencies">
<ivy:cachepath pathid="build.path">
<dependency org="org.codehaus.groovy" name="groovy-all" rev="2.1.0-rc-2" conf="default"/>
<dependency org="org.eclipse.jgit" name="org.eclipse.jgit.ant" rev="2.1.0.201209190230-r" conf="default"/>
<exclude org="org.apache.ant"/>
</ivy:cachepath>
</target>
<target name="clone-repo" depends="resolve" description="Pull code from SCM repository">
<taskdef resource="org/eclipse/jgit/ant/ant-tasks.properties" classpathref="build.path"/>
<git-clone uri="https://github.com/myproj/myrepo.git" dest="build/repo" branch="???"/>
</target>
<target name="get-commit-id" depends="resolve" description="Print git log">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<groovy>
import org.eclipse.jgit.api.Git
Git git = Git.open(new File("build/repo"))
properties["head.commitId"] = git.log().call().first().name()
</groovy>
</target>
<target name="print-commit-id" depends="get-commit-id" description="Print commit id">
<echo message="head.commitId = ${head.commitId}"/>
</target>
<target name="clean" description="Cleanup build files">
<delete dir="build"/>
</target>
</project>
NOTE:
- Apache ivy is used manage 3rd party jars
- I prefer to use Groovy for embedded scripts