evolve: consider all obsolete ancestors when finding new parent for orphan
- Mar 24, 2020
-
-
Manuel Jacob authored
-
- Mar 21, 2020
-
-
Manuel Jacob authored
Both the old and the new logic have in common that the orphan changeset is moved to the headmost successor of one or more ancestors of the orphan changeset. The previous logic considered only the first non-pruned ancestor of the orphan changeset. The new logic considers all obsolete ancestors of the orphan changeset. The logic in _possibledestination() had to be changed to be consistent with the new logic. A changeset may depend on the changes from an arbitrary subset of its ancestors. Draft ancestors may get rewritten in arbitrary ways (e.g. amended, rebased, folded, and reordered). For an orphan changeset, it’s a safe heuristic to rebase it such that it will be based on the successors of all changesets it was based on before. Therefore the new logic moves an orphan changeset onto the headmost successor of all obsolete ancestors. The old logic was only an approximation of that heuristic. When the ancestors of the orphan keep the ordering during rewrite, the result is the same. When the ancestors get reordered such that the parent of the orphan doesn’t become the head of the rewritten changesets, often a suboptimal new parent was found for the orphan. Example: C | B | A A and B are reordered: A' | B' The old logic rebased C onto B': A' C' | / B' The new logic rebases C onto A': C' | A' | B' Another example: D | C | B | A C is folded into A (e.g. by the proposed --from functionality in absorb): B' | AC' The old logic rebased D onto AC' (because it’s the successor of C): B' D' | / AC' The new logic rebases D onto B' (because it’s the headmost successor of A, B and C): D' | B' | AC' The new logic usually produces a better result because the chance of branching is reduced (because the head of a larger set of changesets is chosen).
c0a38b743353
-