1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Add support to marking commits as UNREACHABLE for Mercurial

Summary:
When previously known commits have been destroyed in a Mercurial repository, Phabricator does not end up marking the commits as unreachable. This results in daemon tasks which continuously fail and retry.

This updates `PhabricatorRepositoryDiscoveryEngine` and `PhabricatorManagementRepositoryMarkReachableWorkflow` to include support of marking commits as unreachable for Mercurial repositories.

The `PhabricatorMercurialGraphStream` also needed updated to support a stream with no starting commit.

Refs T13634

Test Plan:
1. I set up a hosted Mercurial repository.
2. I removed the head commit from the on-disk repository state.
3. I attempted to load the repository page and saw an exception due to a missing commit.
4. I went to `/manage` for the repository and scheduled an update of the repository.
5. After an updated performed, I went to the repository main page and saw there was no exception and the history view properly did not have the commit I had removed.
6. I checked the phd logs and verified there were no exceptions related to the repository.
7. I ran the `./bin/repository mark-reachable` command on the Mercurial repository and it reported that it marked the commit as unreachable.
8. I pushed the same commit back upstream and verified that the commit was found and displayed in the history view of the repository page and `mark-unreachable` did not identify it as being unreachable.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T13634

Differential Revision: https://secure.phabricator.com/D21715
This commit is contained in:
Christopher Speck 2021-09-02 22:47:01 -04:00
parent 458ad4a861
commit 09c3c7d879
3 changed files with 30 additions and 12 deletions

View file

@ -16,13 +16,23 @@ final class PhabricatorMercurialGraphStream
private $local = array();
private $localParents = array();
public function __construct(PhabricatorRepository $repository, $commit) {
public function __construct(PhabricatorRepository $repository,
$start_commit = null) {
$this->repository = $repository;
$command = 'log --template %s --rev %s';
$template = '{rev}\1{node}\1{date}\1{parents}\2';
if ($start_commit !== null) {
$revset = hgsprintf('reverse(ancestors(%s))', $start_commit);
} else {
$revset = 'reverse(all())';
}
$future = $repository->getLocalCommandFuture(
'log --template %s --rev %s',
'{rev}\1{node}\1{date}\1{parents}\2',
hgsprintf('reverse(ancestors(%s))', $commit));
$command,
$template,
$revset);
$this->iterator = new LinesOfALargeExecFuture($future);
$this->iterator->setDelimiter("\2");

View file

@ -780,8 +780,7 @@ final class PhabricatorRepositoryDiscoveryEngine
}
private function markUnreachableCommits(PhabricatorRepository $repository) {
// For now, this is only supported for Git.
if (!$repository->isGit()) {
if (!$repository->isGit() && !$repository->isHg()) {
return;
}
@ -799,7 +798,11 @@ final class PhabricatorRepositoryDiscoveryEngine
}
// We can share a single graph stream across all the checks we need to do.
$stream = new PhabricatorGitGraphStream($repository);
if ($repository->isGit()) {
$stream = new PhabricatorGitGraphStream($repository);
} else if ($repository->isHg()) {
$stream = new PhabricatorMercurialGraphStream($repository);
}
foreach ($old_refs as $old_ref) {
$identifier = $old_ref->getCommitIdentifier();
@ -812,7 +815,7 @@ final class PhabricatorRepositoryDiscoveryEngine
private function markUnreachableFrom(
PhabricatorRepository $repository,
PhabricatorGitGraphStream $stream,
PhabricatorRepositoryGraphStream $stream,
$identifier) {
$unreachable = array();

View file

@ -48,11 +48,11 @@ final class PhabricatorRepositoryManagementMarkReachableWorkflow
}
private function markReachable(PhabricatorRepository $repository) {
if (!$repository->isGit()) {
if (!$repository->isGit() && !$repository->isHg()) {
throw new PhutilArgumentUsageException(
pht(
'Only Git repositories are supported, this repository ("%s") is '.
'not a Git repository.',
'Only Git and Mercurial repositories are supported, unable to '.
'operate on this repository ("%s").',
$repository->getDisplayName()));
}
@ -65,7 +65,12 @@ final class PhabricatorRepositoryManagementMarkReachableWorkflow
$flag = PhabricatorRepositoryCommit::IMPORTED_UNREACHABLE;
$graph = new PhabricatorGitGraphStream($repository);
if ($repository->isGit()) {
$graph = new PhabricatorGitGraphStream($repository);
} else if ($repository->isHg()) {
$graph = new PhabricatorMercurialGraphStream($repository);
}
foreach ($commits as $commit) {
$identifier = $commit->getCommitIdentifier();