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

When commits have a "rewritten" hint, try to show that in handles in other applications

Summary:
Ref T11522. This tries to reduce the cost of rewriting a repository by making handles smarter about rewritten commits.

When a handle references an unreachable commit, try to load a rewrite hint for the commit. If we find one, change the handle name to "OldHash > NewHash" to provide a strong hint that the commit was rewritten and that copy/pasting the old hash (say, to the CLI) won't work.

I think this notation isn't totally self-evident, but users can click it to see the big error message on the page, and it's at least obvious that something weird is going on, which I think is the important part.

Some possible future work:

- Not sure this ("Recycling Symbol") is the best symbol? Seems sort of reasonable but mabye there's a better one.
- Putting this information directly on the hovercard could help explain what this means.

Test Plan: {F1780719}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11522

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

+115 -6
+52
src/applications/diffusion/query/DiffusionCommitHintQuery.php
··· 7 7 private $repositoryPHIDs; 8 8 private $oldCommitIdentifiers; 9 9 10 + private $commits; 11 + private $commitMap; 12 + 10 13 public function withIDs(array $ids) { 11 14 $this->ids = $ids; 12 15 return $this; ··· 20 23 public function withOldCommitIdentifiers(array $identifiers) { 21 24 $this->oldCommitIdentifiers = $identifiers; 22 25 return $this; 26 + } 27 + 28 + public function withCommits(array $commits) { 29 + assert_instances_of($commits, 'PhabricatorRepositoryCommit'); 30 + 31 + $repository_phids = array(); 32 + foreach ($commits as $commit) { 33 + $repository_phids[] = $commit->getRepository()->getPHID(); 34 + } 35 + 36 + $this->repositoryPHIDs = $repository_phids; 37 + $this->oldCommitIdentifiers = mpull($commits, 'getCommitIdentifier'); 38 + $this->commits = $commits; 39 + 40 + return $this; 41 + } 42 + 43 + public function getCommitMap() { 44 + if ($this->commitMap === null) { 45 + throw new PhutilInvalidStateException('execute'); 46 + } 47 + 48 + return $this->commitMap; 23 49 } 24 50 25 51 public function newResultObject() { 26 52 return new PhabricatorRepositoryCommitHint(); 27 53 } 28 54 55 + protected function willExecute() { 56 + $this->commitMap = array(); 57 + } 58 + 29 59 protected function loadPage() { 30 60 return $this->loadStandardPage($this->newResultObject()); 31 61 } ··· 55 85 } 56 86 57 87 return $where; 88 + } 89 + 90 + protected function didFilterPage(array $hints) { 91 + if ($this->commits) { 92 + $map = array(); 93 + foreach ($this->commits as $commit) { 94 + $repository_phid = $commit->getRepository()->getPHID(); 95 + $identifier = $commit->getCommitIdentifier(); 96 + $map[$repository_phid][$identifier] = $commit->getPHID(); 97 + } 98 + 99 + foreach ($hints as $hint) { 100 + $repository_phid = $hint->getRepositoryPHID(); 101 + $identifier = $hint->getOldCommitIdentifier(); 102 + if (isset($map[$repository_phid][$identifier])) { 103 + $commit_phid = $map[$repository_phid][$identifier]; 104 + $this->commitMap[$commit_phid] = $hint; 105 + } 106 + } 107 + } 108 + 109 + return $hints; 58 110 } 59 111 60 112 public function getQueryApplicationClass() {
+19
src/applications/diffusion/remarkup/DiffusionCommitRemarkupRule.php
··· 14 14 return PhabricatorRepositoryCommitPHIDType::getCommitObjectNamePattern(); 15 15 } 16 16 17 + protected function getObjectNameText( 18 + $object, 19 + PhabricatorObjectHandle $handle, 20 + $id) { 21 + 22 + // If this commit is unreachable, return the handle name instead of the 23 + // normal text because it may be able to tell the user that the commit 24 + // was rewritten and where to find the new one. 25 + 26 + // By default, we try to preserve what the user actually typed as 27 + // faithfully as possible, but if they're referencing a deleted commit 28 + // it's more valuable to try to pick up any rewrite. See T11522. 29 + if ($object->isUnreachable()) { 30 + return $handle->getName(); 31 + } 32 + 33 + return parent::getObjectNameText($object, $handle, $id); 34 + } 35 + 17 36 protected function loadObjects(array $ids) { 18 37 $viewer = $this->getEngine()->getConfig('viewer'); 19 38
+35 -4
src/applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php
··· 29 29 array $handles, 30 30 array $objects) { 31 31 32 + $unreachable = array(); 33 + foreach ($handles as $phid => $handle) { 34 + $commit = $objects[$phid]; 35 + if ($commit->isUnreachable()) { 36 + $unreachable[$phid] = $commit; 37 + } 38 + } 39 + 40 + if ($unreachable) { 41 + $query = id(new DiffusionCommitHintQuery()) 42 + ->setViewer($query->getViewer()) 43 + ->withCommits($unreachable); 44 + 45 + $query->execute(); 46 + 47 + $hints = $query->getCommitMap(); 48 + } else { 49 + $hints = array(); 50 + } 51 + 32 52 foreach ($handles as $phid => $handle) { 33 53 $commit = $objects[$phid]; 34 54 $repository = $commit->getRepository(); 35 55 $commit_identifier = $commit->getCommitIdentifier(); 36 56 37 57 $name = $repository->formatCommitName($commit_identifier); 58 + 59 + if ($commit->isUnreachable()) { 60 + $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED); 61 + 62 + // If we have a hint about this commit being rewritten, add the 63 + // rewrite target to the handle name. This reduces the chance users 64 + // will be caught offguard by the rewrite. 65 + $hint = idx($hints, $phid); 66 + if ($hint && $hint->isRewritten()) { 67 + $new_name = $hint->getNewCommitIdentifier(); 68 + $new_name = $repository->formatCommitName($new_name); 69 + $name = pht("%s \xE2\x99\xBB %s", $name, $new_name); 70 + } 71 + } 72 + 38 73 $summary = $commit->getSummary(); 39 74 if (strlen($summary)) { 40 75 $full_name = $name.': '.$summary; ··· 46 81 $handle->setFullName($full_name); 47 82 $handle->setURI($commit->getURI()); 48 83 $handle->setTimestamp($commit->getEpoch()); 49 - 50 - if ($commit->isUnreachable()) { 51 - $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED); 52 - } 53 84 } 54 85 } 55 86
+9 -2
src/infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php
··· 25 25 return true; 26 26 } 27 27 28 + protected function getObjectNameText( 29 + $object, 30 + PhabricatorObjectHandle $handle, 31 + $id) { 32 + return $this->getObjectNamePrefix().$id; 33 + } 34 + 28 35 protected function loadHandles(array $objects) { 29 36 $phids = mpull($objects, 'getPHID'); 30 37 ··· 60 67 $id) { 61 68 62 69 $href = $this->getObjectHref($object, $handle, $id); 63 - $text = $this->getObjectNamePrefix().$id; 70 + $text = $this->getObjectNameText($object, $handle, $id); 64 71 65 72 if ($anchor) { 66 73 $href = $href.'#'.$anchor; ··· 85 92 $id) { 86 93 87 94 $href = $this->getObjectHref($object, $handle, $id); 88 - $text = $this->getObjectNamePrefix().$id; 95 + $text = $this->getObjectNameText($object, $handle, $id); 89 96 $status_closed = PhabricatorObjectHandle::STATUS_CLOSED; 90 97 91 98 if ($anchor) {