diff --git a/gitrev.cabal b/gitrev.cabal
--- a/gitrev.cabal
+++ b/gitrev.cabal
@@ -1,5 +1,5 @@
 name:                gitrev
-version:             1.3.0
+version:             1.3.1
 synopsis:            Compile git revision info into Haskell projects
 homepage:            https://github.com/acfoltzer/gitrev
 license:             BSD3
diff --git a/src/Development/GitRev.hs b/src/Development/GitRev.hs
--- a/src/Development/GitRev.hs
+++ b/src/Development/GitRev.hs
@@ -32,7 +32,15 @@
 -- > % cabal exec runhaskell Example.hs
 -- > Example.hs: [panic master@2ae047ba5e4a6f0f3e705a43615363ac006099c1 (Mon Jan 11 11:50:59 2016 -0800) (14 commits in HEAD) (uncommitted files present)] oh no!
 
-module Development.GitRev (gitHash, gitBranch, gitDirty, gitCommitCount, gitCommitDate) where
+module Development.GitRev
+  ( gitBranch
+  , gitCommitCount
+  , gitCommitDate
+  , gitDescribe
+  , gitDirty
+  , gitDirtyTracked
+  , gitHash
+  ) where
 
 import Control.Exception
 import Control.Monad
@@ -58,7 +66,7 @@
   if gitFound
     then do
       -- a lot of bookkeeping to record the right dependencies
-      pwd <- runIO getGitDirectory
+      pwd <- runIO getDotGit
       let hd         = pwd </> ".git" </> "HEAD"
           index      = pwd </> ".git" </> "index"
           packedRefs = pwd </> ".git" </> "packed-refs"
@@ -89,11 +97,11 @@
           ExitFailure _ -> return def
     else return def
 
--- | Determine where our git directory is, in case we're in a
+-- | Determine where our @.git@ directory is, in case we're in a
 -- submodule.
-getGitDirectory :: IO FilePath
-getGitDirectory = do
-  pwd <- getCurrentDirectory
+getDotGit :: IO FilePath
+getDotGit = do
+  pwd <- getGitRoot
   let dotGit = pwd </> ".git"
       oops = return dotGit -- it's gonna fail, that's fine
   isDir <- doesDirectoryExist dotGit
@@ -109,6 +117,16 @@
                else oops
            _ -> oops
 
+-- | Get the root directory of the Git repo.
+getGitRoot :: IO FilePath
+getGitRoot = do
+  pwd <- getCurrentDirectory
+  (code, out, _) <-
+    readProcessWithExitCode "git" ["rev-parse", "--show-toplevel"] ""
+  case code of
+    ExitSuccess   -> return $ takeWhile (/= '\n') out
+    ExitFailure _ -> return pwd -- later steps will fail, that's fine
+
 -- | Type to flag if the git index is used or not in a call to runGit
 data IndexUsed = IdxUsed -- ^ The git index is used
                | IdxNotUsed -- ^ The git index is /not/ used
@@ -127,11 +145,26 @@
 gitBranch =
   stringE =<< runGit ["rev-parse", "--abbrev-ref", "HEAD"] "UNKNOWN" IdxNotUsed
 
+-- | Return the long git description for the current git commit, or
+-- @UNKNOWN@ if not in a git repository.
+gitDescribe :: ExpQ
+gitDescribe =
+  stringE =<< runGit ["describe", "--long", "--always"] "UNKNOWN" IdxNotUsed
+
 -- | Return @True@ if there are non-committed files present in the
 -- repository
 gitDirty :: ExpQ
 gitDirty = do
   output <- runGit ["status", "--porcelain"] "" IdxUsed
+  case output of
+    "" -> conE falseName
+    _  -> conE trueName
+
+-- | Return @True@ if there are non-commited changes to tracked files
+-- present in the repository
+gitDirtyTracked :: ExpQ
+gitDirtyTracked = do
+  output <- runGit ["status", "--porcelain","--untracked-files=no"] "" IdxUsed
   case output of
     "" -> conE falseName
     _  -> conE trueName
