Auto Version numbering your Android App using Git and Eclipse

I believe that computers are the best things for doing repetitive tasks. I certainly am not, I either forget, or (mostly) don’t do things in a consistent way – which isn’t what I want.

One of the things I am likely to do is forget to up the version information in the manifest when I publish a new version of an Android app. In the past I’ve worked with configured build systems that have a auto version numbering feature and I got use to it (or maybe I got lazy).

  • Can't import the volley library in eclipse
  • Import existing Android project in Eclipse: no gen source folder?
  • How to browse Android source code at a particular version?
  • Android Studio: Can't start Git
  • How to insert the commit and branch info from git to the apk when building with gradle?
  • How to upload an APK from Jenkins/Hudson to Play Store?
  • I found this Stackoverflow post very useful in coming up with a solution, but it took me a while to fine tune it so it works just they way I want it. Earlier attempts would sometime cause continues building, which was a pain. So I thought I would publish my solution here in the hope that someone else will find it useful.

  • Trying to find a good strategy using Git for personal development on local/personal machine
  • Suggestions for Grails .gitignore
  • subtree merging master into branch: -s recurisve -Xsubtree=?
  • GIt integration for Coda app
  • Composer install/update not working
  • IntelliJ and Git Branch Name
  • 4 Solutions collect form web for “Auto Version numbering your Android App using Git and Eclipse”

    This solution was developed on Linux. I’m sure skilled Windows & Mac developers can adapt it to their platforms, but I am not such a developer. Linux is where my skill set lives.

    Git has a nice feature in the git describe --dirty command. It scans back down the commit log and finds the tag and then builds a version string from there. If this is a “production build” where the last commit has been tagged and all files have been checked in then that is your version string. If this is a development build then the last tag is appended with the number of additional commits and an abbreviated hash code. The --dirty flag is just the cherry on the icing on the cake: it appends the word dirty if there are any modified files not committed yet. This is perfect for your android:versionName attribute in the manifest file.

    For the android:versionCode a number is required. This needs to clock for releases but not for development build, and as every release will have a tag with a version string I simply count these. I always tag my versions in the form v<major>.<minor>[.<patch>] where <major>, <minor> and <patch> are just numbers. So counting tags that start with a lower case ‘v’ followed with a digit are counted is all thats really needed here.

    After trailing with a template manifest file I discovered that the best way was to simply use the AndroidManifest.xml file in the project base, edited using the stream editor sed and deposit the result in bin/AndroidManifest.xml.

    So I developed the script below, placed it in a scripts folder at the same level as my projects (so that they can all share the same script) and then configured a custom builder in Eclipse.

    There is the script which I called

    echo "Auto Version: `pwd`"
    CODE=`git tag | grep -c ^v[0-9]`
    NAME=`git describe --dirty | sed -e 's/^v//'`
    COMMITS=`echo ${NAME} | sed -e 's/[0-9\.]*//'`
    if [ "x${COMMITS}x" = "xx" ] ; then
        BRANCH=" (`git branch | grep "^\*" | sed -e 's/^..//'`)"
    echo "   Code: ${CODE}"
    echo "   Ver:  ${VERSION}"
    cat AndroidManifest.xml | \
        sed -e "s/android:versionCode=\"[0-9][0-9]*\"/android:versionCode=\"${CODE}\"/" \
            -e "s/android:versionName=\".*\"/android:versionName=\"${VERSION}\"/" \
        > bin/AndroidManifest.xml
    exit 0

    To configure the builder here are the steps:

    1). Right click the project base and select “Properties” and then “Builders”.

    2). Hit the “New” button and select the “Program” option.

    3). Name your version something like “<project> Auto Version”. This string needs to be unique across all projects.

    4). Configure the “Main” tab as follows:

    4a). In the “Location” section use “Browse File System” and navigate and select the script file.

    4b). In the “Working directory” section use “Browse Workspace” to select the project.

    5). Leave the “Refresh resources upon completion” unchecked in the “Refresh” tab.

    6). Don’t set any variables up in the “Environment” tab.

    7). In the “Build Options” tab:

    7a). Make sure that “During manual builds” is ticked, and

    7b). That “During auto builds” is also ticked.

    7c). I now have everything else left unselected. I don’t even allocate a console to it. The eagle eyed out there may have spotted that the script does output some information, but now I’ve got it working I just want the thing to run silently without bothering me.

    8). Okay the build settings and then position your builder between “Android Pre-Compile” and “Java Builder”.

    Go back to developing your apps safe in the knowledge that they are being properly versioned, and check out your app’s info. Isn’t that version number cool. 🙂


    Idea (using ant and git executable)

    ok, here’s a novel way of doing it:

    • for calculating version.code:

      git rev-list master --first-parent --count

      this follows the versioning guideline. As it effectively finds the number of commits from the initial commit (inclusive) which is always incrementing from the previous version.

    • for calculating the

      git describe --tags --dirty --abbrev=7


    build.xml usually imports a custom ant script called custom_rules.xml

    so making the content of the script as:

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="application-custom">
    <macrodef name="git" taskname="@{taskname}">
        <attribute name="command" />
        <attribute name="dir" default="" />
        <attribute name="property" default="" />
        <attribute name="taskname" default="" />
        <attribute name="failonerror" default="on" />
        <element name="args" optional="true" />
            <exec executable="git" dir="@{dir}" outputproperty="@{property}" 
                failifexecutionfails="@{failonerror}" failonerror="@{failonerror}">
                <arg value="@{command}" />
    <target name="-pre-build">
        <git command="rev-list" property="versioning.code" taskname="versioning">
                <arg value="master" />
                <arg value="--first-parent" />
                <arg value="--count" />
        <git command="describe" property="" taskname="versioning">
                <arg value="--tags" />
                <arg value="--dirty" />
                <arg value="--abbrev=7" />
        <echo level="info" taskname="versioning">${versioning.code}, ${}</echo>
        <replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="${versioning.code}"' />
        <replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="${}"' />
    <target name="-post-build" >
        <replaceregexp file="AndroidManifest.xml" match='android:versionCode=".*"' replace='android:versionCode="0"' />
        <replaceregexp file="AndroidManifest.xml" match='android:versionName=".*"' replace='android:versionName="0"' />

    would just do.

    In a nut shell, it just replaces the android.versionCode and android.versionName with the current version code and name, stored in git.


    • initial version code and name is set to 0 upon the completion of build. If you require it, replace the zero in the -post-build target, or (though I highly doubt you would require it) you could make it configurable and place it in some property (file or embedded; your choice)
    • if the build is failed, or aborted, the version will remain as it is. (though i highly doubt it is of any concern, just revert the file!)



    • Best way to integrate Git with Ant?
    • macrodef for git improvised from Ant Tasks for Git | blog

    Important Edit

    1. prevent using HEAD to calculate the build number; causes version downgrade issue when doing a build during development, and later when installing the stable version (or when doing a beta to main release transition). using the master (or the branch which is used for production builds) ref instead.

    PS: relevant for AS users: Automatically versioning Android project from git describe with Android Studio/Gradle

    Using Android Studio (Gradle):
    Check out this blog post:

    Here’s the implementation from the blog:

        android {
        defaultConfig {
            // Fetch the version according to git latest tag and "how far are we from last tag"
            def longVersionName = "git -C ${rootDir} describe --tags --long".execute().text.trim()
            def (fullVersionTag, versionBuild, gitSha) = longVersionName.tokenize('-')
            def(versionMajor, versionMinor, versionPatch) = fullVersionTag.tokenize('.')
            // Set the version name
            versionName "$versionMajor.$versionMinor.$versionPatch($versionBuild)"
            // Turn the version name into a version code
            versionCode versionMajor.toInteger() * 100000 +
                    versionMinor.toInteger() * 10000 +
                    versionPatch.toInteger() * 1000 +
            // Friendly print the version output to the Gradle console
            printf("\n--------" + "VERSION DATA--------" + "\n" + "- CODE: " + versionCode + "\n" + 
                   "- NAME: " + versionName + "\n----------------------------\n")
    '  for windows
    '   preBuildMy.cmd  include  repVer.vbs 
    ' repVer.vbs :
    Dim objFileSystem, objOutputFile
    Dim objInputFile
    Dim sText,gitFile
    FileName = "./bin/AndroidManifest.xml"
    '  gitFile = ".\..\.git\refs\heads\master"
    gitFile = ".\..\.git\refs\remotes\origin\master"
    Set objFileSystem = CreateObject("Scripting.fileSystemObject")
    set objInputFile= objFileSystem.OpenTextFile(FileName)
    sText= objInputFile.ReadAll
    set objOutputFile = objFileSystem.CreateTextFile(FileName , TRUE)
    set objInputFile= objFileSystem.OpenTextFile(gitFile)
    refText= objInputFile.ReadAll
    sText = Replace(sText,"v1.0","v 1.0 " & Now & " ref=" & mid(refText,1,7))
    Set objFileSystem = Nothing
    Git Baby is a git and github fan, let's start git clone.