@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.

Add "bin/repository mark-reachable" for fixing commit reachability flags

Summary:
Ref T9028. This corrects the reachability of existing commits in a repository.

In particular, it can be used to mark deleted commits as unreachable.

Test Plan:
- Ran it on a bad repository, with bad args, etc.
- Ran it on a clean repo, got no changes.
- Marked a reachable commit as unreachable, ran script, got it marked reachable.
- Started deleting tags and branches from the local working copy while running the script, saw greater parts of the repository get marked unreachable.
- Pulled repository again, everything automatically revived.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9028

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

+148 -12
+2
src/__phutil_library_map__.php
··· 3263 3263 'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php', 3264 3264 'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php', 3265 3265 'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php', 3266 + 'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php', 3266 3267 'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php', 3267 3268 'PhabricatorRepositoryManagementMovePathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMovePathsWorkflow.php', 3268 3269 'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php', ··· 8052 8053 'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8053 8054 'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8054 8055 'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8056 + 'PhabricatorRepositoryManagementMarkReachableWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8055 8057 'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8056 8058 'PhabricatorRepositoryManagementMovePathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow', 8057 8059 'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
+11 -5
src/applications/repository/daemon/PhabricatorGitGraphStream.php
··· 11 11 12 12 public function __construct( 13 13 PhabricatorRepository $repository, 14 - $start_commit) { 14 + $start_commit = null) { 15 15 16 16 $this->repository = $repository; 17 17 18 - $future = $repository->getLocalCommandFuture( 19 - 'log --format=%s %s --', 20 - '%H%x01%P%x01%ct', 21 - $start_commit); 18 + if ($start_commit !== null) { 19 + $future = $repository->getLocalCommandFuture( 20 + 'log --format=%s %s --', 21 + '%H%x01%P%x01%ct', 22 + $start_commit); 23 + } else { 24 + $future = $repository->getLocalCommandFuture( 25 + 'log --format=%s --all --', 26 + '%H%x01%P%x01%ct'); 27 + } 22 28 23 29 $this->iterator = new LinesOfALargeExecFuture($future); 24 30 $this->iterator->setDelimiter("\n");
+103
src/applications/repository/management/PhabricatorRepositoryManagementMarkReachableWorkflow.php
··· 1 + <?php 2 + 3 + final class PhabricatorRepositoryManagementMarkReachableWorkflow 4 + extends PhabricatorRepositoryManagementWorkflow { 5 + 6 + private $untouchedCount = 0; 7 + 8 + protected function didConstruct() { 9 + $this 10 + ->setName('mark-reachable') 11 + ->setExamples('**mark-reachable** [__options__] __repository__ ...') 12 + ->setSynopsis( 13 + pht( 14 + 'Rebuild "unreachable" flags for commits in __repository__.')) 15 + ->setArguments( 16 + array( 17 + array( 18 + 'name' => 'repos', 19 + 'wildcard' => true, 20 + ), 21 + )); 22 + } 23 + 24 + public function execute(PhutilArgumentParser $args) { 25 + $repos = $this->loadRepositories($args, 'repos'); 26 + if (!$repos) { 27 + throw new PhutilArgumentUsageException( 28 + pht( 29 + 'Specify one or more repositories to correct reachability status '. 30 + 'for.')); 31 + } 32 + 33 + foreach ($repos as $repo) { 34 + $this->markReachable($repo); 35 + } 36 + 37 + echo tsprintf( 38 + "%s\n", 39 + pht( 40 + 'Examined %s commits already in the correct state.', 41 + new PhutilNumber($this->untouchedCount))); 42 + 43 + echo tsprintf( 44 + "%s\n", 45 + pht('Done.')); 46 + 47 + return 0; 48 + } 49 + 50 + private function markReachable(PhabricatorRepository $repository) { 51 + if (!$repository->isGit()) { 52 + throw new PhutilArgumentUsageException( 53 + pht( 54 + 'Only Git repositories are supported, this repository ("%s") is '. 55 + 'not a Git repository.', 56 + $repository->getDisplayName())); 57 + } 58 + 59 + $viewer = $this->getViewer(); 60 + 61 + $commits = id(new DiffusionCommitQuery()) 62 + ->setViewer($viewer) 63 + ->withRepository($repository) 64 + ->execute(); 65 + 66 + $flag = PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE; 67 + 68 + $graph = new PhabricatorGitGraphStream($repository); 69 + foreach ($commits as $commit) { 70 + $identifier = $commit->getCommitIdentifier(); 71 + 72 + try { 73 + $graph->getCommitDate($identifier); 74 + $unreachable = false; 75 + } catch (Exception $ex) { 76 + $unreachable = true; 77 + } 78 + 79 + // The commit has proper reachability, so do nothing. 80 + if ($commit->isUnreachable() === $unreachable) { 81 + $this->untouchedCount++; 82 + continue; 83 + } 84 + 85 + if ($unreachable) { 86 + echo tsprintf( 87 + "%s: %s\n", 88 + $commit->getMonogram(), 89 + pht('Marking commit unreachable.')); 90 + 91 + $commit->writeImportStatusFlag($flag); 92 + } else { 93 + echo tsprintf( 94 + "%s: %s\n", 95 + $commit->getMonogram(), 96 + pht('Marking commit reachable.')); 97 + 98 + $commit->clearImportStatusFlag($flag); 99 + } 100 + } 101 + } 102 + 103 + }
+32 -7
src/applications/repository/storage/PhabricatorRepositoryCommit.php
··· 64 64 } 65 65 66 66 public function writeImportStatusFlag($flag) { 67 - queryfx( 68 - $this->establishConnection('w'), 69 - 'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d', 70 - $this->getTableName(), 71 - $flag, 72 - $this->getID()); 73 - $this->setImportStatus($this->getImportStatus() | $flag); 67 + return $this->adjustImportStatusFlag($flag, true); 68 + } 69 + 70 + public function clearImportStatusFlag($flag) { 71 + return $this->adjustImportStatusFlag($flag, false); 72 + } 73 + 74 + private function adjustImportStatusFlag($flag, $set) { 75 + $conn_w = $this->establishConnection('w'); 76 + $table_name = $this->getTableName(); 77 + $id = $this->getID(); 78 + 79 + if ($set) { 80 + queryfx( 81 + $conn_w, 82 + 'UPDATE %T SET importStatus = (importStatus | %d) WHERE id = %d', 83 + $table_name, 84 + $flag, 85 + $id); 86 + 87 + $this->setImportStatus($this->getImportStatus() | $flag); 88 + } else { 89 + queryfx( 90 + $conn_w, 91 + 'UPDATE %T SET importStatus = (importStatus & ~%d) WHERE id = %d', 92 + $table_name, 93 + $flag, 94 + $id); 95 + 96 + $this->setImportStatus($this->getImportStatus() & ~$flag); 97 + } 98 + 74 99 return $this; 75 100 } 76 101