简体   繁体   中英

Conflict when merging two branches with git

I have a problem with merging 2 branches. I have a xml file with the following content:

<?xml version="1.0" encoding="utf-8"?>
<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="sk" xsi:noNamespaceSchemaLocation="language.xsd">
  <topic name="topicName">
    <section name="sectionName">
      <pair key="key_1" state="0">value 1</pair>
      <pair key="key_2" state="0">value 2</pair>
    </section>
  </topic>
</language>

Then the following case:

The branch "master" changes at the xml file only the "state" from "0" to "1". ie

<?xml version="1.0" encoding="utf-8"?>
<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="sk" xsi:noNamespaceSchemaLocation="language.xsd">
  <topic name="topicName">
    <section name="sectionName">
      <pair key="key_1" state="1">value 1</pair>
      <pair key="key_2" state="1">value 2</pair>
    </section>
  </topic>
</language>

the changes are than commited and pushed to te cenral repository.

The branch "Test" addes a new node. ie :

<?xml version="1.0" encoding="utf-8"?>
<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="sk" xsi:noNamespaceSchemaLocation="language.xsd">
  <topic name="topicName">
    <section name="sectionName">
      <pair key="key_1" state="0">value 1</pair>
      <pair key="key_2" state="0">value 2</pair>
      <pair key="key_3" state="0">value 3</pair>
    </section>
  </topic>
</language>

the changes are than commited and pushed to te cenral repository.

When I merge the "Test" branch at the "master" branch I get a conflict. ie

[master] git pull origin Test

The conflicted file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<language xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="sk" xsi:noNamespaceSchemaLocation="language.xsd">
  <topic name="topicName">
    <section name="sectionName">
<<<<<<< HEAD
      <pair key="key_1" state="1">value 1</pair>
      <pair key="key_2" state="1">value 2</pair>
=======
      <pair key="key_1" state="0">value 1</pair>
      <pair key="key_2" state="0">value 2</pair>
      <pair key="key_3" state="0">value 3</pair>
>>>>>>> b872e7d1bbbe281482baefa73e322a34c475aa92
    </section>
  </topic>
</language>

I don't understand why these kind of changes lead to conflicts. I can assure that there are no other changes on the files, like spaces, tabs or new lines. (I have reproduced this kind of conflict many times)

When I open the conflicted file with merge tool, it shows no conflict. It shows only the changes, and the merge tool does not automatically merge the new line. (I use git version 1.7.10.4)

Can somebody explain why this happens and how can I avoid this kind of conflicts.

Thanks in advance.

EDIT : I was searching for better merge-tools for resolving git-conflicts. I found kdiff3 . When I did the command:

git mergetool --tool kdiff3 sk.xml

the tool did not show, but it did resolved the conflict automatically. I was very happy.

Now my questions:
1. why can not git do this?
2. Can "kdiff3" by trusted, that it solved the conflict good? I checked manually this type of conflict I posted, and it solved the conflict good. But is there potentiall that, this tool may merge the files automatically unproperly?

While us humans recognize that the 1st branch is just changed a 0 character on each of a pair of lines to 1 , most diff/merge tools don't see things that way. These programs are line oriented.
2 lines were deleted. 2 new lines were inserted in there place. Any similarity is irrelevant.

The 2nd branch inserts another line, but where? We know it's before the </section> line, but the 2 lines before it are cited for deletion by the other branch. The only thing that's the same is the <section ... > line.

A human might reasonably guess that the new key_3 line should be inserted after the two new key_1 & key_2 lines, but there's no reasonable way to be programmaticly sure of that.

Erring on the side of caution is not unreasonable.

Avoiding this would require byte/character oriented diff tools, but there are prices for that too.

Two lines have changed both on master and on Test branch. That's a typical case for a merge conflict.

Git can't know, if that state for key 1 and 2 shall now be 1 (as it is on master) or 0 (as it is on Test). We'll have to resolve that manually.

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