Differential D21510 Diff 51196 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 | |||||