http://bugs.grommit.com/show_bug.cgi?id=347
Summary: recommit can strip local changes in such a way as to corrupt the manifest Product: SCM Migration Version: unspecified Platform: All OS/Version: Solaris 11/Nevada Status: NEW Severity: blocker Priority: P1 Component: cdm AssignedTo: scm-migration-dev at opensolaris.org ReportedBy: richlowe at richlowe.net Bart had a completely linear workspace, with a change he intended to putback. Someone else made a change in the gate he had to merge with, leaving him like this. Before Merge After * |\ * | * * | * | | | -> | | |/ |/ * * | | Then he recommitted with the old Hg, which failed (because Hg was old) and left his workspace at the new rev from the gate. At this point his change was linear, merge-turd free, and totally the right thing. Except Bart didn't know that... He thought his change had vanished (it hadn't), and restored it. Which left him like this: * <- Bart's change from the first recommit | * <- change from gate Bart's change again -> * | | | |/ * | Which left him with two heads again, so he merged again: Before Merge After * |\ * | * | | | * -> | * * | * | | | | | |/ |/ * * | | So, at this point we have Bart's change, twice, a random change, and a merge (+ (Bart's change) (+ (Bart's change) (random change))) Recommit does this: Takes those outgoing changes, commits them above the parent tip (the newest common node, in this case the change from the gate). 113 -> * * <- 112 | |\ \ | * <- 110 \ | | * <- 109 * | <- 111 | | |/ * <- 108 | where 113 is the reci, 108 the base, 109 the parent tip, 110 is the result of the first reci (the one Bart thought failed), and 111 the restored changes he thought were gone forever. reci then strips the now superfluous changes (the complete subgraphs rooted at 110 and 111) Removing 110 and 111 leave us (maintaining revnos, despite them changing, we really mean nodes here): 110 Strip 111 * <- 113 * <- 113 | | * <- 109 -> * <- 109 111 -> * | | | | | |/ | 108 -> * 108 -> * | | Which looks great, exactly what we wanted to happen, right? Except the manifest entry for 113 above has a linkrev that now doesn't exist (it refers to the a revno one higher than exists), which doesn't exist, and the workspace is corrupt. After the strip of 110 the manifests look thusly: 109 82752 76 51 109 c70da36d808c 047eabe09854 000000000000 110 82828 237 51 111 ce97ffb9392c c70da36d808c 000000000000 111 83065 153 51 111 c5c6709cd76c 047eabe09854 000000000000 Where the mapping to our simplified numbering is: 109 -> random change from the gate (109) 110 -> recommitted change (113) 111 -> Bart's change (111) So we have two changes with the same linkrev. This is already bogus, as best as I can tell. What really nails it, however, is when we remove 111, so the link rev referred to in the recommitted change no longer exists. Kablam. The first strip did something pretty bad, the second strip made it fatal. Now, experimentally, if these are done in reverse order (111 removed before 110), everything is fine. However, when I was testing the logic for removing multiple child-local branches, I had workspaces where the reverse was true. There's something subtly order dependent about stripping these and, currently, I don't know what it is. Investigation continues... -- Configure bugmail: http://bugs.grommit.com/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee.