From e8131c3898a7d831faa76b9f45460ec18adeb48a Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 13 Oct 2008 23:43:28 +0200 Subject: [PATCH] Add a diff window This allows you to do something like gitx --diff to display a diff similar to 'git diff', but with GitX prettification. It accepts all git diff parameters, so you can do something like gitx --diff HEAD~10 to show the diff compared to the last 10 commits. Or, you can something like git diff | gitx to pipe anything that produces a diff to GitX --- GitX.xcodeproj/project.pbxproj | 34 +++- PBCLIProxy.h | 1 + PBCLIProxy.mm | 8 + PBDiffWindow.xib | 302 +++++++++++++++++++++++++++++++++ PBDiffWindowController.h | 18 ++ PBDiffWindowController.m | 24 +++ PBWebDiffController.h | 18 ++ PBWebDiffController.m | 41 +++++ gitx.mm | 119 +++++++++---- html/simpleDiff.html | 19 +++ 10 files changed, 546 insertions(+), 38 deletions(-) create mode 100644 PBDiffWindow.xib create mode 100644 PBDiffWindowController.h create mode 100644 PBDiffWindowController.m create mode 100644 PBWebDiffController.h create mode 100644 PBWebDiffController.m create mode 100644 html/simpleDiff.html diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index b639e3a..a79b89c 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -63,6 +63,9 @@ F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C007740E731B48007B84B2 /* PBGitRef.m */; }; F5C6F68D0E65FF9300478D97 /* PBGitLane.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C6F68C0E65FF9300478D97 /* PBGitLane.m */; }; F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DFFA6B0E075D8800617813 /* PBEasyFS.m */; }; + F5E424110EA3E4D60046E362 /* PBDiffWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5E424100EA3E4D60046E362 /* PBDiffWindow.xib */; }; + F5E424150EA3E4E10046E362 /* PBDiffWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E424130EA3E4E10046E362 /* PBDiffWindowController.m */; }; + F5E424180EA3E4EB0046E362 /* PBWebDiffController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E424160EA3E4EB0046E362 /* PBWebDiffController.m */; }; F5E4DBFB0EAB58D90013FAFC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5E4DBFA0EAB58D90013FAFC /* SystemConfiguration.framework */; }; F5E926060E8827D300056E75 /* PBViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E926050E8827D300056E75 /* PBViewController.m */; }; F5E927F80E883E7200056E75 /* PBChangedFile.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E927F70E883E7200056E75 /* PBChangedFile.m */; }; @@ -190,6 +193,11 @@ F5D2DC850EA401A80034AD24 /* PBGitConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitConfig.h; sourceTree = ""; }; F5DFFA6A0E075D8800617813 /* PBEasyFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyFS.h; sourceTree = ""; }; F5DFFA6B0E075D8800617813 /* PBEasyFS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBEasyFS.m; sourceTree = ""; }; + F5E424100EA3E4D60046E362 /* PBDiffWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PBDiffWindow.xib; sourceTree = ""; }; + F5E424130EA3E4E10046E362 /* PBDiffWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBDiffWindowController.m; sourceTree = ""; }; + F5E424140EA3E4E10046E362 /* PBDiffWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBDiffWindowController.h; sourceTree = ""; }; + F5E424160EA3E4EB0046E362 /* PBWebDiffController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBWebDiffController.m; sourceTree = ""; }; + F5E424170EA3E4EB0046E362 /* PBWebDiffController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBWebDiffController.h; sourceTree = ""; }; F5E4DBFA0EAB58D90013FAFC /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = ""; }; F5E926040E8827D300056E75 /* PBViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBViewController.h; sourceTree = ""; }; F5E926050E8827D300056E75 /* PBViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBViewController.m; sourceTree = ""; }; @@ -311,6 +319,7 @@ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, F5B721C20E05CF7E00AF29DC /* MainMenu.xib */, 911111E00E58BD5A00BF76B4 /* RepositoryWindow.xib */, + F5E424100EA3E4D60046E362 /* PBDiffWindow.xib */, F52BCE020E84208300AA3741 /* PBGitHistoryView.xib */, F59116E50E843BB50072CCB1 /* PBGitCommitView.xib */, ); @@ -347,6 +356,7 @@ F56174540E05887E001DCD79 /* Git */ = { isa = PBXGroup; children = ( + F5E424120EA3E4DD0046E362 /* Diff */, F5E927E30E883D6800056E75 /* Commit */, F5E927E10E883D2E00056E75 /* History */, F5945E150E02B0C200706420 /* PBGitRepository.h */, @@ -362,6 +372,7 @@ F57CC3850E05DDC1000472E2 /* Controllers */ = { isa = PBXGroup; children = ( + F5B161BB0EAB6E0C005A1DE1 /* Diff */, F5EF8C880E9D498F0050906B /* History */, F5E927F90E883EF600056E75 /* Commit */, 77C8280B06725ACE000B614F /* ApplicationController.h */, @@ -421,6 +432,15 @@ name = HTML; sourceTree = ""; }; + F5B161BB0EAB6E0C005A1DE1 /* Diff */ = { + isa = PBXGroup; + children = ( + F5E424140EA3E4E10046E362 /* PBDiffWindowController.h */, + F5E424130EA3E4E10046E362 /* PBDiffWindowController.m */, + ); + name = Diff; + sourceTree = ""; + }; F5C6F6750E65FE2B00478D97 /* Graphing */ = { isa = PBXGroup; children = ( @@ -438,6 +458,15 @@ name = Graphing; sourceTree = ""; }; + F5E424120EA3E4DD0046E362 /* Diff */ = { + isa = PBXGroup; + children = ( + F5E424160EA3E4EB0046E362 /* PBWebDiffController.m */, + F5E424170EA3E4EB0046E362 /* PBWebDiffController.h */, + ); + name = Diff; + sourceTree = ""; + }; F5E927E10E883D2E00056E75 /* History */ = { isa = PBXGroup; children = ( @@ -575,6 +604,7 @@ F5E92A230E88569500056E75 /* new_file.png in Resources */, F5EC2DAD0E8C235C000FA381 /* spinner.gif in Resources */, F57240BB0E9678EA00D8EE66 /* deleted_file.png in Resources */, + F5E424110EA3E4D60046E362 /* PBDiffWindow.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -620,8 +650,10 @@ F53C4DF70E97FC630022AD59 /* PBGitBinary.m in Sources */, F593DF780E9E636C003A8559 /* PBFileChangesTableView.m in Sources */, 93F7857F0EA3ABF100C1F443 /* PBCommitMessageView.m in Sources */, - 93FCCBA90EA8AF450061B02B /* PBGitConfig.m in Sources */, 93CB42C20EAB7B2200530609 /* PBGitDefaults.m in Sources */, + F5D2DC870EA401A80034AD24 /* PBGitConfig.m in Sources */, + F5E424150EA3E4E10046E362 /* PBDiffWindowController.m in Sources */, + F5E424180EA3E4EB0046E362 /* PBWebDiffController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBCLIProxy.h b/PBCLIProxy.h index 2dcd639..eb4d735 100644 --- a/PBCLIProxy.h +++ b/PBCLIProxy.h @@ -21,4 +21,5 @@ @protocol GitXCliToolProtocol - (BOOL)openRepository:(NSURL*)repositoryPath arguments: (NSArray*) args error:(NSError**)error; +- (void)openDiffWindowWithDiff:(NSString *)diff; @end \ No newline at end of file diff --git a/PBCLIProxy.mm b/PBCLIProxy.mm index e72ad5b..a4a613d 100644 --- a/PBCLIProxy.mm +++ b/PBCLIProxy.mm @@ -12,6 +12,7 @@ #import "PBGitRepository.h" #import "PBGitWindowController.h" #import "PBGitBinary.h" +#import "PBDiffWindowController.h" @implementation PBCLIProxy @synthesize connection; @@ -61,4 +62,11 @@ return YES; } + +- (void)openDiffWindowWithDiff:(NSString *)diff +{ + PBDiffWindowController *diffController = [[PBDiffWindowController alloc] initWithDiff:[diff copy]]; + [diffController showWindow:nil]; + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; +} @end diff --git a/PBDiffWindow.xib b/PBDiffWindow.xib new file mode 100644 index 0000000..e2942e6 --- /dev/null +++ b/PBDiffWindow.xib @@ -0,0 +1,302 @@ + + + + 1050 + 9F33 + 670 + 949.34 + 352.00 + + YES + + + + YES + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + PBDiffWindowController + + + FirstResponder + + + NSApplication + + + PBWebDiffController + + + 15 + 2 + {{196, 240}, {480, 270}} + 603979776 + GitX Diff + NSWindow + + {3.40282e+38, 3.40282e+38} + + + 256 + + YES + + + 274 + + YES + + YES + Apple HTML 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.url + public.url-name + + + {480, 270} + + + + + + + + YES + + YES + WebKitDefaultFixedFontSize + WebKitDefaultFontSize + WebKitMinimumFontSize + + + YES + + + + + + + YES + YES + + + {480, 270} + + + {{0, 0}, {1680, 1028}} + {3.40282e+38, 3.40282e+38} + DiffWindow + + + + + YES + + + window + + + + 6 + + + + view + + + + 9 + + + + frameLoadDelegate + + + + 10 + + + + UIDelegate + + + + 11 + + + + diffController + + + + 12 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 1 + + + YES + + + + + + 2 + + + YES + + + + Diff View + + + 7 + + + + + 8 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 1.IBWindowTemplateEditedContentRect + 1.NSWindowTemplate.visibleAtLaunch + 1.windowTemplate.maxSize + 2.IBPluginDependency + 7.IBPluginDependency + 8.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + {{312, 725}, {480, 270}} + com.apple.InterfaceBuilder.CocoaPlugin + {{312, 725}, {480, 270}} + + {3.40282e+38, 3.40282e+38} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.WebKitIBPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 12 + + + + YES + + PBDiffWindowController + NSWindowController + + IBProjectSource + PBDiffWindowController.h + + + + PBWebController + NSObject + + view + WebView + + + IBProjectSource + PBWebController.h + + + + PBWebDiffController + PBWebController + + diffController + PBDiffWindowController + + + IBProjectSource + PBWebDiffController.h + + + + + 0 + GitX.xcodeproj + 3 + + diff --git a/PBDiffWindowController.h b/PBDiffWindowController.h new file mode 100644 index 0000000..6cb1baf --- /dev/null +++ b/PBDiffWindowController.h @@ -0,0 +1,18 @@ +// +// PBDiffWindowController.h +// GitX +// +// Created by Pieter de Bie on 13-10-08. +// Copyright 2008 Pieter de Bie. All rights reserved. +// + +#import + + +@interface PBDiffWindowController : NSWindowController { + NSString *diff; +} + +- initWithDiff:(NSString *)diff; +@property (readonly) NSString *diff; +@end diff --git a/PBDiffWindowController.m b/PBDiffWindowController.m new file mode 100644 index 0000000..cd5dcc5 --- /dev/null +++ b/PBDiffWindowController.m @@ -0,0 +1,24 @@ +// +// PBDiffWindowController.m +// GitX +// +// Created by Pieter de Bie on 13-10-08. +// Copyright 2008 Pieter de Bie. All rights reserved. +// + +#import "PBDiffWindowController.h" + + +@implementation PBDiffWindowController +@synthesize diff; + +- (id) initWithDiff:(NSString *)aDiff +{ + if (![super initWithWindowNibName:@"PBDiffWindow"]) + return nil; + + diff = aDiff; + return self; +} + +@end diff --git a/PBWebDiffController.h b/PBWebDiffController.h new file mode 100644 index 0000000..bda6014 --- /dev/null +++ b/PBWebDiffController.h @@ -0,0 +1,18 @@ +// +// PBWebDiffController.h +// GitX +// +// Created by Pieter de Bie on 13-10-08. +// Copyright 2008 Pieter de Bie. All rights reserved. +// + +#import +#import "PBWebController.h" +#import "PBDiffWindowController.h" + +@interface PBWebDiffController : PBWebController { + IBOutlet PBDiffWindowController *diffController; +} + +- (void) showDiff:(NSString *)diff; +@end diff --git a/PBWebDiffController.m b/PBWebDiffController.m new file mode 100644 index 0000000..141961a --- /dev/null +++ b/PBWebDiffController.m @@ -0,0 +1,41 @@ +// +// PBWebDiffController.m +// GitX +// +// Created by Pieter de Bie on 13-10-08. +// Copyright 2008 Pieter de Bie. All rights reserved. +// + +#import "PBWebDiffController.h" + + +@implementation PBWebDiffController + +- (void) awakeFromNib +{ + startFile = @"simpleDiff"; + [super awakeFromNib]; + [diffController addObserver:self forKeyPath:@"diff" options:0 context:@"ChangedDiff"]; +} + +- (void) didLoad +{ + [self showDiff:diffController.diff]; +} + +- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(NSString *)context +{ + if ([context isEqualToString: @"ChangedDiff"]) + [self showDiff:diffController.diff]; +} + +- (void) showDiff: (NSString *) diff +{ + if (diff == nil || !finishedLoading) + return; + + id script = [view windowScriptObject]; + [script callWebScriptMethod:@"showDiff" withArguments: [NSArray arrayWithObject:diff]]; +} + +@end diff --git a/gitx.mm b/gitx.mm index fb4cb9c..65829e0 100644 --- a/gitx.mm +++ b/gitx.mm @@ -8,6 +8,7 @@ #import "PBCLIProxy.h" #import "PBGitBinary.h" +#import "PBEasyPipe.h" NSDistantObject* connect() { @@ -16,6 +17,33 @@ NSDistantObject* connect() return proxy; } +NSDistantObject *createProxy() +{ + NSDistantObject *proxy = connect(); + + if (proxy) + return proxy; + + // The connection failed, so try to launch the app + [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier: @"nl.frim.GitX" + options: NSWorkspaceLaunchWithoutActivation + additionalEventParamDescriptor: nil + launchIdentifier: nil]; + + // Now attempt to connect, allowing the app time to startup + for (int attempt = 0; proxy == nil && attempt < 50; ++attempt) { + if (proxy = connect()) + return proxy; + + usleep(15000); + } + + // not succesful! + fprintf(stderr, "Couldn't connect to app server!\n"); + exit(1); + return nil; +} + void usage(char const *programName) { @@ -46,6 +74,32 @@ void version_info() exit(1); } +void handleSTDINDiff(id proxy) +{ + NSFileHandle *handle = [NSFileHandle fileHandleWithStandardInput]; + NSData *data = [handle readDataToEndOfFile]; + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + + if (string && [string length] > 0) { + [proxy openDiffWindowWithDiff:string]; + exit(0); + } +} + +void handleDiffWithArguments(NSArray *arguments, NSString *directory, id proxy) +{ + int ret; + arguments = [[NSArray arrayWithObject:@"diff"] arrayByAddingObjectsFromArray:arguments]; + NSString *diff = [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir:directory retValue:&ret]; + if (ret) { + printf("Invalid diff command\n"); + exit(3); + } + + [proxy openDiffWindowWithDiff:diff]; + exit(0); +} + int main(int argc, const char** argv) { if (argc >= 2 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) @@ -59,43 +113,34 @@ int main(int argc, const char** argv) } // Attempt to connect to the app - id proxy = connect(); + id proxy = createProxy(); - if (!proxy) { - // If the connection failed, try to launch the app - [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier: @"nl.frim.GitX" - options: NSWorkspaceLaunchWithoutActivation - additionalEventParamDescriptor: nil - launchIdentifier: nil]; + // Create arguments + argv++; argc--; + NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argc]; + int i = 0; + for (i = 0; i < argc; i++) + [arguments addObject: [NSString stringWithCString:argv[i]]]; - // Now attempt to connect, allowing the app time to startup - for (int attempt = 0; proxy == nil && attempt < 50; ++attempt){ - if (proxy = connect()) - break; - usleep(15000); - } + if (!isatty(STDIN_FILENO) && fdopen(STDIN_FILENO, "r")) + handleSTDINDiff(proxy); + + // From this point, we require a working directory + NSString *pwd = [[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"]; + if (!pwd) + exit(2); + + if ([arguments count] > 0 && ([[arguments objectAtIndex:0] isEqualToString:@"--diff"] || + [[arguments objectAtIndex:0] isEqualToString:@"-d"])) + handleDiffWithArguments([arguments subarrayWithRange:NSMakeRange(1, [arguments count] - 1)], pwd, proxy); + + // No diff, just open the current dir + NSURL* url = [NSURL fileURLWithPath:pwd]; + NSError* error = nil; + + if (![proxy openRepository:url arguments: arguments error:&error]) { + fprintf(stderr, "Error opening repository at %s\n", [[url path] UTF8String]); + if (error) + fprintf(stderr, "\t%s\n", [[error localizedFailureReason] UTF8String]); } - if (!proxy) { - fprintf(stderr, "Couldn't connect to app server!\n"); - exit(1); - } - - if ([[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"]) { - int i; - argv++; argc--; - NSURL* url = [NSURL fileURLWithPath:[[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"]]; - - NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argc]; - for (i = 0; i < argc; i++) - [arguments addObject: [NSString stringWithCString:argv[i]]]; - - NSError* error = nil; - if (![proxy openRepository:url arguments: arguments error:&error]) { - fprintf(stderr, "Error opening repository at %s", [[url path] UTF8String]); - if (error) { - fprintf(stderr, ": %s", [[error localizedFailureReason] UTF8String]); - } - fprintf(stderr, "\n"); - } - } -} +} \ No newline at end of file diff --git a/html/simpleDiff.html b/html/simpleDiff.html new file mode 100644 index 0000000..1130b3d --- /dev/null +++ b/html/simpleDiff.html @@ -0,0 +1,19 @@ + + + Details for commit + + + + + + + + +
+