How to rebase a branch off a rebased branch?

Solution 1:

Short answer to How can I effectively rebase B off A so that it looks like B started from A? Assuming you want to move exactly one commit:

git rebase --onto A B~ B

If you want to move more then one commit use:

git rebase --onto A old_A B

The rest of the answer.

Your branch of B is still around (you can check it out), but its parent is still the exact commit object that A was before.
to see a graphical representation of this I use:

git log --graph --decorate --all

to see all branches and where they are with respect to each other.

What you originally had:

o---o---o---o  master
     \
      o---o---o  A
               \
                o B

What you have now:

o---o---o-----------o  master
     \               \
      o---o---o(B~)   o---o---o A
               \
                o B

In terms of using --onto, you need to have a starting point and an ending point. use:

git rebase --onto [target] [rebasing stops] [rebasing head]
git rebase --onto A B~ B

And what you get:

o---o---o----------o  master
     \              \
      o---o---o      o---o---o A
            (old_A)           \
                               o B

[branch_name]~ indicates the parent commit of the branch.

The B~ is the branch that you do not want to change. (It happens to be the old A)

Alternatively, if B was the only commit that had A as a parent, (i.e., B is the end of a chain of commits that branch off master) you could do

git checkout B
git rebase master
git checkout B~   # this is the commit before B (the A commit)
git branch -d A   # remove the old A branch (it was rebased, and so is now invalid
git branch A      # recreate the A branch on the commit that is based on the original A

Solution 2:

I have the same issue of my git flow, and I found a best and fast way to do it.

(1) Project history in the beginning:

    master ---A---B---C
                \
                 D---E---F feature1
                          \
                           G---H feature2

(2) Rebase feature1 onto master and force pushed:

    master ---A---B------------------------C
                \                           \
                 D---E---F feature1(old)     D---E---F feature1
                          \
                           G---H feature2

(3) Rebase feature2 onto featrue1 (the new one)

    master ---A---B------------------------C
                                            \
                                             D---E---F feature1
                                                      \
                                                       G---H feature2

The most confused part is how to do (3) .. but no one has a clear answer of doing it.

I believe many people encountered the same issue as I did, when we were trying to do "rebase --onto", we found that feature1(old) is actually not existing!

    git rebase --onto feature1 feature1(old) feature2

Solution is to use below instead:

    git rebase --onto feature1 feature1@{1} feature2

The syntax feature1@{1} means "the last known state of feature1 before the rebase", answer is refereed from https://coderwall.com/p/xzsr9g/rebasing-dependent-branches-with-git