Adding in a smarter parent-base finding algorithm

Review Request #7985 — Created Feb. 21, 2016 and submitted — Latest diff uploaded

Information

RBTools
master

Reviewers

Main idea

Given a tree like this one:

A - * - * - * - * origin/master
* - B - * - * origin/feature
- C - D topic

when we rbt post, it would like to have three things,
'base': A revision to use as the base of the resulting diff.
'tip': A revision to use as the tip of the resulting diff.
'parent_base': (optional) The revision to use as the base of a
parent diff.
Now, parent_base has to be in the remote repository, in other words, a ancestor of a commit of any branch origin/*. We would also like parent_base to be as young an ancestor of tip as possible, given the first constraint.

A git-rev-list query can find this in the following manner -

git rev-list $TIP --not --remotes=origin | tail -1

should give the oldest ancestor that is not reachable from a public branch, so it's parent will be the best parent base.

The algorithm has been tested extensively. More specifically, GitClient.parse_revision_spec has been tested on the conditions outlined in the following comment (https://reviews.reviewboard.org/r/6797/#comment20865). Detailed documentation and visualization have been added to the tests to aid understanding. I hope this will help a reader understand and review the tests better.

Specifically, the conditions being tested are -

0) Testing GitClient.parse_revision_spec with target branch off a tracking branch not aligned with the remote.
1) Testing GitClient.parse_revision_spec with target branch off a tracking branch aligned with the remote.
2) Testing GitClient.parse_revision_spec with target branch off a tracking branch with changes since the remote.
3) Testing GitClient.parse_revision_spec with target branch off a branch not properly tracking the remote.
4) Testing GitClient.parse_revision_spec with a target branch that merged a tracking branch off another tracking branch.
5) Testing GitClient.parse_revision_spec with a target branch posted off a tracking branch that merged another tracking branch.
6) Testing GitClient.parse_revision_spec with a target branch posted off a remote branch without any tracking branches.
7) Testing GitClient.parse_revision_spec with a target branch posted off a remote branch that is aligned to the same commit as another remote branch.
8) Testing GitClient.parse_revision_spec with a target branch not up-to-date with a remote branch.
9) Testing GitClient.parse_revision_spec with a target branch that has branches from different remotes in its path.

Note - The above test descriptions make more sense when we actually view the commit graphs representing each of these scenarios. These commit graphs can be found as part of the documentation of my tests.

Note 2 - The test functions are named in a serial manner (i.e. with suffixes case_one, case_two ... case_nine etc.). This was done because it was not always easy to capture what the test was trying to test in a few words. Hence giving uniform but serial names helped because essentially, all of these tests test the same thing - i.e. whether GitClient.parse_revision_spec can find a good parent, parent_base in each of these scenarios.

I also had to alter one of the existing tests in order to align it with the new algorithm.