I have a branch A, with several commits I want to squash, and from this branch has been created an other branch (B), with several commits I want also to squash.
I rebased the branch A from develop, and squashed all commits in one commit. OK.
I then try to rebase B from the A (whose SHA1 changed because of previous commit), but the window Git shows me the list of commits since the old branch A, not the squashed one.
Why ?
Here's what's happening, made clearer with some graphs. Initially, you start out with 3 branches,
develop,A, andB:Now you run
git rebase -i develop A(equivalent togit checkout A && git rebase -i develop) and squash all commits:f'is the squashed commit. BranchBstill references the unrelated and untouched commiti. Since every commit keeps an (immutable) reference to its parent commit (or parent commits), the original, unsquashed commitd,e, andfare still reachable fromB.When you now run
git rebase A B(or the equivalentgit checkout B && git rebase A), then Git will replay all commits reachable fromBthat are not reachable fromA. Looking at the graph it is clear that these are commitsd..i(d, e, f, g, h, i), including the original, unsquashed commits. Consequently, you would end up witha-b-c-f'-d-e-f-g-h-i– but sincef'already contains the changes ofd,e, andf, they cannot be reapplied and will result in conflicts.What you want to do instead is specify the upstream and new base explicitly:
git rebase --onto A f B(interactive rebase is supported as well with-i). Running this command results in the following history:or
a-b-c-f'-i'if you decide to squashg..iinto a single commit.