Skip to content
Snippets Groups Projects

evolve: consider all obsolete ancestors when finding new parent for orphan

  1. Mar 24, 2020
  2. Mar 21, 2020
    • Manuel Jacob's avatar
      evolve: consider all obsolete ancestors when finding new parent for orphan · c0a38b743353
      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
Loading