diff --git a/PBDiffWindowController.h b/PBDiffWindowController.h index 6cb1baf..b8dba7e 100644 --- a/PBDiffWindowController.h +++ b/PBDiffWindowController.h @@ -8,11 +8,14 @@ #import +@class PBGitCommit; @interface PBDiffWindowController : NSWindowController { NSString *diff; } -- initWithDiff:(NSString *)diff; ++ (void) showDiffWindowWithFiles:(NSArray *)filePaths fromCommit:(PBGitCommit *)startCommit diffCommit:(PBGitCommit *)diffCommit; +- (id) initWithDiff:(NSString *)diff; + @property (readonly) NSString *diff; @end diff --git a/PBDiffWindowController.m b/PBDiffWindowController.m index cd5dcc5..496c850 100644 --- a/PBDiffWindowController.m +++ b/PBDiffWindowController.m @@ -7,6 +7,8 @@ // #import "PBDiffWindowController.h" +#import "PBGitRepository.h" +#import "PBGitCommit.h" @implementation PBDiffWindowController @@ -21,4 +23,32 @@ return self; } + ++ (void) showDiffWindowWithFiles:(NSArray *)filePaths fromCommit:(PBGitCommit *)startCommit diffCommit:(PBGitCommit *)diffCommit +{ + if (!startCommit) + return; + + if (!diffCommit) + diffCommit = [startCommit.repository headCommit]; + + NSString *commitSelector = [NSString stringWithFormat:@"%@..%@", [startCommit realSha], [diffCommit realSha]]; + NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"diff", commitSelector, nil]; + if (filePaths) { + [arguments addObject:@"--"]; + [arguments addObjectsFromArray:filePaths]; + } + + int retValue; + NSString *diff = [startCommit.repository outputInWorkdirForArguments:arguments retValue:&retValue]; + if (retValue) { + NSLog(@"diff failed with retValue: %d for command: '%@' output: '%@'", retValue, [arguments componentsJoinedByString:@" "], diff); + return; + } + + PBDiffWindowController *diffController = [[PBDiffWindowController alloc] initWithDiff:[diff copy]]; + [diffController showWindow:nil]; +} + + @end diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index 79b77c3..8fc914e 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -16,6 +16,7 @@ #import "PBAddRemoteSheet.h" #import "PBGitSidebarController.h" #import "PBGitGradientBarView.h" +#import "PBDiffWindowController.h" #define QLPreviewPanel NSClassFromString(@"QLPreviewPanel") @@ -294,6 +295,10 @@ [repository checkoutFiles:files fromRefish:realCommit]; } +- (void) diffFilesAction:(id)sender +{ + [PBDiffWindowController showDiffWindowWithFiles:[sender representedObject] fromCommit:realCommit diffCommit:nil]; +} - (NSMenu *)contextMenuForTreeView { @@ -315,6 +320,15 @@ NSMenuItem *historyItem = [[NSMenuItem alloc] initWithTitle:multiple? @"Show history of files" : @"Show history of file" action:@selector(showCommitsFromTree:) keyEquivalent:@""]; + + PBGitRef *headRef = [[repository headRef] ref]; + NSString *headRefName = [headRef shortName]; + NSString *diffTitle = [NSString stringWithFormat:@"Diff %@ with %@", multiple ? @"files" : @"file", headRefName]; + BOOL isHead = [[realCommit realSha] isEqualToString:[repository headSHA]]; + NSMenuItem *diffItem = [[NSMenuItem alloc] initWithTitle:diffTitle + action:isHead ? nil : @selector(diffFilesAction:) + keyEquivalent:@""]; + NSMenuItem *checkoutItem = [[NSMenuItem alloc] initWithTitle:multiple ? @"Checkout files" : @"Checkout file" action:@selector(checkoutFiles:) keyEquivalent:@""]; @@ -325,7 +339,7 @@ action:@selector(openFilesAction:) keyEquivalent:@""]; - NSArray *menuItems = [NSArray arrayWithObjects:historyItem, checkoutItem, finderItem, openFilesItem, nil]; + NSArray *menuItems = [NSArray arrayWithObjects:historyItem, diffItem, checkoutItem, finderItem, openFilesItem, nil]; for (NSMenuItem *item in menuItems) { [item setTarget:self]; [item setRepresentedObject:filePaths]; diff --git a/PBRefController.h b/PBRefController.h index 3794d51..76e5cd8 100644 --- a/PBRefController.h +++ b/PBRefController.h @@ -37,6 +37,7 @@ - (void) createBranch:(PBRefMenuItem *)sender; - (void) copySHA:(PBRefMenuItem *)sender; - (void) copyPatch:(PBRefMenuItem *)sender; +- (void) diffWithHEAD:(PBRefMenuItem *)sender; - (void) createTag:(PBRefMenuItem *)sender; - (void) showTagInfoSheet:(PBRefMenuItem *)sender; diff --git a/PBRefController.m b/PBRefController.m index af51b10..ebddf1a 100644 --- a/PBRefController.m +++ b/PBRefController.m @@ -12,6 +12,7 @@ #import "PBCreateBranchSheet.h" #import "PBCreateTagSheet.h" #import "PBGitDefaults.h" +#import "PBDiffWindowController.h" @implementation PBRefController @@ -204,6 +205,19 @@ } +#pragma mark Diff + +- (void) diffWithHEAD:(PBRefMenuItem *)sender +{ + PBGitCommit *commit = nil; + if ([[sender refish] refishType] == kGitXCommitType) + commit = (PBGitCommit *)[sender refish]; + else + commit = [historyController.repository commitForRef:[sender refish]]; + + [PBDiffWindowController showDiffWindowWithFiles:nil fromCommit:commit diffCommit:nil]; +} + #pragma mark Tags - (void) createTag:(PBRefMenuItem *)sender diff --git a/PBRefMenuItem.m b/PBRefMenuItem.m index 532636e..8a571d5 100644 --- a/PBRefMenuItem.m +++ b/PBRefMenuItem.m @@ -66,6 +66,10 @@ // view tag info if ([ref isTag]) [items addObject:[PBRefMenuItem itemWithTitle:@"View tag info…" action:@selector(showTagInfoSheet:) enabled:YES]]; + + // Diff + NSString *diffTitle = [NSString stringWithFormat:@"Diff with %@", headRefName]; + [items addObject:[PBRefMenuItem itemWithTitle:diffTitle action:@selector(diffWithHEAD:) enabled:!isHead]]; [items addObject:[PBRefMenuItem separatorItem]]; // merge ref @@ -141,6 +145,7 @@ NSString *headBranchName = [[[commit.repository headRef] ref] shortName]; BOOL isOnHeadBranch = [commit isOnHeadBranch]; + BOOL isHead = [[commit realSha] isEqualToString:[commit.repository headSHA]]; [items addObject:[PBRefMenuItem itemWithTitle:@"Checkout Commit" action:@selector(checkout:) enabled:YES]]; [items addObject:[PBRefMenuItem separatorItem]]; @@ -151,6 +156,8 @@ [items addObject:[PBRefMenuItem itemWithTitle:@"Copy SHA" action:@selector(copySHA:) enabled:YES]]; [items addObject:[PBRefMenuItem itemWithTitle:@"Copy Patch" action:@selector(copyPatch:) enabled:YES]]; + NSString *diffTitle = [NSString stringWithFormat:@"Diff with %@", headBranchName]; + [items addObject:[PBRefMenuItem itemWithTitle:diffTitle action:@selector(diffWithHEAD:) enabled:!isHead]]; [items addObject:[PBRefMenuItem separatorItem]]; // merge commit diff --git a/PBWebDiffController.m b/PBWebDiffController.m index a537bd0..0e820b3 100644 --- a/PBWebDiffController.m +++ b/PBWebDiffController.m @@ -35,7 +35,10 @@ return; id script = [view windowScriptObject]; - [script callWebScriptMethod:@"showDiff" withArguments: [NSArray arrayWithObject:diff]]; + if ([diff length] == 0) + [script callWebScriptMethod:@"setMessage" withArguments:[NSArray arrayWithObject:@"There are no differences"]]; + else + [script callWebScriptMethod:@"showDiff" withArguments:[NSArray arrayWithObject:diff]]; } @end diff --git a/html/views/diff/diffWindow.css b/html/views/diff/diffWindow.css new file mode 100644 index 0000000..e9a5122 --- /dev/null +++ b/html/views/diff/diffWindow.css @@ -0,0 +1,14 @@ +#message { + margin-left: 20px; + margin-right: 20px; + margin-top: 40px; + text-align: center; + font-size: 200%; + padding: 20px; + width: auto; + + background-color: #B4D7FF; + border: 2px solid #45A1FE; + + -webkit-border-radius: 10px; +} \ No newline at end of file diff --git a/html/views/diff/diffWindow.js b/html/views/diff/diffWindow.js new file mode 100644 index 0000000..6cef3d7 --- /dev/null +++ b/html/views/diff/diffWindow.js @@ -0,0 +1,8 @@ +// for diffs shown in the PBDiffWindow + +var setMessage = function(message) { + $("message").style.display = ""; + $("message").innerHTML = message.escapeHTML(); + $("diff").style.display = "none"; +} + diff --git a/html/views/diff/index.html b/html/views/diff/index.html index f437056..dc4e6f3 100644 --- a/html/views/diff/index.html +++ b/html/views/diff/index.html @@ -7,6 +7,9 @@ + + +