diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -607,6 +607,7 @@ 'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php', 'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php', 'DiffusionLowLevelMercurialPathsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php', + 'DiffusionLowLevelMercurialPathsQueryTests' => 'applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php', 'DiffusionLowLevelParentsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php', 'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php', 'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php', @@ -4340,6 +4341,7 @@ 'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery', + 'DiffusionLowLevelMercurialPathsQueryTests' => 'PhabricatorTestCase', 'DiffusionLowLevelParentsQuery' => 'DiffusionLowLevelQuery', 'DiffusionLowLevelQuery' => 'Phobject', 'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery', diff --git a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php --- a/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php +++ b/src/applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php @@ -24,13 +24,41 @@ $path = $this->path; $commit = $this->commit; + $hg_version = PhabricatorRepositoryVersion::getMercurialVersion(); + $hg_paths_command = $this->getMercurialPathsCommand($hg_version); + $match_against = trim($path, '/'); $prefix = trim('./'.$match_against, '/'); list($entire_manifest) = $repository->execxLocalCommand( - 'locate --print0 --rev %s -I %s', + $hg_paths_command, hgsprintf('%s', $commit), $prefix); return explode("\0", $entire_manifest); } + /** The `locate` command is deprecated as of Mercurial 3.2, to be + * replaced with `files` command, which supports most of the same + * arguments. This returns the correct command to use based on the + * version of Mercurial in use. The returned value is expected to + * be used directly by PhabricatorRepository::execxLocalCommand with + * two arguments. + * + * @param string $hg_version - The current version of mercurial + * which can be retrieved by calling: + * PhabricatorRepositoryVersion::getMercurialVersion() + * + * @return string The mercurial command & arguments to be used in + * order to retrieve paths of tracked files. The returned string + * is formatted with two '%s' to supply argument values. The first + * is the revision argument ('--rev') and the second is the include + * file pattern ('-I'). + */ + public function getMercurialPathsCommand($hg_version) { + $min_version_for_files = '3.2'; + if (version_compare($hg_version, $min_version_for_files, '>=')) { + return 'files --print0 --rev %s -I %s'; + } + return 'locate --print0 --rev %s -I %s'; + } + } diff --git a/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php b/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php new file mode 100644 --- /dev/null +++ b/src/applications/diffusion/query/lowlevel/__tests__/DiffusionLowLevelMercurialPathsQueryTests.php @@ -0,0 +1,31 @@ + pht('Versions which should use `locate`'), + 'versions' => array('2.6.2', '2.9', '3.1'), + 'match' => 'locate', + ), + + array( + 'name' => pht('Versions which should use `files`'), + 'versions' => array('3.2', '3.3', '3.5.2'), + 'match' => 'files', + ), + ); + + foreach ($cases as $case) { + $query = new DiffusionLowLevelMercurialPathsQuery(); + foreach ($case['versions'] as $version) { + $actual = $query->getMercurialPathsCommand($version); + $expect = preg_match('/^'.$case['match'].'/', $actual); + $this->assertEqual($expect, 1, $case['name']); + } + } + } + +}