diff --git a/src/filesystem/binary/PhutilMercurialBinaryAnalyzer.php b/src/filesystem/binary/PhutilMercurialBinaryAnalyzer.php
--- a/src/filesystem/binary/PhutilMercurialBinaryAnalyzer.php
+++ b/src/filesystem/binary/PhutilMercurialBinaryAnalyzer.php
@@ -7,6 +7,7 @@
 
   const CAPABILITY_FILES = 'files';
   const CAPABILITY_INJECTION = 'injection';
+  const CAPABILITY_TEMPLATE_PNODE = 'template_pnode';
 
   protected function newBinaryVersion() {
     $future = id(new ExecFuture('hg --version --quiet'))
@@ -60,6 +61,19 @@
       self::CAPABILITY_INJECTION);
   }
 
+  /**
+   * When using `--template` the format for accessing individual parents
+   * changed from `{p1node}` to `{p1.node}` in Mercurial 4.9.
+   *
+   * @return boolean  True if the versino of Mercurial is new enough to support
+   *   the `{p1.node} format in templates, or false if otherwise.
+   */
+  public function isMercurialTemplatePnodeAvailable() {
+    return self::versionHasCapability(
+      $this->requireBinaryVersion(),
+      self::CAPABILITY_TEMPLATE_PNODE);
+  }
+
 
   public static function versionHasCapability(
     $mercurial_version,
@@ -70,6 +84,8 @@
         return version_compare($mercurial_version, '3.2', '>=');
       case self::CAPABILITY_INJECTION:
         return version_compare($mercurial_version, '3.2.4', '<');
+      case self::CAPABILITY_TEMPLATE_PNODE:
+        return version_compare($mercurial_version, '4.9', '>=');
       default:
         throw new Exception(
           pht(