diff --git a/build.xml b/build.xml
index cd64b37d177a932574cd5518bd8593266d66e333..fd000731d19f29368f45cd465e4a5290ecc90801 100644
--- a/build.xml
+++ b/build.xml
@@ -5,7 +5,6 @@
     nshmp-haz is a platform for conducting seismic hazard calculations
   </description>
 
-  <!-- PROPERTIES -->
   <property name="src" location="src" />
   <property name="test" location="test" />
   <property name="lib" location="lib" />
@@ -14,6 +13,8 @@
   <property name="docs" location="docs" />
   <property name="javadoc" location="${docs}/javadoc" />
 
+  <property name="app.properties" location="${dist}/app.properties" />
+  <available file=".git" type="dir" property="git.present" />
 
   <property name="reports" location="${docs}/reports" />
   <property name="reports.xml" location="${reports}/junit-xml" />
@@ -56,14 +57,35 @@
        and internal package; need to check dependencies
   -->
 
-  <target name="jar" depends="compile.source">
+  <target name="jar" depends="compile.source,set.app.properties">
     <jar destfile="${dist}/nshmp-haz.jar">
       <fileset dir="${classes}" />
+      <fileset file="${app.properties}" />
       <zipfileset src="${guava.jar}" excludes="**/META-INF/**" />
       <zipfileset src="${gson.jar}" />
     </jar>
+    <delete file="${app.properties}" />
   </target>
 
+  <target name="set.app.properties" depends="check.git">
+    <condition property="app.version" value="${git.tag}" else="unknown">
+      <isset property="git.tag" />
+    </condition>
+    <echo>app.version=${app.version}</echo>
+    <echo file="${app.properties}">app.version=${app.version}</echo>
+    <echo file="${app.properties}" append="true">${line.separator}</echo>
+  </target>
+
+  <target name="check.git" if="git.present">
+    <exec executable="git"
+          outputproperty="git.tag"
+          failifexecutionfails="false">
+      <arg value="describe" />
+      <arg value="--tags" />
+    </exec>
+  </target>
+
+
   <target name="compile">
     <mkdir dir="${classes}" />
     <javac srcdir="${param.srcdir}"
diff --git a/src/org/opensha2/DeaggCalc.java b/src/org/opensha2/DeaggCalc.java
index cc2399283009cb49a6cfc05f48cabdf9c723fc26..dbf87e9c5a8c56dc52770b0fcbc2719f493088d4 100644
--- a/src/org/opensha2/DeaggCalc.java
+++ b/src/org/opensha2/DeaggCalc.java
@@ -82,7 +82,7 @@ public class DeaggCalc {
       fh.setFormatter(new Logging.ConsoleFormatter());
       log.getParent().addHandler(fh);
 
-      log.info(PROGRAM + ": initializing...");
+      log.info(PROGRAM + ": " + HazardCalc.VERSION);
       Path modelPath = Paths.get(args[0]);
       HazardModel model = HazardModel.load(modelPath);
 
@@ -199,7 +199,9 @@ public class DeaggCalc {
 
   private static final String USAGE = new StringBuilder()
       .append(NEWLINE)
-      .append(PROGRAM).append(" usage:").append(NEWLINE)
+      .append(PROGRAM).append(" [").append(HazardCalc.VERSION).append("]").append(NEWLINE)
+      .append(NEWLINE)
+      .append("Usage:").append(NEWLINE)
       .append("  ").append(USAGE_COMMAND).append(NEWLINE)
       .append(NEWLINE)
       .append("Where:").append(NEWLINE)
diff --git a/src/org/opensha2/HazardCalc.java b/src/org/opensha2/HazardCalc.java
index ea538651806b228203f8f095f7a55dbc575c0da2..85734df9b4cf8862612d5cf1db5595998b950770 100644
--- a/src/org/opensha2/HazardCalc.java
+++ b/src/org/opensha2/HazardCalc.java
@@ -18,11 +18,15 @@ import org.opensha2.internal.Logging;
 import com.google.common.base.Optional;
 import com.google.common.base.Throwables;
 
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.Properties;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
@@ -89,7 +93,7 @@ public class HazardCalc {
       fh.setFormatter(new Logging.ConsoleFormatter());
       log.getParent().addHandler(fh);
 
-      log.info(PROGRAM + ": initializing...");
+      log.info(PROGRAM + ": " + VERSION);
       Path modelPath = Paths.get(args[0]);
       HazardModel model = HazardModel.load(modelPath);
 
@@ -229,7 +233,12 @@ public class HazardCalc {
       throw new RuntimeException(e);
     }
   }
-  
+
+  /**
+   * The Git application version. This version string applies to all other
+   * nshnmp-haz applications.
+   */
+  public static final String VERSION = version();
 
   private static final String PROGRAM = HazardCalc.class.getSimpleName();
   private static final String USAGE_COMMAND =
@@ -238,9 +247,36 @@ public class HazardCalc {
   private static final String USAGE_URL2 = "https://github.com/usgs/nshmp-haz/tree/master/etc";
   private static final String SITE_STRING = "name,lon,lat[,vs30,vsInf[,z1p0,z2p5]]";
 
+  private static String version() {
+    String version = "unknown";
+    /* Assume we're running from a jar. */
+    try {
+      InputStream is = HazardCalc.class.getResourceAsStream("/app.properties");
+      Properties props = new Properties();
+      props.load(is);
+      is.close();
+      version = props.getProperty("app.version");
+    } catch (Exception e1) {
+      /* Otherwise check for a repository. */
+      Path gitDir = Paths.get(".git");
+      if (Files.exists(gitDir)) {
+        try {
+          Process pr = Runtime.getRuntime().exec("git describe --tags");
+          BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
+          version = br.readLine();
+          br.close();
+          /* Detached from repository. */
+        } catch (Exception e2) {}
+      }
+    }
+    return version;
+  }
+
   private static final String USAGE = new StringBuilder()
       .append(NEWLINE)
-      .append(PROGRAM).append(" usage:").append(NEWLINE)
+      .append(PROGRAM).append(" [").append(VERSION).append("]").append(NEWLINE)
+      .append(NEWLINE)
+      .append("Usage:").append(NEWLINE)
       .append("  ").append(USAGE_COMMAND).append(NEWLINE)
       .append(NEWLINE)
       .append("Where:").append(NEWLINE)