Git rebase branch with merged children

Today I faced with one problem. My teammate created branch from master. He developed one feature in this branch and after that developed two subfeatures in subfeature’s branches. At last he did two refactoring commit of the entire thing. So…

     C--D    E--F             | subfeatures
    /    \  /    \
   B------M1------M2--G--H    | feature
  /
 A-------------------K        | master

Usually we rebase feature branches before no-fast-forward merge it into master. But of course this rebase fails. Rebased feature branch became looking like:

  • Git branch has diverged after rebase, so why rebase?
  • Difference between `git branch -f <branch_name> <hash>` and `git checkout <branch_name>; git reset --hard <hash>` under a clean working tree?
  • Update git-svn list of remote branches
  • remote branching after the fact
  • git: put a branch in a subdirectory
  • Git Workflow leads to Unsyncronized Branches on Bitbucket
  •      B'--C'--D'--E'--F'--G'--H'
        /
    A--K
    

    Of course pointers of C & D became wrong so I also get two subfeature branches growing ‘from air’. I understand how to fix it if subfeature branches wasn’t merged into feature, but at this time I was confused. I cherry-picked everything in rebased recovery branch and merged all again. Is here a easier way to do it?

  • Mercurial equivilent to git's HEAD~1
  • Git push -f vs. +
  • Fix broken git submodule due to manual directory mv
  • Git how to I make a repo branch identical to the master branch?
  • GIT GUI for solo project: Windows PC for development, but git + active, working project repo on a LAN headless linux server?
  • git central repository and Team
  • 2 Solutions collect form web for “Git rebase branch with merged children”

    Note that you need a git1.7.6+ for git rebase --preserve-merges to work properly.

    • a rebase --preserve-merges --onto didn’t work before (“git rebase --preserve-merges --onto doesn’t preserve merges”)
    • a rebase --preserve-merges had issue in some instance:
      • see this thread, when both sides of the merge are replayed)
      • “Git: Rebasing Merge Commits ” (post from Alexandru Pasca)

    Long story short: You just completed a merge and somebody has pushed a commit before you were able to push yours. The solution is to make git aware of the merge you did.

    git rebase --preserve-merges <upstream>
    

    or

    git rebase -p <upstream>
    

    But there’s a problem, if your merge had conflicts that you solved they won’t be picked up by the rebase machinery.
    And you will end up resolving the conflicts again … at least this is the case with git version 1.7.5.4

    (That would call for git rerere)

    Did you cherrypick every commit one by one by hand?

    Just run git rebase -i master feature and rewrite the history as you please.

    Git Baby is a git and github fan, let's start git clone.