How to do a partial merge in git?

偶尔善良 提交于 2020-01-03 03:26:11

问题


This question is inspired by the following excellent post: https://blogs.msdn.microsoft.com/oldnewthing/20180312-00/?p=98215 https://blogs.msdn.microsoft.com/oldnewthing/20180313-00/?p=98225 https://blogs.msdn.microsoft.com/oldnewthing/20180314-00/?p=98235

This post explains why cherry picking is evil and how it can be replaced with partial merge. Here is the picture:

Its meaning is that if we need to make a change in the feature branch that will have to also be in the master branch, we do it on a patch branch and then merge it to both the feature and the master branches.

But it implies that we know beforehand that the change will have to be in the master too. The post does not explain what to do if the change is originally checked in to the feature branch and only later do we discover it has to be in the master branch as well.

What to do then? How to merge only this change to the master? No cherry picking, please.


回答1:


(As several people have noted, there is no such thing as a partial merge in Git.)

I am not the author of the original blog posts and cannot speak for him, but I will say that he is right in general. The inspiring example is a little silly, but this is almost inevitable when one attempts to make a simple example of why we might do something that looks complicated.

If you know in advance that some change needs to be applied to several branches (and are using Git), you can work your way back to the earliest commit at which the change can be made—which, by our definition of "be applied", is going to be before the other branches fork from this commit—and make a new branch from that point. You can then make the change and commit. This produces the patch branch (see the diagram Mr Chen shows in the third post, that you have copied into the question).

You can then merge this new branch into all the other branches, as shown here (and there).

But it implies that we know beforehand that the change will have to be in the master too.

Correct. In order to employ this strategy, we must know that this particular patch is destined to go into some set of N branches, and find a suitable ancestor commit that is contained in all of them.

The post does not explain what to do if the change is originally checked in to the feature branch and only later do we discover it has to be in [another] branch as well.

There is no perfect solution to this, but there is one that is Good Enough. It violates your complaint, though:

What to do then? How to merge only this change to the [other branch]? No cherry picking, please.

The way we do this is by identifying that ancestor commit—wherever it may be—and cherry-picking. (Sorry!) The cherry-pick creates one new commit that is solely on the patch branch. We then merge the patch branch into both branches, as if we had done the Right Thing the first time. This produces the following:

(apple)   (berry)
  M1---------M2     <-- master
 /          /
A----------P'     <-- patch
 \          \
  F1------P--F2     <-- feature
(apple)   (berry)

Note that merging patch into feature has no effect on the source tree in commit F2 on feature: the source tree in F2 matches that in the original patch P. This is true even if there are commits on feature after P, e.g.:

  M1---------M2     <-- master
 /          /
A----------P'     <-- patch
 \          \
  F1--P--Q---F2     <-- feature

If necessary, we can do the merge into feature with -s ours to avoid "undoing" some change or getting some sort of merge conflict. The point of doing this merge, into feature, is to make Git aware of the fact that the common ancestor of master and feature is now commit P'. Commit P' must exist, even if we have to create it just for this purpose. The easiest way to create it is to use git cherry-pick.

Cherry picking is a tool, not a solution. Mr Chen's blog post is pointing out that people use the tool poorly. That does not mean that the tool itself is bad!



来源:https://stackoverflow.com/questions/52527195/how-to-do-a-partial-merge-in-git

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!