Git/Workflow/Topic/Conflicts

From KitwarePublic
< Git‎ | Workflow‎ | Topic
Jump to: navigation, search

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:

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:

Note that one may not merge the branch into the topic as in the single-integration-branch case because next may never be merged into a 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