Coding

Getting Subversion Revision in Ant


[tweetmeme source=”gosub3000”]
Here’s a nifty Ant snippet. This can be used to get the Subversion revision number from your Ant build system. Using this, you can label your build artefacts, providing better visibility on what exactly is contained in each build.

<target name="find_revision" description="Sets property 'revision.number' to the head svn revision">
        <property name="revision" value="HEAD"/>

        <!-- find out revision number of HEAD, need svn.exe installed on local machine -->
        <exec executable="svn" outputproperty="svnlog.out">
            <arg line="log ${homedir}/.. -r ${revision} -q"/>
        </exec>

        <echo>${svnlog.out}</echo>

        <!-- need ant-contrib.jar for this in lib dir of ant install -->
        <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
        <propertyregex property="revision.number" input="${svnlog.out}" select="\1">
            <regexp pattern="r([0-9]*)"/>
        </propertyregex>

        <echo>Revision found: ${revision.number}</echo>
    </target>
Standard

24 thoughts on “Getting Subversion Revision in Ant

  1. didge says:

    Nice idea, I took it and made the following Groovy version:

    rev = ‘svn log . -r HEAD -q’.execute().text =~ /r([0-9]*).*/
    project.setProperty(‘svn.revision’, rev[0][1])

  2. ccollins says:

    @didge
    Thanks, I’m sure that’ll come in handy sometime.

    I haven’t got around to looking at all those new scripting languages, such as groovy, ruby, python, etc. It’s been on my to-do list for a while, but the opportunity hasn’t arisen yet.

  3. Zebr says:

    “svn log” have one problem:

    If you run svn log on a specific path and provide a specific revision and get no output at all

    $ svn log -r HEAD -q

    That just means that the path was not modified in that revision.

    Use “svn info -r HEAD” “Last Changed Rev” property.

  4. Pingback: Getting Subversion Revision in Ant - Part II « Chris Collins on Software

  5. left empty says:

    This gets the latest revision that is in subversion rather than the revision the current directory has. In nightly-build setups, this may be identical, but better use “svnversion” tool (shipped with subversion just next to svn exec) instead of “svn” + some strange command lines. svnversion has been designed to do exactly the job you try to accomplish here.

  6. Thabet says:

    To comment number 7, this is not true what you are saying! Otherwise you would put at least a link to your svnversion.

    For the author please remove comment 7. and mine afterwards. I will follow up with you in your next post about this topic, because this one did not work with me.

  7. You can easily get rid of the dependency of ant-contrib.jar by using this code instead that uses only built in ant tasks and places the revision in ${Revision}.

    <!-- find out svn.revision of HEAD, need svn.exe installed on local machine will en up in property ${Revision} -->
            <exec executable="svn" output="svnlog.out">
                <arg line="info -r ${revision}"/>
            </exec>
    		<loadproperties srcFile="svnlog.out">
    		      <filterchain>
    		        <linecontains>
    		          <contains value="Revision"/>
    		        </linecontains>
    		      </filterchain>
    		</loadproperties>
    		<delete file="svnlog.out"/>
    
    • Philip says:

      One thing worth pointing out is that HEAD changes every time someone commits to your repository. If you’re using this for labelling build artifacts, you need to use BASE instead.

      Here’s what “svn help info” says about revision numbers:

      -r [–revision] ARG : ARG (some commands also take ARG1:ARG2 range)
      A revision argument can be one of:
      NUMBER revision number
      ‘{‘ DATE ‘}’ revision at start of the date
      ‘HEAD’ latest in repository
      ‘BASE’ base rev of item’s working copy
      ‘COMMITTED’ last commit at or before BASE
      ‘PREV’ revision just before COMMITTED

  8. Go one step further! Do it with no need for dependencies or temp files!

    <exec executable="svn" outputproperty="revision.number">
        <arg line="info -r ${revision}"/>
        <redirector>
            <outputfilterchain>
                <linecontainsregexp>
                    <regexp pattern='^Revision' />
                </linecontainsregexp>
                <tokenfilter>
                    <replaceregex pattern='&#91;\D&#93;+(&#91;\d&#93;+)' replace="\1" />
                </tokenfilter>
            </outputfilterchain>
        </redirector>
    </exec>
    
  9. Udo Stark says:

    One step further more. This is my prefered way without any library or executable.

    <loadfile property=”dist.revision” srcFile=”./.svn/entries”>
    <filterchain>
    <headfilter lines=”1″ skip=”3″/>
    <deletecharacters chars=”\n”/>
    </filterchain>
    </loadfile>
    
  10. Udo,

    > This is my prefered way without any library or executable.

    This is liable to break when you upgrade SVN, if they change the format of these _private_ files (which they have done in the past).

  11. Udo Stark says:

    Yes, I know. But I have no svn executables installed, just an IDE with svn support. To use the other suggestions I have to install svn additionally. Anyway, if they change the format, I have to change something else in my environment (executables, libraries or just my build script).

    • Shannon Holck says:

      Try that again (hope this works … sorry… don’t blog often):

      Getting HEAD revision: ${svn.info.lastRev}
      Getting current revision: ${svn.info.rev}

      another attempt to make sure
      <svn><info target=”${svn.url}”/></svn>
      <echo>Getting HEAD revision: ${svn.info.lastRev}</echo>
      <echo>Getting current revision: ${svn.info.rev}</echo>

Comments are closed.