Index: dashboard/dashboard/pinpoint/models/change/change.py |
diff --git a/dashboard/dashboard/pinpoint/models/change/change.py b/dashboard/dashboard/pinpoint/models/change/change.py |
index ade1c48f1d047df26e855b10a0d0caceaa5c8f11..b8ca94c3473e03a45ce73e8bd5fe4b0efe4712f1 100644 |
--- a/dashboard/dashboard/pinpoint/models/change/change.py |
+++ b/dashboard/dashboard/pinpoint/models/change/change.py |
@@ -86,17 +86,21 @@ class Change(collections.namedtuple('Change', ('commits', 'patch'))): |
not linear if any of the following is true: |
* They have different patches. |
* Their repositories don't match even after expanding DEPS rolls. |
- * The left Change comes after the right Change. |
- * They are the same or adjacent. |
+ * The left Change does not come before the right Change. |
See change_test.py for examples of linear and nonlinear Changes. |
+ If the range has an even number of Changes, the midpoint is the Change just |
+ before the halfway point. The range includes both change_a and change_b; |
+ i.e. if change_a and change_b are adjacent or the same, the midpoint is |
+ change_a. |
+ |
Args: |
change_a: The first Change in the range. |
change_b: The last Change in the range. |
Returns: |
- A new Change representing the midpoint. |
- The Change before the midpoint if the range has an even number of commits. |
+ A tuple of (Change, (left, right)). left and right are the distances |
perezju
2017/09/19 15:58:05
I think it's cleaner if it returns just (change, l
|
+ between the midpoint and change_a and change_b, respectively. |
Raises: |
NonLinearError: The Changes are not linear. |
@@ -110,12 +114,12 @@ class Change(collections.namedtuple('Change', ('commits', 'patch'))): |
commits_b = list(change_b.commits) |
_ExpandDepsToMatchRepositories(commits_a, commits_b) |
- commits_midpoint = _FindMidpoints(commits_a, commits_b) |
- |
- if commits_a == commits_midpoint: |
- raise commit_module.NonLinearError('Changes are the same or adjacent.') |
+ midpoints = _FindMidpoints(commits_a, commits_b) |
+ commits_midpoint, distances = zip(*midpoints) |
- return cls(commits_midpoint, change_a.patch) |
+ midpoint = cls(commits_midpoint, change_a.patch) |
+ distances = tuple(map(max, zip(*distances))) |
+ return midpoint, distances |
def _ExpandDepsToMatchRepositories(commits_a, commits_b): |
@@ -159,7 +163,7 @@ def _ExpandDepsToMatchRepositories(commits_a, commits_b): |
def _FindMidpoints(commits_a, commits_b): |
- """Returns the midpoint of two Commit lists. |
+ """Returns the midpoints of two Commit lists. |
Loops through each pair of Commits and takes the midpoint. If the repositories |
don't match, a NonLinearError is raised. If the Commits are adjacent and |
@@ -170,15 +174,14 @@ def _FindMidpoints(commits_a, commits_b): |
commits_b: A list of Commits. |
Returns: |
- A list of Commits, each of which is the midpoint of the respective Commit in |
- commits_a and commits_b. |
+ A list of tuples. Each tuple is the result of Commit.Midpoint(). |
Raises: |
NonLinearError: The lists have a different number of commits even after |
expanding DEPS rolls, a Commit pair contains differing repositories, or a |
Commit pair is in the wrong order. |
""" |
- commits_midpoint = [] |
+ midpoints = [] |
for commit_a, commit_b in itertools.izip_longest(commits_a, commits_b): |
if not (commit_a and commit_b): |
@@ -188,9 +191,10 @@ def _FindMidpoints(commits_a, commits_b): |
raise commit_module.NonLinearError( |
'Changes have a different number of commits.') |
- commit_midpoint = commit_module.Commit.Midpoint(commit_a, commit_b) |
- commits_midpoint.append(commit_midpoint) |
- if commit_a == commit_midpoint != commit_b: |
+ midpoint, distances = commit_module.Commit.Midpoint(commit_a, commit_b) |
+ midpoints.append((midpoint, distances)) |
+ |
+ if sum(distances) == 1: |
# Commits are adjacent. |
# Add any DEPS changes to the commit lists. |
deps_a = commit_a.Deps() |
@@ -202,7 +206,7 @@ def _FindMidpoints(commits_a, commits_b): |
dep for dep in deps_b.difference(deps_a) |
if not _FindCommitWithRepository(commits_b, dep.repository)) |
- return commits_midpoint |
+ return midpoints |
def _FindCommitWithRepository(commits, repository): |