Git/Workflow/Topic/Conflicts
This page documents conflict resolution in a topic-based branchy workflow.
Whenever two paths of development make different changes to the same initial content conflicts may occur when merging the branches.
Single Integration Branch
Consider two conflicting topic branches, topic and other-topic, with the latter already merged to master:
...o----o-------o master \ \ / \ o---o other-topic \ o----o topic
An attempt to merge topic into master will fail with conflicts. One may use the following approaches to resolve the situation:
- Merge the topic to the branch
- Merge the branch to the topic
Topic-to-Single-Branch
If one performs the merge in a local work tree it is possible to simply resolve the conflicts and complete the merge:
...o----o-------o----o master \ \ / / \ o---o / other-topic \ / o---------o topic
This approach does not work when using a topic stage. It cannot resolve the conflicts automatically and may print instructions to follow the next approach.
Branch-to-Topic
Since a developer works on a topic branch locally one may simply merge the conflicting integration branch into the topic and resolve the conflicts:
...o----o-------o master \ \ / \ \ o---o \ other-topic \ \ o----o-------o topic
In order to maintain a good shape of history one may then
merge the topic into the integration branch without allowing a fast-forward (merge --no-ff
):
...o----o-------o-------o master \ \ / \ / \ o---o \ / other-topic \ \ / o----o-------o topic
Our topic stages use this approach when working with a single integration branch.
Multiple Integration Branches
In a workflow using multiple integration branches one must deal differently with conflicting topics. Consider two conflicting topic branches, topic and other-topic, with the latter already merged to next:
...o----o master . \ \ . \ o---o topic . \ . o--------o other-topic . \ ............o next
An attempt to merge topic into next will fail with conflicts. One may use the following approaches to resolve the situation:
- Merge the topic to the branch
- Merge one topic into the other
- Merge both topics into a resolution topic
Topic-to-Branch
If one performs the merge in a local work tree it is possible to simply resolve the conflicts and complete the merge:
...o----o master . \ \ . \ o--------o topic . \ \ . o--------o \ other-topic . \ \ ............o----o next
However, the topics eventually must be merged to master. Assume topic is merged first:
...o----o------------o master . \ \ / . \ o--------o topic . \ \ . o--------o \ other-topic . \ \ ............o----o next
An attempt to merge other-topic into master will fail with the same conflicts!
...o----o------------o-----? master . \ \ / / . \ o--------o / topic . \ \ / . o--------o----\-- other-topic . \ \ ............o----o next
The only branch that contains a resolution to these conflicts is next, but that may not be merged to master. Therefore one must resolve the conflicts a second time.
If the second resolution is not byte-for-byte identical to the first then the new master will not merge cleanly into next:
...o----o------------o-----o master . \ \ / / \ . \ o--------o / \ topic . \ \ / \ . o--------o----\-- \ other-topic . \ \ \ ............o----o---------? next
Then one must resolve conflicts a third time!
This approach works with manual merging but requires care. It does not work when using a topic stage that cannot resolve the conflicts automatically and may print instructions to follow the next approach.
Topic-to-Topic
The design of our topic-based workflow guarantees that work is always committed on topic branches and never directly on an integration branch. If conflicts occur while merging a topic into an integration branch it means that the topic conflics with another topic that has already been merged.
One may manually merge the conflicting other-topic into one's own topic and resolve the conflicts:
...o----o master . \ \ . \ o---o---o topic . \ / . o--------o other-topic . \ ............o next
Then topic will merge cleanly into next:
...o----o master . \ \ . \ o---o---o topic . \ / \ . o--------o \ other-topic . \ \ ............o---o next
Later topic may be merged cleanly into master to bring in both topics (or just topic if other-topic has already been merged):
...o----o-----------o master . \ \ / . \ o---o---o topic . \ / \ . o--------o \ other-topic . \ \ ............o---o next
Finally, master may be merged cleanly into next:
...o----o-----------o master . \ \ / \ . \ o---o---o \ topic . \ / \ \ . o--------o \ \ other-topic . \ \ \ ............o---o---o next
Note that this produces an artificial topic dependency introduced by the conflict resolution commit. See the next approach to avoid this problem.
Resolution Topic
The above approach introduces an artificial topic dependency because it asymmetrically favors one topic over another. Instead one may use a third topic to resolve the conflicts.
One may start a new resolve/topic/other-topic branch from topic, merge other-topic into it, and resolve the conflicts:
...o----o master . \ \ . \ o---o topic . \ \ . \ o resolve/topic/other-topic . \ / . o----o other-topic . \ ........o next
The resolution topic will merge cleanly into next to bring in the changes from topic through the conflict resolution commit:
...o----o master . \ \ . \ o---o topic . \ \ . \ o resolve/topic/other-topic . \ / \ . o----o \ other-topic . \ \ ........o---o next
Since topic and other-topic are still independent either may be merged to master first. Assume topic is merged first:
...o----o-------o master . \ \ / . \ o---o topic . \ \ . \ o resolve/topic/other-topic . \ / \ . o----o \ other-topic . \ \ ........o---o next
As above an attempt to merge other-topic directly into master will fail with the original conflicts but now we have a topic containing the resolution commit independent of next. One may merge the resolution topic to master to bring in the changes from other-topic and the conflict resolution:
...o----o-------o---o master . \ \ / / . \ o---o / topic . \ \ / . \ o resolve/topic/other-topic . \ / \ . o----o \ other-topic . \ \ ........o---o next
Finally, master may be merged cleanly into next:
...o----o-------o---o master . \ \ / / \ . \ o---o / \ topic . \ \ / \ . \ o \ resolve/topic/other-topic . \ / \ \ . o----o \ \ other-topic . \ \ \ ........o---o-------o next