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

Unify code for parsing "Reverts X" magic, and when something "reverts <hash>", also revert associated revisions

Summary:
Depends on D20468. Ref T13276. See PHI1008.

When a commit or revision "reverts <hash>", and that's the hash of a commit which has a revision, also write a "reverts" edge to the revision.

Test Plan:
Created "reverts X" objects for:

- a revision;
- a commit;
- a commit with a revision (both got marked properly).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13276

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

+81 -36
+6 -23
src/applications/audit/editor/PhabricatorAuditEditor.php
··· 390 390 ->parseCorpus($huge_block); 391 391 $reverts = array_mergev(ipull($reverts_refs, 'monograms')); 392 392 if ($reverts) { 393 - // Only allow commits to revert other commits in the same repository. 394 - $reverted_commits = id(new DiffusionCommitQuery()) 395 - ->setViewer($actor) 396 - ->withRepository($object->getRepository()) 397 - ->withIdentifiers($reverts) 398 - ->execute(); 393 + $reverted_objects = DiffusionCommitRevisionQuery::loadRevertedObjects( 394 + $actor, 395 + $object, 396 + $reverts, 397 + $object->getRepository()); 399 398 400 - $reverted_revisions = id(new PhabricatorObjectQuery()) 401 - ->setViewer($actor) 402 - ->withNames($reverts) 403 - ->withTypes( 404 - array( 405 - DifferentialRevisionPHIDType::TYPECONST, 406 - )) 407 - ->execute(); 408 - 409 - $reverted_phids = 410 - mpull($reverted_commits, 'getPHID', 'getPHID') + 411 - mpull($reverted_revisions, 'getPHID', 'getPHID'); 412 - 413 - // NOTE: Skip any write attempts if a user cleverly implies a commit 414 - // reverts itself, although this would be exceptionally clever in Git 415 - // or Mercurial. 416 - unset($reverted_phids[$object->getPHID()]); 399 + $reverted_phids = mpull($reverted_objects, 'getPHID', 'getPHID'); 417 400 418 401 $reverts_edge = DiffusionCommitRevertsCommitEdgeType::EDGECONST; 419 402 $result[] = id(new PhabricatorAuditTransaction())
+5 -13
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 832 832 } 833 833 834 834 if ($revert_monograms) { 835 - $revert_objects = id(new PhabricatorObjectQuery()) 836 - ->setViewer($this->getActor()) 837 - ->withNames($revert_monograms) 838 - ->withTypes( 839 - array( 840 - DifferentialRevisionPHIDType::TYPECONST, 841 - PhabricatorRepositoryCommitPHIDType::TYPECONST, 842 - )) 843 - ->execute(); 835 + $revert_objects = DiffusionCommitRevisionQuery::loadRevertedObjects( 836 + $this->getActor(), 837 + $object, 838 + $revert_monograms, 839 + null); 844 840 845 841 $revert_phids = mpull($revert_objects, 'getPHID', 'getPHID'); 846 - 847 - // Don't let an object revert itself, although other silly stuff like 848 - // cycles of objects reverting each other is not prevented. 849 - unset($revert_phids[$object->getPHID()]); 850 842 851 843 $revert_type = DiffusionCommitRevertsCommitEdgeType::EDGECONST; 852 844 $edges[$revert_type] = $revert_phids;
+70
src/applications/diffusion/query/DiffusionCommitRevisionQuery.php
··· 64 64 ->executeOne(); 65 65 } 66 66 67 + public static function loadRevertedObjects( 68 + PhabricatorUser $viewer, 69 + $source_object, 70 + array $object_names, 71 + PhabricatorRepository $repository_scope = null) { 72 + 73 + // Fetch commits first, since we need to load data on commits in order 74 + // to identify associated revisions later on. 75 + $commit_query = id(new DiffusionCommitQuery()) 76 + ->setViewer($viewer) 77 + ->withIdentifiers($object_names) 78 + ->needCommitData(true); 79 + 80 + // If we're acting in a specific repository, only allow commits in that 81 + // repository to be affected: when commit X reverts commit Y by hash, we 82 + // only want to revert commit Y in the same repository, even if other 83 + // repositories have a commit with the same hash. 84 + if ($repository_scope) { 85 + $commit_query->withRepository($repository_scope); 86 + } 87 + 88 + $objects = $commit_query->execute(); 89 + 90 + $more_objects = id(new PhabricatorObjectQuery()) 91 + ->setViewer($viewer) 92 + ->withNames($object_names) 93 + ->withTypes( 94 + array( 95 + DifferentialRevisionPHIDType::TYPECONST, 96 + )) 97 + ->execute(); 98 + foreach ($more_objects as $object) { 99 + $objects[] = $object; 100 + } 101 + 102 + // See PHI1008 and T13276. If something reverts commit X, we also revert 103 + // any associated revision. 104 + 105 + // For now, we don't try to find associated commits if something reverts 106 + // revision Y. This is less common, although we could make more of an 107 + // effort in the future. 108 + 109 + foreach ($objects as $object) { 110 + if (!($object instanceof PhabricatorRepositoryCommit)) { 111 + continue; 112 + } 113 + 114 + // NOTE: If our object "reverts X", where "X" is a commit hash, it is 115 + // possible that "X" will not have parsed yet, so we'll fail to find 116 + // a revision even though one exists. 117 + 118 + // For now, do nothing. It's rare to push a commit which reverts some 119 + // commit "X" before "X" has parsed, so we expect this to be unusual. 120 + 121 + $revision = self::loadRevisionForCommit( 122 + $viewer, 123 + $object); 124 + if ($revision) { 125 + $objects[] = $revision; 126 + } 127 + } 128 + 129 + $objects = mpull($objects, null, 'getPHID'); 130 + 131 + // Prevent an object from reverting itself, although this would be very 132 + // clever in Git or Mercurial. 133 + unset($objects[$source_object->getPHID()]); 134 + 135 + return $objects; 136 + } 67 137 68 138 }