mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Implement "git:branch-unique(*)" in the base commit DSL
Summary: Add a DSL command to select the first commit between HEAD and (the merge-base of some target with HEAD) that's on more than one branch. This is similar to @csilvers' suggestion in <https://secure.phabricator.com/T1233#comment-8>. A specific problem this address is that, currently, if you use this workflow: $ git checkout -b feature $ git commit $ git checkout -b subfeature $ git commit ..i.e., develop dependent features in sub-branches, "arc diff" will try to send up (feature + subfeature). If you use the rule 'git:branch-unique(origin/master)' instead, diffing from 'subfeature' will correctly select only the commit(s) on 'subfeature'. Test Plan: Constructed feature/subfeature branches, verified that we select the correct base commit. Reviewers: dschleimer, csilvers, btrahan, jungejason Reviewed By: dschleimer CC: aran Maniphest Tasks: T1233 Differential Revision: https://secure.phabricator.com/D2866
This commit is contained in:
parent
33e53a2852
commit
98b3dfda3b
1 changed files with 46 additions and 0 deletions
|
@ -856,6 +856,52 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
|||
"configuration.");
|
||||
return trim($merge_base);
|
||||
}
|
||||
} else if (preg_match('/^branch-unique\((.+)\)$/', $name, $matches)) {
|
||||
list($err, $merge_base) = $this->execManualLocal(
|
||||
'merge-base %s HEAD',
|
||||
$matches[1]);
|
||||
if ($err) {
|
||||
return null;
|
||||
}
|
||||
$merge_base = trim($merge_base);
|
||||
|
||||
list($commits) = $this->execxLocal(
|
||||
'log --format=%C %s..HEAD --',
|
||||
'%H',
|
||||
$merge_base);
|
||||
$commits = array_filter(explode("\n", $commits));
|
||||
|
||||
if (!$commits) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$commits[] = $merge_base;
|
||||
|
||||
$head_branch_count = null;
|
||||
foreach ($commits as $commit) {
|
||||
list($branches) = $this->execxLocal(
|
||||
'branch --contains %s',
|
||||
$commit);
|
||||
$branches = array_filter(explode("\n", $branches));
|
||||
if ($head_branch_count === null) {
|
||||
// If this is the first commit, it's HEAD. Count how many
|
||||
// branches it is on; we want to include commits on the same
|
||||
// number of branches. This covers a case where this branch
|
||||
// has sub-branches and we're running "arc diff" here again
|
||||
// for whatever reason.
|
||||
$head_branch_count = count($branches);
|
||||
} else if (count($branches) > $head_branch_count) {
|
||||
foreach ($branches as $key => $branch) {
|
||||
$branches[$key] = trim($branch, ' *');
|
||||
}
|
||||
$branches = implode(', ', $branches);
|
||||
$this->setBaseCommitExplanation(
|
||||
"it is the first commit between '{$merge_base}' (the ".
|
||||
"merge-base of '{$matches[1]}' and HEAD) which is also ".
|
||||
"contained by another branch ({$branches}).");
|
||||
return $commit;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
list($err) = $this->execManualLocal(
|
||||
'cat-file -t %s',
|
||||
|
|
Loading…
Reference in a new issue