mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Make arcanist more flexible about SVN base revisions
Summary: When running "arc diff" in a mixed-base-revision working copy, we prevent the operation. Relax this restriction so that having a different root revision is okay, so long as all affected files share the same revision. This facilitates multiple similar edits without updates. Test Plan: Reverted a file to an older revision in an SVN working copy, ran "arc diff", was rejected. Applied patch, ran "arc diff", diff went through and was recorded with the right SVN base revision in the database. Reviewers: CC:
This commit is contained in:
parent
ed53f98e9e
commit
309609169d
2 changed files with 55 additions and 33 deletions
|
@ -29,6 +29,8 @@ class ArcanistSubversionAPI extends ArcanistRepositoryAPI {
|
|||
|
||||
protected $svnInfoRaw = array();
|
||||
protected $svnDiffRaw = array();
|
||||
|
||||
private $svnBaseRevisionNumber;
|
||||
|
||||
public function getSourceControlSystemName() {
|
||||
return 'svn';
|
||||
|
@ -161,7 +163,20 @@ class ArcanistSubversionAPI extends ArcanistRepositoryAPI {
|
|||
|
||||
public function getSourceControlBaseRevision() {
|
||||
$info = $this->getSVNInfo('/');
|
||||
return $info['URL'].'@'.$info['Revision'];
|
||||
return $info['URL'].'@'.$this->getSVNBaseRevisionNumber();
|
||||
}
|
||||
|
||||
public function getSVNBaseRevisionNumber() {
|
||||
if ($this->svnBaseRevisionNumber) {
|
||||
return $this->svnBaseRevisionNumber;
|
||||
}
|
||||
$info = $this->getSVNInfo('/');
|
||||
return $info['Revision'];
|
||||
}
|
||||
|
||||
public function overrideSVNBaseRevisionNumber($effective_base_revision) {
|
||||
$this->svnBaseRevisionNumber = $effective_base_revision;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBranchName() {
|
||||
|
|
|
@ -201,21 +201,6 @@ EOTEXT
|
|||
|
||||
$parent = null;
|
||||
|
||||
$base_revision = $repository_api->getSourceControlBaseRevision();
|
||||
$base_path = $repository_api->getSourceControlPath();
|
||||
if ($repository_api instanceof ArcanistGitAPI) {
|
||||
$info = $this->getGitParentLogInfo();
|
||||
if ($info['parent']) {
|
||||
$parent = $info['parent'];
|
||||
}
|
||||
if ($info['base_revision']) {
|
||||
$base_revision = $info['base_revision'];
|
||||
}
|
||||
if ($info['base_path']) {
|
||||
$base_path = $info['base_path'];
|
||||
}
|
||||
}
|
||||
|
||||
$paths = $this->generateAffectedPaths();
|
||||
|
||||
$lint_result = $this->runLint($paths);
|
||||
|
@ -256,6 +241,23 @@ EOTEXT
|
|||
$unit = 'none';
|
||||
}
|
||||
|
||||
// NOTE: This has to happen after generateChanges(), since it may overwrite
|
||||
// the SVN effective base revision.
|
||||
$base_revision = $repository_api->getSourceControlBaseRevision();
|
||||
$base_path = $repository_api->getSourceControlPath();
|
||||
if ($repository_api instanceof ArcanistGitAPI) {
|
||||
$info = $this->getGitParentLogInfo();
|
||||
if ($info['parent']) {
|
||||
$parent = $info['parent'];
|
||||
}
|
||||
if ($info['base_revision']) {
|
||||
$base_revision = $info['base_revision'];
|
||||
}
|
||||
if ($info['base_path']) {
|
||||
$base_path = $info['base_path'];
|
||||
}
|
||||
}
|
||||
|
||||
$diff = array(
|
||||
'changes' => $change_list,
|
||||
'sourceMachine' => php_uname('n'),
|
||||
|
@ -505,26 +507,31 @@ EOTEXT
|
|||
}
|
||||
|
||||
if ($bases) {
|
||||
// We have at least one path which isn't new.
|
||||
$repository_info = $repository_api->getSVNInfo('/');
|
||||
$bases['.'] = $repository_info['Revision'];
|
||||
if ($bases['.']) {
|
||||
$rev = $bases['.'];
|
||||
foreach ($bases as $path => $baserev) {
|
||||
if ($baserev !== $rev) {
|
||||
$revlist = array();
|
||||
foreach ($bases as $path => $baserev) {
|
||||
$revlist[] = " Revision {$baserev}, {$path}";
|
||||
}
|
||||
$revlist = implode("\n", $revlist);
|
||||
throw new ArcanistUsageException(
|
||||
"Base revisions of changed paths are mismatched. Update all ".
|
||||
"paths to the same base revision before creating a diff: ".
|
||||
"\n\n".
|
||||
$revlist);
|
||||
$rev = reset($bases);
|
||||
foreach ($bases as $path => $baserev) {
|
||||
if ($baserev !== $rev) {
|
||||
$revlist = array();
|
||||
foreach ($bases as $path => $baserev) {
|
||||
$revlist[] = " Revision {$baserev}, {$path}";
|
||||
}
|
||||
$revlist = implode("\n", $revlist);
|
||||
throw new ArcanistUsageException(
|
||||
"Base revisions of changed paths are mismatched. Update all ".
|
||||
"paths to the same base revision before creating a diff: ".
|
||||
"\n\n".
|
||||
$revlist);
|
||||
}
|
||||
}
|
||||
|
||||
// If you have a change which affects several files, all of which are
|
||||
// at a consistent base revision, treat that revision as the effective
|
||||
// base revision. The use case here is that you made a change to some
|
||||
// file, which updates it to HEAD, but want to be able to change it
|
||||
// again without updating the entire working copy. This is a little
|
||||
// sketchy but it arises in Facebook Ops workflows with config files and
|
||||
// doesn't have any real material tradeoffs (e.g., these patches are
|
||||
// perfectly applyable).
|
||||
$repository_api->overrideSVNBaseRevisionNumber($rev);
|
||||
}
|
||||
|
||||
$changes = $parser->parseSubversionDiff(
|
||||
|
|
Loading…
Reference in a new issue