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); }
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); }