@@ -121,11 +121,11 @@
121 121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# looking at all changesets to create a sql which selects all
122 122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# the branch changesets from the state in one go instead of
123 123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# having to check each changeset separately. Consider this
124 124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# later, get the pass working first.
125 125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- # NOTE 2: Might we even be able to select the retrograde
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # NOTE 2: Might we even be able to select the backward branch
127 127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# changesets too ?
128 128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
129 129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
foreach cset [$graph nodes] {
130 130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if {![$cset isbranch]} continue
131 131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
CheckAndBreakBackwardBranch $graph $cset
@@ -135,11 +135,49 @@
135 135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
136 136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc CheckAndBreakBackwardBranch {graph cset} {
137 137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
while {[IsABackwardBranch $graph $cset]} {
138 138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
log write 5 breakacycle "Breaking backward branch changeset <[$cset id]>"
139 139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- break
140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Knowing that the branch is backward we now look at the
141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # individual revisions in the changeset and determine
142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # which of them are responsible for the overlap. This
143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # allows us to split them into two sets, one of
144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # non-overlapping revisions, and of overlapping ones. Each
145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # induces a new changeset, and the second may still be
146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # backward and need further splitting. Hence the looping.
147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ #
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # The border used for the split is the minimal commit
149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # position among the minimal sucessor commit positions for
150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # the revisions in the changeset.
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Note that individual revisions may not have revision
153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # changesets are predecessors and/or successors, leaving
154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # the limits partially or completely undefined.
155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # limits : dict (revision -> list (max predecessor commit, min sucessor commit))
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ComputeLimits $cset limits border
159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ log write 6 breakacycle "At commit position border $border"
161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Then we sort the file level items based on there they
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # sit relative to the border into before and after the
164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # border.
165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ SplitRevisions $limits normalrevisions backwardrevisions
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set replacements [project::rev split $cset $normalrevisions $backwardrevisions]
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ cyclebreaker replace $graph $cset $replacements
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # At last check that the normal frament is indeed not
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # backward, and iterate over the possibly still backward
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # second fragment.
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ struct::list assign $replacements normal backward
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {[IsABackwardBranch $dg $normal]} { trouble internal "The normal fragment is unexpectedly a backward branch" }
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set cset $backward
141 179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
142 180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
143 181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
144 182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
145 183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc IsABackwardBranch {dg cset} {
@@ -182,10 +220,89 @@
182 220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
[myproc ValidPosition]]
183 221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
184 222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
185 223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc ToPosition {cset} { $cset pos }
186 224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc ValidPosition {pos} { expr {$pos ne ""} }
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc ComputeLimits {cset lv bv} {
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ upvar 1 $lv thelimits $bv border
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Initialize the boundaries for all revisions.
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ array set limits {}
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach revision [$cset revisions] {
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set limits($revision) {0 {}}
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Compute and store the maximal predecessors per revision
237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach {revision csets} [$cset predecessormap] {
239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set s [Positions $csets]
240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $s]} continue
241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set limits($revision) [lreplace $limits($revision) 0 0 [max $s]]
242 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
244 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Compute and store the minimal successors per revision
245 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach {revision csets} [$cset successormap] {
247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set s [Positions $csets]
248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $s]} continue
249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set limits($revision) [lreplace $limits($revision) 1 1 [min $s]]
250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
252 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Check that the ordering at the file level is correct. We
253 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # cannot have backward ordering per revision, or something is
254 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # wrong.
255 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
256 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach revision [array names limits] {
257 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ struct::list assign $limits($revision) maxp mins
258 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Handle min successor position "" as representing infinity
259 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {$mins eq ""} continue
260 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {$maxp < $mins} continue
261 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
262 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ trouble internal "Branch revision $revision is backward at file level ($maxp >= $mins)"
263 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
264 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
265 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # Save the limits for the splitter, and compute the border at
266 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # which to split as the minimum of all minimal successor
267 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ # positions.
268 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
269 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set thelimits [array get limits]
270 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set border [min [struct::list filter [struct::list map [Values $thelimits] \
271 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ [myproc MinSuccessorPosition]] \
272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ [myproc ValidPosition]]]
273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc Values {dict} {
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set res {}
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach {k v} $dict { lappend res $v }
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return $res
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
282 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc MinSuccessorPosition {item} { lindex $item 1 }
283 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
284 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ proc SplitRevisions {limits nv bv} {
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ upvar 1 $nv normalrevisions $bv backwardrevisions
286 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
287 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set normalrevisions {}
288 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ set backwardrevisions {}
289 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ foreach {rev v} $limits {
291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ struct::list assign $v maxp mins
292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {$maxp >= $border} {
293 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lappend backwardrevisions $rev
294 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
295 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ lappend normalrevisions $rev
296 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $normalrevisions]} { trouble internal "Set of normal revisions is empty" }
300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if {![llength $backwardrevisions]} { trouble internal "Set of backward revisions is empty" }
301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
187 304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
188 305 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
# # ## ### ##### ######## #############
189 306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
190 307 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
proc SaveOrder {cset pos} {
191 308 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
192 309 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!