59

How can I lookup the latest git commit hash from an ant build script?

I am currently working on a new open source project which I store on github. I would like to extend my existing ANT build file to allow me to create numbered builds. I am imagining that I would launch the build with something like "ant buildnum -Dnum=12".

I would like the resulting jar to have two crucial bits of information in it's manifest file:

  • build.number=12
  • build.gitcommit=

I know how to create the build.number line. However, I am unsure of the best ant plumbing to lookup the latest git commit hash which is the value I want to fill in for .

mchr
  • 6,161
  • 6
  • 52
  • 74

7 Answers7

89

I wrote the following ant target for a project on github. Usage:

  • stores version in property "repository.version"
  • works if no git is installed or no .git directory is present (fallback)
  • other targets must depend on this target if they need the git version
  • only one git command gets executed (--always)

<available file=".git" type="dir" property="git.present"/>

<target name="git.revision" description="Store git revision in ${repository.version}" if="git.present">
    <exec executable="git" outputproperty="git.revision" failifexecutionfails="false" errorproperty="">
        <arg value="describe"/>
        <arg value="--tags"/>
        <arg value="--always"/>
        <arg value="HEAD"/>
    </exec>
    <condition property="repository.version" value="${git.revision}" else="unknown">
        <and>
            <isset property="git.revision"/>
            <length string="${git.revision}" trim="yes" length="0" when="greater"/>
        </and>
    </condition>
</target>

It e.g. be used for expanding the token @repository.version@ in a template file:

<target name="index.html" depends="git.revision" description="build index.html from template">
    <copy file="index.html.template" tofile="index.html" overwrite="yes">
        <filterchain>
            <replacetokens>
                <token key="repository.version" value="${repository.version}" />
            </replacetokens>
        </filterchain>
    </copy>
</target>
jmuc
  • 1,551
  • 1
  • 14
  • 16
  • 1
    Ii integrated this target into my build.xml, but how do i get the output of this target into a file? – Martin Schlagnitweit Jan 31 '12 at 11:36
  • @MartinSchlagnitweit you could use `echo`, e.g. `${repository.version}` – Richard Marr Feb 14 '13 at 14:13
  • @MartinSchlagnitweit You can also use the token `@repository.version@` in a template file and expand the git version (see addition to original answer above). – jmuc Feb 21 '13 at 22:41
  • Also, you can add `` and it will append "`-dirty`" to `${svn.revision}` if the working copy contains local modifications. – gub Jun 10 '15 at 17:46
  • @StevenVascellaro: "The name of a property in which the standard error of the command should be stored" https://ant.apache.org/manual/Tasks/exec.html – jmuc Apr 27 '17 at 20:52
  • @jmuc So then I presume that line is so that error messages about git aren't logged? – Stevoisiak Apr 27 '17 at 21:24
  • @StevenVascellaro: So that the error messages are not used in the expanded `@repository.version@`. You can use `logError="true"` instead to see the git error on the command line. – jmuc Apr 29 '17 at 02:45
23

This command returns always the working folder's last commit SHA1, useful when you don't always build from HEAD. The command should run both on Windows and *nix systems

<exec executable="git" outputproperty="git.revision">
    <arg value="log" />
    <arg value="-1" />
    <arg value="--pretty=format:%H" />
</exec>
Gian Marco
  • 22,140
  • 8
  • 55
  • 44
8

Would that be what you are looking for?

git rev-parse HEAD
Olivier Verdier
  • 46,998
  • 29
  • 98
  • 90
5

I actually used both answers. The ant code I wrote was as follows.

  <target name="getgitdetails" >
    <exec executable="git" outputproperty="git.tagstring">
      <arg value="describe"/>
    </exec>
    <exec executable="git" outputproperty="git.revision">
      <arg value="rev-parse"/>
      <arg value="HEAD"/>
    </exec>
    <if>
      <contains string="${git.tagstring}" substring="cannot"/>
      <then>
        <property name="git.tag" value="none"/>
      </then>
      <else>
        <property name="git.tag" value="${git.tagstring}"/>
      </else>
    </if>
  </target>

mchr
  • 6,161
  • 6
  • 52
  • 74
2

I wrote an Ant task to determine build version without explicitly calling the Git command, so that I don't need to have it installed (on Windows I'd also need to include it in PATH). The versioning workflow:

  • Any "milestone" version changes (i.e. first 2 or 3 numbers) are set manually via tags on branch master.
  • Each commit subsequent to the tag adds to the build number. (Only for tags on master.)
  • If building from a separate branch, its name should be included in the version.

Source code and examples: https://github.com/Hunternif/JGitVersion

Hunternif
  • 2,370
  • 2
  • 17
  • 14
1

You should tag a version (starting with a 0.1 or similar) and then just use git describe.

This will give you readable unique identifiers as reference points from your tag. When you release, this version number will be whatever you specified it to be.

Dustin
  • 89,080
  • 21
  • 111
  • 133
0

In a large company I found <exec> git command-line quickly ran into problems, some devs used a GUI, some had different command-line versions installed in different places, some had other problems. I realised that the way to go was a pure Java solution with the dependencies being part of the project build system, much as we had used before with Svnkit for Subversion.

One condition was that only 'mainstream' library dependencies were permitted. We could use the JGit library but the many git ant tasks projects scattered around github and the like were excluded.

The solution was to use a combination of within build.xml and JGit library.

TODO: paste code...

Ed Randall
  • 6,887
  • 2
  • 50
  • 45