Differential D21510 Diff 51199 src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | protected function getGitResult(ConduitAPIRequest $request) { | ||||
if ($path == '') { | if ($path == '') { | ||||
// Fast path to improve the performance of the repository view; we know | // Fast path to improve the performance of the repository view; we know | ||||
// the root is always a tree at any commit and always exists. | // the root is always a tree at any commit and always exists. | ||||
$stdout = 'tree'; | $stdout = 'tree'; | ||||
} else { | } else { | ||||
try { | try { | ||||
list($stdout) = $repository->execxLocalCommand( | list($stdout) = $repository->execxLocalCommand( | ||||
'cat-file -t %s:%s', | 'cat-file -t -- %s:%s', | ||||
$commit, | $commit, | ||||
$path); | $path); | ||||
} catch (CommandException $e) { | } catch (CommandException $e) { | ||||
// The "cat-file" command may fail if the path legitimately does not | // The "cat-file" command may fail if the path legitimately does not | ||||
// exist, but it may also fail if the path is a submodule. This can | // exist, but it may also fail if the path is a submodule. This can | ||||
// produce either "Not a valid object name" or "could not get object | // produce either "Not a valid object name" or "could not get object | ||||
// info". | // info". | ||||
// To detect if we have a submodule, use `git ls-tree`. If the path | // To detect if we have a submodule, use `git ls-tree`. If the path | ||||
// is a submodule, we'll get a "160000" mode mask with type "commit". | // is a submodule, we'll get a "160000" mode mask with type "commit". | ||||
list($sub_err, $sub_stdout) = $repository->execLocalCommand( | list($sub_err, $sub_stdout) = $repository->execLocalCommand( | ||||
'ls-tree %s -- %s', | 'ls-tree %s -- %s', | ||||
$commit, | gitsprintf('%s', $commit), | ||||
$path); | $path); | ||||
if (!$sub_err) { | if (!$sub_err) { | ||||
// If the path failed "cat-file" but "ls-tree" worked, we assume it | // If the path failed "cat-file" but "ls-tree" worked, we assume it | ||||
// must be a submodule. If it is, the output will look something | // must be a submodule. If it is, the output will look something | ||||
// like this: | // like this: | ||||
// | // | ||||
// 160000 commit <hash> <path> | // 160000 commit <hash> <path> | ||||
// | // | ||||
// We make sure it has the 160000 mode mask to confirm that it's | // We make sure it has the 160000 mode mask to confirm that it's | ||||
// definitely a submodule. | // definitely a submodule. | ||||
$mode = (int)$sub_stdout; | $mode = (int)$sub_stdout; | ||||
if ($mode & 160000) { | if ($mode & 160000) { | ||||
$submodule_reason = DiffusionBrowseResultSet::REASON_IS_SUBMODULE; | $submodule_reason = DiffusionBrowseResultSet::REASON_IS_SUBMODULE; | ||||
$result | $result | ||||
->setReasonForEmptyResultSet($submodule_reason); | ->setReasonForEmptyResultSet($submodule_reason); | ||||
return $result; | return $result; | ||||
} | } | ||||
} | } | ||||
$stderr = $e->getStderr(); | $stderr = $e->getStderr(); | ||||
if (preg_match('/^fatal: Not a valid object name/', $stderr)) { | if (preg_match('/^fatal: Not a valid object name/', $stderr)) { | ||||
// Grab two logs, since the first one is when the object was deleted. | // Grab two logs, since the first one is when the object was deleted. | ||||
list($stdout) = $repository->execxLocalCommand( | list($stdout) = $repository->execxLocalCommand( | ||||
'log -n2 --format="%%H" %s -- %s', | 'log -n2 %s %s -- %s', | ||||
$commit, | '--format=%H', | ||||
gitsprintf('%s', $commit), | |||||
$path); | $path); | ||||
$stdout = trim($stdout); | $stdout = trim($stdout); | ||||
if ($stdout) { | if ($stdout) { | ||||
$commits = explode("\n", $stdout); | $commits = explode("\n", $stdout); | ||||
$result | $result | ||||
->setReasonForEmptyResultSet( | ->setReasonForEmptyResultSet( | ||||
DiffusionBrowseResultSet::REASON_IS_DELETED) | DiffusionBrowseResultSet::REASON_IS_DELETED) | ||||
->setDeletedAtCommit(idx($commits, 0)) | ->setDeletedAtCommit(idx($commits, 0)) | ||||
Show All 17 Lines | protected function getGitResult(ConduitAPIRequest $request) { | ||||
} | } | ||||
$result->setIsValidResults(true); | $result->setIsValidResults(true); | ||||
if ($this->shouldOnlyTestValidity($request)) { | if ($this->shouldOnlyTestValidity($request)) { | ||||
return $result; | return $result; | ||||
} | } | ||||
list($stdout) = $repository->execxLocalCommand( | list($stdout) = $repository->execxLocalCommand( | ||||
'ls-tree -z -l %s:%s', | 'ls-tree -z -l %s -- %s', | ||||
$commit, | gitsprintf('%s', $commit), | ||||
$path); | $path); | ||||
$submodules = array(); | $submodules = array(); | ||||
if (strlen($path)) { | if (strlen($path)) { | ||||
$prefix = rtrim($path, '/').'/'; | $prefix = rtrim($path, '/').'/'; | ||||
} else { | } else { | ||||
$prefix = ''; | $prefix = ''; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | if ($submodules) { | ||||
// NOTE: This file may not exist, e.g. because the commit author removed | // NOTE: This file may not exist, e.g. because the commit author removed | ||||
// it when they added the submodule. See T1448. If it's not present, just | // it when they added the submodule. See T1448. If it's not present, just | ||||
// show the submodule without enriching it. If ".gitmodules" was removed | // show the submodule without enriching it. If ".gitmodules" was removed | ||||
// it seems to partially break submodules, but the repository as a whole | // it seems to partially break submodules, but the repository as a whole | ||||
// continues to work fine and we've seen at least two cases of this in | // continues to work fine and we've seen at least two cases of this in | ||||
// the wild. | // the wild. | ||||
list($err, $contents) = $repository->execLocalCommand( | list($err, $contents) = $repository->execLocalCommand( | ||||
'cat-file blob %s:.gitmodules', | 'cat-file blob -- %s:.gitmodules', | ||||
$commit); | $commit); | ||||
if (!$err) { | if (!$err) { | ||||
$tmp = new TempFile(); | $tmp = new TempFile(); | ||||
Filesystem::writeFile($tmp, $contents); | Filesystem::writeFile($tmp, $contents); | ||||
list($module_info) = $repository->execxLocalCommand( | list($module_info) = $repository->execxLocalCommand( | ||||
'config -l -f %s', | 'config -l -f %s', | ||||
$tmp); | $tmp); | ||||
▲ Show 20 Lines • Show All 330 Lines • Show Last 20 Lines |