Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / diffusion / query / lowlevel / DiffusionLowLevelFilesizeQuery.php
blob89840037116a41cb337a7eeec42bb4ae2f0a15bd
1 <?php
3 final class DiffusionLowLevelFilesizeQuery
4 extends DiffusionLowLevelQuery {
6 private $identifier;
8 public function withIdentifier($identifier) {
9 $this->identifier = $identifier;
10 return $this;
13 protected function executeQuery() {
14 if (!strlen($this->identifier)) {
15 throw new PhutilInvalidStateException('withIdentifier');
18 $type = $this->getRepository()->getVersionControlSystem();
19 switch ($type) {
20 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
21 $result = $this->loadGitFilesizes();
22 break;
23 default:
24 throw new Exception(pht('Unsupported repository type "%s"!', $type));
27 return $result;
30 private function loadGitFilesizes() {
31 $repository = $this->getRepository();
32 $identifier = $this->identifier;
34 $paths_future = $repository->getLocalCommandFuture(
35 'diff-tree -z -r --no-commit-id %s --',
36 gitsprintf('%s', $identifier));
38 // With "-z" we get "<fields>\0<filename>\0" for each line. Process the
39 // delimited text as "<fields>, <filename>" pairs.
41 $path_lines = id(new LinesOfALargeExecFuture($paths_future))
42 ->setDelimiter("\0");
44 $paths = array();
46 $path_pairs = new PhutilChunkedIterator($path_lines, 2);
47 foreach ($path_pairs as $path_pair) {
48 if (count($path_pair) != 2) {
49 throw new Exception(
50 pht(
51 'Unexpected number of output lines from "git diff-tree" when '.
52 'processing commit ("%s"): expected an even number of lines.',
53 $identifier));
56 list($fields, $pathname) = array_values($path_pair);
57 $fields = explode(' ', $fields);
59 // Fields are:
61 // :100644 100644 aaaa bbbb M
63 // [0] Old file mode.
64 // [1] New file mode.
65 // [2] Old object hash.
66 // [3] New object hash.
67 // [4] Change mode.
69 $paths[] = array(
70 'path' => $pathname,
71 'newHash' => $fields[3],
75 $path_sizes = array();
77 if (!$paths) {
78 return $path_sizes;
81 $check_paths = array();
82 foreach ($paths as $path) {
83 if ($path['newHash'] === DiffusionCommitHookEngine::EMPTY_HASH) {
84 $path_sizes[$path['path']] = 0;
85 continue;
87 $check_paths[$path['newHash']][] = $path['path'];
90 if (!$check_paths) {
91 return $path_sizes;
94 $future = $repository->getLocalCommandFuture(
95 'cat-file --batch-check=%s',
96 '%(objectsize)');
98 $future->write(implode("\n", array_keys($check_paths)));
100 $size_lines = id(new LinesOfALargeExecFuture($future))
101 ->setDelimiter("\n");
102 foreach ($size_lines as $line) {
103 $object_size = (int)$line;
105 $object_hash = head_key($check_paths);
106 $path_names = $check_paths[$object_hash];
107 unset($check_paths[$object_hash]);
109 foreach ($path_names as $path_name) {
110 $path_sizes[$path_name] = $object_size;
114 if ($check_paths) {
115 throw new Exception(
116 pht(
117 'Unexpected number of output lines from "git cat-file" when '.
118 'processing commit ("%s").',
119 $identifier));
122 return $path_sizes;