@@ -45,11 +45,32 @@ class VersionMerger(private val storeCache: IDeserializingKeyValueStore, private
45
45
}
46
46
}
47
47
48
+ private fun collectLatestNonMerges (version : CLVersion ? , visited : MutableSet <String >, result : MutableSet <Long >) {
49
+ if (version == null ) return
50
+ if (! visited.add(version.getContentHash())) return
51
+ if (version.isMerge()) {
52
+ collectLatestNonMerges(version.getMergedVersion1(), visited, result)
53
+ collectLatestNonMerges(version.getMergedVersion2(), visited, result)
54
+ } else {
55
+ result.add(version.id)
56
+ collectLatestNonMerges(version.baseVersion, visited, result)
57
+ }
58
+ }
59
+
48
60
protected fun mergeHistory (leftVersion : CLVersion , rightVersion : CLVersion ): CLVersion {
49
61
if (leftVersion.hash == rightVersion.hash) return leftVersion
50
62
val commonBase = Companion .commonBaseVersion(leftVersion, rightVersion)
51
63
if (commonBase?.hash == leftVersion.hash) return rightVersion
52
64
if (commonBase?.hash == rightVersion.hash) return leftVersion
65
+
66
+ val leftNonMerges = HashSet <Long >().also { collectLatestNonMerges(leftVersion, HashSet (), it) }
67
+ val rightNonMerges = HashSet <Long >().also { collectLatestNonMerges(rightVersion, HashSet (), it) }
68
+ if (leftNonMerges == rightNonMerges) {
69
+ // If there is no actual change on both sides, but they just did the same merge, we have to pick one
70
+ // of them, otherwise both sides will continue creating merges forever.
71
+ return if (leftVersion.id < rightVersion.id) leftVersion else rightVersion
72
+ }
73
+
53
74
val versionsToApply = LinearHistory (commonBase?.hash).load(leftVersion, rightVersion)
54
75
55
76
// println("merge ${getVersion(leftVersionHash).id.toString(16)} ${LinearHistory(storeCache, commonBase).load(leftVersion).map { it.id.toString(16) }} and ${getVersion(rightVersionHash).id.toString(16)} ${LinearHistory(storeCache, commonBase).load(rightVersion).map { it.id.toString(16) }}: ${commonBase?.let{getVersion(it)}?.id?.toString(16)} + ${versionsToApply.map { it.id.toString(16) }}")
0 commit comments