Skip to content
  • Johannes Schindelin's avatar
    rebase -i: introduce --rebase-merges=[no-]rebase-cousins · 7543f6f4
    Johannes Schindelin authored and Junio C Hamano's avatar Junio C Hamano committed
    
    
    When running `git rebase --rebase-merges` non-interactively with an
    ancestor of HEAD as <upstream> (or leaving the todo list unmodified),
    we would ideally recreate the exact same commits as before the rebase.
    
    However, if there are commits in the commit range <upstream>.. that do not
    have <upstream> as direct ancestor (i.e. if `git log <upstream>..` would
    show commits that are omitted by `git log --ancestry-path <upstream>..`),
    this is currently not the case: we would turn them into commits that have
    <upstream> as direct ancestor.
    
    Let's illustrate that with a diagram:
    
            C
          /   \
    A - B - E - F
      \   /
        D
    
    Currently, after running `git rebase -i --rebase-merges B`, the new branch
    structure would be (pay particular attention to the commit `D`):
    
           --- C' --
          /         \
    A - B ------ E' - F'
          \    /
            D'
    
    This is not really preserving the branch topology from before! The
    reason is that the commit `D` does not have `B` as ancestor, and
    therefore it gets rebased onto `B`.
    
    This is unintuitive behavior. Even worse, when recreating branch
    structure, most use cases would appear to want cousins *not* to be
    rebased onto the new base commit. For example, Git for Windows (the
    heaviest user of the Git garden shears, which served as the blueprint
    for --rebase-merges) frequently merges branches from `next` early, and
    these branches certainly do *not* want to be rebased. In the example
    above, the desired outcome would look like this:
    
           --- C' --
          /         \
    A - B ------ E' - F'
      \        /
       -- D' --
    
    Let's introduce the term "cousins" for such commits ("D" in the
    example), and let's not rebase them by default. For hypothetical
    use cases where cousins *do* need to be rebased, `git rebase
    --rebase=merges=rebase-cousins` needs to be used.
    
    Signed-off-by: default avatarJohannes Schindelin <johannes.schindelin@gmx.de>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    7543f6f4