In "arc land", if rebasing a range fails, attempt to "reduce" it
Summary:
Ref T13576. See that task for discussion.
When a user runs arc land --pick A, they may be selecting a range of commits ("X..Y") which have ancestors ("V..W") that should NOT land.
We must slice "X..Y" out of history before we can merge it, to avoid landing changes from "V..W".
When "X..Y" is simple and linear, we can rebase the range to pick our desired slice out of history.
When "X..Y" includes merge commits, we frequently can not, and I could not identify any simple alternative. The best alternative I came up with is this "reduce" operation:
- squash "into" onto Y, producing S, to guarantee there are no natural conflicts;
- squash S onto X^, producing T, to get rid of the merge commits;
- rebase T onto "into", producing R, to slice "X..Y" out of history;
- squash R onto "into", producing Q. (R and Q will be the same, but this simplies the code.)
This feels flimsy and fragile, but I can't immediately find a way to break it. See T13576 for more discussion.
Test Plan:
- Applied conflicting changes to example.txt in master and feature1.
- Ran arc land, got a merge conflict.
- Resolved the conflict with git merge master.
- Ran arc land.
- Before: merge conflict.
- After: arc land resolves the merge correctly.
- Stacked feature2 on feature1, and made various mutations to feature1 and feature2, then ran arc land --pick feature2. Changes made in feature1 should not land, and they mostly do not. See T13576.
Maniphest Tasks: T13576
Differential Revision: https://secure.phabricator.com/D21590