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();