Commits

Jens Alfke  committed 93d09ce

Overhauled the infamous _checkRevisions, and made it stop screwing up if revisions disappear (i.e. after a rollback.) Should also fix KVO exceptions that people keep reporting.

  • Participants
  • Parent commits 4d1a90b

Comments (0)

Files changed (2)

File Source/HgRepository.m

     if( tip==NSNotFound )
         return NO;
     
+    NSMutableArray *nuRevisions = [_revisions mutableCopy];
+    
     HgRevision *tipRevision = self.tipRevision;
     int curTip = tipRevision ?tipRevision.localNumber :-1;
-    if( tip != curTip ) {
-        // Revisions have changed!
+    if( tip > curTip ) {
+        // New revisions have been added!
         LogTo(HgRepository,@"_checkRevisions: Tip changed from %i to %i (cur=%i) ... updating revisions", curTip,tip, curRevNo);
 
         // Run "hg log" to get all revisions of this repository:
                   @"Unexpected revision numbers from log: expected starting %u, got %u", 
                   curTip+1, [[op.revisions objectAtIndex: 0] localNumber]);
         
-        // Add the new revisions, but before the uncommitted one if any:
-        NSMutableArray *nuRevisions = [_revisions mutableCopy];
+        // Add the new revisions, but before the uncommitted one:
         [nuRevisions removeObject: _uncommittedRevision];
         [nuRevisions addObjectsFromArray: op.revisions];
         [nuRevisions addObject: _uncommittedRevision];
         
-        _currentRevision = [nuRevisions objectAtIndex: curRevNo];
-        _uncommittedRevision.parent = _currentRevision;
-        _uncommittedRevision.parent2 = curParent2>=0 ?[nuRevisions objectAtIndex: curParent2] :nil;
+    } else if( tip < curTip ) {
+        // Revisions have been removed, due to a rollback:
+        [nuRevisions removeObjectsInRange: NSMakeRange(tip+1, curTip-tip)];
                 
-        self.revisions = nuRevisions;
-        
-        [self _checkWorkingTree: &error];
-        return YES;
-        
     } else if( curRevNo != _uncommittedRevision.parent.localNumber || curParent2 != parent2) {
         // A different revision is current; or the parents have changed
         LogTo(HgRepository, @"_checkRevisions: Current revision changed to %i/%i", curRevNo,curParent2);
-        [self willChangeValueForKey: @"revisions"];
-        _currentRevision = curRevNo>=0 ?[_revisions objectAtIndex: curRevNo] :nil;
-        _uncommittedRevision.parent = _currentRevision;
-        _uncommittedRevision.parent2 = curParent2>=0 ?[_revisions objectAtIndex: curParent2] :nil;
-        if (_revisions.count==0)
-            _revisions = $array(_uncommittedRevision);
-        [self didChangeValueForKey: @"revisions"];
-        [self _checkWorkingTree: &error];
-        return YES;
     } else {
         LogTo(HgRepository,@"_checkRevisions: No change");
+        return NO;
     }
-    return NO;
+
+    // Revision list must end with the uncommitted revision:
+    if (nuRevisions.count==0)
+        nuRevisions = $array(_uncommittedRevision);
+    else
+        AssertEq([nuRevisions lastObject],_uncommittedRevision);
+    
+    // Update the list of revisions, the current revision, and the uncommitted revision's parents:
+    [self willChangeValueForKey: @"currentRevision"];
+    [self willChangeValueForKey: @"revisions"];
+    _currentRevision = curRevNo>=0 ?[nuRevisions objectAtIndex: curRevNo] :nil;
+    _uncommittedRevision.parent = _currentRevision;
+    _uncommittedRevision.parent2 = curParent2>=0 ?[nuRevisions objectAtIndex: curParent2] :nil;
+    if (!$equal(nuRevisions,self.revisions))
+        self.revisions = nuRevisions;
+    [self didChangeValueForKey: @"revisions"];
+    [self willChangeValueForKey: @"currentRevision"];
+
+    [self _checkWorkingTree: &error];
+    return YES;
 }
 
 

File Source/HgUncommittedRevision.m

     _shortComment = nil;
 }
 
++ (NSSet*) keyPathsForValuesAffectingComment {
+    return [NSSet setWithObject: @"root.isUncommitted"];
+}
+
 - (NSString*) formattedDescription                  {return _comment;}
 - (void) setFormattedDescription: (NSString*)str    {self.comment = str;}