示例#1
0
void ThreeWayMerge::detectConflicts (const MergeTask & task, MergeResult & mergeResult, bool reverseConflictMeta = false)
{
	Key our;
	cursor_t savedCursor = task.ours.getCursor ();
	task.ours.rewind ();

	while ((our = task.ours.next ()))
	{
		string theirLookup = rebasePath (our, task.ourParent, task.theirParent);
		Key theirLookupResult = task.theirs.lookup (theirLookup);

		// we have to copy it to obtain owner etc...
		Key mergeKey = rebaseKey (our, task.ourParent, task.mergeRoot);

		if (keyDataEqual (our, theirLookupResult))
		{
			// keydata matches, see if metakeys match
			if (keyMetaEqual (our, theirLookupResult))
			{
				if (task.ourParent.getFullName () == task.mergeRoot.getFullName ())
				{
					// the key was not rebased, we can reuse our (prevents that the key is rewritten)
					mergeResult.addMergeKey (our);
				}
				else
				{
					// the key causes no merge conflict, but the merge result is below a new parent
					mergeResult.addMergeKey (mergeKey);
				}
			}
			else
			{
				// metakeys are different
				mergeResult.addConflict (mergeKey, CONFLICT_META, CONFLICT_META);
			}
		}
		else
		{
			string baseLookup = rebasePath (our, task.ourParent, task.baseParent);
			Key baseLookupResult = task.base.lookup (baseLookup);

			// check if the keys was newly added in ours
			if (baseLookupResult)
			{
				// the key exists in base, check if the key still exists in theirs
				if (theirLookupResult)
				{
					// check if only they modified it
					if (!keyDataEqual (our, baseLookupResult) && keyDataEqual (theirLookupResult, baseLookupResult))
					{
						// the key was only modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, CONFLICT_MODIFY, CONFLICT_SAME,
								       reverseConflictMeta);
					}
					else
					{
						// check if both modified it
						if (!keyDataEqual (our, baseLookupResult) &&
						    !keyDataEqual (theirLookupResult, baseLookupResult))
						{
							// the key was modified on both sides
							mergeResult.addConflict (mergeKey, CONFLICT_MODIFY, CONFLICT_MODIFY);
						}
					}
				}
				else
				{
					// the key does not exist in theirs anymore, check if ours has modified it
					if (keyDataEqual (our, baseLookupResult))
					{
						// the key was deleted in theirs, and not modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, CONFLICT_SAME, CONFLICT_DELETE,
								       reverseConflictMeta);
					}
					else
					{
						// the key was deleted in theirs, but modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, CONFLICT_MODIFY, CONFLICT_DELETE,
								       reverseConflictMeta);
					}
				}
			}
			else
			{
				// the key does not exist in base, check if the key was added in theirs
				if (theirLookupResult)
				{
					// check if the key was added with the same value in theirs
					if (keyDataEqual (mergeKey, theirLookupResult))
					{
						if (keyMetaEqual (our, theirLookupResult))
						{
							// the key was added on both sides with the same value
							if (task.ourParent.getFullName () == task.mergeRoot.getFullName ())
							{
								// the key was not rebased, we can reuse our and prevent the sync flag being
								// set
								mergeResult.addMergeKey (our);
							}
							else
							{
								// the key causes no merge conflict, but the merge result is below a new
								// parent
								mergeResult.addMergeKey (mergeKey);
							}
						}
						else
						{
							// metakeys are different
							mergeResult.addConflict (mergeKey, CONFLICT_META, CONFLICT_META);
						}
					}
					else
					{
						// the key was added on both sides with different values
						mergeResult.addConflict (mergeKey, CONFLICT_ADD, CONFLICT_ADD);
					}
				}
				else
				{
					// the key was only added to ours
					addAsymmetricConflict (mergeResult, mergeKey, CONFLICT_ADD, CONFLICT_SAME, reverseConflictMeta);
				}
			}
		}
	}

	task.ours.setCursor (savedCursor);
}
示例#2
0
void ThreeWayMerge::detectConflicts(const MergeTask& task, MergeResult& mergeResult, bool reverseConflictMeta = false)
{
	Key our;
	cursor_t savedCursor = task.ours.getCursor ();
	task.ours.rewind ();

	while ((our = task.ours.next ()))
	{
		if (our.getName() == task.ourParent.getName())
			continue;

		string theirLookup = rebasePath (our, task.ourParent, task.theirParent);
		Key theirLookupResult = task.theirs.lookup (theirLookup);

		// we have to copy it to obtain owner etc...
		Key mergeKey = rebaseKey (our, task.ourParent, task.mergeRoot);

		if (keyDataEqual (our, theirLookupResult))
		{
			// keydata matches, see if metakeys match
			if (keyMetaEqual (our, theirLookupResult))
			{
				mergeResult.addMergeKey (mergeKey);
			}
			else
			{
				// metakeys are different
				mergeResult.addConflict (mergeKey, META, META);
			}
		}
		else
		{
			string baseLookup = rebasePath (our, task.ourParent, task.baseParent);
			Key baseLookupResult = task.base.lookup (baseLookup);

			// check if the keys was newly added in ours
			if (baseLookupResult)
			{
				// the key exists in base, check if the key still exists in theirs
				if (theirLookupResult)
				{
					// check if only they modified it
					if (!keyDataEqual (our, baseLookupResult) && keyDataEqual (theirLookupResult, baseLookupResult))
					{
						// the key was only modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, MODIFY, SAME, reverseConflictMeta);
					}
					else
					{
						// check if both modified it
						if (!keyDataEqual (our, baseLookupResult) && !keyDataEqual (theirLookupResult, baseLookupResult))
						{
							// the key was modified on both sides
							mergeResult.addConflict (mergeKey, MODIFY, MODIFY);
						}
					}
				}
				else
				{
					// the key does not exist in theirs anymore, check if ours has modified it
					if (keyDataEqual (our, baseLookupResult))
					{
						// the key was deleted in theirs, and not modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, SAME, DELETE, reverseConflictMeta);
					}
					else
					{
						// the key was deleted in theirs, but modified in ours
						addAsymmetricConflict (mergeResult, mergeKey, MODIFY, DELETE, reverseConflictMeta);
					}
				}
			}
			else
			{
				// the key does not exist in base, check if the key was added in theirs
				if (theirLookupResult)
				{
					// check if the key was added with the same value in theirs
					if (keyDataEqual (mergeKey, theirLookupResult))
					{
						if (keyMetaEqual (our, theirLookupResult))
						{
							// the key was added on both sides with the same value
							mergeResult.addMergeKey (mergeKey);
						}
						else
						{
							// metakeys are different
							mergeResult.addConflict (mergeKey, META, META);
						}
					}
					else
					{
						// the key was added on both sides with different values
						mergeResult.addConflict (mergeKey, ADD, ADD);
					}
				}
				else
				{
					// the key was only added to ours
					addAsymmetricConflict (mergeResult, mergeKey, ADD, SAME, reverseConflictMeta);
				}
			}
		}
	}

	task.ours.setCursor (savedCursor);
}