MeanwhileInHell MeanwhileInHell - 2 months ago 9
Git Question

Rebasing branch1 with changes in master from branch2

I have two branches off

master
;
branch1
and
branch2
. I have some changes made on
branch1
and have an active PR up for this. I also have changes on
branch2
that have been reviewed and merged into
master
and the branch subsequently deleted.

I have updated my local
master
by doing a
git fetch -ap
and a
git pull
which brought down the changes made in
branch2
. I now want to update
branch1
with these changes so that the only differences are the ones I have made on that branch. I tried
git checkout branch1
followed by
git rebase master
.

However, when I do a
git status
on
branch1
it says:

On branch branch1
Your branch and 'origin/branch1' have diverged,
and have 3 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)


Doing a
git pull
here opens up a merge comment dialog. But now when I look at my PR on
branch1
it now includes the changes from
branch2
as new changes. What has happened here, and how can I fix this?

Answer

(For this answer, I'm assuming you have branch1 checked out. If not, do git checkout branch1.)

When you do git rebase master, you are rewriting the commits in branch1, since they now have a new parent. This is what your history might look like:

X--*--Y [master]
 \     \
  \     A'--B'--C' [branch1]  <--
   \                            | (git rebase master)
    A--B--C [origin/branch1] ----

where e.g. A' has the same contents as A, but a different commit hash, because its parent is Y instead of X.

Since the commits have changed, you will have to force-update origin. After you finish the rebase, you should do:

git push --force-with-lease

However, since you already did a git pull post-rebase, you'll need to fix that first. Do e.g.:

git reset --hard C'

Or:

git reset --hard HEAD^

This will remove the merge commit from branch1, and you can force push as described above. First, to ensure your branch was reset properly, do:

git log --oneline --decorate master..HEAD

The output of that command should show all the commits that should be in branch1, and only those commits.

(Aside: if you do git status at this point, you might see some output like this:

On branch branch1
Your branch is behind 'origin/branch1' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

You can safely ignore this warning, since the one of those commits was the merge commit, and the other was the 1 different commit from your original error message.)

As mentioned above, at this point you should do:

git push --force-with-lease

And now the remote branch1 will have the same commits as your local branch1.


Obligatory warning: Since a rebase rewrites history, this can be dangerous / disruptive for anyone else working on this branch. Be sure you clearly communicate what you have done with anyone you are collaborating with.

Comments