1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-09-20 08:58:55 +02: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:
epriestley 2012-06-27 12:12:39 -07:00
parent 33e53a2852
commit 98b3dfda3b

View file

@ -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',