@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Further correct and disambigutate ref selectors passed to Git on the CLI

Summary:
Ref T13589. In D21510, not every ref selector got touched, and this isn't a valid construction in Git:

```
$ git ls-tree ... -- ''
```

Thus:

- Disambiguate more (all?) ref selectors.
- Correct the construction of "git ls-tree" when there is no path.
- Clean some stuff up: make the construction of some flags and arguments more explicit, get rid of a needless "%C", prefer "%Ls" over acrobatics, etc.

Test Plan: Browsed/updated a local Git repository. (This change is somewhat difficult to test exhaustively, as evidenced by the "ls-tree" issue in D21510.)

Maniphest Tasks: T13589

Differential Revision: https://secure.phabricator.com/D21511

+103 -67
+21 -11
src/applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php
··· 35 35 protected function getGitResult(ConduitAPIRequest $request) { 36 36 $drequest = $this->getDiffusionRequest(); 37 37 $repository = $drequest->getRepository(); 38 + 38 39 $path = $request->getValue('path'); 40 + if (!strlen($path)) { 41 + $path = null; 42 + } 43 + 39 44 $commit = $request->getValue('commit'); 40 45 $offset = (int)$request->getValue('offset'); 41 46 $limit = (int)$request->getValue('limit'); 42 47 $result = $this->getEmptyResultSet(); 43 48 44 - if ($path == '') { 49 + if ($path === null) { 45 50 // Fast path to improve the performance of the repository view; we know 46 51 // the root is always a tree at any commit and always exists. 47 52 $stdout = 'tree'; 48 53 } else { 49 54 try { 50 55 list($stdout) = $repository->execxLocalCommand( 51 - 'cat-file -t -- %s:%s', 52 - $commit, 53 - $path); 56 + 'cat-file -t -- %s', 57 + sprintf('%s:%s', $commit, $path)); 54 58 } catch (CommandException $e) { 55 59 // The "cat-file" command may fail if the path legitimately does not 56 60 // exist, but it may also fail if the path is a submodule. This can ··· 121 125 return $result; 122 126 } 123 127 124 - list($stdout) = $repository->execxLocalCommand( 125 - 'ls-tree -z -l %s -- %s', 126 - gitsprintf('%s', $commit), 127 - $path); 128 + if ($path === null) { 129 + list($stdout) = $repository->execxLocalCommand( 130 + 'ls-tree -z -l %s --', 131 + gitsprintf('%s', $commit)); 132 + } else { 133 + list($stdout) = $repository->execxLocalCommand( 134 + 'ls-tree -z -l %s -- %s', 135 + gitsprintf('%s', $commit), 136 + $path); 137 + } 128 138 129 139 $submodules = array(); 130 140 131 - if (strlen($path)) { 141 + if ($path !== null) { 132 142 $prefix = rtrim($path, '/').'/'; 133 143 } else { 134 144 $prefix = ''; ··· 226 236 $dict[$key] = $value; 227 237 } 228 238 229 - foreach ($submodules as $path) { 230 - $full_path = $path->getFullPath(); 239 + foreach ($submodules as $submodule_path) { 240 + $full_path = $submodule_path->getFullPath(); 231 241 $key = 'submodule.'.$full_path.'.url'; 232 242 if (isset($dict[$key])) { 233 243 $path->setExternalURI($dict[$key]);
+25 -11
src/applications/diffusion/conduit/DiffusionHistoryQueryConduitAPIMethod.php
··· 45 45 $repository = $drequest->getRepository(); 46 46 $commit_hash = $request->getValue('commit'); 47 47 $against_hash = $request->getValue('against'); 48 + 48 49 $path = $request->getValue('path'); 50 + if (!strlen($path)) { 51 + $path = null; 52 + } 53 + 49 54 $offset = $request->getValue('offset'); 50 55 $limit = $request->getValue('limit'); 51 56 ··· 55 60 $commit_range = $commit_hash; 56 61 } 57 62 63 + $argv = array(); 64 + 65 + $argv[] = '--skip'; 66 + $argv[] = $offset; 67 + 68 + $argv[] = '--max-count'; 69 + $argv[] = $limit; 70 + 71 + $argv[] = '--format=%H:%P'; 72 + 73 + $argv[] = gitsprintf('%s', $commit_range); 74 + 75 + $argv[] = '--'; 76 + 77 + if ($path !== null) { 78 + $argv[] = $path; 79 + } 80 + 58 81 list($stdout) = $repository->execxLocalCommand( 59 - 'log '. 60 - '--skip=%d '. 61 - '-n %d '. 62 - '--pretty=format:%s '. 63 - '%s -- %C', 64 - $offset, 65 - $limit, 66 - '%H:%P', 67 - gitsprintf('%s', $commit_range), 68 - // Git omits merge commits if the path is provided, even if it is empty. 69 - (strlen($path) ? csprintf('%s', $path) : '')); 82 + 'log %Ls', 83 + $argv); 70 84 71 85 $lines = explode("\n", trim($stdout)); 72 86 $lines = array_filter($lines);
+8 -8
src/applications/diffusion/conduit/DiffusionInternalGitRawDiffQueryConduitAPIMethod.php
··· 43 43 // it requires the commit to have a parent that we can diff against. The 44 44 // first commit doesn't, so "commit^" is not a valid ref. 45 45 list($parents) = $repository->execxLocalCommand( 46 - 'log -n1 --format=%s %s', 47 - '%P', 48 - $commit); 46 + 'log -n1 %s %s --', 47 + '--format=%P', 48 + gitsprintf('%s', $commit)); 49 49 $use_log = !strlen(trim($parents)); 50 50 51 51 // First, get a fast raw diff without "--find-copies-harder". This flag ··· 96 96 // NOTE: "--pretty=format: " is to disable diff output, we only want the 97 97 // part we get from "--raw". 98 98 $future = $repository->getLocalCommandFuture( 99 - 'log %Ls --pretty=format: %s', 99 + 'log %Ls --pretty=format: %s --', 100 100 $flags, 101 - $commit); 101 + gitsprintf('%s', $commit)); 102 102 } else { 103 103 // Otherwise, we can use "diff", which will give us output for merges. 104 104 // We diff against the first parent, as this is generally the expectation 105 105 // and results in sensible behavior. 106 106 $future = $repository->getLocalCommandFuture( 107 - 'diff %Ls %s^1 %s', 107 + 'diff %Ls %s %s --', 108 108 $flags, 109 - $commit, 110 - $commit); 109 + gitsprintf('%s^1', $commit), 110 + gitsprintf('%s', $commit)); 111 111 } 112 112 113 113 // Don't spend more than 30 seconds generating the slower output.
+2 -1
src/applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php
··· 33 33 continue; 34 34 } 35 35 list($hash) = $repository->execxLocalCommand( 36 - 'log -n1 --format=%%H %s -- %s', 36 + 'log -n1 %s %s -- %s', 37 + '--format=%H', 37 38 gitsprintf('%s', $commit), 38 39 $path); 39 40 $results[$path] = trim($hash);
+4 -4
src/applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php
··· 35 35 $limit = $this->getLimit($request); 36 36 37 37 list($parents) = $repository->execxLocalCommand( 38 - 'log -n 1 --format=%s %s --', 39 - '%P', 38 + 'log -n 1 %s %s --', 39 + '--format=%P', 40 40 gitsprintf('%s', $commit)); 41 41 42 42 $parents = preg_split('/\s+/', trim($parents)); ··· 50 50 51 51 $first_parent = head($parents); 52 52 list($logs) = $repository->execxLocalCommand( 53 - 'log -n %d --format=%s %s %s --', 53 + 'log -n %d %s %s %s --', 54 54 // NOTE: "+ 1" accounts for the merge commit itself. 55 55 $limit + 1, 56 - '%H', 56 + '--format=%H', 57 57 gitsprintf('%s', $commit), 58 58 gitsprintf('%s', '^'.$first_parent)); 59 59
+3 -3
src/applications/diffusion/conduit/DiffusionRefsQueryConduitAPIMethod.php
··· 28 28 $commit = $request->getValue('commit'); 29 29 30 30 list($stdout) = $repository->execxLocalCommand( 31 - 'log --format=%s -n 1 %s --', 32 - '%d', 33 - $commit); 31 + 'log -n 1 %s %s --', 32 + '--format=%d', 33 + gitsprintf('%s', $commit)); 34 34 35 35 // %d, gives a weird output format 36 36 // similar to (remote/one, remote/two, remote/three)
+3 -3
src/applications/diffusion/engine/DiffusionCommitHookEngine.php
··· 608 608 // repository. Particularly, this will cover the cases of a new branch, a 609 609 // completely moved tag, etc. 610 610 $futures[$key] = $this->getRepository()->getLocalCommandFuture( 611 - 'log --format=%s %s --not --all', 612 - '%H', 613 - $ref_update->getRefNew()); 611 + 'log %s %s --not --all --', 612 + '--format=%H', 613 + gitsprintf('%s', $ref_update->getRefNew())); 614 614 } 615 615 616 616 $content_updates = array();
+2 -3
src/applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php
··· 10 10 $commit = $drequest->getCommit(); 11 11 12 12 return $repository->getLocalCommandFuture( 13 - 'cat-file blob -- %s:%s', 14 - $commit, 15 - $path); 13 + 'cat-file blob -- %s', 14 + sprintf('%s:%s', $commit, $path)); 16 15 } 17 16 18 17 }
+18 -8
src/applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php
··· 55 55 $split_body = true; 56 56 } 57 57 58 - // Even though we pass --encoding here, git doesn't always succeed, so 59 - // we try a little harder, since git *does* tell us what the actual encoding 60 - // is correctly (unless it doesn't; encoding is sometimes empty). 61 - list($info) = $repository->execxLocalCommand( 62 - 'log -n 1 --encoding=%s --format=%s %s --', 63 - 'UTF-8', 58 + $argv = array(); 59 + 60 + $argv[] = '-n'; 61 + $argv[] = '1'; 62 + 63 + $argv[] = '--encoding=UTF-8'; 64 + 65 + $argv[] = sprintf( 66 + '--format=%s', 64 67 implode( 65 68 '%x00', 66 69 array( ··· 78 81 // so include an explicit terminator: this makes sure the exact 79 82 // body text is surrounded by "\0" characters. 80 83 '~', 81 - )), 82 - $this->identifier); 84 + ))); 85 + 86 + // Even though we pass --encoding here, git doesn't always succeed, so 87 + // we try a little harder, since git *does* tell us what the actual encoding 88 + // is correctly (unless it doesn't; encoding is sometimes empty). 89 + list($info) = $repository->execxLocalCommand( 90 + 'log -n 1 %Ls %s --', 91 + $argv, 92 + gitsprintf('%s', $this->identifier)); 83 93 84 94 $parts = explode("\0", $info); 85 95 $encoding = array_shift($parts);
+1 -1
src/applications/diffusion/query/lowlevel/DiffusionLowLevelFilesizeQuery.php
··· 33 33 34 34 $paths_future = $repository->getLocalCommandFuture( 35 35 'diff-tree -z -r --no-commit-id %s --', 36 - $identifier); 36 + gitsprintf('%s', $identifier)); 37 37 38 38 // With "-z" we get "<fields>\0<filename>\0" for each line. Process the 39 39 // delimited text as "<fields>, <filename>" pairs.
+2 -2
src/applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php
··· 37 37 $repository = $this->getRepository(); 38 38 39 39 list($stdout) = $repository->execxLocalCommand( 40 - 'log -n 1 --format=%s %s --', 41 - '%P', 40 + 'log -n 1 %s %s --', 41 + '--format=%P', 42 42 gitsprintf('%s', $this->identifier)); 43 43 44 44 return preg_split('/\s+/', trim($stdout));
+2 -2
src/applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php
··· 23 23 // Check if this is the root commit by seeing if it has parents, since 24 24 // `git diff X^ X` does not work if "X" is the initial commit. 25 25 list($parents) = $repository->execxLocalCommand( 26 - 'log -n 1 --format=%s %s --', 27 - '%P', 26 + 'log -n 1 %s --', 27 + '--format=%P', 28 28 gitsprintf('%s', $commit)); 29 29 30 30 if (strlen(trim($parents))) {
+5 -5
src/applications/repository/daemon/PhabricatorGitGraphStream.php
··· 19 19 20 20 if ($start_commit !== null) { 21 21 $future = $repository->getLocalCommandFuture( 22 - 'log --format=%s %s --', 23 - '%H%x01%P%x01%ct', 24 - $start_commit); 22 + 'log %s %s --', 23 + '--format=%H%x01%P%x01%ct', 24 + gitsprintf('%s', $start_commit)); 25 25 } else { 26 26 $future = $repository->getLocalCommandFuture( 27 - 'log --format=%s --all --', 28 - '%H%x01%P%x01%ct'); 27 + 'log %s --all --', 28 + '--format=%H%x01%P%x01%ct'); 29 29 } 30 30 31 31 $this->iterator = new LinesOfALargeExecFuture($future);
+5 -5
src/applications/repository/engine/PhabricatorRepositoryRefEngine.php
··· 483 483 $ref_list = implode("\n", $ref_list)."\n"; 484 484 485 485 $future = $this->getRepository()->getLocalCommandFuture( 486 - 'log --format=%s --stdin', 487 - '%H'); 486 + 'log %s --stdin --', 487 + '--format=%H'); 488 488 489 489 list($stdout) = $future 490 490 ->write($ref_list) 491 491 ->resolvex(); 492 492 } else { 493 493 list($stdout) = $this->getRepository()->execxLocalCommand( 494 - 'log --format=%s %s', 495 - '%H', 496 - $new_head); 494 + 'log %s %s --', 495 + '--format=%H', 496 + gitsprintf('%s', $new_head)); 497 497 } 498 498 499 499 $stdout = trim($stdout);
+2
src/applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php
··· 4 4 extends PhabricatorWorkingCopyTestCase { 5 5 6 6 public function testSubversionCommitDiscovery() { 7 + $this->requireBinaryForTest('svn'); 8 + 7 9 $refs = $this->discoverRefs('ST'); 8 10 $this->assertEqual( 9 11 array(