Author: ericwa
Date: Thu Mar 27 07:18:21 2014
New Revision: 10653

URL: http://svn.gna.org/viewcvs/etoile?rev=10653&view=rev
Log:
ProjectDemo/Typewriter: quickly hack in merge context menu in the revision 
history window

Modified:
    trunk/Etoile/Frameworks/CoreObject/Core/COBranch.h
    trunk/Etoile/Frameworks/CoreObject/Core/COBranch.m
    trunk/Etoile/Frameworks/CoreObject/Diff/COLeastCommonAncestor.m
    
trunk/Etoile/Frameworks/CoreObject/English.lproj/Commits/org.etoile.CoreObject.json
    trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWGraphRenderer.m
    
trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWHistoryWindowController.m

Modified: trunk/Etoile/Frameworks/CoreObject/Core/COBranch.h
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/Core/COBranch.h?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- trunk/Etoile/Frameworks/CoreObject/Core/COBranch.h  (original)
+++ trunk/Etoile/Frameworks/CoreObject/Core/COBranch.h  Thu Mar 27 07:18:21 2014
@@ -107,6 +107,7 @@
     ETUUID *_parentBranchUUID;
        NSMutableArray *_revisions;
        COBranch *_mergingBranch;
+       CORevision *_mergingRevision;
 }
 
 
@@ -400,13 +401,24 @@
 /**
  * The branch that is currently being merged. 
  *
- * Always returns nil unless explicitly set. 
+ * Always returns nil unless explicitly set. Only one of mergingBranch
+ * or mergingRevision can be set to non-nil.
  * 
  * If it is set at commit time, records the <em>current revision</em> of 
  * the merging branch as the merge parent of the new commit.
  */
 @property (nonatomic, strong) COBranch *mergingBranch;
 /**
+ * The revision that is currently being merged.
+ *
+ * Always returns nil unless explicitly set. Only one of mergingBranch
+ * or mergingRevision can be set to non-nil.
+ *
+ * If it is set at commit time, records the given revision
+ * as the merge parent of the new commit.
+ */
+@property (nonatomic, strong) CORevision *mergingRevision;
+/**
  * Returns a merge info object representing the changes between the receiver 
and 
  * the given branch to be merged.
  *

Modified: trunk/Etoile/Frameworks/CoreObject/Core/COBranch.m
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/Core/COBranch.m?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- trunk/Etoile/Frameworks/CoreObject/Core/COBranch.m  (original)
+++ trunk/Etoile/Frameworks/CoreObject/Core/COBranch.m  Thu Mar 27 07:18:21 2014
@@ -41,6 +41,7 @@
 @synthesize UUID = _UUID, persistentRoot = _persistentRoot;
 @synthesize shouldMakeEmptyCommit = _shouldMakeEmptyCommit, supportsRevert = 
_supportsRevert;
 @synthesize mergingBranch = _mergingBranch;
+@synthesize mergingRevision = _mergingRevision;
 
 + (void) initialize
 {
@@ -624,10 +625,17 @@
                if ([[modifiedItems itemUUIDs] count] > 0 || 
self.shouldMakeEmptyCommit)
                {
                        ETUUID *mergeParent = nil;
+                       ETAssert(self.mergingBranch == nil
+                                        || self.mergingRevision == nil);
                        if (self.mergingBranch != nil)
                        {
                                mergeParent = [[self.mergingBranch 
currentRevision] UUID];
                                self.mergingBranch = nil;
+                       }
+                       else if (self.mergingRevision != nil)
+                       {
+                               mergeParent = [self.mergingRevision UUID];
+                               self.mergingRevision = nil;
                        }
                        
                        ETUUID *revUUID = [ETUUID UUID];

Modified: trunk/Etoile/Frameworks/CoreObject/Diff/COLeastCommonAncestor.m
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/Diff/COLeastCommonAncestor.m?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- trunk/Etoile/Frameworks/CoreObject/Diff/COLeastCommonAncestor.m     
(original)
+++ trunk/Etoile/Frameworks/CoreObject/Diff/COLeastCommonAncestor.m     Thu Mar 
27 07:18:21 2014
@@ -13,27 +13,56 @@
 
 @implementation COEditingContext (CommonAncestor)
 
-/**
- * Naiive algorithm: gather paths from commitA to the root, and commitB to the 
root,
- * and return their first intersection.
- */
+- (void) addUUIDAndParents: (ETUUID *)aUUID persistentRoot: (ETUUID 
*)persistentRoot toSet: (NSMutableSet *)dest
+{
+       if ([dest containsObject: aUUID])
+               return;
+       
+       [dest addObject: aUUID];
+       
+       CORevision *revision = [self revisionForRevisionUUID: aUUID 
persistentRootUUID: persistentRoot];
+       
+       if (revision.parentRevision != nil)
+               [self addUUIDAndParents: revision.parentRevision.UUID 
persistentRoot: persistentRoot toSet: dest];
+       
+       if (revision.mergeParentRevision != nil)
+               [self addUUIDAndParents: revision.mergeParentRevision.UUID 
persistentRoot: persistentRoot toSet: dest];
+}
+
 - (ETUUID *)commonAncestorForCommit: (ETUUID *)commitA
                                                  andCommit: (ETUUID *)commitB
                                         persistentRoot: (ETUUID 
*)persistentRoot
 {
        NSMutableSet *ancestorsOfA = [NSMutableSet set];
        
-       for (ETUUID *temp = commitA; temp != nil; temp = [[[self 
revisionForRevisionUUID: temp persistentRootUUID: persistentRoot] 
parentRevision] UUID])
+       [self addUUIDAndParents: commitA persistentRoot: persistentRoot toSet: 
ancestorsOfA];
+       
+       // Do a BFS starting at commitB until we hit a commit in ancestorsOfA
+       // TODO: Check whether this makes sense
+       
+       NSMutableArray *siblingsArray = [NSMutableArray arrayWithObject: 
commitB];
+       
+       while ([siblingsArray count] > 0)
        {
-               [ancestorsOfA addObject: temp];
-       }
-       
-       for (ETUUID *temp = commitB; temp != nil; temp = [[[self 
revisionForRevisionUUID: temp persistentRootUUID: persistentRoot] 
parentRevision] UUID])
-       {
-               if ([ancestorsOfA containsObject: temp])
+               NSMutableArray *nextSiblingsArray = [NSMutableArray new];
+               
+               for (ETUUID *sibling in siblingsArray)
                {
-                       return temp;
+                       if ([ancestorsOfA containsObject: sibling])
+                       {
+                               return sibling;
+                       }
+                       
+                       CORevision *revision = [self revisionForRevisionUUID: 
sibling persistentRootUUID: persistentRoot];
+                       
+                       if (revision.parentRevision != nil)
+                               [nextSiblingsArray addObject: 
revision.parentRevision.UUID];
+                       
+                       if (revision.mergeParentRevision != nil)
+                               [nextSiblingsArray addObject: 
revision.mergeParentRevision.UUID];
                }
+               
+               [siblingsArray setArray: nextSiblingsArray];
        }
        
        // No common ancestor

Modified: 
trunk/Etoile/Frameworks/CoreObject/English.lproj/Commits/org.etoile.CoreObject.json
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/English.lproj/Commits/org.etoile.CoreObject.json?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- 
trunk/Etoile/Frameworks/CoreObject/English.lproj/Commits/org.etoile.CoreObject.json
 (original)
+++ 
trunk/Etoile/Frameworks/CoreObject/English.lproj/Commits/org.etoile.CoreObject.json
 Thu Mar 27 07:18:21 2014
@@ -52,6 +52,12 @@
                {
                        "type": "history",
                        "shortDescription": "Checkpoint"
-               }               
+               },
+               
+               "merge":
+               {
+                       "type": "history",
+                       "shortDescription": "Merge changes from '%@'"
+               }
        }
 }

Modified: trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWGraphRenderer.m
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWGraphRenderer.m?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWGraphRenderer.m       
(original)
+++ trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWGraphRenderer.m       
Thu Mar 27 07:18:21 2014
@@ -171,7 +171,19 @@
        }
        else
        {
-               ETUUID *parentUUID = [self parentUUIDsForRevisionUUID: 
currentRevision][0];
+               NSArray *parentUUIDs = [self parentUUIDsForRevisionUUID: 
currentRevision];
+               ETUUID *parentUUID = nil;
+               
+               // Set parentUUID to the first parent for which we have already 
assigned a level
+               for (ETUUID *aParent in parentUUIDs)
+               {
+                       if (levelForUUID[aParent] != nil)
+                       {
+                               parentUUID = aParent;
+                               break;
+                       }
+               }
+               
                ETAssert(parentUUID != nil);
                
                NSInteger value = [self maxLevelFromUUIDInclusive: 
currentRevision

Modified: 
trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWHistoryWindowController.m
URL: 
http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWHistoryWindowController.m?rev=10653&r1=10652&r2=10653&view=diff
==============================================================================
--- 
trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWHistoryWindowController.m 
    (original)
+++ 
trunk/Etoile/Frameworks/CoreObject/Samples/CommonUI/EWHistoryWindowController.m 
    Thu Mar 27 07:18:21 2014
@@ -49,6 +49,17 @@
        [self update];
        
        [[self window] setTitle: [self windowTitle]];
+       
+       [table setMenu: [self makeTableViewMenu]];
+}
+
+- (NSMenu *) makeTableViewMenu
+{
+       NSMenu *menu = [[NSMenu alloc] initWithTitle: @""];
+       
+       [menu addItemWithTitle:@"Merge into Current Revision" action: 
@selector(merge:) keyEquivalent:@""];
+       
+       return menu;
 }
 
 - (NSString *)windowTitle
@@ -168,6 +179,40 @@
        }
 }
 
+- (IBAction)merge:(id)sender
+{
+       const NSInteger clickedRow = [table clickedRow];
+       if (clickedRow < 0 || clickedRow >= [graphRenderer count])
+               return;
+       
+       CORevision *clickedRevision = (CORevision *)[graphRenderer 
revisionAtIndex: clickedRow];
+       CORevision *currentRevision = [inspectedBranch currentRevision];
+       
+       NSLog(@"Merge %@ into %@", clickedRevision, currentRevision);
+       
+       COMergeInfo *mergeInfo = [inspectedBranch mergeInfoForMergingRevision: 
clickedRevision];
+       
+       if (nil == mergeInfo)
+       {
+               NSLog(@"No merge info generated");
+               return;
+       }
+       if ([mergeInfo.diff hasConflicts])
+       {
+               NSLog(@"Can't merge, diff has conflicts. %@", mergeInfo.diff);
+               return;
+       }
+       
+       // FIXME: Inefficient, ugly
+       COObjectGraphContext *temp = [inspectedPersistentRoot 
objectGraphContextForPreviewingRevision: mergeInfo.baseRevision];
+    [mergeInfo.diff applyTo: temp];
+       [[inspectedBranch objectGraphContext] insertOrUpdateItems: (NSArray 
*)[[[temp loadedObjects] mappedCollection] storeItem]];
+       
+       inspectedBranch.mergingRevision = clickedRevision;
+       
+       [self commitWithIdentifier: @"merge" descriptionArguments: 
@[[clickedRevision localizedShortDescription]]];
+}
+
 /* Convenience */
 
 - (id<COTrackNode>) selectedNode


_______________________________________________
Etoile-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-cvs

Reply via email to