diff --git a/Classes/Controllers/PBDiffWindowController.m b/Classes/Controllers/PBDiffWindowController.m index 8b525bd8a..2028363ee 100644 --- a/Classes/Controllers/PBDiffWindowController.m +++ b/Classes/Controllers/PBDiffWindowController.m @@ -34,7 +34,7 @@ + (void) showDiffWindowWithFiles:(NSArray *)filePaths fromCommit:(PBGitCommit *) if (!diffCommit) diffCommit = [startCommit.repository headCommit]; - NSString *commitSelector = [NSString stringWithFormat:@"%@..%@", [startCommit realSha], [diffCommit realSha]]; + NSString *commitSelector = [NSString stringWithFormat:@"%@..%@", startCommit.SHA, diffCommit.SHA]; NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"diff", @"--no-ext-diff", commitSelector, nil]; if (![PBGitDefaults showWhitespaceDifferences]) diff --git a/Classes/Controllers/PBGitCommitController.h b/Classes/Controllers/PBGitCommitController.h index 060733f24..ea19c1db9 100644 --- a/Classes/Controllers/PBGitCommitController.h +++ b/Classes/Controllers/PBGitCommitController.h @@ -22,9 +22,16 @@ PBGitIndex *index; IBOutlet PBCommitMessageView *commitMessageView; + + BOOL stashKeepIndex; + IBOutlet NSArrayController *unstagedFilesController; IBOutlet NSArrayController *cachedFilesController; + IBOutlet NSArrayController *trackedFilesController; + + IBOutlet NSTabView *controlsTabView; IBOutlet NSButton *commitButton; + IBOutlet NSButton *stashButton; IBOutlet PBGitIndexController *indexController; IBOutlet PBWebChangesController *webController; @@ -32,9 +39,15 @@ } @property(readonly) PBGitIndex *index; +@property(assign) BOOL stashKeepIndex; - (IBAction) refresh:(id) sender; - (IBAction) commit:(id) sender; - (IBAction) forceCommit:(id) sender; -- (IBAction)signOff:(id)sender; +- (IBAction) signOff:(id)sender; +- (IBAction) stashChanges:(id) sender; + +- (NSView *) nextKeyViewFor:(NSView *)view; +- (NSView *) previousKeyViewFor:(NSView *)view; + @end diff --git a/Classes/Controllers/PBGitCommitController.m b/Classes/Controllers/PBGitCommitController.m index e10067f82..a9552fdec 100644 --- a/Classes/Controllers/PBGitCommitController.m +++ b/Classes/Controllers/PBGitCommitController.m @@ -14,13 +14,16 @@ #import "PBNiceSplitView.h" #import "PBGitRepositoryWatcher.h" #import "PBCommitMessageView.h" +#import "PBGitIndexController.h" #import #import #define kCommitSplitViewPositionDefault @"Commit SplitView Position" +#define kControlsTabIndexCommit 0 +#define kControlsTabIndexStash 1 -@interface PBGitCommitController () +@interface PBGitCommitController () - (void)refreshFinished:(NSNotification *)notification; - (void)commitWithVerification:(BOOL) doVerify; - (void)commitStatusUpdated:(NSNotification *)notification; @@ -36,6 +39,7 @@ - (void)saveCommitSplitViewPosition; @implementation PBGitCommitController @synthesize index; +@synthesize stashKeepIndex; - (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller { @@ -62,11 +66,13 @@ - (void)awakeFromNib [super awakeFromNib]; commitMessageView.repository = self.repository; + commitMessageView.delegate = self; [commitMessageView setTypingAttributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:12.0] forKey:NSFontAttributeName]]; [unstagedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasUnstagedChanges == 1"]]; [cachedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"hasStagedChanges == 1"]]; + [trackedFilesController setFilterPredicate:[NSPredicate predicateWithFormat:@"status > 0"]]; [unstagedFilesController setSortDescriptors:[NSArray arrayWithObjects: [[NSSortDescriptor alloc] initWithKey:@"status" ascending:false], @@ -126,6 +132,8 @@ - (IBAction)signOff:(id)sender - (void) refresh:(id) sender { + [controlsTabView selectTabViewItemAtIndex:kControlsTabIndexCommit]; + self.isBusy = YES; self.status = @"Refreshing index…"; [index refresh]; @@ -139,6 +147,12 @@ - (void) updateView [self refresh:nil]; } +- (IBAction) stashChanges:(id)sender +{ + NSLog(@"stash changes: %@", stashKeepIndex ? @"keep index" : @""); + [self.repository stashSaveWithKeepIndex:stashKeepIndex]; +} + - (IBAction) commit:(id) sender { [self commitWithVerification:YES]; @@ -229,12 +243,12 @@ - (void)indexChanged:(NSNotification *)notification { [cachedFilesController rearrangeObjects]; [unstagedFilesController rearrangeObjects]; - if ([[cachedFilesController arrangedObjects] count]) { - [commitButton setEnabled:YES]; - } else { - [commitButton setEnabled:NO]; - } - + + NSUInteger tracked = [[trackedFilesController arrangedObjects] count]; + NSUInteger staged = [[cachedFilesController arrangedObjects] count]; + + [commitButton setEnabled:(staged > 0)]; + [stashButton setEnabled:(staged > 0 || tracked > 0)]; } - (void)indexOperationFailed:(NSNotification *)notification @@ -316,4 +330,70 @@ - (void)restoreCommitSplitViewPositiion [commitSplitView setHidden:NO]; } +#pragma mark Handle "alt" key-down/up events +// to toggle commit/stash controls + +- (void)flagsChanged:(NSEvent *)theEvent +{ + BOOL altDown = !!([theEvent modifierFlags] & NSAlternateKeyMask); + int currIndex = [controlsTabView indexOfTabViewItem:controlsTabView.selectedTabViewItem]; + int desiredIndex = altDown ? kControlsTabIndexStash : kControlsTabIndexCommit; + if (currIndex != desiredIndex) { + [controlsTabView selectTabViewItemAtIndex:desiredIndex]; + } +} + +#pragma mark NSTextView delegate methods + +- (void)focusTable:(NSTableView *)table +{ + if ([table numberOfRows] > 0) { + if ([table numberOfSelectedRows] == 0) { + [table selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:NO]; + } + [[table window] makeFirstResponder:table]; + } +} + +- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector; +{ + if (commandSelector == @selector(insertTab:)) { + [self focusTable:indexController.stagedTable]; + return YES; + } else if (commandSelector == @selector(insertBacktab:)) { + [self focusTable:indexController.unstagedTable]; + return YES; + } + return NO; +} + +# pragma mark Key View Chain + +-(NSView *)nextKeyViewFor:(NSView *)view +{ + NSView * next = nil; + if (view == indexController.unstagedTable) { + next = commitMessageView; + } + else if (view == commitMessageView) { + next = indexController.stagedTable; + } + else if (view == indexController.stagedTable) { + next = commitButton; + } + return next; +} + +-(NSView *)previousKeyViewFor:(NSView *)view +{ + NSView * next = nil; + if (view == indexController.stagedTable) { + next = commitMessageView; + } + else if (view == commitMessageView) { + next = indexController.unstagedTable; + } + return next; +} + @end diff --git a/Classes/Controllers/PBGitHistoryController.m b/Classes/Controllers/PBGitHistoryController.m index ef37d2c23..722af6aca 100644 --- a/Classes/Controllers/PBGitHistoryController.m +++ b/Classes/Controllers/PBGitHistoryController.m @@ -296,9 +296,9 @@ - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:( [self updateStatus]; if ([repository.currentBranch isSimpleRef]) - [self selectCommit:[repository shaForRef:[repository.currentBranch ref]]]; + [self selectCommit:[repository OIDForRef:repository.currentBranch.ref]]; else - [self selectCommit:[[self firstCommit] sha]]; + [self selectCommit:self.firstCommit.OID]; return; } @@ -322,7 +322,11 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if ([menuItem action] == @selector(setTreeView:)) { [menuItem setState:(self.selectedCommitDetailsIndex == kHistoryTreeViewIndex) ? NSOnState : NSOffState]; } - return YES; + + if ([self respondsToSelector:[menuItem action]]) + return YES; + + return [[self nextResponder] validateMenuItem:menuItem]; } - (IBAction) setDetailedView:(id)sender @@ -382,7 +386,7 @@ - (void) copyCommitInfo PBGitCommit *commit = [[commitController selectedObjects] objectAtIndex:0]; if (!commit) return; - NSString *info = [NSString stringWithFormat:@"%@ (%@)", [[commit realSha] substringToIndex:10], [commit subject]]; + NSString *info = [NSString stringWithFormat:@"%@ (%@)", [commit.SHA substringToIndex:10], commit.subject]; NSPasteboard *a =[NSPasteboard generalPasteboard]; [a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; @@ -395,7 +399,7 @@ - (void) copyCommitSHA PBGitCommit *commit = [[commitController selectedObjects] objectAtIndex:0]; if (!commit) return; - NSString *info = [[commit realSha] substringWithRange:NSMakeRange(0, 7)]; + NSString *info = [commit.SHA substringWithRange:NSMakeRange(0, 7)]; NSPasteboard *a =[NSPasteboard generalPasteboard]; [a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; @@ -487,9 +491,9 @@ - (void) scrollSelectionToTopOfViewFrom:(NSInteger)oldIndex commitList.useAdjustScroll = NO; } -- (NSArray *) selectedObjectsForSHA:(GTOID *)commitSHA +- (NSArray *) selectedObjectsForOID:(GTOID *)commitOID { - NSPredicate *selection = [NSPredicate predicateWithFormat:@"sha == %@", commitSHA]; + NSPredicate *selection = [NSPredicate predicateWithFormat:@"OID == %@", commitOID]; NSArray *selectedCommits = [[commitController content] filteredArrayUsingPredicate:selection]; if (([selectedCommits count] == 0) && [self firstCommit]) @@ -498,14 +502,14 @@ - (NSArray *) selectedObjectsForSHA:(GTOID *)commitSHA return selectedCommits; } -- (void)selectCommit:(GTOID *)commitSHA +- (void)selectCommit:(GTOID *)commitOID { - if (!forceSelectionUpdate && [[[[commitController selectedObjects] lastObject] sha] isEqual:commitSHA]) + if (!forceSelectionUpdate && [[[commitController.selectedObjects lastObject] OID] isEqual:commitOID]) return; NSInteger oldIndex = [[commitController selectionIndexes] firstIndex]; - NSArray *selectedCommits = [self selectedObjectsForSHA:commitSHA]; + NSArray *selectedCommits = [self selectedObjectsForOID:commitOID]; [commitController setSelectedObjects:selectedCommits]; [self scrollSelectionToTopOfViewFrom:oldIndex]; @@ -564,31 +568,6 @@ - (void)showCommitsFromTree:(id)sender [searchController setHistorySearch:searchString mode:kGitXPathSearchMode]; } -- (void)showInFinderAction:(id)sender -{ - NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"]; - NSString *path; - NSWorkspace *ws = [NSWorkspace sharedWorkspace]; - - for (NSString *filePath in [sender representedObject]) { - path = [workingDirectory stringByAppendingPathComponent:filePath]; - [ws selectFile: path inFileViewerRootedAtPath:path]; - } - -} - -- (void)openFilesAction:(id)sender -{ - NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"]; - NSString *path; - NSWorkspace *ws = [NSWorkspace sharedWorkspace]; - - for (NSString *filePath in [sender representedObject]) { - path = [workingDirectory stringByAppendingPathComponent:filePath]; - [ws openFile:path]; - } -} - - (void) checkoutFiles:(id)sender { NSMutableArray *files = [NSMutableArray array]; @@ -627,7 +606,7 @@ - (NSArray *)menuItemsForPaths:(NSArray *)paths PBGitRef *headRef = [[repository headRef] ref]; NSString *headRefName = [headRef shortName]; NSString *diffTitle = [NSString stringWithFormat:@"Diff %@ with %@", multiple ? @"files" : @"file", headRefName]; - BOOL isHead = [[selectedCommit sha] isEqual:[repository headSHA]]; + BOOL isHead = [selectedCommit.OID isEqual:repository.headOID]; NSMenuItem *diffItem = [[NSMenuItem alloc] initWithTitle:diffTitle action:isHead ? nil : @selector(diffFilesAction:) keyEquivalent:@""]; @@ -644,7 +623,6 @@ - (NSArray *)menuItemsForPaths:(NSArray *)paths NSArray *menuItems = [NSArray arrayWithObjects:historyItem, diffItem, checkoutItem, finderItem, openFilesItem, nil]; for (NSMenuItem *item in menuItems) { - [item setTarget:self]; [item setRepresentedObject:filePaths]; } diff --git a/Classes/Controllers/PBGitIndexController.h b/Classes/Controllers/PBGitIndexController.h index 2e7277a1c..44b831a83 100644 --- a/Classes/Controllers/PBGitIndexController.h +++ b/Classes/Controllers/PBGitIndexController.h @@ -18,10 +18,16 @@ IBOutlet NSTableView *stagedTable; } +@property (readonly) NSTableView *unstagedTable; +@property (readonly) NSTableView *stagedTable; + - (IBAction) rowClicked:(NSCell *) sender; - (IBAction) tableClicked:(NSTableView *)tableView; - (NSMenu *) menuForTable:(NSTableView *)table; +- (NSView *) nextKeyViewFor:(NSView *)view; +- (NSView *) previousKeyViewFor:(NSView *)view; + - (void) stageSelectedFiles; - (void) unstageSelectedFiles; diff --git a/Classes/Controllers/PBGitIndexController.m b/Classes/Controllers/PBGitIndexController.m index ec7f575d9..faa7ac088 100644 --- a/Classes/Controllers/PBGitIndexController.m +++ b/Classes/Controllers/PBGitIndexController.m @@ -17,8 +17,12 @@ @interface PBGitIndexController () - (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force; @end +// FIXME: This isn't a view/window/whatever controller, though it acts like one... +// See for example -menuForTable and its setTarget: calls. @implementation PBGitIndexController +@synthesize stagedTable, unstagedTable; + - (void)awakeFromNib { [unstagedTable setDoubleAction:@selector(tableClicked:)]; @@ -99,20 +103,17 @@ - (NSMenu *) menuForTable:(NSTableView *)table if ([table tag] == 0) { NSMenuItem *stageItem = [[NSMenuItem alloc] initWithTitle:@"Stage Changes" action:@selector(stageFilesAction:) keyEquivalent:@"s"]; [stageItem setTarget:self]; - [stageItem setRepresentedObject:selectedFiles]; [menu addItem:stageItem]; } else if ([table tag] == 1) { NSMenuItem *unstageItem = [[NSMenuItem alloc] initWithTitle:@"Unstage Changes" action:@selector(unstageFilesAction:) keyEquivalent:@"u"]; [unstageItem setTarget:self]; - [unstageItem setRepresentedObject:selectedFiles]; [menu addItem:unstageItem]; } NSString *title = [selectedFiles count] == 1 ? @"Open file" : @"Open files"; NSMenuItem *openItem = [[NSMenuItem alloc] initWithTitle:title action:@selector(openFilesAction:) keyEquivalent:@""]; - [openItem setTarget:self]; - [openItem setRepresentedObject:selectedFiles]; + [openItem setTarget:commitController.repository]; [menu addItem:openItem]; // Attempt to ignore @@ -120,14 +121,12 @@ - (NSMenu *) menuForTable:(NSTableView *)table NSString *ignoreText = [selectedFiles count] == 1 ? @"Ignore File": @"Ignore Files"; NSMenuItem *ignoreItem = [[NSMenuItem alloc] initWithTitle:ignoreText action:@selector(ignoreFilesAction:) keyEquivalent:@""]; [ignoreItem setTarget:self]; - [ignoreItem setRepresentedObject:selectedFiles]; [menu addItem:ignoreItem]; } if ([selectedFiles count] == 1) { NSMenuItem *showInFinderItem = [[NSMenuItem alloc] initWithTitle:@"Show in Finder" action:@selector(showInFinderAction:) keyEquivalent:@""]; - [showInFinderItem setTarget:self]; - [showInFinderItem setRepresentedObject:selectedFiles]; + [showInFinderItem setTarget:commitController.repository]; [menu addItem:showInFinderItem]; } @@ -140,52 +139,63 @@ - (NSMenu *) menuForTable:(NSTableView *)table break; } } - if (!addDiscardMenu) - { - return menu; - } - NSMenuItem *discardItem = [[NSMenuItem alloc] initWithTitle:@"Discard changes…" action:@selector(discardFilesAction:) keyEquivalent:@""]; - [discardItem setTarget:self]; - [discardItem setAlternate:NO]; - [discardItem setRepresentedObject:selectedFiles]; + if (addDiscardMenu) + { + NSMenuItem *discardItem = [[NSMenuItem alloc] initWithTitle:@"Discard changes…" action:@selector(discardFilesAction:) keyEquivalent:@""]; + [discardItem setAlternate:NO]; + [discardItem setTarget:self]; - [menu addItem:discardItem]; + [menu addItem:discardItem]; - NSMenuItem *discardForceItem = [[NSMenuItem alloc] initWithTitle:@"Discard changes" action:@selector(forceDiscardFilesAction:) keyEquivalent:@""]; - [discardForceItem setTarget:self]; - [discardForceItem setAlternate:YES]; - [discardForceItem setRepresentedObject:selectedFiles]; - [discardForceItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; - [menu addItem:discardForceItem]; - - BOOL trashInsteadOfDiscard = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7; - if (trashInsteadOfDiscard) - { - for (PBChangedFile* file in selectedFiles) - { - if (file.status != NEW) - { - trashInsteadOfDiscard = NO; - break; - } - } - } - - if (trashInsteadOfDiscard && [selectedFiles count] > 0) - { - NSMenuItem* moveToTrashItem = [[NSMenuItem alloc] initWithTitle:@"Move to Trash" action:@selector(moveToTrashAction:) keyEquivalent:@""]; - [moveToTrashItem setTarget:self]; - [moveToTrashItem setRepresentedObject:selectedFiles]; - [menu addItem:moveToTrashItem]; - - [menu removeItem:discardItem]; - [menu removeItem:discardForceItem]; - } + NSMenuItem *discardForceItem = [[NSMenuItem alloc] initWithTitle:@"Discard changes" action:@selector(forceDiscardFilesAction:) keyEquivalent:@""]; + [discardForceItem setAlternate:YES]; + [discardForceItem setKeyEquivalentModifierMask:NSAlternateKeyMask]; + [discardForceItem setTarget:self]; + [menu addItem:discardForceItem]; + BOOL trashInsteadOfDiscard = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7; + if (trashInsteadOfDiscard) + { + for (PBChangedFile* file in selectedFiles) + { + if (file.status != NEW) + { + trashInsteadOfDiscard = NO; + break; + } + } + } + + if (trashInsteadOfDiscard && [selectedFiles count] > 0) + { + NSMenuItem* moveToTrashItem = [[NSMenuItem alloc] initWithTitle:@"Move to Trash" action:@selector(moveToTrashAction:) keyEquivalent:@""]; + [moveToTrashItem setTarget:self]; + [menu addItem:moveToTrashItem]; + + [menu removeItem:discardItem]; + [menu removeItem:discardForceItem]; + } + } + + for (NSMenuItem *item in [menu itemArray]) { + [item setRepresentedObject:selectedFiles]; + } + return menu; } +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + if ([self respondsToSelector:[menuItem action]]) + return YES; + + if ([commitController respondsToSelector:[menuItem action]]) + return YES; + + return [[commitController nextResponder] validateMenuItem:menuItem]; +} + - (void) stageSelectedFiles { [commitController.index stageFiles:[unstagedFilesController selectedObjects]]; @@ -207,14 +217,6 @@ - (void) unstageFilesAction:(id) sender [commitController.index unstageFiles:[sender representedObject]]; } -- (void) openFilesAction:(id) sender -{ - NSArray *files = [sender representedObject]; - NSString *workingDirectory = [commitController.repository workingDirectory]; - for (PBChangedFile *file in files) - [[NSWorkspace sharedWorkspace] openFile:[workingDirectory stringByAppendingPathComponent:[file path]]]; -} - - (void) ignoreFilesAction:(id) sender { NSArray *selectedFiles = [sender representedObject]; @@ -239,28 +241,16 @@ - (void)forceDiscardFilesAction:(id) sender [self discardChangesForFiles:selectedFiles force:TRUE]; } -- (void) showInFinderAction:(id) sender -{ - NSArray *selectedFiles = [sender representedObject]; - if ([selectedFiles count] == 0) - return; - NSString *workingDirectory = [[commitController.repository workingDirectory] stringByAppendingString:@"/"]; - NSString *path = [workingDirectory stringByAppendingPathComponent:[[selectedFiles objectAtIndex:0] path]]; - NSWorkspace *ws = [NSWorkspace sharedWorkspace]; - [ws selectFile: path inFileViewerRootedAtPath:nil]; -} - - (void)moveToTrashAction:(id)sender { NSArray *selectedFiles = [sender representedObject]; - NSString *workingDirectory = [commitController.repository workingDirectory]; - NSURL* workDirURL = [NSURL fileURLWithPath:workingDirectory isDirectory:YES]; + NSURL *workingDirectoryURL = commitController.repository.workingDirectoryURL; BOOL anyTrashed = NO; - for (PBChangedFile* file in selectedFiles) + for (PBChangedFile *file in selectedFiles) { - NSURL* fileURL = [workDirURL URLByAppendingPathComponent:[file path]]; + NSURL* fileURL = [workingDirectoryURL URLByAppendingPathComponent:[file path]]; NSError* error = nil; NSURL* resultURL = nil; @@ -343,14 +333,14 @@ - (BOOL)tableView:(NSTableView *)tv // External, to drag them to for example XCode or Textmate NSArrayController *controller = [tv tag] == 0 ? unstagedFilesController : stagedFilesController; - NSArray *files = [[controller arrangedObjects] objectsAtIndexes:rowIndexes]; - NSString *workingDirectory = [commitController.repository workingDirectory]; + NSArray *files = [controller.arrangedObjects objectsAtIndexes:rowIndexes]; + NSURL *workingDirectoryURL = commitController.repository.workingDirectoryURL; - NSMutableArray *filenames = [NSMutableArray arrayWithCapacity:[rowIndexes count]]; + NSMutableArray *URLs = [NSMutableArray arrayWithCapacity:rowIndexes.count]; for (PBChangedFile *file in files) - [filenames addObject:[workingDirectory stringByAppendingPathComponent:[file path]]]; + [URLs addObject:[workingDirectoryURL URLByAppendingPathComponent:file.path]]; - [pboard setPropertyList:filenames forType:NSFilenamesPboardType]; + [pboard setPropertyList:URLs forType:NSURLPboardType]; return YES; } @@ -386,4 +376,16 @@ - (BOOL)tableView:(NSTableView *)aTableView return YES; } +# pragma mark Key View Chain + +-(NSView *)nextKeyViewFor:(NSView *)view +{ + return [commitController nextKeyViewFor:view]; +} + +-(NSView *)previousKeyViewFor:(NSView *)view +{ + return [commitController previousKeyViewFor:view]; +} + @end diff --git a/Classes/Controllers/PBGitSidebarController.h b/Classes/Controllers/PBGitSidebarController.h index e28936c33..f825ec87b 100644 --- a/Classes/Controllers/PBGitSidebarController.h +++ b/Classes/Controllers/PBGitSidebarController.h @@ -25,7 +25,7 @@ /* Specific things */ PBSourceViewItem *stage; - PBSourceViewItem *branches, *remotes, *tags, *others, *submodules; + PBSourceViewItem *branches, *remotes, *tags, *others, *submodules, *stashes; PBGitHistoryController *historyViewController; PBGitCommitController *commitViewController; diff --git a/Classes/Controllers/PBGitSidebarController.m b/Classes/Controllers/PBGitSidebarController.m index 7833838cd..bbe184b94 100644 --- a/Classes/Controllers/PBGitSidebarController.m +++ b/Classes/Controllers/PBGitSidebarController.m @@ -16,6 +16,8 @@ #import "PBAddRemoteSheet.h" #import "PBGitDefaults.h" #import "PBHistorySearchController.h" +#import "PBGitStash.h" +#import "PBGitSVStashItem.h" @interface PBGitSidebarController () @@ -53,6 +55,7 @@ - (void)awakeFromNib [repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"]; [repository addObserver:self forKeyPath:@"branches" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:@"branchesModified"]; + [repository addObserver:self forKeyPath:@"stashes" options:0 context:@"stashesModified"]; [sourceView setTarget:self]; [sourceView setDoubleAction:@selector(doubleClicked:)]; @@ -82,6 +85,7 @@ - (void)closeView [repository removeObserver:self forKeyPath:@"currentBranch"]; [repository removeObserver:self forKeyPath:@"branches"]; + [repository removeObserver:self forKeyPath:@"stashes"]; [super closeView]; } @@ -111,6 +115,20 @@ - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:( } return; } + + if ([@"stashesModified" isEqualToString:(__bridge NSString*)context]) { + + for (PBGitSVStashItem *stashItem in stashes.sortedChildren) + [stashes removeChild:stashItem]; + + for (PBGitStash *stash in repository.stashes) + [stashes addChild: [PBGitSVStashItem itemWithStash:stash]]; + + [sourceView expandItem:stashes]; + [sourceView reloadItem:stashes reloadChildren:YES]; + + return; + } [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } @@ -283,9 +301,13 @@ - (void)populateList branches = [PBSourceViewItem groupItemWithTitle:@"Branches"]; remotes = [PBSourceViewItem groupItemWithTitle:@"Remotes"]; tags = [PBSourceViewItem groupItemWithTitle:@"Tags"]; + stashes = [PBSourceViewItem groupItemWithTitle:@"Stashes"]; submodules = [PBSourceViewItem groupItemWithTitle:@"Submodules"]; others = [PBSourceViewItem groupItemWithTitle:@"Other"]; + for (PBGitStash *stash in repository.stashes) + [stashes addChild: [PBGitSVStashItem itemWithStash:stash]]; + for (PBGitRevSpecifier *rev in repository.branches) { [self addRevSpec:rev]; } @@ -298,6 +320,7 @@ - (void)populateList [items addObject:branches]; [items addObject:remotes]; [items addObject:tags]; + [items addObject:stashes]; [items addObject:submodules]; [items addObject:others]; @@ -305,6 +328,7 @@ - (void)populateList [sourceView expandItem:project]; [sourceView expandItem:branches expandChildren:YES]; [sourceView expandItem:remotes]; + [sourceView expandItem:stashes]; [sourceView expandItem:submodules]; [sourceView reloadItem:nil reloadChildren:YES]; diff --git a/Classes/Controllers/PBGitWindowController.h b/Classes/Controllers/PBGitWindowController.h index b16f04ea5..9bcb6126b 100644 --- a/Classes/Controllers/PBGitWindowController.h +++ b/Classes/Controllers/PBGitWindowController.h @@ -48,6 +48,9 @@ - (IBAction) revealInFinder:(id)sender; - (IBAction) openInTerminal:(id)sender; - (IBAction) refresh:(id)sender; +- (IBAction) stashSave:(id) sender; +- (IBAction) stashSaveWithKeepIndex:(id) sender; +- (IBAction) stashPop:(id) sender; - (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode; diff --git a/Classes/Controllers/PBGitWindowController.m b/Classes/Controllers/PBGitWindowController.m index b3c9b82bc..172bffaad 100644 --- a/Classes/Controllers/PBGitWindowController.m +++ b/Classes/Controllers/PBGitWindowController.m @@ -41,12 +41,7 @@ - (void)synchronizeWindowTitleWithDocumentName [super synchronizeWindowTitleWithDocumentName]; // Point window proxy icon at project directory, not internal .git dir - NSString *workingDirectory = [self.repository workingDirectory]; - if (workingDirectory) - { - [[self window] setRepresentedURL:[NSURL fileURLWithPath:workingDirectory - isDirectory:YES]]; - } + [[self window] setRepresentedURL:self.repository.workingDirectoryURL]; } - (void)windowWillClose:(NSNotification *)notification @@ -176,13 +171,13 @@ - (void)showErrorSheetTitle:(NSString *)title message:(NSString *)message argume - (IBAction) revealInFinder:(id)sender { - [[NSWorkspace sharedWorkspace] openFile:[repository workingDirectory]]; + [[NSWorkspace sharedWorkspace] openURL:self.repository.workingDirectoryURL]; } - (IBAction) openInTerminal:(id)sender { TerminalApplication *term = [SBApplication applicationWithBundleIdentifier: @"com.apple.Terminal"]; - NSString *workingDirectory = [[repository workingDirectory] stringByAppendingString:@"/"]; + NSString *workingDirectory = [self.repository.workingDirectoryURL.path stringByAppendingString:@"/"]; NSString *cmd = [NSString stringWithFormat: @"cd \"%@\"; clear; echo '# Opened by GitX:'; git status", workingDirectory]; [term doScript: cmd in: nil]; [NSThread sleepForTimeInterval: 0.1]; @@ -254,6 +249,31 @@ - (void)hideModalSheet:(RJModalRepoSheet *)sheet } } +#pragma mark SplitView Delegates + +- (IBAction) stashSave:(id) sender +{ + [repository stashSaveWithKeepIndex:NO]; +} + +- (IBAction) stashSaveWithKeepIndex:(id) sender +{ + [repository stashSaveWithKeepIndex:YES]; +} + +- (IBAction) stashPop:(id) sender +{ + if ([repository.stashes count] > 0) { + PBGitStash * latestStash = [repository.stashes objectAtIndex:0]; + [repository stashPop:latestStash]; + } +} + +- (void)flagsChanged:(NSEvent *)theEvent { + [sidebarController.commitViewController flagsChanged:theEvent]; +} + + #pragma mark - #pragma mark SplitView Delegates diff --git a/Classes/Controllers/PBHistorySearchController.m b/Classes/Controllers/PBHistorySearchController.m index 19606c4a7..d17a91429 100644 --- a/Classes/Controllers/PBHistorySearchController.m +++ b/Classes/Controllers/PBHistorySearchController.m @@ -152,7 +152,7 @@ - (void)selectIndex:(NSUInteger)index { if ([[commitController arrangedObjects] count] > index) { PBGitCommit *commit = [[commitController arrangedObjects] objectAtIndex:index]; - [historyController selectCommit:[commit sha]]; + [historyController selectCommit:commit.OID]; } } @@ -454,7 +454,7 @@ - (void)parseBackgroundSearchResults:(NSNotification *)notification NSArray *arrangedObjects = [commitController arrangedObjects]; NSIndexSet *indexes = [arrangedObjects indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { PBGitCommit *commit = obj; - return [matches containsObject:commit.sha]; + return [matches containsObject:commit.OID]; }]; results = indexes; diff --git a/Classes/Controllers/PBRefController.m b/Classes/Controllers/PBRefController.m index ec27403a4..29d6121ae 100644 --- a/Classes/Controllers/PBRefController.m +++ b/Classes/Controllers/PBRefController.m @@ -14,6 +14,7 @@ #import "PBGitDefaults.h" #import "PBDiffWindowController.h" #import "PBGitRevSpecifier.h" +#import "PBGitStash.h" #define kDialogAcceptDroppedRef @"Accept Dropped Ref" #define kDialogConfirmPush @"Confirm Push" @@ -189,7 +190,7 @@ - (void) copySHA:(PBRefMenuItem *)sender NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; [pasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; - [pasteboard setString:[commit realSha] forType:NSStringPboardType]; + [pasteboard setString:commit.SHA forType:NSStringPboardType]; } @@ -234,6 +235,41 @@ - (void) diffWithHEAD:(PBRefMenuItem *)sender [PBDiffWindowController showDiffWindowWithFiles:nil fromCommit:commit diffCommit:nil]; } +#pragma mark Stash + +-(void) stashPop:(id)sender +{ + PBGitStash * stash = [historyController.repository stashForRef:[sender refish]]; + BOOL ok = [historyController.repository stashPop:stash]; + if (ok) { + [historyController.repository.windowController showCommitView:sender]; + } +} + +-(void) stashApply:(id)sender +{ + PBGitStash * stash = [historyController.repository stashForRef:[sender refish]]; + BOOL ok = [historyController.repository stashApply:stash]; + if (ok) { + [historyController.repository.windowController showCommitView:sender]; + } +} + +-(void) stashDrop:(id)sender +{ + PBGitStash * stash = [historyController.repository stashForRef:[sender refish]]; + BOOL ok = [historyController.repository stashDrop:stash]; + if (ok) { + [historyController.repository.windowController showHistoryView:sender]; + } +} + +-(void) stashViewDiff:(id)sender +{ + PBGitStash * stash = [historyController.repository stashForRef:[sender refish]]; + [PBDiffWindowController showDiffWindowWithFiles:nil fromCommit:stash.ancestorCommit diffCommit:stash.commit]; +} + #pragma mark Tags - (void) createTag:(PBRefMenuItem *)sender @@ -389,7 +425,7 @@ - (void) dropRef:(NSDictionary *)dropInfo return; int retValue = 1; - [historyController.repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-mUpdate from GitX", [ref ref], [dropCommit realSha], NULL] retValue:&retValue]; + [historyController.repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-mUpdate from GitX", ref.ref, dropCommit.SHA, NULL] retValue:&retValue]; if (retValue) return; diff --git a/Classes/Controllers/PBWebHistoryController.h b/Classes/Controllers/PBWebHistoryController.h index 9ddaad40c..495c58b58 100644 --- a/Classes/Controllers/PBWebHistoryController.h +++ b/Classes/Controllers/PBWebHistoryController.h @@ -21,7 +21,7 @@ IBOutlet PBGitHistoryController* historyController; IBOutlet id contextMenuDelegate; - GTOID* currentSha; + GTOID *currentOID; NSString* diff; } diff --git a/Classes/Controllers/PBWebHistoryController.m b/Classes/Controllers/PBWebHistoryController.m index ce95b9432..407c6df8d 100644 --- a/Classes/Controllers/PBWebHistoryController.m +++ b/Classes/Controllers/PBWebHistoryController.m @@ -34,7 +34,7 @@ - (void)closeView - (void) didLoad { - currentSha = nil; + currentOID = nil; [self changeContentTo: historyController.webCommit]; } @@ -52,7 +52,7 @@ - (void) changeContentTo: (PBGitCommit *) content return; // The sha is the same, but refs may have changed.. reload it lazy - if ([currentSha isEqual:[content sha]]) + if ([currentOID isEqual:content.OID]) { [[self script] callWebScriptMethod:@"reload" withArguments: nil]; return; @@ -65,13 +65,13 @@ - (void) changeContentTo: (PBGitCommit *) content [self performSelector:_cmd withObject:content afterDelay:0.05]; return; } - currentSha = [content sha]; + currentOID = content.OID; // Now we load the extended details. We used to do this in a separate thread, // but this caused some funny behaviour because NSTask's and NSThread's don't really // like each other. Instead, just do it async. - NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", [currentSha SHA], nil]; + NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", currentOID.SHA, nil]; if (![PBGitDefaults showWhitespaceDifferences]) [taskArguments insertObject:@"-w" atIndex:1]; diff --git a/Classes/Views/PBFileChangesTableView.m b/Classes/Views/PBFileChangesTableView.m index ba73e3a6e..a0ce4a554 100644 --- a/Classes/Views/PBFileChangesTableView.m +++ b/Classes/Views/PBFileChangesTableView.m @@ -70,4 +70,19 @@ - (void)keyDown:(NSEvent *)theEvent } } +-(BOOL)acceptsFirstResponder +{ + return [self numberOfRows] > 0; +} + +-(NSView *)nextKeyView +{ + return [(PBGitIndexController*)[self delegate] nextKeyViewFor:self]; +} + +-(NSView *)previousKeyView +{ + return [(PBGitIndexController*)[self delegate] previousKeyViewFor:self]; +} + @end diff --git a/Classes/Views/PBGitRevisionCell.m b/Classes/Views/PBGitRevisionCell.m index acf4fc2d8..dce8f7dc2 100644 --- a/Classes/Views/PBGitRevisionCell.m +++ b/Classes/Views/PBGitRevisionCell.m @@ -106,12 +106,12 @@ - (void) drawLineFromColumn: (int) from toColumn: (int) to inRect: (NSRect) r of - (BOOL) isCurrentCommit { - GTOID *thisSha = [self.objectValue sha]; + GTOID *thisOID = self.objectValue.OID; PBGitRepository* repository = [self.objectValue repository]; - GTOID *currentSha = [repository headSHA]; + GTOID *currentOID = [repository headOID]; - return [currentSha isEqual:thisSha]; + return [currentOID isEqual:thisOID]; } - (void) drawCircleInRect: (NSRect) r diff --git a/Classes/Views/PBRefMenuItem.m b/Classes/Views/PBRefMenuItem.m index 4eefea30a..e7e4e3c22 100644 --- a/Classes/Views/PBRefMenuItem.m +++ b/Classes/Views/PBRefMenuItem.m @@ -31,11 +31,48 @@ + (PBRefMenuItem *) separatorItem } ++ (NSArray *) defaultMenuItemsForStashRef:(PBGitRef *)ref inRepository:(PBGitRepository *)repo target:(id)target +{ + NSMutableArray *items = [NSMutableArray array]; + NSString *targetRefName = [ref shortName]; + BOOL isCleanWorkingCopy = YES; + + // pop + NSString *stashPopTitle = [NSString stringWithFormat:@"Pop %@", targetRefName]; + [items addObject:[PBRefMenuItem itemWithTitle:stashPopTitle action:@selector(stashPop:) enabled:isCleanWorkingCopy]]; + + // apply + NSString *stashApplyTitle = @"Apply"; + [items addObject:[PBRefMenuItem itemWithTitle:stashApplyTitle action:@selector(stashApply:) enabled:YES]]; + + // view diff + NSString *stashDiffTitle = @"View Diff"; + [items addObject:[PBRefMenuItem itemWithTitle:stashDiffTitle action:@selector(stashViewDiff:) enabled:YES]]; + + [items addObject:[PBRefMenuItem separatorItem]]; + + // drop + NSString *stashDropTitle = @"Drop"; + [items addObject:[PBRefMenuItem itemWithTitle:stashDropTitle action:@selector(stashDrop:) enabled:YES]]; + + for (PBRefMenuItem *item in items) { + [item setTarget:target]; + [item setRefish:ref]; + } + + return items; +} + + + (NSArray *) defaultMenuItemsForRef:(PBGitRef *)ref inRepository:(PBGitRepository *)repo target:(id)target { if (!ref || !repo || !target) { return nil; } + + if ([ref isStash]) { + return [self defaultMenuItemsForStashRef:ref inRepository:repo target:target]; + } NSMutableArray *items = [NSMutableArray array]; @@ -134,11 +171,12 @@ + (NSArray *) defaultMenuItemsForRef:(PBGitRef *)ref inRepository:(PBGitReposito // delete ref [items addObject:[PBRefMenuItem separatorItem]]; { + BOOL isStash = [[ref ref] hasPrefix:@"refs/stash"]; NSString *deleteTitle = [NSString stringWithFormat:@"Delete %@…", targetRefName]; if ([ref isRemote]) { deleteTitle = [NSString stringWithFormat:@"Remove %@…", targetRefName]; } - BOOL deleteEnabled = !(isDetachedHead || isHead); + BOOL deleteEnabled = !(isDetachedHead || isHead || isStash); PBRefMenuItem *deleteItem = [PBRefMenuItem itemWithTitle:deleteTitle action:@selector(showDeleteRefSheet:) enabled:deleteEnabled]; [items addObject:deleteItem]; } @@ -158,7 +196,7 @@ + (NSArray *) defaultMenuItemsForCommit:(PBGitCommit *)commit target:(id)target NSString *headBranchName = [[[commit.repository headRef] ref] shortName]; BOOL isOnHeadBranch = [commit isOnHeadBranch]; - BOOL isHead = [[commit sha] isEqual:[commit.repository headSHA]]; + BOOL isHead = [commit.OID isEqual:commit.repository.headOID]; [items addObject:[PBRefMenuItem itemWithTitle:@"Checkout Commit" action:@selector(checkout:) enabled:YES]]; [items addObject:[PBRefMenuItem separatorItem]]; diff --git a/Classes/Views/PBRemoteProgressSheet.m b/Classes/Views/PBRemoteProgressSheet.m index f8d656a94..166ee2f69 100644 --- a/Classes/Views/PBRemoteProgressSheet.m +++ b/Classes/Views/PBRemoteProgressSheet.m @@ -97,7 +97,7 @@ + (void) beginRemoteProgressSheetForArguments:(NSArray *)args [PBRemoteProgressSheet beginRemoteProgressSheetForArguments:args title:theTitle description:theDescription - inDir:[repo workingDirectory] + inDir:repo.workingDirectoryURL.path windowController:repo.windowController]; } @@ -110,7 +110,7 @@ + (void) beginRemoteProgressSheetForArguments:(NSArray *)args [PBRemoteProgressSheet beginRemoteProgressSheetForArguments:args title:theTitle description:theDescription - inDir:[repo workingDirectory] + inDir:repo.workingDirectoryURL.path windowController:repo.windowController hideSuccessScreen:hideSucc]; } @@ -162,8 +162,6 @@ - (void) beginRemoteProgressSheetForArguments:(NSArray *)args [gitTask launch]; } - - #pragma mark Notifications - (void) taskCompleted:(NSNotification *)notification diff --git a/Classes/git/PBGitCommit.h b/Classes/git/PBGitCommit.h index 1ae528207..a6c619ab2 100644 --- a/Classes/git/PBGitCommit.h +++ b/Classes/git/PBGitCommit.h @@ -21,7 +21,7 @@ extern NSString * const kGitXCommitType; @property (nonatomic, weak, readonly) PBGitRepository* repository; -@property (nonatomic, strong, readonly) GTOID *sha; +@property (nonatomic, strong, readonly) GTOID *OID; @property (nonatomic, strong, readonly) NSDate *date; @property (nonatomic, strong, readonly) NSString *subject; @@ -29,7 +29,7 @@ extern NSString * const kGitXCommitType; @property (nonatomic, strong, readonly) NSString *committer; @property (nonatomic, strong, readonly) NSString *details; @property (nonatomic, strong, readonly) NSString *patch; -@property (nonatomic, strong, readonly) NSString *realSHA; +@property (nonatomic, strong, readonly) NSString *SHA; @property (nonatomic, strong, readonly) NSString *SVNRevision; @property (nonatomic, strong, readonly) NSArray *parents; @@ -48,7 +48,7 @@ extern NSString * const kGitXCommitType; - (void) removeRef:(id)ref; - (BOOL) hasRef:(PBGitRef *)ref; -- (NSString *)realSha; +- (NSString *)SHA; - (BOOL) isOnSameBranchAs:(PBGitCommit *)other; - (BOOL) isOnHeadBranch; diff --git a/Classes/git/PBGitCommit.m b/Classes/git/PBGitCommit.m index c0b59aeb5..35c3e1e27 100644 --- a/Classes/git/PBGitCommit.m +++ b/Classes/git/PBGitCommit.m @@ -21,7 +21,7 @@ @interface PBGitCommit () @property (nonatomic, strong) NSArray *parents; @property (nonatomic, strong) NSString *patch; -@property (nonatomic, strong) GTOID *sha; +@property (nonatomic, strong) GTOID *oid; @end @@ -113,20 +113,17 @@ - (NSString *)SVNRevision return result; } -- (GTOID *)sha +- (GTOID *)OID { - GTOID *result = _sha; - if (result) { - return result; + if (!_oid) { + _oid = self.gtCommit.OID; } - result = self.gtCommit.OID; - _sha = result; - return result; + return _oid; } -- (NSString *)realSha +- (NSString *)SHA { - return self.gtCommit.SHA; + return self.OID.SHA; } - (BOOL) isOnSameBranchAs:(PBGitCommit *)otherCommit @@ -137,7 +134,7 @@ - (BOOL) isOnSameBranchAs:(PBGitCommit *)otherCommit if ([self isEqual:otherCommit]) return YES; - return [self.repository isOnSameBranch:otherCommit.sha asSHA:self.sha]; + return [self.repository isOIDOnSameBranch:otherCommit.OID asOID:self.OID]; } - (BOOL) isOnHeadBranch @@ -155,7 +152,7 @@ - (BOOL)isEqual:(id)otherCommit - (NSUInteger)hash { - return [self.sha hash]; + return self.OID.hash; } // FIXME: Remove this method once it's unused. @@ -169,7 +166,7 @@ - (NSString *) patch if (self->_patch != nil) return _patch; - NSString *p = [self.repository outputForArguments:[NSArray arrayWithObjects:@"format-patch", @"-1", @"--stdout", [self realSha], nil]]; + NSString *p = [self.repository outputForArguments:[NSArray arrayWithObjects:@"format-patch", @"-1", @"--stdout", self.SHA, nil]]; // Add a GitX identifier to the patch ;) self.patch = [[p substringToIndex:[p length] -1] stringByAppendingString:@"+GitX"]; return self->_patch; @@ -210,12 +207,12 @@ - (BOOL) hasRef:(PBGitRef *)ref - (NSMutableArray *)refs { - return self.repository.refs[self.sha]; + return self.repository.refs[self.OID]; } - (void) setRefs:(NSMutableArray *)refs { - self.repository.refs[self.sha] = [NSMutableArray arrayWithArray:refs]; + self.repository.refs[self.OID] = [NSMutableArray arrayWithArray:refs]; } @@ -233,7 +230,7 @@ + (BOOL)isKeyExcludedFromWebScript:(const char *)name { - (NSString *) refishName { - return [self realSha]; + return self.SHA; } - (NSString *) shortName diff --git a/Classes/git/PBGitGrapher.mm b/Classes/git/PBGitGrapher.mm index d2319e20b..5e254fdf1 100644 --- a/Classes/git/PBGitGrapher.mm +++ b/Classes/git/PBGitGrapher.mm @@ -67,7 +67,7 @@ - (void) decorateCommit: (PBGitCommit *) commit PBGitLane *currentLane = NULL; BOOL didFirst = NO; - const git_oid *commit_oid = [[commit sha] git_oid]; + const git_oid *commit_oid = commit.OID.git_oid; // First, iterate over earlier columns and pass through any that don't want this commit if (self.previous != nil) { diff --git a/Classes/git/PBGitHistoryGrapher.h b/Classes/git/PBGitHistoryGrapher.h index 0e02e6a3e..02aa931cd 100644 --- a/Classes/git/PBGitHistoryGrapher.h +++ b/Classes/git/PBGitHistoryGrapher.h @@ -20,7 +20,7 @@ id delegate; NSOperationQueue *currentQueue; - NSMutableSet *searchSHAs; + NSMutableSet *searchOIDs; PBGitGrapher *grapher; BOOL viewAllBranches; } diff --git a/Classes/git/PBGitHistoryGrapher.m b/Classes/git/PBGitHistoryGrapher.m index 7fea53cd7..f79f75b44 100644 --- a/Classes/git/PBGitHistoryGrapher.m +++ b/Classes/git/PBGitHistoryGrapher.m @@ -19,7 +19,7 @@ - (id) initWithBaseCommits:(NSSet *)commits viewAllBranches:(BOOL)viewAll queue: delegate = theDelegate; currentQueue = queue; - searchSHAs = [NSMutableSet setWithSet:commits]; + searchOIDs = [NSMutableSet setWithSet:commits]; grapher = [[PBGitGrapher alloc] initWithRepository:nil]; viewAllBranches = viewAll; @@ -48,13 +48,13 @@ - (void) graphCommits:(NSArray *)revList for (PBGitCommit *commit in revList) { if ([currentThread isCancelled]) return; - GTOID *commitSHA = [commit sha]; - if (viewAllBranches || [searchSHAs containsObject:commitSHA]) { + GTOID *commitOID = commit.OID; + if (viewAllBranches || [searchOIDs containsObject:commitOID]) { [grapher decorateCommit:commit]; [commits addObject:commit]; if (!viewAllBranches) { - [searchSHAs removeObject:commitSHA]; - [searchSHAs addObjectsFromArray:[commit parents]]; + [searchOIDs removeObject:commitOID]; + [searchOIDs addObjectsFromArray:[commit parents]]; } } if (++counter % 100 == 0) { diff --git a/Classes/git/PBGitHistoryList.h b/Classes/git/PBGitHistoryList.h index 9166051bf..66e21f1fd 100644 --- a/Classes/git/PBGitHistoryList.h +++ b/Classes/git/PBGitHistoryList.h @@ -22,8 +22,8 @@ PBGitRevList *projectRevList; PBGitRevList *currentRevList; - GTOID *lastSHA; - NSSet *lastRefSHAs; + GTOID *lastOID; + NSSet *lastRefOIDs; NSInteger lastBranchFilter; PBGitRef *lastRemoteRef; BOOL resetCommits; diff --git a/Classes/git/PBGitHistoryList.m b/Classes/git/PBGitHistoryList.m index 72387f301..41cfee2ac 100644 --- a/Classes/git/PBGitHistoryList.m +++ b/Classes/git/PBGitHistoryList.m @@ -171,47 +171,47 @@ - (NSInvocationOperation *) operationForCommits:(NSArray *)newCommits - (NSSet *) baseCommitsForLocalRefs { - NSMutableSet *baseCommitSHAs = [NSMutableSet set]; + NSMutableSet *baseCommitOIDs = [NSMutableSet set]; NSDictionary *refs = repository.refs; - for (GTOID *sha in refs) - for (PBGitRef *ref in [refs objectForKey:sha]) + for (GTOID *OID in refs) + for (PBGitRef *ref in [refs objectForKey:OID]) if ([ref isBranch] || [ref isTag]) - [baseCommitSHAs addObject:sha]; + [baseCommitOIDs addObject:OID]; if (![[PBGitRef refFromString:[[repository headRef] simpleRef]] type]) - [baseCommitSHAs addObject:[repository headSHA]]; + [baseCommitOIDs addObject:repository.headOID]; - return baseCommitSHAs; + return baseCommitOIDs; } - (NSSet *) baseCommitsForRemoteRefs { - NSMutableSet *baseCommitSHAs = [NSMutableSet set]; + NSMutableSet *baseCommitOIDs = [NSMutableSet set]; NSDictionary *refs = repository.refs; PBGitRef *remoteRef = [[repository.currentBranch ref] remoteRef]; - for (GTOID *sha in refs) - for (PBGitRef *ref in [refs objectForKey:sha]) + for (GTOID *OID in refs) + for (PBGitRef *ref in [refs objectForKey:OID]) if ([remoteRef isEqualToRef:[ref remoteRef]]) - [baseCommitSHAs addObject:sha]; + [baseCommitOIDs addObject:OID]; - return baseCommitSHAs; + return baseCommitOIDs; } - (NSSet *) baseCommits { if ((repository.currentBranchFilter == kGitXSelectedBranchFilter) || (repository.currentBranchFilter == kGitXAllBranchesFilter)) { - if (lastSHA) - return [NSMutableSet setWithObject:lastSHA]; + if (lastOID) + return [NSMutableSet setWithObject:lastOID]; else if ([repository.currentBranch isSimpleRef]) { PBGitRef *currentRef = [repository.currentBranch ref]; - GTOID *sha = [repository shaForRef:currentRef]; - if (sha) - return [NSMutableSet setWithObject:sha]; + GTOID *OID = [repository OIDForRef:currentRef]; + if (OID) + return [NSMutableSet setWithObject:OID]; } } else if (repository.currentBranchFilter == kGitXLocalRemoteBranchesFilter) { @@ -274,18 +274,18 @@ - (BOOL) selectedBranchNeedsNewGraph:(PBGitRevSpecifier *)rev if ([self isAllBranchesOnlyUpdate] || [self isLocalRemoteOnlyUpdate:rev]) { lastRemoteRef = [[rev ref] remoteRef]; - lastSHA = nil; + lastOID = nil; self.isUpdating = NO; return NO; } - GTOID *revSHA = [repository shaForRef:[rev ref]]; - if ([revSHA isEqual:lastSHA] && (lastBranchFilter == repository.currentBranchFilter)) + GTOID *revOID = [repository OIDForRef:[rev ref]]; + if ([revOID isEqual:lastOID] && (lastBranchFilter == repository.currentBranchFilter)) return NO; lastBranchFilter = repository.currentBranchFilter; lastRemoteRef = [[rev ref] remoteRef]; - lastSHA = revSHA; + lastOID = revOID; return YES; } @@ -295,11 +295,11 @@ - (BOOL) haveRefsBeenModified { [repository reloadRefs]; - NSMutableSet *currentRefSHAs = [NSMutableSet setWithArray:[repository.refs allKeys]]; - [currentRefSHAs minusSet:lastRefSHAs]; - lastRefSHAs = [NSSet setWithArray:[repository.refs allKeys]]; + NSMutableSet *currentRefOIDs = [NSMutableSet setWithArray:[repository.refs allKeys]]; + [currentRefOIDs minusSet:lastRefOIDs]; + lastRefOIDs = [NSSet setWithArray:[repository.refs allKeys]]; - return [currentRefSHAs count] != 0; + return [currentRefOIDs count] != 0; } @@ -321,7 +321,7 @@ - (void) updateProjectHistoryForRev:(PBGitRevSpecifier *)rev shouldReloadProjectHistory = NO; lastBranchFilter = -1; lastRemoteRef = nil; - lastSHA = nil; + lastOID = nil; self.commits = [NSMutableArray array]; [projectRevList loadRevisons]; return; @@ -339,7 +339,7 @@ - (void) updateHistoryForRev:(PBGitRevSpecifier *)rev [self resetGraphing]; lastBranchFilter = -1; lastRemoteRef = nil; - lastSHA = nil; + lastOID = nil; self.commits = [NSMutableArray array]; [otherRevListParser loadRevisons]; diff --git a/Classes/git/PBGitIndex.h b/Classes/git/PBGitIndex.h index 2a068fb37..e7edd6c93 100644 --- a/Classes/git/PBGitIndex.h +++ b/Classes/git/PBGitIndex.h @@ -41,21 +41,12 @@ extern NSString *PBGitIndexOperationFailed; // As a single git repository can have multiple trees, // the tree has to be given explicitly, even though // multiple trees is not yet supported in GitX -@interface PBGitIndex : NSObject { - -@private - __weak PBGitRepository *repository; - NSURL *workingDirectory; - NSMutableArray *files; - - NSUInteger refreshStatus; - NSDictionary *amendEnvironment; - BOOL amend; -} +@interface PBGitIndex : NSObject // Whether we want the changes for amending, -// or for -@property BOOL amend; +// or for making a new commit. +@property (assign, readonly, getter=isAmend) BOOL amend; +@property (weak, readonly) PBGitRepository *repository; - (id)initWithRepository:(PBGitRepository *)repository; diff --git a/Classes/git/PBGitIndex.m b/Classes/git/PBGitIndex.m index 70726946e..4290c73bb 100644 --- a/Classes/git/PBGitIndex.m +++ b/Classes/git/PBGitIndex.m @@ -52,10 +52,17 @@ - (void)postCommitFailure:(NSString *)reason; - (void)postCommitHookFailure:(NSString *)reason; - (void)postIndexChange; - (void)postOperationFailed:(NSString *)description; + +@property (retain) NSDictionary *amendEnvironment; +@property (retain) NSMutableArray *files; +@property (assign) NSUInteger refreshStatus; + @end @implementation PBGitIndex +@synthesize amend=_amend; + - (id)initWithRepository:(PBGitRepository *)theRepository { if (!(self = [super init])) @@ -63,29 +70,25 @@ - (id)initWithRepository:(PBGitRepository *)theRepository NSAssert(theRepository, @"PBGitIndex requires a repository"); - repository = theRepository; - NSString* workingPath = theRepository.workingDirectory; - if (workingPath) - { - workingDirectory = [NSURL fileURLWithPath:workingPath]; - } - files = [NSMutableArray array]; + _repository = theRepository; + + _files = [NSMutableArray array]; return self; } - (NSArray *)indexChanges { - return files; + return self.files; } - (void)setAmend:(BOOL)newAmend { - if (newAmend == amend) + if (newAmend == _amend) return; - amend = newAmend; - amendEnvironment = nil; + _amend = newAmend; + self.amendEnvironment = nil; [self refresh]; @@ -95,13 +98,13 @@ - (void)setAmend:(BOOL)newAmend // If we amend, we want to keep the author information for the previous commit // We do this by reading in the previous commit, and storing the information // in a dictionary. This dictionary will then later be read by [self commit:] - NSString *message = [repository outputForCommand:@"cat-file commit HEAD"]; + NSString *message = [self.repository outputForCommand:@"cat-file commit HEAD"]; NSArray *match = [message substringsMatchingRegularExpression:@"\nauthor ([^\n]*) <([^\n>]*)> ([0-9]+[^\n]*)\n" count:3 options:0 ranges:nil error:nil]; if (match) - amendEnvironment = [NSDictionary dictionaryWithObjectsAndKeys:[match objectAtIndex:1], @"GIT_AUTHOR_NAME", - [match objectAtIndex:2], @"GIT_AUTHOR_EMAIL", - [match objectAtIndex:3], @"GIT_AUTHOR_DATE", - nil]; + self.amendEnvironment = [NSDictionary dictionaryWithObjectsAndKeys:[match objectAtIndex:1], @"GIT_AUTHOR_NAME", + [match objectAtIndex:2], @"GIT_AUTHOR_EMAIL", + [match objectAtIndex:3], @"GIT_AUTHOR_DATE", + nil]; // Find the commit message NSRange r = [message rangeOfString:@"\n\n"]; @@ -114,9 +117,9 @@ - (void)setAmend:(BOOL)newAmend } -- (BOOL) amend +- (BOOL)isAmend { - return amend; + return _amend; } - (void)refresh @@ -124,14 +127,14 @@ - (void)refresh // If we were already refreshing the index, we don't want // double notifications. As we can't stop the tasks anymore, // just cancel the notifications - refreshStatus = 0; + self.refreshStatus = 0; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self]; // Ask Git to refresh the index NSFileHandle *updateHandle = [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"update-index", @"-q", @"--unmerged", @"--ignore-missing", @"--refresh", nil] - inDir:[workingDirectory path]]; + inDir:self.repository.workingDirectoryURL.path]; [nc addObserver:self selector:@selector(indexRefreshFinished:) @@ -143,9 +146,9 @@ - (void)refresh - (NSString *) parentTree { - NSString *parent = amend ? @"HEAD^" : @"HEAD"; + NSString *parent = self.amend ? @"HEAD^" : @"HEAD"; - if (![repository parseReference:parent]) + if (![self.repository parseReference:parent]) // We don't have a head ref. Return the empty tree. return @"4b825dc642cb6eb9a060e54bf8d69288fbee4904"; @@ -163,20 +166,20 @@ - (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify [commitSubject appendString:[commitMessage substringToIndex:newLine.location]]; NSString *commitMessageFile; - commitMessageFile = [repository.gitURL.path stringByAppendingPathComponent:@"COMMIT_EDITMSG"]; + commitMessageFile = [self.repository.gitURL.path stringByAppendingPathComponent:@"COMMIT_EDITMSG"]; [commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil]; [self postCommitUpdate:@"Creating tree"]; - NSString *tree = [repository outputForCommand:@"write-tree"]; + NSString *tree = [self.repository outputForCommand:@"write-tree"]; if ([tree length] != 40) return [self postCommitFailure:@"Creating tree failed"]; NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"commit-tree", tree, nil]; - NSString *parent = amend ? @"HEAD^" : @"HEAD"; - if ([repository parseReference:parent]) { + NSString *parent = self.amend ? @"HEAD^" : @"HEAD"; + if ([self.repository parseReference:parent]) { [arguments addObject:@"-p"]; [arguments addObject:parent]; } @@ -188,13 +191,13 @@ - (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify [self postCommitUpdate:@"Running hooks"]; NSString *hookFailureMessage = nil; NSString *hookOutput = nil; - if (![repository executeHook:@"pre-commit" output:&hookOutput]) { + if (![self.repository executeHook:@"pre-commit" output:&hookOutput]) { hookFailureMessage = [NSString stringWithFormat:@"Pre-commit hook failed%@%@", [hookOutput length] > 0 ? @":\n" : @"", hookOutput]; } - if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) { + if (![self.repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) { hookFailureMessage = [NSString stringWithFormat:@"Commit-msg hook failed%@%@", [hookOutput length] > 0 ? @":\n" : @"", hookOutput]; @@ -207,23 +210,23 @@ - (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify commitMessage = [NSString stringWithContentsOfFile:commitMessageFile encoding:NSUTF8StringEncoding error:nil]; - NSString *commit = [repository outputForArguments:arguments + NSString *commit = [self.repository outputForArguments:arguments inputString:commitMessage - byExtendingEnvironment:amendEnvironment + byExtendingEnvironment:self.amendEnvironment retValue: &ret]; if (ret || [commit length] != 40) return [self postCommitFailure:@"Could not create a commit object"]; [self postCommitUpdate:@"Updating HEAD"]; - [repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] - retValue: &ret]; + [self.repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] + retValue: &ret]; if (ret) return [self postCommitFailure:@"Could not update HEAD"]; [self postCommitUpdate:@"Running post-commit hook"]; - BOOL success = [repository executeHook:@"post-commit" output:nil]; + BOOL success = [self.repository executeHook:@"post-commit" output:nil]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithBool:success] forKey:@"success"]; NSString *description; if (success) @@ -240,10 +243,10 @@ - (void)commitWithMessage:(NSString *)commitMessage andVerify:(BOOL) doVerify if (!success) return; - repository.hasChanged = YES; + self.repository.hasChanged = YES; - amendEnvironment = nil; - if (amend) + self.amendEnvironment = nil; + if (self.amend) self.amend = NO; else [self refresh]; @@ -310,9 +313,9 @@ - (BOOL)stageFiles:(NSArray *)stageFiles int ret = 1; - [repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil] - inputString:input - retValue:&ret]; + [self.repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil] + inputString:input + retValue:&ret]; if (ret) { [self postOperationFailed:[NSString stringWithFormat:@"Error in staging files. Return value: %i", ret]]; @@ -365,10 +368,10 @@ - (BOOL)unstageFiles:(NSArray *)unstageFiles } int ret = 1; - [repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil] - inputString:input - retValue:&ret]; - + [self.repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil] + inputString:input + retValue:&ret]; + if (ret) { [self postOperationFailed:[NSString stringWithFormat:@"Error in unstaging files. Return value: %i", ret]]; @@ -401,7 +404,7 @@ - (void)discardChangesForFiles:(NSArray *)discardFiles NSArray *arguments = [NSArray arrayWithObjects:@"checkout-index", @"--index", @"--quiet", @"--force", @"-z", @"--stdin", nil]; int ret = 1; - [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir:[workingDirectory path] inputString:input retValue:&ret]; + [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir:self.repository.workingDirectoryURL.path inputString:input retValue:&ret]; if (ret) { [self postOperationFailed:[NSString stringWithFormat:@"Discarding changes failed with return value %i", ret]]; @@ -424,9 +427,9 @@ - (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; [array addObject:@"--reverse"]; int ret = 1; - NSString *error = [repository outputForArguments:array - inputString:hunk - retValue:&ret]; + NSString *error = [self.repository outputForArguments:array + inputString:hunk + retValue:&ret]; if (ret) { [self postOperationFailed:[NSString stringWithFormat:@"Applying patch failed with return value %i. Error: %@", ret, error]]; @@ -446,26 +449,26 @@ - (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines NSString *indexPath = [@":0:" stringByAppendingString:file.path]; if (file.status == NEW) - return [repository outputForArguments:[NSArray arrayWithObjects:@"show", indexPath, nil]]; + return [self.repository outputForArguments:[NSArray arrayWithObjects:@"show", indexPath, nil]]; - return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-index", parameter, @"--cached", [self parentTree], @"--", file.path, nil]]; + return [self.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-index", parameter, @"--cached", [self parentTree], @"--", file.path, nil]]; } // unstaged if (file.status == NEW) { NSStringEncoding encoding; NSError *error = nil; - NSString *path = [[repository workingDirectory] stringByAppendingPathComponent:file.path]; - NSString *contents = [NSString stringWithContentsOfFile:path - usedEncoding:&encoding - error:&error]; + NSURL *fileURL = [self.repository.workingDirectoryURL URLByAppendingPathComponent:file.path]; + NSString *contents = [NSString stringWithContentsOfURL:fileURL + usedEncoding:&encoding + error:&error]; if (error) return nil; return contents; } - return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", parameter, @"--", file.path, nil]]; + return [self.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", parameter, @"--", file.path, nil]]; } - (void)postIndexChange @@ -502,32 +505,32 @@ - (void)indexRefreshFinished:(NSNotification *)notification // Now that the index is refreshed, we need to read the information from the index NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - if ([repository isBareRepository]) + if ([self.repository isBareRepository]) { return; } // Other files (not tracked, not ignored) - refreshStatus++; + self.refreshStatus++; NSFileHandle *handle = [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"ls-files", @"--others", @"--exclude-standard", @"-z", nil] - inDir:[workingDirectory path]]; + inDir:self.repository.workingDirectoryURL.path]; [nc addObserver:self selector:@selector(readOtherFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; [handle readToEndOfFileInBackgroundAndNotify]; // Unstaged files - refreshStatus++; + self.refreshStatus++; handle = [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"diff-files", @"-z", nil] - inDir:[workingDirectory path]]; + inDir:self.repository.workingDirectoryURL.path]; [nc addObserver:self selector:@selector(readUnstagedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; [handle readToEndOfFileInBackgroundAndNotify]; // Staged files - refreshStatus++; + self.refreshStatus++; handle = [PBEasyPipe handleForCommand:[PBGitBinary path] withArgs:[NSArray arrayWithObjects:@"diff-index", @"--cached", @"-z", [self parentTree], nil] - inDir:[workingDirectory path]]; + inDir:self.repository.workingDirectoryURL.path]; [nc addObserver:self selector:@selector(readStagedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; [handle readToEndOfFileInBackgroundAndNotify]; } @@ -568,7 +571,7 @@ - (void) readUnstagedFiles:(NSNotification *)notification - (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked { // Iterate over all existing files - for (PBChangedFile *file in files) { + for (PBChangedFile *file in self.files) { NSArray *fileStatus = [dictionary objectForKey:file.path]; // Object found, this is still a cached / uncached thing if (fileStatus) { @@ -639,7 +642,7 @@ - (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)s file.hasStagedChanges = staged; file.hasUnstagedChanges = !staged; - [files addObject:file]; + [self.files addObject:file]; } [self didChangeValueForKey:@"indexChanges"]; } @@ -692,7 +695,7 @@ - (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines - (void)indexStepComplete { // if we're still busy, do nothing :) - if (--refreshStatus) { + if (--self.refreshStatus) { [self postIndexChange]; return; } @@ -702,7 +705,7 @@ - (void)indexStepComplete // staged or unstaged files, and delete them NSMutableArray *deleteFiles = [NSMutableArray array]; - for (PBChangedFile *file in files) { + for (PBChangedFile *file in self.files) { if (!file.hasStagedChanges && !file.hasUnstagedChanges) [deleteFiles addObject:file]; } @@ -710,7 +713,7 @@ - (void)indexStepComplete if ([deleteFiles count]) { [self willChangeValueForKey:@"indexChanges"]; for (PBChangedFile *file in deleteFiles) - [files removeObject:file]; + [self.files removeObject:file]; [self didChangeValueForKey:@"indexChanges"]; } diff --git a/Classes/git/PBGitRef.h b/Classes/git/PBGitRef.h index 22a464996..6497e929e 100644 --- a/Classes/git/PBGitRef.h +++ b/Classes/git/PBGitRef.h @@ -13,10 +13,12 @@ extern NSString * const kGitXTagType; extern NSString * const kGitXBranchType; extern NSString * const kGitXRemoteType; extern NSString * const kGitXRemoteBranchType; +extern NSString * const kGitXStashType; extern NSString * const kGitXTagRefPrefix; extern NSString * const kGitXBranchRefPrefix; extern NSString * const kGitXRemoteRefPrefix; +extern NSString * const kGitXStashRefPrefix; @interface PBGitRef : NSObject @@ -36,6 +38,7 @@ extern NSString * const kGitXRemoteRefPrefix; - (BOOL) isTag; - (BOOL) isRemote; - (BOOL) isRemoteBranch; +- (BOOL) isStash; - (PBGitRef *) remoteRef; diff --git a/Classes/git/PBGitRef.m b/Classes/git/PBGitRef.m index 7ff76fac6..7f08eb593 100644 --- a/Classes/git/PBGitRef.m +++ b/Classes/git/PBGitRef.m @@ -13,10 +13,12 @@ NSString * const kGitXBranchType = @"branch"; NSString * const kGitXRemoteType = @"remote"; NSString * const kGitXRemoteBranchType = @"remote branch"; +NSString * const kGitXStashType = @"stash"; NSString * const kGitXTagRefPrefix = @"refs/tags/"; NSString * const kGitXBranchRefPrefix = @"refs/heads/"; NSString * const kGitXRemoteRefPrefix = @"refs/remotes/"; +NSString * const kGitXStashRefPrefix = @"refs/stash@"; @interface PBGitRef () @@ -68,6 +70,8 @@ - (NSString *) type return @"tag"; if ([self isRemote]) return @"remote"; + if ([self isStash]) + return @"stash"; return nil; } @@ -94,6 +98,11 @@ - (BOOL) isRemoteBranch return ([[ref componentsSeparatedByString:@"/"] count] > 3); } +- (BOOL) isStash +{ + return [ref hasPrefix:kGitXStashRefPrefix]; +} + - (BOOL) isEqualToRef:(PBGitRef *)otherRef { return [ref isEqualToString:[otherRef ref]]; @@ -141,6 +150,8 @@ - (NSString *) refishName - (NSString *) shortName { + if ([self isStash]) + return [ref substringFromIndex:5]; if ([self type]) return [ref substringFromIndex:[[self type] length] + 7]; return ref; @@ -156,6 +167,8 @@ - (NSString *) refishType return kGitXRemoteBranchType; if ([self isRemote]) return kGitXRemoteType; + if ([self isStash]) + return kGitXStashType; return nil; } diff --git a/Classes/git/PBGitRepository.h b/Classes/git/PBGitRepository.h index 5664984c9..a533ee242 100644 --- a/Classes/git/PBGitRepository.h +++ b/Classes/git/PBGitRepository.h @@ -12,6 +12,7 @@ @class PBGitRevSpecifier; @protocol PBGitRefish; @class PBGitRef; +@class PBGitStash; @class GTRepository; @class GTConfiguration; @@ -49,7 +50,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { @interface PBGitRepository : NSDocument { __strong PBGitRepositoryWatcher *watcher; __strong PBGitRevSpecifier *_headRef; // Caching - __strong GTOID* _headSha; + __strong GTOID* _headOID; __strong GTRepository* _gtRepo; } @@ -61,6 +62,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { @property (readonly, getter = getIndexURL) NSURL* indexURL; @property (nonatomic, strong) PBGitHistoryList *revisionList; +@property (nonatomic, readonly, strong) NSArray* stashes; @property (nonatomic, readonly, strong) NSArray* branches; @property (nonatomic, strong) NSMutableOrderedSet* branchesSet; @property (nonatomic, strong) PBGitRevSpecifier* currentBranch; @@ -83,6 +85,11 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { - (BOOL) createTag:(NSString *)tagName message:(NSString *)message atRefish:(id )commitSHA; - (BOOL) deleteRemote:(PBGitRef *)ref; - (BOOL) deleteRef:(PBGitRef *)ref; +- (BOOL) stashPop:(PBGitStash *)stash; +- (BOOL) stashApply:(PBGitStash *)stash; +- (BOOL) stashDrop:(PBGitStash *)stash; +- (BOOL) stashSave; +- (BOOL) stashSaveWithKeepIndex:(BOOL)keepIndex; - (NSURL *) gitURL ; @@ -102,8 +109,9 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { - (BOOL)executeHook:(NSString *)name output:(NSString **)output GITX_DEPRECATED; - (BOOL)executeHook:(NSString *)name withArgs:(NSArray*) arguments output:(NSString **)output GITX_DEPRECATED; -- (NSString *)workingDirectory; -- (NSString *) projectName; +- (NSString *)workingDirectory GITX_DEPRECATED; +- (NSURL *)workingDirectoryURL; +- (NSString *)projectName; - (NSString *)gitIgnoreFilename; - (BOOL)isBareRepository; @@ -112,13 +120,14 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { - (void) reloadRefs; - (void) lazyReload; - (PBGitRevSpecifier*)headRef; -- (GTOID *)headSHA; +- (GTOID *)headOID; - (PBGitCommit *)headCommit; -- (GTOID *)shaForRef:(PBGitRef *)ref; +- (GTOID *)OIDForRef:(PBGitRef *)ref; - (PBGitCommit *)commitForRef:(PBGitRef *)ref; -- (PBGitCommit *)commitForSHA:(GTOID *)sha; -- (BOOL)isOnSameBranch:(GTOID *)baseSHA asSHA:(GTOID *)testSHA; -- (BOOL)isSHAOnHeadBranch:(GTOID *)testSHA; +- (PBGitCommit *)commitForOID:(GTOID *)sha; +- (BOOL)isOIDOnSameBranch:(GTOID *)baseOID asOID:(GTOID *)testOID; +- (BOOL)isOIDOnHeadBranch:(GTOID *)testOID; +- (PBGitStash *)stashForRef:(PBGitRef *)ref; - (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef; - (BOOL)checkRefFormat:(NSString *)refName; - (BOOL)refExists:(PBGitRef *)ref; @@ -142,4 +151,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { // for the scripting bridge - (void)findInModeScriptCommand:(NSScriptCommand *)command; +- (IBAction)showInFinderAction:(id)sender; +- (IBAction)openFilesAction:(id)sender; + @end diff --git a/Classes/git/PBGitRepository.m b/Classes/git/PBGitRepository.m index 2ad0a6418..ee7246523 100644 --- a/Classes/git/PBGitRepository.m +++ b/Classes/git/PBGitRepository.m @@ -23,7 +23,7 @@ #import "PBGitRepositoryWatcher.h" #import "GitRepoFinder.h" #import "PBGitHistoryList.h" - +#import "PBGitStash.h" NSString *PBGitRepositoryDocumentType = @"Git Repository"; @@ -170,6 +170,53 @@ - (void)showWindows [super showWindows]; } +#pragma mark - +#pragma mark NSResponder methods + +- (NSArray *)selectedURLsFromSender:(id)sender { + NSArray *selectedFiles = [sender representedObject]; + if ([selectedFiles count] == 0) + return nil; + + NSURL *workingDirectoryURL = self.workingDirectoryURL; + NSMutableArray *URLs = [NSMutableArray array]; + for (id file in selectedFiles) { + NSString *path = file; + // Those can be PBChangedFiles sent by PBGitIndexController. Get their path. + if ([file respondsToSelector:@selector(path)]) { + path = [file path]; + } + + if (![path isKindOfClass:[NSString class]]) + continue; + [URLs addObject:[workingDirectoryURL URLByAppendingPathComponent:path]]; + } + + return URLs; +} + +- (IBAction)showInFinderAction:(id)sender { + NSArray *URLs = [self selectedURLsFromSender:sender]; + if ([URLs count] == 0) + return; + + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:URLs]; +} + +- (IBAction)openFilesAction:(id)sender { + NSArray *URLs = [self selectedURLsFromSender:sender]; + + if ([URLs count] == 0) + return; + + [[NSWorkspace sharedWorkspace] openURLs:URLs + withAppBundleIdentifier:nil + options:0 + additionalEventParamDescriptor:nil + launchIdentifiers:NULL]; +} + + #pragma mark - #pragma mark Properties/General methods @@ -281,11 +328,16 @@ - (void) reloadRefs { // clear out ref caches _headRef = nil; - _headSha = nil; + _headOID = nil; self->refs = [NSMutableDictionary dictionary]; NSError* error = nil; NSArray* allRefs = [self.gtRepo referenceNamesWithError:&error]; + + if ([self.gtRepo isHEADDetached]) { + // Add HEAD when we're detached + allRefs = [allRefs arrayByAddingObject:@"HEAD"]; + } // load all named refs NSMutableOrderedSet *oldBranches = [self.branchesSet mutableCopy]; @@ -324,7 +376,9 @@ - (void) reloadRefs [self loadSubmodules]; [self willChangeValueForKey:@"refs"]; + [self willChangeValueForKey:@"stashes"]; [self didChangeValueForKey:@"refs"]; + [self didChangeValueForKey:@"stashes"]; [[[self windowController] window] setTitle:[self displayName]]; } @@ -349,25 +403,25 @@ - (PBGitRevSpecifier *)headRef else _headRef = [[PBGitRevSpecifier alloc] initWithRef:[PBGitRef refFromString:@"HEAD"]]; - _headSha = [self shaForRef:[_headRef ref]]; + _headOID = [self OIDForRef:[_headRef ref]]; return _headRef; } -- (GTOID *)headSHA +- (GTOID *)headOID { - if (! _headSha) + if (! _headOID) [self headRef]; - return _headSha; + return _headOID; } - (PBGitCommit *)headCommit { - return [self commitForSHA:[self headSHA]]; + return [self commitForOID:self.headOID]; } -- (GTOID *)shaForRef:(PBGitRef *)ref +- (GTOID *)OIDForRef:(PBGitRef *)ref { if (!ref) return nil; @@ -394,18 +448,7 @@ - (GTOID *)shaForRef:(PBGitRef *)ref NSLog(@"Error looking up ref for %@", ref.ref); return nil; } - const git_oid* refOid = gtRef.git_oid; - - if (refOid) - { - char buffer[41]; - buffer[40] = '\0'; - git_oid_fmt(buffer, refOid); - NSString* shaForRef = [NSString stringWithUTF8String:buffer]; - GTOID* result = [GTOID oidWithSHA: shaForRef]; - return result; - } - return nil; + return gtRef.OID; } - (PBGitCommit *)commitForRef:(PBGitRef *)ref @@ -413,10 +456,10 @@ - (PBGitCommit *)commitForRef:(PBGitRef *)ref if (!ref) return nil; - return [self commitForSHA:[self shaForRef:ref]]; + return [self commitForOID:[self OIDForRef:ref]]; } -- (PBGitCommit *)commitForSHA:(GTOID *)sha +- (PBGitCommit *)commitForOID:(GTOID *)sha { if (!sha) return nil; @@ -427,50 +470,50 @@ - (PBGitCommit *)commitForSHA:(GTOID *)sha revList = revisionList.projectCommits; } for (PBGitCommit *commit in revList) - if ([[commit sha] isEqual:sha]) + if ([commit.OID isEqual:sha]) return commit; return nil; } -- (BOOL)isOnSameBranch:(GTOID *)branchSHA asSHA:(GTOID *)testSHA +- (BOOL)isOIDOnSameBranch:(GTOID *)branchOID asOID:(GTOID *)testOID { - if (!branchSHA || !testSHA) + if (!branchOID || !testOID) return NO; - if ([testSHA isEqual:branchSHA]) + if ([testOID isEqual:branchOID]) return YES; NSArray *revList = revisionList.projectCommits; - NSMutableSet *searchSHAs = [NSMutableSet setWithObject:branchSHA]; + NSMutableSet *searchOIDs = [NSMutableSet setWithObject:branchOID]; for (PBGitCommit *commit in revList) { - GTOID *commitSHA = [commit sha]; - if ([searchSHAs containsObject:commitSHA]) { - if ([testSHA isEqual:commitSHA]) + GTOID *commitOID = commit.OID; + if ([searchOIDs containsObject:commitOID]) { + if ([testOID isEqual:commitOID]) return YES; - [searchSHAs removeObject:commitSHA]; - [searchSHAs addObjectsFromArray:commit.parents]; + [searchOIDs removeObject:commitOID]; + [searchOIDs addObjectsFromArray:commit.parents]; } - else if ([testSHA isEqual:commitSHA]) + else if ([testOID isEqual:commitOID]) return NO; } return NO; } -- (BOOL)isSHAOnHeadBranch:(GTOID *)testSHA +- (BOOL)isOIDOnHeadBranch:(GTOID *)testOID { - if (!testSHA) + if (!testOID) return NO; - GTOID *headSHA = [self headSHA]; + GTOID *headOID = self.headOID; - if ([testSHA isEqual:headSHA]) + if ([testOID isEqual:headOID]) return YES; - return [self isOnSameBranch:headSHA asSHA:testSHA]; + return [self isOIDOnSameBranch:headOID asOID:testOID]; } - (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef @@ -478,7 +521,7 @@ - (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef if (!testRef) return NO; - return [self isSHAOnHeadBranch:[self shaForRef:testRef]]; + return [self isOIDOnHeadBranch:[self OIDForRef:testRef]]; } - (BOOL) checkRefFormat:(NSString *)refName @@ -566,18 +609,89 @@ - (void) readCurrentBranch self.currentBranch = [self addBranch: [self headRef]]; } -- (NSString *) workingDirectory +- (NSURL *)workingDirectoryURL { + return self.gtRepo.fileURL; +} + +- (NSString *)workingDirectory { - const char* workdir = git_repository_workdir(self.gtRepo.git_repository); - if (workdir) - { - NSString* result = [[NSString stringWithUTF8String:workdir] stringByStandardizingPath]; - return result; - } - else - { - return self.fileURL.path; - } + return [self.workingDirectoryURL path]; +} + +#pragma mark Stashes + +- (NSArray *)stashes +{ + NSMutableArray *stashes = [NSMutableArray array]; + [self.gtRepo enumerateStashesUsingBlock:^(NSUInteger index, NSString *message, GTOID *oid, BOOL *stop) { + PBGitStash *stash = [[PBGitStash alloc] initWithRepository:self stashOID:oid index:index message:message]; + [stashes addObject:stash]; + }]; + return [NSArray arrayWithArray:stashes]; +} + +- (PBGitStash *)stashForRef:(PBGitRef *)ref { + __block PBGitStash * found = nil; + + [self.gtRepo enumerateStashesUsingBlock:^(NSUInteger index, NSString *message, GTOID *oid, BOOL *stop) { + PBGitStash *stash = [[PBGitStash alloc] initWithRepository:self stashOID:oid index:index message:message]; + if ([stash.ref isEqualToRef:ref]) { + found = stash; + stop = YES; + (void)stop; + } + }]; + return found; +} + +- (BOOL)stashRunCommand:(NSString *)command withStash:(PBGitStash *)stash +{ + int retValue; + NSArray *arguments = @[@"stash", command, stash.ref.refishName]; + NSString *output = [self outputInWorkdirForArguments:arguments retValue:&retValue]; + [self willChangeValueForKey:@"stashes"]; + [self didChangeValueForKey:@"stashes"]; + if (retValue) { + NSString *title = [NSString stringWithFormat:@"Stash %@ failed!", command]; + NSString *message = [NSString stringWithFormat:@"There was an error!"]; + [self.windowController showErrorSheetTitle:title message:message arguments:arguments output:output]; + } + return retValue ? NO : YES; +} + +- (BOOL)stashPop:(PBGitStash *)stash +{ + return [self stashRunCommand:@"pop" withStash:stash]; +} + +- (BOOL)stashApply:(PBGitStash *)stash +{ + return [self stashRunCommand:@"apply" withStash:stash]; +} + +- (BOOL)stashDrop:(PBGitStash *)stash +{ + return [self stashRunCommand:@"drop" withStash:stash]; +} + +- (BOOL)stashSave +{ + return [self stashSaveWithKeepIndex:NO]; +} + +- (BOOL)stashSaveWithKeepIndex:(BOOL)keepIndex +{ + int retValue; + NSArray * arguments = @[@"stash", @"save", keepIndex?@"--keep-index":@"--no-keep-index"]; + NSString * output = [self outputInWorkdirForArguments:arguments retValue:&retValue]; + [self willChangeValueForKey:@"stashes"]; + [self didChangeValueForKey:@"stashes"]; + if (retValue) { + NSString *title = [NSString stringWithFormat:@"Stash save failed!"]; + NSString *message = [NSString stringWithFormat:@"There was an error!"]; + [self.windowController showErrorSheetTitle:title message:message arguments:arguments output:output]; + } + return retValue ? NO : YES; } #pragma mark Remotes diff --git a/Classes/git/PBGitSVStashItem.h b/Classes/git/PBGitSVStashItem.h new file mode 100644 index 000000000..332a37a92 --- /dev/null +++ b/Classes/git/PBGitSVStashItem.h @@ -0,0 +1,19 @@ +// +// PBSourceViewStash.h +// GitX +// +// Created by Mathias Leppich on 8/1/13. +// +// + +#import +#import "PBSourceViewItem.h" +#import "PBGitStash.h" + +@interface PBGitSVStashItem : PBSourceViewItem + ++ (id) itemWithStash:(PBGitStash*)stash; + +@property (nonatomic, strong) PBGitStash* stash; + +@end diff --git a/Classes/git/PBGitSVStashItem.m b/Classes/git/PBGitSVStashItem.m new file mode 100644 index 000000000..ccdd67829 --- /dev/null +++ b/Classes/git/PBGitSVStashItem.m @@ -0,0 +1,28 @@ +// +// PBSourceViewStash.m +// GitX +// +// Created by Mathias Leppich on 8/1/13. +// +// + +#import "PBGitSVStashItem.h" +#import "PBGitRevSpecifier.h" + + +@implementation PBGitSVStashItem + ++ (id)itemWithStash:(PBGitStash *)stash +{ + NSString * title = [NSString stringWithFormat:@"@{%zd}: %@", stash.index, stash.message]; + PBGitSVStashItem * item = [self itemWithTitle:title]; + item.stash = stash; + item.revSpecifier = [[PBGitRevSpecifier alloc] initWithRef:stash.ref]; + return item; +} + +-(PBGitRef *)ref { + return self.stash.ref; +} + +@end diff --git a/Classes/git/PBGitStash.h b/Classes/git/PBGitStash.h new file mode 100644 index 000000000..0f921b690 --- /dev/null +++ b/Classes/git/PBGitStash.h @@ -0,0 +1,27 @@ +// +// PBGitStash.h +// GitX +// +// Created by Mathias Leppich on 8/1/13. +// +// + +#import +#import + +@class PBGitCommit; +@class PBGitRef; +@class PBGitRepository; + +@interface PBGitStash : NSObject +@property (nonatomic, readonly) NSInteger index; +@property (nonatomic, readonly) PBGitCommit *commit; +@property (nonatomic, readonly) NSString *message; +@property (nonatomic, readonly) PBGitRef *ref; + +@property (nonatomic, readonly) PBGitCommit *indexCommit; +@property (nonatomic, readonly) PBGitCommit *ancestorCommit; + +- (id)initWithRepository:(PBGitRepository *)repo stashOID:(GTOID *)stashOID index:(NSInteger)index message:(NSString *)message; + +@end diff --git a/Classes/git/PBGitStash.m b/Classes/git/PBGitStash.m new file mode 100644 index 000000000..93a268501 --- /dev/null +++ b/Classes/git/PBGitStash.m @@ -0,0 +1,49 @@ +// +// PBGitStash.m +// GitX +// +// Created by Mathias Leppich on 8/1/13. +// +// + +#import "PBGitStash.h" +#import "PBGitRef.h" +#import "PBGitCommit.h" +#import "PBGitRepository.h" + +@implementation PBGitStash + +-(id)initWithRepository:(PBGitRepository *)repo stashOID:(GTOID *)stashOID index:(NSInteger)index message:(NSString *)message +{ + self = [self init]; + if (!self) return nil; + + _index = index; + _message = message; + + GTRepository * gtRepo = repo.gtRepo; + NSError * error = nil; + GTCommit * gtCommit = (GTCommit *)[gtRepo lookUpObjectByOID:stashOID objectType:GTObjectTypeCommit error:&error]; + NSArray * parents = [gtCommit parents]; + GTCommit * gtIndexCommit = [parents objectAtIndex:1]; + GTCommit * gtAncestorCommit = [parents objectAtIndex:0]; + + _commit = [[PBGitCommit alloc] initWithRepository:repo andCommit:gtCommit]; + _indexCommit = [[PBGitCommit alloc] initWithRepository:repo andCommit:gtIndexCommit]; + _ancestorCommit = [[PBGitCommit alloc] initWithRepository:repo andCommit:gtAncestorCommit]; + + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"stash@{%zd}: %@", _index, _message]; +} + +- (PBGitRef *)ref +{ + NSString * refStr = [NSString stringWithFormat:@"refs/stash@{%zd}", _index]; + return [[PBGitRef alloc] initWithString:refStr]; +} + +@end diff --git a/Classes/git/PBGitTree.m b/Classes/git/PBGitTree.m index bf782aa1e..df857bc41 100644 --- a/Classes/git/PBGitTree.m +++ b/Classes/git/PBGitTree.m @@ -23,7 +23,7 @@ + (PBGitTree*) rootForCommit:(id) commit PBGitTree* tree = [[self alloc] init]; tree.parent = nil; tree.leaf = NO; - tree.sha = [c realSha]; + tree.sha = c.SHA; tree.repository = c.repository; tree.path = @""; return tree; diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index 8345f800e..787111b89 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -1,2253 +1,440 @@ - - - - 1070 - 12E55 - 3084 - 1187.39 - 626.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 3084 - - - NSCustomObject - NSMenu - NSMenuItem - NSUserDefaultsController - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - - NSApplication - - - - FirstResponder - - - NSApplication - - - MainMenu - - - - GitX - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - GitX - - - - About GitX - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Enable Terminal Usage… - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - Check for Updates… - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - - Services - - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide GitX - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit GitX - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - - File - - - - - New… - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Clone… - - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - - Open Recent - - - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Clone To… - - 2147483647 - - - - - - YES - Save - s - 1048576 - 2147483647 - - - - - - YES - Save As… - S - 1048576 - 2147483647 - - - - - - YES - Revert to Saved - - 2147483647 - - - - - - YES - YES - YES - - - 1048576 - 2147483647 - - - - - - YES - Page Setup… - P - 1048576 - 2147483647 - - - - - - YES - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - - Edit - - - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - YES - Copy SHA - c - 1572864 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - - Find - - - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1048576 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - - - Show Spelling… - : - 1048576 - 2147483647 - - - - - - Check Spelling - ; - 1048576 - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - - - - Smart Quotes - g - 1048576 - 2147483647 - - - - - - Smart Links - G - 1048576 - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - - - Start Speaking - - 2147483647 - - - - - - Stop Speaking - - 2147483647 - - - - - - - - - - - - Repository - - 2147483647 - - - submenuAction: - - Repository - - - - Create Tag - t - 1048576 - 2147483647 - - - - - - Create Branch - b - 1048576 - 2147483647 - - - - - - Add Remote - r - 1572864 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Open in Terminal - T - 1048576 - 2147483647 - - - - - - Reveal in Finder - F - 1048576 - 2147483647 - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - History - 1 - 1048576 - 2147483647 - - - - - - Commit - 2 - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Detail View - 1 - 1572864 - 2147483647 - - - - - - Tree View - 2 - 1572864 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Refresh - r - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - - Window - - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 1048576 - 2147483647 - - - submenuAction: - - Help - - - - GitX Help - ? - 1048576 - 2147483647 - - - - - - Report a problem - - 2147483647 - - - - - - Latest changes - - 2147483647 - - - - - - Discuss GitX - - 2147483647 - - - - - - - - _NSMainMenu - - - ApplicationController - - - PBRepositoryDocumentController - - - YES - - - SUUpdater - - - - - - - terminate: - - - - 139 - - - - hideOtherApplications: - - - - 146 - - - - hide: - - - - 152 - - - - unhideAllApplications: - - - - 153 - - - - delegate - - - - 206 - - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - cut: - - - - 175 - - - - paste: - - - - 176 - - - - redo: - - - - 178 - - - - selectAll: - - - - 179 - - - - undo: - - - - 180 - - - - copy: - - - - 181 - - - - showGuessPanel: - - - - 188 - - - - checkSpelling: - - - - 190 - - - - toggleContinuousSpellChecking: - - - - 192 - - - - performClose: - - - - 193 - - - - delete: - - - - 195 - - - - performFindPanelAction: - - - - 199 - - - - performFindPanelAction: - - - - 202 - - - - centerSelectionInVisibleArea: - - - - 203 - - - - performMiniaturize: - - - - 247 - - - - performZoom: - - - - 248 - - - - arrangeInFront: - - - - 249 - - - - startSpeaking: - - - - 257 - - - - stopSpeaking: - - - - 258 - - - - toggleToolbarShown: - - - - 342 - - - - runToolbarCustomizationPalette: - - - - 343 - - - - openDocument: - - - - 907 - - - - refresh: - - - - 926 - - - - showHistoryView: - - - - 930 - - - - showCommitView: - - - - 931 - - - - newDocument: - - - - 934 - - - - createBranch: - - - - 941 - - - - openInTerminal: - - - - 944 - - - - revealInFinder: - - - - 948 - - - - createTag: - - - - 950 - - - - showAddRemoteSheet: - - - - 953 - - - - cloneTo: - - - - 955 - - - - showCloneRepository: - - - - 958 - - - - setDetailedView: - - - - 962 - - - - setTreeView: - - - - 963 - - - - copySHA: - - - - 966 - - - - selectNext: - - - - 967 - - - - selectPrevious: - - - - 968 - - - - showAboutPanel: - - - - 142 - - - - firstResponder - - - - 868 - - - - installCliTool: - - - - 910 - - - - showHelp: - - - - 932 - - - - openPreferencesWindow: - - - - 933 - - - - reportAProblem: - - - - 971 - - - - showChangeLog: - - - - 976 - - - - checkForUpdates: - - - - 920 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - - - - - - - - - - MainMenu - - - 56 - - - - - - - - 57 - - - - - - - - - - - - - - - - - - - - 58 - - - - - 129 - - - - - 131 - - - - - - - - 130 - - - - - 134 - - - - - 136 - - - - - 143 - - - - - 144 - - - - - 145 - - - - - 149 - - - - - 150 - - - - - 196 - - - - - 83 - - - - - - - - 81 - - - - - - - - - - - - - - - - - - - - 72 - - - - - 73 - - - - - 74 - - - - - 75 - - - - - 77 - - - - - 78 - - - - - 79 - - - - - 80 - - - - - 82 - - - - - 112 - - - - - 124 - - - - - - - - 125 - - - - - - - - 126 - - - - - 103 - - - - - - - - 106 - - - - - - - - - - - 111 - - - - - 163 - - - - - - - - 169 - - - - - - - - - - - - - - - - - - - - - 156 - - - - - 157 - - - - - 158 - - - - - 160 - - - - - 164 - - - - - 168 - - - - - - - - 159 - - - - - - - - - - - - 154 - - - - - 155 - - - - - 161 - - - - - 162 - - - - - 167 - - - - - 171 - - - - - 172 - - - - - 173 - - - - - 174 - - - - - 184 - - - - - - - - 185 - - - - - - - - - - - 187 - - - - - 189 - - - - - 191 - - - - - 212 - - - - - 214 - - - - - - - - 215 - - - - - - - - - - 216 - - - - - 218 - - - - - 219 - - - - - 224 - - - - - - - - 225 - - - - - - - - - 227 - - - - - 228 - - - - - 241 - - - - - - - - 242 - - - - - - - - - - - 243 - - - - - 244 - - - - - 245 - - - - - 246 - - - - - 338 - - - - - - - - 339 - - - - - - - - - - - - - - - - - 340 - - - - - 341 - - - - - 205 - - - ApplicationController - - - 847 - - - - - 848 - - - - - 852 - - - - - 908 - - - - - 909 - - - - - 912 - - - - - 915 - - - - - 916 - - - - - 918 - - - - - 919 - - - - - 927 - - - - - 928 - - - - - 929 - - - - - 936 - - - - - - - - 937 - - - - - - - - - - - - - 938 - - - - - 942 - - - - - 943 - - - - - 947 - - - - - 949 - - - - - 951 - - - - - 954 - - - - - 956 - - - - - 964 - - - - - 969 - - - - - 972 - - - - - 974 - - - Menu Item - Change Log - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 976 - - - - - FirstResponder - - id - id - id - id - - - - copySHA: - id - - - setDetailedView: - id - - - setRawView: - id - - - setTreeView: - id - - - - IBUserSource - - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - {11, 11} - {10, 3} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index 5301ed124..ff04e774d 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -166,6 +166,8 @@ 97CF01F918A6C5BB00E30F2B /* deleted_file.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 97CF01F618A6C5BB00E30F2B /* deleted_file.pdf */; }; 97CF01FA18A6C5BB00E30F2B /* empty_file.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 97CF01F718A6C5BB00E30F2B /* empty_file.pdf */; }; 97CF01FB18A6C5BB00E30F2B /* new_file.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 97CF01F818A6C5BB00E30F2B /* new_file.pdf */; }; + A2F8D0DF17AAB32500580B84 /* PBGitStash.m in Sources */ = {isa = PBXBuildFile; fileRef = A2F8D0DE17AAB32500580B84 /* PBGitStash.m */; }; + A2F8D0EB17AAB95E00580B84 /* PBGitSVStashItem.m in Sources */ = {isa = PBXBuildFile; fileRef = A2F8D0EA17AAB95E00580B84 /* PBGitSVStashItem.m */; }; D87127011229A21C00012334 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D87127001229A21C00012334 /* QuartzCore.framework */; }; D89E9B141218BA260097A90B /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D89E9AB21218A9DA0097A90B /* ScriptingBridge.framework */; }; D8E3B2B810DC9FB2001096A3 /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */; }; @@ -563,6 +565,10 @@ 97CF01F618A6C5BB00E30F2B /* deleted_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = deleted_file.pdf; sourceTree = ""; }; 97CF01F718A6C5BB00E30F2B /* empty_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = empty_file.pdf; sourceTree = ""; }; 97CF01F818A6C5BB00E30F2B /* new_file.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = new_file.pdf; sourceTree = ""; }; + A2F8D0DD17AAB32500580B84 /* PBGitStash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitStash.h; sourceTree = ""; }; + A2F8D0DE17AAB32500580B84 /* PBGitStash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitStash.m; sourceTree = ""; }; + A2F8D0E917AAB95E00580B84 /* PBGitSVStashItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSVStashItem.h; sourceTree = ""; }; + A2F8D0EA17AAB95E00580B84 /* PBGitSVStashItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSVStashItem.m; sourceTree = ""; }; D87127001229A21C00012334 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; D89E9AB21218A9DA0097A90B /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = System/Library/Frameworks/ScriptingBridge.framework; sourceTree = SDKROOT; }; D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ScriptingBridge.framework; path = /System/Library/Frameworks/ScriptingBridge.framework; sourceTree = ""; }; @@ -897,12 +903,18 @@ 4A5D767C14A9A9CC00DF6C68 /* PBGitSVStageItem.m */, 4A5D767D14A9A9CC00DF6C68 /* PBGitSVTagItem.h */, 4A5D767E14A9A9CC00DF6C68 /* PBGitSVTagItem.m */, + A2F8D0E917AAB95E00580B84 /* PBGitSVStashItem.h */, + A2F8D0EA17AAB95E00580B84 /* PBGitSVStashItem.m */, 4A5D767F14A9A9CC00DF6C68 /* PBGitTree.h */, 4A5D768014A9A9CC00DF6C68 /* PBGitTree.m */, 4A5D768114A9A9CC00DF6C68 /* PBGitXErrors.h */, 4A5D768214A9A9CC00DF6C68 /* PBGitXErrors.m */, 4A5D768314A9A9CC00DF6C68 /* PBGitXProtocol.h */, 4A5D768414A9A9CC00DF6C68 /* PBGitXProtocol.m */, + 643952721603E9BC00BB7AFF /* PBGitSubmodule.h */, + 643952731603E9BC00BB7AFF /* PBGitSubmodule.m */, + A2F8D0DD17AAB32500580B84 /* PBGitStash.h */, + A2F8D0DE17AAB32500580B84 /* PBGitStash.m */, 643952751603EF9B00BB7AFF /* PBGitSVSubmoduleItem.h */, 643952761603EF9B00BB7AFF /* PBGitSVSubmoduleItem.m */, 4AB057E11652652000DE751D /* GitRepoFinder.h */, @@ -1397,6 +1409,8 @@ 643952771603EF9B00BB7AFF /* PBGitSVSubmoduleItem.m in Sources */, 4AB057E31652652000DE751D /* GitRepoFinder.m in Sources */, 4A2125A417C0C78A00B5B582 /* NSColor+RGB.m in Sources */, + A2F8D0DF17AAB32500580B84 /* PBGitStash.m in Sources */, + A2F8D0EB17AAB95E00580B84 /* PBGitSVStashItem.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Resources/XIBs/PBGitCommitView.xib b/Resources/XIBs/PBGitCommitView.xib index bbd55c3c4..7100b06fa 100644 --- a/Resources/XIBs/PBGitCommitView.xib +++ b/Resources/XIBs/PBGitCommitView.xib @@ -1,1622 +1,362 @@ - - - - 1070 - 12E55 - 3084 - 1187.39 - 626.00 - - 3084 - 2053 - - - NSArrayController - NSBox - NSButton - NSButtonCell - NSCustomObject - NSCustomView - NSScrollView - NSScroller - NSSplitView - NSTableColumn - NSTableView - NSTextFieldCell - NSTextView - NSUserDefaultsController - WebView - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - - - PluginDependencyRecalculationVersion - - - - - PBGitCommitController - - - FirstResponder - - - NSApplication - - - - 274 - - - - 274 - - - - 274 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple URL pasteboard type - Apple Web Archive pasteboard type - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - WebURLsWithTitlesPboardType - public.png - public.url - public.url-name - - {852, 181} - - - - - - - - - - - - - YES - YES - - - - 256 - - - - 36 - - - - 274 - - - - 4370 - - - - 2304 - - - - 4352 - {189, 221} - - - YES - NO - YES - - - 256 - {{244, 0}, {16, 17}} - - - - 186 - 10 - 3.4028229999999999e+38 - - 75497536 - 2048 - - - LucidaGrande - 11 - 3100 - - - 6 - System - headerColor - - 3 - MQA - - - - 6 - System - headerTextColor - - 3 - MAA - - - - - 337641536 - 133632 - Text Cell - - - - 6 - System - controlBackgroundColor - - 3 - MC42NjY2NjY2NjY3AA - - - - 6 - System - controlTextColor - - - - 3 - YES - - - - 3 - 2 - - - 6 - System - gridColor - - 3 - MC41AA - - - 15 - -566231040 - - - 4 - 15 - 0 - YES - 0 - 1 - - - {{1, 1}, {189, 221}} - - - - - 4 - - - - -2147483392 - {{174, 1}, {15, 178}} - - - NO - - _doScroller: - 0.99337750000000002 - - - - -2147483392 - {{1, 179}, {173, 15}} - - - NO - 1 - - _doScroller: - 0.99470899999999995 - - - {{-1, -1}, {191, 223}} - - - 133682 - - - - QSAAAEEgAABBiAAAQYgAAA - 0.25 - 4 - 1 - - - {190, 227} - - - - - {190, 242} - - - {0, 0} - - 67108864 - 0 - Unstaged Changes - - - 6 - System - textBackgroundColor - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 0 - 2 - NO - - - - 36 - - - - 274 - - - - 289 - {{339, 0}, {96, 32}} - - - YES - - 67108864 - 134217728 - Commit - - LucidaGrande - 13 - 1044 - - - -2038284288 - 268435585 - - DQ - 200 - 25 - - NO - - - - 274 - - - - 2304 - - - - 2322 - - Apple HTML pasteboard type - Apple PDF pasteboard type - Apple PICT pasteboard type - Apple PNG pasteboard type - Apple URL pasteboard type - CorePasteboardFlavorType 0x6D6F6F76 - NSColor pasteboard type - NSFilenamesPboardType - NSStringPboardType - NeXT Encapsulated PostScript v1.2 pasteboard type - NeXT RTFD pasteboard type - NeXT Rich Text Format v1.0 pasteboard type - NeXT TIFF v4.0 pasteboard type - NeXT font pasteboard type - NeXT ruler pasteboard type - WebURLsWithTitlesPboardType - public.url - - {427, 184} - - - - - - - - - - - - - - 38 - - - - 427 - 1 - - - 67407747 - 0 - - - - - 6 - System - selectedTextBackgroundColor - - - - 6 - System - selectedTextColor - - - - - - - 1 - MCAwIDEAA - - - - - - 0 - - 6 - {1161, 10000000} - - - - {{1, 1}, {427, 184}} - - - - - - {4, 5} - - 79691776 - - - - - - file://localhost/Applications/Xcode.app/Contents/SharedFrameworks/DVTKit.framework/Resources/DVTIbeamCursor.tiff - - - - - 3 - MCAwAA - - - - 4 - - - - -2147483392 - {{346, 1}, {15, 164}} - - - NO - - _doScroller: - 0.99166670000000001 - - - - -2147483392 - {{-100, -100}, {87, 18}} - - - NO - 1 - - _doScroller: - 1 - 0.94565220000000005 - - - {{0, 36}, {429, 186}} - - - 133650 - - - - 0.25 - 4 - 1 - - - - 292 - {{-2, 9}, {82, 18}} - - - YES - - -2080374784 - 0 - Amend - - - 1211912448 - 402653186 - - NSImage - NSSwitch - - - NSSwitch - - - a - 200 - 25 - - NO - - - - 289 - {{243, 0}, {96, 32}} - - - YES - - 67108864 - 134217728 - Sign-Off - - - -2038284288 - 129 - - - 200 - 25 - - NO - - - {429, 227} - - - - - {{199, 0}, {429, 242}} - - - {0, 0} - - 67108864 - 0 - Commit Message - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 0 - 2 - NO - - - - 17 - - - - 274 - - - - 4370 - - - - 2304 - - - - 4352 - {214, 221} - - - 1 - YES - NO - YES - - - 256 - {{244, 0}, {16, 17}} - - - - 211 - 10 - 3.4028229999999999e+38 - - 75497536 - 2048 - - - - - - - 67108928 - 133632 - Text Cell - - - - - - 3 - YES - YES - - - - 3 - 2 - - - 15 - -566231040 - - - 4 - 15 - 0 - YES - 0 - 1 - - - {{1, 1}, {214, 221}} - - - - - 4 - - - - -2147483392 - {{257, 1}, {15, 246}} - - - NO - - _doScroller: - 0.99519230000000003 - - - - -2147483392 - {{1, 247}, {256, 15}} - - NO - 1 - - _doScroller: - 0.90033220000000003 - - - {{0, -1}, {216, 223}} - - - 133682 - - - - QSAAAEEgAABBiAAAQYgAAA - 0.25 - 4 - 1 - - - {215, 227} - - - - - {{637, 0}, {215, 242}} - - - {0, 0} - - 67108864 - 0 - Staged Changes - - - - 3 - MCAwLjgwMDAwMDAxAA - - - - 0 - 0 - 2 - NO - - - {{0, 190}, {852, 242}} - - - YES - - - {852, 432} - - - - - {852, 432} - - NSView - - - YES - - - - path - icon - - YES - - YES - YES - YES - - - - value - description - path - icon - commitBlobSHA - - YES - - YES - YES - YES - - - PBWebChangesController - - - PBGitIndexController - - - - - - - view - - - - 44 - - - - cachedFilesController - - - - 155 - - - - unstagedFilesController - - - - 156 - - - - commit: - - - - 212 - - - - commitMessageView - - - - 213 - - - - webController - - - - 253 - - - - indexController - - - - 256 - - - - signOff: - - - - 280 - - - - commitButton - - - - 307 - - - - commitSplitView - - - - 314 - - - - delegate - - - - 258 - - - - dataSource - - - - 276 - - - - delegate - - - - 259 - - - - dataSource - - - - 277 - - - - contentArray: index.indexChanges - - - - - - contentArray: index.indexChanges - contentArray - index.indexChanges - 2 - - - 281 - - - - contentArray: index.indexChanges - - - - - - contentArray: index.indexChanges - contentArray - index.indexChanges - 2 - - - 282 - - - - cachedFilesController - - - - 97 - - - - unstagedFilesController - - - - 98 - - - - controller - - - - 101 - - - - view - - - - 136 - - - - indexController - - - - 262 - - - - value: arrangedObjects.path - - - - - - value: arrangedObjects.path - value - arrangedObjects.path - 2 - - - 139 - - - - value: arrangedObjects.path - - - - - - value: arrangedObjects.path - value - arrangedObjects.path - 2 - - - 122 - - - - frameLoadDelegate - - - - 137 - - - - delegate - - - - 313 - - - - value: index.amend - - - - - - value: index.amend - value - index.amend - 2 - - - 283 - - - - commitController - - - - 257 - - - - unstagedFilesController - - - - 260 - - - - stagedFilesController - - - - 261 - - - - stagedTable - - - - 263 - - - - unstagedTable - - - - 264 - - - - rowClicked: - - - - 268 - - - - rowClicked: - - - - 269 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 1 - - - - - - - - 77 - - - - - 81 - - - Unstaged Files - - - 86 - - - Cached Files - - - 96 - - - Diff Controller - - - 186 - - - - - - - - - 125 - - - - - 209 - - - - - - - - - - 208 - - - - - - - - 207 - - - - - - - - - - - 206 - - - - - - - - 45 - - - - - - - - - - 48 - - - - - - - - 47 - - - - - 46 - - - - - 104 - - - - - - - - 105 - - - - - 163 - - - - - - - - 130 - - - - - - - - - - 133 - - - - - 132 - - - - - 131 - - - - - 164 - - - - - 54 - - - - - - - - - - 57 - - - - - - - - 56 - - - - - 55 - - - - - 113 - - - - - - - - 114 - - - - - 247 - - - - - - - - 248 - - - - - 254 - - - - - 278 - - - - - - - - 279 - - - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBIconAndTextCell - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBIconAndTextCell - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.WebKitIBPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBCommitMessageView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBNiceSplitView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBFileChangesTableView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - PBFileChangesTableView - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 314 - - - - - PBCommitMessageView - NSTextView - - IBProjectSource - ./Classes/PBCommitMessageView.h - - - - PBFileChangesTableView - NSTableView - - IBProjectSource - ./Classes/PBFileChangesTableView.h - - - - PBGitCommitController - PBViewController - - id - id - id - id - - - - commit: - id - - - forceCommit: - id - - - refresh: - id - - - signOff: - id - - - - NSArrayController - NSButton - NSTextView - PBNiceSplitView - PBGitIndexController - NSArrayController - PBWebChangesController - - - - cachedFilesController - NSArrayController - - - commitButton - NSButton - - - commitMessageView - NSTextView - - - commitSplitView - PBNiceSplitView - - - indexController - PBGitIndexController - - - unstagedFilesController - NSArrayController - - - webController - PBWebChangesController - - - - IBProjectSource - ./Classes/PBGitCommitController.h - - - - PBGitIndexController - NSObject - - NSCell - NSTableView - - - - rowClicked: - NSCell - - - tableClicked: - NSTableView - - - - PBGitCommitController - NSArrayController - NSTableView - NSArrayController - NSTableView - - - - commitController - PBGitCommitController - - - stagedFilesController - NSArrayController - - - stagedTable - NSTableView - - - unstagedFilesController - NSArrayController - - - unstagedTable - NSTableView - - - - IBProjectSource - ./Classes/PBGitIndexController.h - - - - PBIconAndTextCell - NSTextFieldCell - - IBProjectSource - ./Classes/PBIconAndTextCell.h - - - - PBNiceSplitView - NSSplitView - - IBProjectSource - ./Classes/PBNiceSplitView.h - - - - PBViewController - NSViewController - - refresh: - id - - - refresh: - - refresh: - id - - - - IBProjectSource - ./Classes/PBViewController.h - - - - PBWebChangesController - PBWebController - - NSArrayController - PBGitCommitController - PBGitIndexController - NSArrayController - - - - cachedFilesController - NSArrayController - - - controller - PBGitCommitController - - - indexController - PBGitIndexController - - - unstagedFilesController - NSArrayController - - - - IBProjectSource - ./Classes/PBWebChangesController.h - - - - PBWebController - NSObject - - id - WebView - - - - repository - id - - - view - WebView - - - - IBProjectSource - ./Classes/PBWebController.h - - - - WebView - - reloadFromOrigin: - id - - - reloadFromOrigin: - - reloadFromOrigin: - id - - - - IBProjectSource - ./Classes/WebView.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - YES - 3 - - NSSwitch - {15, 15} - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + path + icon + + + + + + + + value + description + path + icon + commitBlobSHA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/views/history/history.js b/html/views/history/history.js index 4fdf88495..3acbc1c59 100644 --- a/html/views/history/history.js +++ b/html/views/history/history.js @@ -8,7 +8,7 @@ var Commit = function(obj) { this.refs = obj.refs(); this.author_name = obj.author(); this.committer_name = obj.committer(); - this.sha = obj.realSha(); + this.sha = obj.SHA(); this.parents = obj.parents(); this.subject = obj.subject(); this.notificationID = null;