简体   繁体   中英

git How to merge a branch into the master branch by completely overwriting master branch

I started work on the branch. 分支上工作。 Almost one year ago, I created another branch in which I made some changes. ,我做了一些更改。 From that time on I continued work on dev branch. Now I want to merge dev into master which results in lot of conflicts. I want to merge dev into master by overwriting master branch's contents ie for any conflict that arises I want to keep dev branch's version of the code. How can it be done ?

You'll want to use a "merge using theirs" strategy, which is set using the -X flag

git checkout master
git merge -X theirs dev

You can specify the strategy option with -X switch:

git checkout master
git merge -X theirs dev

A bit explanation. The -X theirs means: Use recursive strategy with the merge but fallback to their changes if the strategy cannot resolve the conflict.

This is different from -s ours (for some reason there's no -s theirs ) which would be a greedy take ours always solution to conflicts.

git-merge(1) Merge Strategies section provides a deeper explanation on this.

您可以使用所有提交强制推送到master

git push -f origin master

As Paulo Bu noted , git provides different methods for this when you want a merge with an "ours" approach, but only one "out of the box" when you want a merge with a "theirs" approach. It's worth illustrating the two by example:

$ git merge -s ours deadbranch  # merge deadbranch and ignore all its code

or:

$ git merge -X ours livebranch  # merge livebranch but use ours when conflicting

Let me also note here that when you use git merge , git first finds the "merge base", the point at which the two branches were last in sync:

            o - X   <-- master
          /
o - o - B
          \
            o - Y   <-- otherbranch

Here B represents the commit that is the merge-base, X is the tip of your branch ( master ), and Y is the tip of the other branch. What git will do is diff B vs X and B vs Y .

Let's say that in "our" branch, master , we have files unchanged , no-conflicts , conflict , and removed . These names are with respect to what happened in the other two branches.

File unchanged is unchanged in the to-be-merged branch (that is, the diff from B to Y shows nothing at all for file unchanged ). git merge never touches it, so nothing changes no matter what arguments we give to git merge .

The other files have some changes in master and/or the other branch.

File no-conflicts has one change in master at the top, and one change in the other branch at the bottom. These two changes do not conflict. git merge -s recursive will combine the changes, whether or not you use the -X ours option. However, git merge -s ours will discard their change, keeping our version of file no-conflicts . For this case, the result is different.

File conflict has one change in master at the top of the file, and a different change in the other branch also at the top. (The changes could be anywhere, they just have to overlap. "At the top" makes it overlap.) That means these changes conflict. Using git merge -s recursive , you'll get a complaint and have to resolve the conflict. Add -X ours and git will take your change, throwing away their change. Using git merge -s ours , git will take your change and throw away their change—so for this case, the result is the same.

File removed has no change in master but is removed in the other branch. In this case, git merge -s recursive will remove the file, whether or not you use -X ours . However, git merge -s ours will ignore the removal.

In short, the difference between -s ours and -s recursive -X ours is that with the former, git completely ignores the diff from B to Y ; with the latter, git attempts to combine the diffs B -to- X (ours) and B -to- Y (theirs), but in the case of a conflict during combining, it picks the B -to- X change.

With -X theirs (which is really -s recursive -X theirs ), git attempts to combine the diffs, and in the case of conflict, chooses the B -to- Y change over the B -to- X change.


It is possible to achieve the equivalent of -s theirs even though git does not have this built in. To do this, use git merge --no-commit otherbranch , then git rm -rf . from the top level to remove the resulting merge (with or without conflicts), then git checkout otherbranch -- . from the top level to re-populate the tree and index based on otherbranch . Then simply git commit the result. It's pretty rare to want this, though, which is why git does not have it as a built in strategy.

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