简体   繁体   中英

Git rebase from one parent commit on top of a new parent commit (that doesn't have the old parent commit as one of its parents)

EDIT: We are using Gerrit. Local changes are transferred to Gerrit, where they undergo review and are then merged (by Gerrit) to the remote master branch.

A number of times now I have run into a specific rebase problem that exceeds my limited understanding of how Git functions. Imagine the following scenario (while all this is happening, no other activity takes place on origin/master ):

You create a new commit A that is based directly on what is currently on origin/master . Before A has even been merged to origin/master , you already create a new commit B that is based directly on commit A .

Now while commit A is undergoing review, it is decided that commit A should be split up into two separate commits. So you create a new commit A0 that is based directly on origin/master and move part of the changes in A into the newly created A0 . Now A0 is merged, becoming the new origin/master . Next the original A (which is now slimmer because it no longer contains the stuff that was moved to A0 ) is rebased on top of A0 (ie on top of origin/master ) and then merged to origin/master . So far so good.

Next (to prepare for merging B to origin/master ) you try to rebase B on top of origin/master . And this is where it all goes horribly wrong (for me, anyway).

When I run the steps (in a Git bash) I normally do to rebase a change:

  • git fetch --prune
  • git rebase origin/master

Git complains that there is one conflict that must be resolved manually. In my case, this is a changelog.txt file. In B 's original history, this changelog.txt file contained one combined change log entry for the formerly combined A0 and A change. In the new parent B is being rebased on top of this combined change log entry has now been split into 2 separate change log entries, and apparently that is not something that Git can resolve automatically.

I'm fine with that. Resolving that myself shouldn't be particularly hard, so I start my graphical merge tool. HOWEVER, while the merge tool lets me choose between the old combined change log entry on one side and the new separate change log entries on the other side, I notice that the new change log entry supplied by B itself is missing completely (regardless of which choice I make)!! I don't understand why Git forgets about this part. What am I doing wrong?

The problem is that B is standing on top of the original A.... you could do this:

git rebase --onto origin/master B~1 B

This way you are only moving the very only revision that is B-related and not anything coming from A. If there is more than one revision related to B, just adjust the number of revisions on the second-to-last argument (3 revisions? B~3).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM