diff --git a/src/parser/ArcanistBundle.php b/src/parser/ArcanistBundle.php
--- a/src/parser/ArcanistBundle.php
+++ b/src/parser/ArcanistBundle.php
@@ -15,6 +15,8 @@
   private $loadFileDataCallback;
   private $authorName;
   private $authorEmail;
+  private $subject;
+  private $dateString;
   private $byteLimit;
   private $reservedBytes;
 
@@ -59,6 +61,25 @@
     return $full_author;
   }
 
+  public function setSubject($subject) {
+    $this->subject = $subject;
+    return $this;
+  }
+
+  public function getSubject() {
+    return $this->subject;
+  }
+
+  public function setDateString($date_string) {
+    $this->dateString = $date_string;
+    return $this;
+  }
+
+  public function getDateString() {
+    return $this->dateString;
+  }
+
+
   public function setConduit(ConduitClient $conduit) {
     $this->conduit = $conduit;
     return $this;
@@ -318,6 +339,8 @@
     $result = array();
     $changes = $this->getChanges();
 
+    $result[] = $this->buildGitPatchHeader();
+
     $binary_sources = array();
     foreach ($changes as $change) {
       if (!$this->isGitBinaryChange($change)) {
@@ -484,6 +507,37 @@
     return $this->convertNonUTF8Diff($diff);
   }
 
+  private function buildGitPatchHeader() {
+    $header = array();
+
+    // Not using pht() here, because this is is read by a machine (git am).
+
+    if ($this->getFullAuthor() !== null) {
+      $header[] = 'From: '.$this->getFullAuthor();
+    }
+
+    if (phutil_nonempty_string($this->getDateString())) {
+      $header[] = 'Date: '.$this->getDateString();
+    }
+
+    if (phutil_nonempty_string($this->getSubject())) {
+      $header[] = 'Subject: '.$this->getSubject();
+    }
+
+    if (!$header) {
+      return null;
+    }
+
+    $eol = $this->getEOL('git');
+    foreach ($header as $i => $value) {
+      // minimal sanitation
+      $header[$i] = str_replace($eol, ' ', $value);
+    }
+
+    $header[] = $eol;
+    return implode($eol, $header);
+  }
+
   private function isGitBinaryChange(ArcanistDiffChange $change) {
     $file_type = $change->getFileType();
     return ($file_type == ArcanistDiffChangeType::FILE_BINARY ||
@@ -762,26 +816,26 @@
       $old_data = $this->getBlob($old_phid, $name);
     }
 
-    $old_length = strlen($old_data);
-
-    // Here, and below, the binary will be emitted with base85 encoding. This
-    // encoding encodes each 4 bytes of input in 5 bytes of output, so we may
-    // need up to 5/4ths as many bytes to represent it.
-
-    // We reserve space up front because base85 encoding isn't super cheap. If
-    // the blob is enormous, we'd rather just bail out now before doing a ton
-    // of work and then throwing it away anyway.
-
-    // However, the data is compressed before it is emitted so we may actually
-    // end up using fewer bytes. For now, the allocator just assumes the worst
-    // case since it isn't important to be precise, but we could do a more
-    // exact job of this.
-    $this->reserveBytes($old_length * 5 / 4);
-
     if ($old_data === null) {
+      $old_length = 0;
       $old_data = '';
       $old_sha1 = str_repeat('0', 40);
     } else {
+      $old_length = strlen($old_data);
+
+      // Here, and below, the binary will be emitted with base85 encoding. This
+      // encoding encodes each 4 bytes of input in 5 bytes of output, so we may
+      // need up to 5/4ths as many bytes to represent it.
+
+      // We reserve space up front because base85 encoding isn't super cheap. If
+      // the blob is enormous, we'd rather just bail out now before doing a ton
+      // of work and then throwing it away anyway.
+
+      // However, the data is compressed before it is emitted so we may actually
+      // end up using fewer bytes. For now, the allocator just assumes the worst
+      // case since it isn't important to be precise, but we could do a more
+      // exact job of this.
+      $this->reserveBytes($old_length * 5 / 4);
       $old_sha1 = sha1("blob {$old_length}\0{$old_data}");
     }
 
@@ -795,13 +849,13 @@
       $new_data = $this->getBlob($new_phid, $name);
     }
 
-    $new_length = strlen($new_data);
-    $this->reserveBytes($new_length * 5 / 4);
-
     if ($new_data === null) {
+      $new_length = 0;
       $new_data = '';
       $new_sha1 = str_repeat('0', 40);
     } else {
+      $new_length = strlen($new_data);
+      $this->reserveBytes($new_length * 5 / 4);
       $new_sha1 = sha1("blob {$new_length}\0{$new_data}");
     }
 
diff --git a/src/workflow/ArcanistExportWorkflow.php b/src/workflow/ArcanistExportWorkflow.php
--- a/src/workflow/ArcanistExportWorkflow.php
+++ b/src/workflow/ArcanistExportWorkflow.php
@@ -203,7 +203,7 @@
 
           $author = sprintf('%s <%s>',
             $author_dict['realName'],
-            $email);
+            trim($email));
         } else if ($repository_api instanceof ArcanistMercurialAPI) {
           $this->parseBaseCommitArgument($this->getArgument('paths'));
           $diff = $repository_api->getFullMercurialDiff();