Differential D21027 Diff 50092 src/applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php
Show All 35 Lines | protected function executeQuery() { | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
private function loadGitCommitRef() { | private function loadGitCommitRef() { | ||||
$repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
// NOTE: %B was introduced somewhat recently in git's history, so pull | // See T5028. The "%B" (raw body) mode is not present in very old versions | ||||
// commit message information with %s and %b instead. | // of Git. Use "%s" and "%b" ("subject" and "wrapped body") as an | ||||
// approximation. | |||||
$git_binary = PhutilBinaryAnalyzer::getForBinary('git'); | |||||
$git_version = $git_binary->getBinaryVersion(); | |||||
if (version_compare($git_version, '1.7.2', '>=')) { | |||||
$body_format = '%B'; | |||||
$split_body = false; | |||||
} else { | |||||
$body_format = '%s%x00%b'; | |||||
$split_body = true; | |||||
} | |||||
// Even though we pass --encoding here, git doesn't always succeed, so | // Even though we pass --encoding here, git doesn't always succeed, so | ||||
// we try a little harder, since git *does* tell us what the actual encoding | // we try a little harder, since git *does* tell us what the actual encoding | ||||
// is correctly (unless it doesn't; encoding is sometimes empty). | // is correctly (unless it doesn't; encoding is sometimes empty). | ||||
list($info) = $repository->execxLocalCommand( | list($info) = $repository->execxLocalCommand( | ||||
'log -n 1 --encoding=%s --format=%s %s --', | 'log -n 1 --encoding=%s --format=%s %s --', | ||||
'UTF-8', | 'UTF-8', | ||||
implode( | implode( | ||||
'%x00', | '%x00', | ||||
array('%e', '%cn', '%ce', '%an', '%ae', '%T', '%at', '%s%n%n%b')), | array( | ||||
'%e', | |||||
'%cn', | |||||
'%ce', | |||||
'%an', | |||||
'%ae', | |||||
'%T', | |||||
'%at', | |||||
$body_format, | |||||
// The "git log" output includes a trailing newline. We want to | |||||
// faithfully capture only the exact text of the commit message, | |||||
// so include an explicit terminator: this makes sure the exact | |||||
// body text is surrounded by "\0" characters. | |||||
'~', | |||||
)), | |||||
$this->identifier); | $this->identifier); | ||||
$parts = explode("\0", $info); | $parts = explode("\0", $info); | ||||
$encoding = array_shift($parts); | $encoding = array_shift($parts); | ||||
foreach ($parts as $key => $part) { | foreach ($parts as $key => $part) { | ||||
if ($encoding) { | if ($encoding) { | ||||
$part = phutil_utf8_convert($part, 'UTF-8', $encoding); | $part = phutil_utf8_convert($part, 'UTF-8', $encoding); | ||||
Show All 13 Lines | $hashes = array( | ||||
->setHashValue($parts[4]), | ->setHashValue($parts[4]), | ||||
); | ); | ||||
$author_epoch = (int)$parts[5]; | $author_epoch = (int)$parts[5]; | ||||
if (!$author_epoch) { | if (!$author_epoch) { | ||||
$author_epoch = null; | $author_epoch = null; | ||||
} | } | ||||
if ($split_body) { | |||||
// Here, the body is: "subject", "\0", "wrapped body". Stitch the | |||||
// pieces back together by putting a newline between them if both | |||||
// parts are nonempty. | |||||
$head = $parts[6]; | |||||
$tail = $parts[7]; | |||||
if (strlen($head) && strlen($tail)) { | |||||
$body = $head."\n\n".$tail; | |||||
} else if (strlen($head)) { | |||||
$body = $head; | |||||
} else if (strlen($tail)) { | |||||
$body = $tail; | |||||
} else { | |||||
$body = ''; | |||||
} | |||||
} else { | |||||
// Here, the body is the raw unwrapped body. | |||||
$body = $parts[6]; | |||||
} | |||||
return id(new DiffusionCommitRef()) | return id(new DiffusionCommitRef()) | ||||
->setCommitterName($parts[0]) | ->setCommitterName($parts[0]) | ||||
->setCommitterEmail($parts[1]) | ->setCommitterEmail($parts[1]) | ||||
->setAuthorName($parts[2]) | ->setAuthorName($parts[2]) | ||||
->setAuthorEmail($parts[3]) | ->setAuthorEmail($parts[3]) | ||||
->setHashes($hashes) | ->setHashes($hashes) | ||||
->setAuthorEpoch($author_epoch) | ->setAuthorEpoch($author_epoch) | ||||
->setMessage($parts[6]); | ->setMessage($body); | ||||
} | } | ||||
private function loadMercurialCommitRef() { | private function loadMercurialCommitRef() { | ||||
$repository = $this->getRepository(); | $repository = $this->getRepository(); | ||||
list($stdout) = $repository->execxLocalCommand( | list($stdout) = $repository->execxLocalCommand( | ||||
'log --template %s --rev %s', | 'log --template %s --rev %s', | ||||
'{author}\\n{desc}', | '{author}\\n{desc}', | ||||
▲ Show 20 Lines • Show All 65 Lines • Show Last 20 Lines |