简体   繁体   中英

How to merge a branch with a master which was partially rebased and force pushed?

Initially, I needed to revert some commits from master including merged pull request. Let's call it 'unwanted refactoring'.

But these changes would be needed in the future.

I created a new branch develop based on the current state of master to have these changes there.

  1. I decided to do a hard reset of master to the parent commit of pull request merge (It was stable state of repo):

    git reset --hard ad23b887

  2. And then, to pick other commits which are not 'unwanted refactoring':

    git cherry-pick

Now I want to do a force push command, which should overwrite the origin/master branch history.

In the future, I will need to merge 'unwanted refactoring' back to master from develop when it will be 100% tested. But how, then, should I merge these two branches, if, in fact, they have different histories (because of cherry-picks and resetting a HEAD)?

Is it the right way to revert commits with resetting a HEAD and cherry-picking only ones I need in my situation?

Ps My team consists of two people, and I don't see any problems with doing such manipulations.

Let's visualize it.

Initially, I needed to revert some commits from master including merged pull request...

A - B - C --------- M [master]
     \             /
      F - G - H - I 

I created a new branch develop based on the current state of master to have these changes there.

                      [develop]
A - B - C --------- M [master]
     \             /
      F - G - H - I 

I decided to do a hard reset of master to the parent commit of pull request merge (It was stable state of repo): git reset --hard ad23b887

Let's say ad23b887 is commit B.

A - B [master]
    |\
    | C ----------- M [develop]
     \             /
      F - G - H - I 

That's the same diagram, just shifted a bit so we can work with master.

And then, to pick other commits which are not 'unwanted refactoring': git cherry-pick

Let's say that's G and I.

A - B - G1 - I1 [master]
    |\
    | C ----------- M [develop]
     \             /
      F - G - H - I 

Now I want to do a force push command, which should overwrite the origin/master branch history.

Yes, but use git push --force-with-lease . It's safer. I have it aliased to repush.

In the future, I will need to merge 'unwanted refactoring' back to master from develop when it will be 100% tested. But how, then, should I merge these two branches, if, in fact, they have different histories (because of cherry-picks and resetting a HEAD)?

Rebase develop on top of master. This will replay develop's commits on top of master. The merge will go away. And so will the now redundant commits you cherry picked from because develop now already has those changes from master.

A - B - G1 - I1 [master]
    |\
    | C ----------- M [develop]
     \             /
      F - G - H - I 

$ git checkout develop
$ git rebase master

A - B - G1 - I1 [master]
              \
               C - F - H [develop]

Now you can merge develop through the normal PR process.

A - B - G1 - I1 -------- M1 [master]
              \         /
               C - F - H

Is it the right way to revert commits with resetting a HEAD and cherry-picking only ones I need in my situation?

Let's go back to just before you cherry picked.

Avoid generic branches like develop. Give it a name associated with what you're doing. A good choice is to use the ID in your issue tracker, this encourages every branch to have an issue.

A - B [master]
    |\
    | C ----------- M [issue/#1234]
     \             /
      F - G - H - I 

I would suggest never committing straight to master and instead always using feature branches . This ensures every change has gone through the PR process of review, QA, and so on. It means master is always stable to work on top of.

To do this, make a new branch just for incorporating the cherry picks.

$ git checkout -b issue/#abcd
$ git cherry-pick G I

      G1 - I1 [issue/#abcd]
     /
A - B [master]
    |\
    | C ----------- M [issue/#1234]
     \             /
      F - G - H - I 

Them merge it through the normal PR process.

      G1 - I1
     /       \
A - B ------- N [master]
    |\
    | C ----------- M [issue/#1234]
     \             /
      F - G - H - I 

And now rebase issue/#1234 on top of master.

      G1 - I1
     /       \
A - B ------- N [master]
               \
                C - F - H [issue/#1234]

And merge issue/#1234 through the normal PR process.

      G1 - I1
     /       \
A - B ------- N --------- M1 [master]
               \         /
                C - F - H

Those bumps in the history are referred to as "feature bubbles" and they're what you want to see. They help keep the history simple to follow, and master stable.

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