From 3861deecfaa204cd127263dc8c8963ec974a27f4 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 00:06:57 +0200 Subject: [PATCH 01/42] Require Git 1.6.0 or higher Git 1.6.0 was released over a year ago now, so it shouldn't be too hard to get people to upgrade to that. We need 1.6.0 for the --children revlist option. Requiring Git 1.6.0 or higher means we can also revert a94981f35 (RevList: Don't rely on the presence of %x00) sometime. --- PBGitBinary.h | 1 + PBGitBinary.m | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/PBGitBinary.h b/PBGitBinary.h index 804cbe9..5008b3d 100644 --- a/PBGitBinary.h +++ b/PBGitBinary.h @@ -8,6 +8,7 @@ #import +#define MIN_GIT_VERSION "1.6.0" @interface PBGitBinary : NSObject { diff --git a/PBGitBinary.m b/PBGitBinary.m index ccb0b0b..795891d 100644 --- a/PBGitBinary.m +++ b/PBGitBinary.m @@ -37,7 +37,7 @@ static NSString* gitPath = nil; if (!version) return NO; - int c = [version compare:@"1.5.4"]; + int c = [version compare:@"" MIN_GIT_VERSION]; if (c == NSOrderedSame || c == NSOrderedDescending) { gitPath = path; return YES; @@ -60,7 +60,7 @@ static NSString* gitPath = nil; alternateButton:nil otherButton:nil informativeTextWithFormat:@"You entered a custom git path in the Preferences pane, " - "but this path is not a valid git v1.5.4 or higher binary. We're going to use the default " + "but this path is not a valid git v" MIN_GIT_VERSION " or higher binary. We're going to use the default " "search paths instead"] runModal]; } @@ -80,7 +80,7 @@ static NSString* gitPath = nil; return; } - NSLog(@"Could not find a git binary higher than version 1.5.4."); + NSLog(@"Could not find a git binary higher than version " MIN_GIT_VERSION); } + (NSString *) path; @@ -109,7 +109,7 @@ static NSMutableArray *locations = nil; + (NSString *) notFoundError { NSMutableString *error = [NSMutableString stringWithString: - @"Could not find a git binary version 1.5.4 or higher.\n" + @"Could not find a git binary version " MIN_GIT_VERSION " or higher.\n" "Please make sure there is a git binary in one of the following locations:\n\n"]; for (NSString *location in [PBGitBinary searchLocations]) { [error appendFormat:@"\t%@\n", location]; From 3a1b10ae8fe875a9f5bccda171c1a18f131508fb Mon Sep 17 00:00:00 2001 From: Johannes Gilger Date: Tue, 8 Sep 2009 15:11:17 +0200 Subject: [PATCH 02/42] PBGitTree: Improve binary-file decision This uses the same mechanisms as git to determine whether a file is binary: By simply searching the first 8000 bytes for a 0-byte. This gets rid of the call to "file" and is a much cleaner and shorter implementation. Signed-off-by: Johannes Gilger --- PBGitTree.m | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/PBGitTree.m b/PBGitTree.m index 21c91f8..c8003d1 100644 --- a/PBGitTree.m +++ b/PBGitTree.m @@ -63,18 +63,12 @@ return NO; } -- (BOOL)hasBinaryHeader:(NSString *)fileHeader +- (BOOL)hasBinaryHeader:(NSString*)contents { - if (!fileHeader) + if(!contents) return NO; - NSString *filetype = [PBEasyPipe outputForCommand:@"/usr/bin/file" - withArgs:[NSArray arrayWithObjects:@"-b", @"-N", @"-", nil] - inDir:[repository workingDirectory] - inputString:fileHeader - retValue:nil]; - - return [filetype rangeOfString:@"text"].location == NSNotFound; + return [contents rangeOfString:@"\0" options:0 range:NSMakeRange(0, ([contents length] >= 8000) ? 7999 : [contents length])].location != NSNotFound; } - (BOOL)hasBinaryAttributes @@ -143,14 +137,13 @@ if ([self hasBinaryAttributes]) return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]]; - long long fileSize = [self fileSize]; - if (fileSize > 52428800) // ~50MB - return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], fileSize]; + if ([self fileSize] > 52428800) // ~50MB + return [NSString stringWithFormat:@"%@ is too big to be displayed (%d bytes)", [self fullPath], [self fileSize]]; - NSString *contents = [self contents]; + NSString* contents = [self contents]; - if ([self hasBinaryHeader:([contents length] >= 100) ? [contents substringToIndex:99] : contents]) - return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], fileSize]; + if ([self hasBinaryHeader:contents]) + return [NSString stringWithFormat:@"%@ appears to be a binary file of %d bytes", [self fullPath], [self fileSize]]; return contents; } From b6575d9dbaee1cf36f892da43d75b52349223653 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 15:19:04 +0200 Subject: [PATCH 03/42] Update site to mention git v1.6.0 requirement' --- Site/text/index.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Site/text/index.markdown b/Site/text/index.markdown index 12f32f9..1f60b02 100644 --- a/Site/text/index.markdown +++ b/Site/text/index.markdown @@ -27,7 +27,7 @@ then in silky smooth OS X style!

Requirements

- GitX runs on Mac OS X 10.5 Leopard and Mac OS X 10.6 Snow Leopard. Because it uses features like Garbage Collection, you can't compile it on earlier systems. GitX also requires a fairly recent Git -- version 1.5.6 and higher are all supported. + GitX runs on Mac OS X 10.5 Leopard and Mac OS X 10.6 Snow Leopard. Because it uses features like Garbage Collection, you can't compile it on earlier systems. GitX also requires a fairly recent Git -- version 1.6.0 and higher are all supported.

Download

From 53ca665271b1acdc8d39934fe6fb5fc74055c124 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 15:53:43 +0200 Subject: [PATCH 04/42] Delete this test file. I don't think we need it anymore. Otherwise, we can alway get it back. --- html/test.html | 3061 ------------------------------------------------ 1 file changed, 3061 deletions(-) delete mode 100644 html/test.html diff --git a/html/test.html b/html/test.html deleted file mode 100644 index 8d9be6d..0000000 --- a/html/test.html +++ /dev/null @@ -1,3061 +0,0 @@ - - - Details for commit - - - - - - - - -
-
- -
- From ff5388cc24722af39ac25c551e99b067a8c96d07 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Tue, 8 Sep 2009 16:42:55 +0200 Subject: [PATCH 05/42] HistoryView: Remove focus border That's so 1999! --- PBGitHistoryView.xib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PBGitHistoryView.xib b/PBGitHistoryView.xib index 741ed2c..b8c820e 100644 --- a/PBGitHistoryView.xib +++ b/PBGitHistoryView.xib @@ -153,7 +153,7 @@ YES - 274 + 4370 YES From b7945b05e908bfc179d79c172f33556b9780fed6 Mon Sep 17 00:00:00 2001 From: Johannes Gilger Date: Tue, 8 Sep 2009 19:44:18 +0200 Subject: [PATCH 06/42] UserManual: Clarify double-click in stage-lines Signed-off-by: Johannes Gilger --- Site/UserManual/text/03 - Committing.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Site/UserManual/text/03 - Committing.markdown b/Site/UserManual/text/03 - Committing.markdown index 51c3b27..dbd53aa 100644 --- a/Site/UserManual/text/03 - Committing.markdown +++ b/Site/UserManual/text/03 - Committing.markdown @@ -31,9 +31,9 @@ changes will be staged. Clicking the 'Discard' button will irreversibly throw aw confirmation can be silenced using Alt-Click. GitX 0.7 introduced a new way of staging lines: Simply drag-select a few of the lines you want to stage/unstage and a -'Stage lines' button will appear next to it. This allows for much finer granularity than the hunks determined by diff. -Double-clicking a line selects the sub-part of this hunk which isn't separated by blank lines. Selecting lines across -hunks is currently not possible. +'Stage lines' button will appear next to it. This allows for much finer granularity than the hunks determined by diff. +Double-clicking a changed line selects the entire surrounding block of changes. Selecting lines across hunks is not +possible. #### Committing From 4544816ac85411b99cdd20746ad70ae3c58638c5 Mon Sep 17 00:00:00 2001 From: Johannes Gilger Date: Wed, 9 Sep 2009 14:44:53 +0200 Subject: [PATCH 07/42] GitX.css: Set a default-font for body Some people have had Serif-fonts in their interface where no specific fonts for classes/ids were specified. This sets the default-font to 'Lucida Grande' in order to have a nice non-serif on any system. Signed-off-by: Johannes Gilger --- html/css/GitX.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/html/css/GitX.css b/html/css/GitX.css index d4b0e48..c8a03f3 100644 --- a/html/css/GitX.css +++ b/html/css/GitX.css @@ -5,4 +5,5 @@ body { margin: 0; margin-top: 5px; width: 100%; -} \ No newline at end of file + font-family: 'Lucida Grande', Arial; +} From 916711324f4b04b1538f6af06b1f4ae85faf2927 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 12 Sep 2009 23:43:14 +0200 Subject: [PATCH 08/42] IndexController: de-privatize the index-stopping stuff We shouldn't need to do this, but we still need to, because our index operations are split between two different controllers, which is a bit odd. --- PBGitIndexController.h | 3 +++ PBGitIndexController.m | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/PBGitIndexController.h b/PBGitIndexController.h index a3bc191..184d670 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -36,5 +36,8 @@ - (NSString *) stagedChangesForFile:(PBChangedFile *)file; - (NSString *) unstagedChangesForFile:(PBChangedFile *)file; +- (void)stopTrackingIndex; +- (void)resumeTrackingIndex; + - (NSMenu *) menuForTable:(NSTableView *)table; @end diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 21c7076..6645ca1 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -12,11 +12,6 @@ #define FileChangesTableViewType @"GitFileChangedType" -@interface PBGitIndexController (PrivateMethods) -- (void)stopTrackingIndex; -- (void)resumeTrackingIndex; -@end - @implementation PBGitIndexController @synthesize contextSize; From 00731eb285650df15befdda83ffccecd73012324 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sat, 12 Sep 2009 23:43:35 +0200 Subject: [PATCH 09/42] CommitView: Don't keep rearranging when iterating over files --- PBGitCommitController.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 1e894ee..3f156aa 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -11,7 +11,7 @@ #import "PBChangedFile.h" #import "PBWebChangesController.h" #import "NSString_RegEx.h" - +#import "PBGitIndexController.h" @interface PBGitCommitController (PrivateMethods) - (NSArray *) linesFromNotification:(NSNotification *)notification; @@ -240,6 +240,7 @@ - (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked { // Iterate over all existing files + [indexController stopTrackingIndex]; for (PBChangedFile *file in files) { NSArray *fileStatus = [dictionary objectForKey:file.path]; // Object found, this is still a cached / uncached thing @@ -270,6 +271,7 @@ file.hasUnstagedChanges = NO; } } + [indexController resumeTrackingIndex]; // Do new files if (![[dictionary allKeys] count]) From 95a9cc81fc08392e3889dc9fa6ec8ff65c81a1d9 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 7 Sep 2009 23:05:12 +0200 Subject: [PATCH 10/42] RevSpecifier: Add support for a working directory This indicates the directory in which the Revparameters should be run, useful when the parameters are requested from the CLI --- PBGitRevSpecifier.h | 11 +++++++---- PBGitRevSpecifier.m | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/PBGitRevSpecifier.h b/PBGitRevSpecifier.h index 1be1199..0461908 100644 --- a/PBGitRevSpecifier.h +++ b/PBGitRevSpecifier.h @@ -10,8 +10,9 @@ #import @interface PBGitRevSpecifier : NSObject { - NSString* description; - NSArray* parameters; + NSString *description; + NSArray *parameters; + NSURL *workingDirectory; } - (id) initWithParameters:(NSArray*) params; @@ -27,6 +28,8 @@ + (PBGitRevSpecifier *)allBranchesRevSpec; + (PBGitRevSpecifier *)localBranchesRevSpec; -@property(copy) NSString* description; -@property(readonly) NSArray* parameters; +@property(retain) NSString *description; +@property(readonly) NSArray *parameters; +@property(retain) NSURL *workingDirectory; + @end diff --git a/PBGitRevSpecifier.m b/PBGitRevSpecifier.m index ded8575..0fe9093 100644 --- a/PBGitRevSpecifier.m +++ b/PBGitRevSpecifier.m @@ -11,7 +11,7 @@ @implementation PBGitRevSpecifier -@synthesize parameters, description; +@synthesize parameters, description, workingDirectory; - (id) initWithParameters:(NSArray*) params { From d59745294dc71f661e3f2309c06d058a8c732cac Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 7 Sep 2009 23:05:27 +0200 Subject: [PATCH 11/42] CLIProxy: pass on the directory in which the `gitx` command is run --- PBCLIProxy.m | 1 + 1 file changed, 1 insertion(+) diff --git a/PBCLIProxy.m b/PBCLIProxy.m index 1ac0e03..83507d2 100644 --- a/PBCLIProxy.m +++ b/PBCLIProxy.m @@ -56,6 +56,7 @@ [document.windowController showCommitView:self]; else { PBGitRevSpecifier* rev = [[PBGitRevSpecifier alloc] initWithParameters:arguments]; + rev.workingDirectory = repositoryPath; document.currentBranch = [document addBranch: rev]; [document.windowController showHistoryView:self]; } From 86ea9b5469bf07e46582e8df0999eb46b0903561 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 7 Sep 2009 23:05:57 +0200 Subject: [PATCH 12/42] GitRevList: replace 'id' with PBGitRepository --- PBGitRevList.h | 5 +++-- PBGitRevList.mm | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/PBGitRevList.h b/PBGitRevList.h index 2f71c3f..42bc82a 100644 --- a/PBGitRevList.h +++ b/PBGitRevList.h @@ -8,14 +8,15 @@ #import +@class PBGitRepository; @interface PBGitRevList : NSObject { NSArray* commits; - id repository; + PBGitRepository *repository; NSString* lastSha; } -- initWithRepository:(id)repo; +- initWithRepository:(PBGitRepository *)repo; - (void) readCommitsForce: (BOOL) force; - (void) reload; diff --git a/PBGitRevList.mm b/PBGitRevList.mm index 1d8023a..b2d8a49 100644 --- a/PBGitRevList.mm +++ b/PBGitRevList.mm @@ -23,7 +23,7 @@ using namespace std; @implementation PBGitRevList @synthesize commits; -- initWithRepository: (id) repo +- (id)initWithRepository:(PBGitRepository *)repo { repository = repo; [repository addObserver:self forKeyPath:@"currentBranch" options:0 context:nil]; From 8ae2cde4379551d92c5430d8117016320f0f1595 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 7 Sep 2009 23:07:14 +0200 Subject: [PATCH 13/42] GitRevList: Always run --children It's very difficult to determine whether or not we have a path specifier. Because it's so difficult, it's better to just always run --children. A quick test indicates that it doesn't matter much in run-time, and it's better to be conservative in what we accept than to show bogus lines because the children haven't been rewritten. --- PBGitRevList.mm | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/PBGitRevList.mm b/PBGitRevList.mm index b2d8a49..9de94cb 100644 --- a/PBGitRevList.mm +++ b/PBGitRevList.mm @@ -74,21 +74,19 @@ using namespace std; PBGitGrapher* g = [[PBGitGrapher alloc] initWithRepository: repository]; std::map encodingMap; - NSMutableArray* arguments; + NSString *formatString = @"--pretty=format:%H\01%e\01%an\01%s\01%P\01%at"; BOOL showSign = [rev hasLeftRight]; if (showSign) - arguments = [NSMutableArray arrayWithObjects:@"log", @"-z", @"--early-output", @"--topo-order", @"--pretty=format:%H\01%e\01%an\01%s\01%P\01%at\01%m", nil]; - else - arguments = [NSMutableArray arrayWithObjects:@"log", @"-z", @"--early-output", @"--topo-order", @"--pretty=format:%H\01%e\01%an\01%s\01%P\01%at", nil]; + formatString = [formatString stringByAppendingString:@"\01%m"]; + + NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"log", @"-z", @"--early-output", @"--topo-order", @"--children", formatString, nil]; if (!rev) [arguments addObject:@"HEAD"]; else [arguments addObjectsFromArray:[rev parameters]]; - if ([rev hasPathLimiter]) - [arguments insertObject:@"--children" atIndex:1]; NSTask *task = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:arguments inDir:[repository fileURL].path]; [task launch]; From 44768921f37c099a5e8d24801c34c07837085dd6 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 7 Sep 2009 23:07:40 +0200 Subject: [PATCH 14/42] GitRevList: run the log command in the correct directory when available --- PBGitRevList.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PBGitRevList.mm b/PBGitRevList.mm index 9de94cb..ca3704f 100644 --- a/PBGitRevList.mm +++ b/PBGitRevList.mm @@ -87,8 +87,8 @@ using namespace std; else [arguments addObjectsFromArray:[rev parameters]]; - - NSTask *task = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:arguments inDir:[repository fileURL].path]; + NSString *directory = rev.workingDirectory ? rev.workingDirectory.path : repository.fileURL.path; + NSTask *task = [PBEasyPipe taskForCommand:[PBGitBinary path] withArgs:arguments inDir:directory]; [task launch]; NSFileHandle* handle = [task.standardOutput fileHandleForReading]; From 6531cfce3bc6b4bd55607304169809e2c3defcc8 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 01:59:28 +0200 Subject: [PATCH 15/42] Add a new class, PBGitIndex, which integrates functionality from both indexcontrollers --- GitX.xcodeproj/project.pbxproj | 18 +- PBGitIndex.h | 52 +++++ PBGitIndex.m | 345 +++++++++++++++++++++++++++++++++ 3 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 PBGitIndex.h create mode 100644 PBGitIndex.m diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index be97512..d091d92 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -97,6 +97,7 @@ F59116E90E843BCB0072CCB1 /* PBGitCommitController.m in Sources */ = {isa = PBXBuildFile; fileRef = F59116E80E843BCB0072CCB1 /* PBGitCommitController.m */; }; F593DF780E9E636C003A8559 /* PBFileChangesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = F593DF770E9E636C003A8559 /* PBFileChangesTableView.m */; }; F5945E170E02B0C200706420 /* PBGitRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = F5945E160E02B0C200706420 /* PBGitRepository.m */; }; + F59F1DD5105C4FF300115F88 /* PBGitIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = F59F1DD4105C4FF300115F88 /* PBGitIndex.m */; }; F5AD56790E79B78100EDAAFE /* PBCommitList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5AD56780E79B78100EDAAFE /* PBCommitList.m */; }; F5B721C40E05CF7E00AF29DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5B721C20E05CF7E00AF29DC /* MainMenu.xib */; }; F5C007750E731B48007B84B2 /* PBGitRef.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C007740E731B48007B84B2 /* PBGitRef.m */; }; @@ -250,6 +251,8 @@ F593DF770E9E636C003A8559 /* PBFileChangesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBFileChangesTableView.m; sourceTree = ""; }; F5945E150E02B0C200706420 /* PBGitRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRepository.h; sourceTree = ""; }; F5945E160E02B0C200706420 /* PBGitRepository.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRepository.m; sourceTree = ""; }; + F59F1DD3105C4FF300115F88 /* PBGitIndex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitIndex.h; sourceTree = ""; }; + F59F1DD4105C4FF300115F88 /* PBGitIndex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitIndex.m; sourceTree = ""; }; F5AD56770E79B78100EDAAFE /* PBCommitList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCommitList.h; sourceTree = ""; }; F5AD56780E79B78100EDAAFE /* PBCommitList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCommitList.m; sourceTree = ""; }; F5B721C30E05CF7E00AF29DC /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; @@ -467,6 +470,7 @@ F56174540E05887E001DCD79 /* Git */ = { isa = PBXGroup; children = ( + F59F1DD2105C4FDE00115F88 /* Index */, F5E927E30E883D6800056E75 /* Commit */, F5E927E10E883D2E00056E75 /* History */, F5945E150E02B0C200706420 /* PBGitRepository.h */, @@ -549,6 +553,17 @@ name = SpeedTest; sourceTree = ""; }; + F59F1DD2105C4FDE00115F88 /* Index */ = { + isa = PBXGroup; + children = ( + F5E927F60E883E7200056E75 /* PBChangedFile.h */, + F5E927F70E883E7200056E75 /* PBChangedFile.m */, + F59F1DD3105C4FF300115F88 /* PBGitIndex.h */, + F59F1DD4105C4FF300115F88 /* PBGitIndex.m */, + ); + name = Index; + sourceTree = ""; + }; F5B161BB0EAB6E0C005A1DE1 /* Diff */ = { isa = PBXGroup; children = ( @@ -604,8 +619,6 @@ children = ( 93F7857D0EA3ABF100C1F443 /* PBCommitMessageView.h */, 93F7857E0EA3ABF100C1F443 /* PBCommitMessageView.m */, - F5E927F60E883E7200056E75 /* PBChangedFile.h */, - F5E927F70E883E7200056E75 /* PBChangedFile.m */, F593DF760E9E636C003A8559 /* PBFileChangesTableView.h */, F593DF770E9E636C003A8559 /* PBFileChangesTableView.m */, ); @@ -854,6 +867,7 @@ 47DBDBCA0E95016F00671A1E /* PBNSURLPathUserDefaultsTransfomer.m in Sources */, F562C8870FE1766C000EC528 /* NSString_RegEx.m in Sources */, EB2A734A0FEE3F09006601CF /* PBCollapsibleSplitView.m in Sources */, + F59F1DD5105C4FF300115F88 /* PBGitIndex.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitIndex.h b/PBGitIndex.h new file mode 100644 index 0000000..9fc784e --- /dev/null +++ b/PBGitIndex.h @@ -0,0 +1,52 @@ +// +// PBGitIndex.h +// GitX +// +// Created by Pieter de Bie on 9/12/09. +// Copyright 2009 Pieter de Bie. All rights reserved. +// + +#import + +@class PBGitRepository; + +// Represents a git index for a given work tree. +// 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 + PBGitRepository *repository; + NSURL *workingDirectory; + NSMutableArray *files; + + NSUInteger refreshStatus; + NSDictionary *amendEnvironment; + BOOL amend; +} + +// Whether we want the changes for amending, +// or for +@property BOOL amend; + +- (id)initWithRepository:(PBGitRepository *)repository workingDirectory:(NSURL *)workingDirectory; + +// A list of PBChangedFile's with differences between the work tree and the index +// This method is KVO-aware, so changes when any of the index-modifying methods are called +// (including -refresh) +- (NSArray *)indexChanges; + +// Refresh the index +- (void)refresh; + +//- (void)commit; + +// Inter-file changes: +//- (void)stageFiles:(NSArray *)files; +//- (void)unstageFiles:(NSArray *)files; + +// Intra-file changes +//- (void)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; + +@end diff --git a/PBGitIndex.m b/PBGitIndex.m new file mode 100644 index 0000000..29e9ff8 --- /dev/null +++ b/PBGitIndex.m @@ -0,0 +1,345 @@ +// +// PBGitIndex.m +// GitX +// +// Created by Pieter de Bie on 9/12/09. +// Copyright 2009 Pieter de Bie. All rights reserved. +// + +#import "PBGitIndex.h" +#import "PBGitRepository.h" +#import "PBGitBinary.h" +#import "PBEasyPipe.h" +#import "NSString_RegEx.h" +#import "PBChangedFile.h" + +@interface PBGitIndex (IndexRefreshMethods) + +- (NSArray *)linesFromNotification:(NSNotification *)notification; +- (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines; +- (void)addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked; + +- (void)indexStepComplete; + +- (void)indexRefreshFinished:(NSNotification *)notification; +- (void)readOtherFiles:(NSNotification *)notification; +- (void)readUnstagedFiles:(NSNotification *)notification; +- (void)readStagedFiles:(NSNotification *)notification; + +@end + +@interface PBGitIndex () + +// Returns the tree to compare the index to, based +// on whether amend is set or not. +- (NSString *) parentTree; + +@end + +@implementation PBGitIndex + +@synthesize amend; + +- (id)initWithRepository:(PBGitRepository *)theRepository workingDirectory:(NSURL *)theWorkingDirectory +{ + if (!(self = [super init])) + return nil; + + NSAssert(theWorkingDirectory, @"PBGitIndex requires a working directory"); + NSAssert(theRepository, @"PBGitIndex requires a repository"); + + repository = theRepository; + workingDirectory = theWorkingDirectory; + files = [NSMutableArray array]; + + return self; +} + +- (NSArray *)indexChanges +{ + return files; +} + +- (void)setAmend:(BOOL)newAmend +{ + if (newAmend == amend) + return; + + amend = newAmend; + amendEnvironment = nil; + + [self refresh]; + + if (!newAmend) + return; + + // 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"]; + 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]; +} + +- (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; + 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]]; + + [nc addObserver:self + selector:@selector(indexRefreshFinished:) + name:NSFileHandleReadToEndOfFileCompletionNotification + object:updateHandle]; + [updateHandle readToEndOfFileInBackgroundAndNotify]; + +} + +- (NSString *) parentTree +{ + NSString *parent = amend ? @"HEAD^" : @"HEAD"; + + if (![repository parseReference:parent]) + // We don't have a head ref. Return the empty tree. + return @"4b825dc642cb6eb9a060e54bf8d69288fbee4904"; + + return parent; +} + +@end + +@implementation PBGitIndex (IndexRefreshMethods) + +- (void)indexRefreshFinished:(NSNotification *)notification +{ + if ([(NSNumber *)[(NSDictionary *)[notification userInfo] objectForKey:@"NSFileHandleError"] intValue]) + { + // TODO: send updatefailed notification? + return; + } + + // Now that the index is refreshed, we need to read the information from the index + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + + // Other files (not tracked, not ignored) + NSFileHandle *handle = [PBEasyPipe handleForCommand:[PBGitBinary path] + withArgs:[NSArray arrayWithObjects:@"ls-files", @"--others", @"--exclude-standard", @"-z", nil] + inDir:[workingDirectory path]]; + [nc addObserver:self selector:@selector(readOtherFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; + [handle readToEndOfFileInBackgroundAndNotify]; + refreshStatus++; + + // Unstaged files + handle = [PBEasyPipe handleForCommand:[PBGitBinary path] + withArgs:[NSArray arrayWithObjects:@"diff-files", @"-z", nil] + inDir:[workingDirectory path]]; + [nc addObserver:self selector:@selector(readUnstagedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; + [handle readToEndOfFileInBackgroundAndNotify]; + refreshStatus++; + + // Staged files + handle = [PBEasyPipe handleForCommand:[PBGitBinary path] + withArgs:[NSArray arrayWithObjects:@"diff-index", @"--cached", @"-z", [self parentTree], nil] + inDir:[workingDirectory path]]; + [nc addObserver:self selector:@selector(readStagedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; + [handle readToEndOfFileInBackgroundAndNotify]; + refreshStatus++; +} + +- (void)readOtherFiles:(NSNotification *)notification +{ + NSArray *lines = [self linesFromNotification:notification]; + NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:[lines count]]; + // Other files are untracked, so we don't have any real index information. Instead, we can just fake it. + // The line below is used to add the file to the index + // FIXME: request the real file mode + NSArray *fileStatus = [NSArray arrayWithObjects:@":000000", @"100644", @"0000000000000000000000000000000000000000", @"0000000000000000000000000000000000000000", @"A", nil]; + for (NSString *path in lines) { + if ([path length] == 0) + continue; + [dictionary setObject:fileStatus forKey:path]; + } + + [self addFilesFromDictionary:dictionary staged:NO tracked:NO]; + [self indexStepComplete]; +} + +- (void) readStagedFiles:(NSNotification *)notification +{ + NSArray *lines = [self linesFromNotification:notification]; + NSMutableDictionary *dic = [self dictionaryForLines:lines]; + [self addFilesFromDictionary:dic staged:YES tracked:YES]; + [self indexStepComplete]; +} + +- (void) readUnstagedFiles:(NSNotification *)notification +{ + NSArray *lines = [self linesFromNotification:notification]; + NSMutableDictionary *dic = [self dictionaryForLines:lines]; + [self addFilesFromDictionary:dic staged:NO tracked:YES]; + [self indexStepComplete]; +} + +- (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked +{ + // TODO: Stop tracking files + // Iterate over all existing files + for (PBChangedFile *file in files) { + NSArray *fileStatus = [dictionary objectForKey:file.path]; + // Object found, this is still a cached / uncached thing + if (fileStatus) { + if (tracked) { + NSString *mode = [[fileStatus objectAtIndex:0] substringFromIndex:1]; + NSString *sha = [fileStatus objectAtIndex:2]; + file.commitBlobSHA = sha; + file.commitBlobMode = mode; + + if (staged) + file.hasStagedChanges = YES; + else + file.hasUnstagedChanges = YES; + } else { + // Untracked file, set status to NEW, only unstaged changes + file.hasStagedChanges = NO; + file.hasUnstagedChanges = YES; + file.status = NEW; + } + + // We handled this file, remove it from the dictionary + [dictionary removeObjectForKey:file.path]; + } else { + // Object not found in the dictionary, so let's reset its appropriate + // change (stage or untracked) if necessary. + + // Staged dictionary, so file does not have staged changes + if (staged) + file.hasStagedChanges = NO; + // Tracked file does not have unstaged changes, file is not new, + // so we can set it to No. (If it would be new, it would not + // be in this dictionary, but in the "other dictionary"). + else if (tracked && file.status != NEW) + file.hasUnstagedChanges = NO; + // Unstaged, untracked dictionary ("Other" files), and file + // is indicated as new (which would be untracked), so let's + // remove it + else if (!tracked && file.status == NEW) + file.hasUnstagedChanges = NO; + } + } + // TODO: Finish tracking files + + // Do new files only if necessary + if (![[dictionary allKeys] count]) + return; + + // All entries left in the dictionary haven't been accounted for + // above, so we need to add them to the "files" array + [self willChangeValueForKey:@"indexChanges"]; + for (NSString *path in [dictionary allKeys]) { + NSArray *fileStatus = [dictionary objectForKey:path]; + + PBChangedFile *file = [[PBChangedFile alloc] initWithPath:path]; + if ([[fileStatus objectAtIndex:4] isEqualToString:@"D"]) + file.status = DELETED; + else if([[fileStatus objectAtIndex:0] isEqualToString:@":000000"]) + file.status = NEW; + else + file.status = MODIFIED; + + if (tracked) { + file.commitBlobMode = [[fileStatus objectAtIndex:0] substringFromIndex:1]; + file.commitBlobSHA = [fileStatus objectAtIndex:2]; + } + + file.hasStagedChanges = staged; + file.hasUnstagedChanges = !staged; + + [files addObject:file]; + } + [self didChangeValueForKey:@"indexChanges"]; +} + +# pragma mark Utility methods +- (NSArray *)linesFromNotification:(NSNotification *)notification +{ + NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; + if (!data) + return [NSArray array]; + + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + // FIXME: Return an error? + if (!string) + return [NSArray array]; + + // Strip trailing null + if ([string hasSuffix:@"\0"]) + string = [string substringToIndex:[string length]-1]; + + if ([string length] == 0) + return [NSArray array]; + + return [string componentsSeparatedByString:@"\0"]; +} + +- (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines +{ + NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:[lines count]/2]; + + // Fill the dictionary with the new information. These lines are in the form of: + // :00000 :0644 OTHER INDEX INFORMATION + // Filename + + NSAssert1([lines count] % 2 == 0, @"Lines must have an even number of lines: %@", lines); + + NSEnumerator *enumerator = [lines objectEnumerator]; + NSString *fileStatus; + while (fileStatus = [enumerator nextObject]) { + NSString *fileName = [enumerator nextObject]; + [dictionary setObject:[fileStatus componentsSeparatedByString:@" "] forKey:fileName]; + } + + return dictionary; +} + +// This method is called for each of the three processes from above. +// If all three are finished (self.busy == 0), then we can delete +// all files previously marked as deletable +- (void)indexStepComplete +{ + // if we're still busy, do nothing :) + if (--refreshStatus) + return; + + // At this point, all index operations have finished. + // We need to find all files that don't have either + // staged or unstaged files, and delete them + + NSMutableArray *deleteFiles = [NSMutableArray array]; + for (PBChangedFile *file in files) { + if (!file.hasStagedChanges && !file.hasUnstagedChanges) + [deleteFiles addObject:file]; + } + + if ([deleteFiles count]) { + [self willChangeValueForKey:@"indexChanges"]; + for (PBChangedFile *file in deleteFiles) + [files removeObject:file]; + [self didChangeValueForKey:@"indexChanges"]; + } + + // TODO: Sent index refresh finished operation +} + +@end From 03e1d3e882ef051bf0acbb645c14c848847218b0 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 01:59:48 +0200 Subject: [PATCH 16/42] WIP: Add GUI support for the new index --- PBGitCommitController.h | 26 +--- PBGitCommitController.m | 273 ++++----------------------------------- PBGitCommitView.xib | 109 ++++++++-------- PBGitIndexController.m | 2 +- PBWebChangesController.m | 8 +- 5 files changed, 88 insertions(+), 330 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index 0976738..f96e986 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -9,12 +9,10 @@ #import #import "PBViewController.h" -@class PBGitIndexController; -@class PBIconAndTextCell; -@class PBWebChangesController; +@class PBGitIndexController, PBIconAndTextCell, PBWebChangesController, PBGitIndex; @interface PBGitCommitController : PBViewController { - NSMutableArray *files; + PBGitIndex *index; IBOutlet NSTextView *commitMessageView; IBOutlet NSArrayController *unstagedFilesController; @@ -25,28 +23,14 @@ NSString *status; - // We use busy as a count of active processes. - // You can increase it when your process start - // And decrease it after you have finished. - int busy; - BOOL amend; NSDictionary *amendEnvironment; } -@property (retain) NSMutableArray *files; -@property (copy) NSString *status; -@property (assign) int busy; -@property (assign) BOOL amend; - -- (void) readCachedFiles:(NSNotification *)notification; -- (void) readOtherFiles:(NSNotification *)notification; -- (void) readUnstagedFiles:(NSNotification *)notification; -- (void) stageHunk: (NSString *)hunk reverse:(BOOL)reverse; -- (void)discardHunk:(NSString *)hunk; - -- (NSString *)parentTree; +@property(copy) NSString *status; +@property(readonly) PBGitIndex *index; +// FIXME: redo 0823ff859dc65db238951c16e49293ea411c2b5a - (IBAction) refresh:(id) sender; - (IBAction) commit:(id) sender; - (IBAction)signOff:(id)sender; diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 1e894ee..be3f309 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -10,26 +10,36 @@ #import "NSFileHandleExt.h" #import "PBChangedFile.h" #import "PBWebChangesController.h" +#import "PBGitIndex.h" #import "NSString_RegEx.h" @interface PBGitCommitController (PrivateMethods) -- (NSArray *) linesFromNotification:(NSNotification *)notification; -- (void) doneProcessingIndex; -- (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines; -- (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked; - (void)processHunk:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; @end @implementation PBGitCommitController -@synthesize files, status, busy, amend; +@synthesize status, index; + +- (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller +{ + if (!(self = [super initWithRepository:theRepository superController:controller])) + return nil; + + index = [[PBGitIndex alloc] initWithRepository:theRepository workingDirectory:[NSURL fileURLWithPath:[theRepository workingDirectory]]]; + [index refresh]; + return self; +} + +- (BOOL)busy +{ + return NO; +} - (void)awakeFromNib { - self.files = [NSMutableArray array]; [super awakeFromNib]; - [self refresh:self]; [commitMessageView setTypingAttributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:12.0] forKey:NSFontAttributeName]]; @@ -68,106 +78,9 @@ } } -- (void) setAmend:(BOOL)newAmend -{ - if (newAmend == amend) - return; - - amend = newAmend; - amendEnvironment = nil; - - // 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:] - if (amend) { - NSString *message = [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]; - - // Replace commit message with the old one if it's less than 3 characters long. - // This is just a random number. - if ([[commitMessageView string] length] <= 3) { - // Find the commit message - NSRange r = [message rangeOfString:@"\n\n"]; - if (r.location != NSNotFound) - message = [message substringFromIndex:r.location + 2]; - - commitMessageView.string = message; - } - } - - [self refresh:self]; -} - -- (NSArray *) linesFromNotification:(NSNotification *)notification -{ - NSDictionary *userInfo = [notification userInfo]; - NSData *data = [userInfo valueForKey:NSFileHandleNotificationDataItem]; - if (!data) - return NULL; - - NSString* string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (!string) - return NULL; - - // Strip trailing newline - if ([string hasSuffix:@"\n"]) - string = [string substringToIndex:[string length]-1]; - - NSArray *lines = [string componentsSeparatedByString:@"\0"]; - return lines; -} - -- (NSString *) parentTree -{ - NSString *parent = amend ? @"HEAD^" : @"HEAD"; - - if (![repository parseReference:parent]) - // We don't have a head ref. Return the empty tree. - return @"4b825dc642cb6eb9a060e54bf8d69288fbee4904"; - - return parent; -} - - (void) refresh:(id) sender { - if (![repository workingDirectory]) - return; - - self.status = @"Refreshing index…"; - - // If self.busy reaches 0, all tasks have finished - self.busy = 0; - - // Refresh the index, necessary for the next methods (that's why it's blocking) - // FIXME: Make this non-blocking. This call can be expensive in large repositories - [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"update-index", @"-q", @"--unmerged", @"--ignore-missing", @"--refresh", nil]]; - - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc removeObserver:self]; - - // Other files (not tracked, not ignored) - NSArray *arguments = [NSArray arrayWithObjects:@"ls-files", @"--others", @"--exclude-standard", @"-z", nil]; - NSFileHandle *handle = [repository handleInWorkDirForArguments:arguments]; - [nc addObserver:self selector:@selector(readOtherFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; - self.busy++; - [handle readToEndOfFileInBackgroundAndNotify]; - - // Unstaged files - handle = [repository handleInWorkDirForArguments:[NSArray arrayWithObjects:@"diff-files", @"-z", nil]]; - [nc addObserver:self selector:@selector(readUnstagedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; - self.busy++; - [handle readToEndOfFileInBackgroundAndNotify]; - - // Staged files - handle = [repository handleInWorkDirForArguments:[NSArray arrayWithObjects:@"diff-index", @"--cached", @"-z", [self parentTree], nil]]; - [nc addObserver:self selector:@selector(readCachedFiles:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; - self.busy++; - [handle readToEndOfFileInBackgroundAndNotify]; + [index refresh]; // Reload refs (in case HEAD changed) [repository reloadRefs]; @@ -178,147 +91,9 @@ [self refresh:nil]; } -// This method is called for each of the three processes from above. -// If all three are finished (self.busy == 0), then we can delete -// all files previously marked as deletable -- (void) doneProcessingIndex -{ - // if we're still busy, do nothing :) - if (--self.busy) - return; - - NSMutableArray *deleteFiles = [NSMutableArray array]; - for (PBChangedFile *file in files) { - if (!file.hasStagedChanges && !file.hasUnstagedChanges) - [deleteFiles addObject:file]; - } - - if ([deleteFiles count]) { - [self willChangeValueForKey:@"files"]; - for (PBChangedFile *file in deleteFiles) - [files removeObject:file]; - [self didChangeValueForKey:@"files"]; - } - self.status = @"Ready"; -} - -- (void) readOtherFiles:(NSNotification *)notification; -{ - NSArray *lines = [self linesFromNotification:notification]; - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:[lines count]]; - // We fake this files status as good as possible. - NSArray *fileStatus = [NSArray arrayWithObjects:@":000000", @"100644", @"0000000000000000000000000000000000000000", @"0000000000000000000000000000000000000000", @"A", nil]; - for (NSString *path in lines) { - if ([path length] == 0) - continue; - [dictionary setObject:fileStatus forKey:path]; - } - [self addFilesFromDictionary:dictionary staged:NO tracked:NO]; - [self doneProcessingIndex]; -} - -- (NSMutableDictionary *)dictionaryForLines:(NSArray *)lines -{ - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:[lines count]/2]; - - // Fill the dictionary with the new information - NSArray *fileStatus; - BOOL even = FALSE; - for (NSString *line in lines) { - if (!even) { - even = TRUE; - fileStatus = [line componentsSeparatedByString:@" "]; - continue; - } - - even = FALSE; - [dictionary setObject:fileStatus forKey:line]; - } - return dictionary; -} - -- (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked -{ - // Iterate over all existing files - for (PBChangedFile *file in files) { - NSArray *fileStatus = [dictionary objectForKey:file.path]; - // Object found, this is still a cached / uncached thing - if (fileStatus) { - if (tracked) { - NSString *mode = [[fileStatus objectAtIndex:0] substringFromIndex:1]; - NSString *sha = [fileStatus objectAtIndex:2]; - file.commitBlobSHA = sha; - file.commitBlobMode = mode; - - if (staged) - file.hasStagedChanges = YES; - else - file.hasUnstagedChanges = YES; - } else { - // Untracked file, set status to NEW, only unstaged changes - file.hasStagedChanges = NO; - file.hasUnstagedChanges = YES; - file.status = NEW; - } - [dictionary removeObjectForKey:file.path]; - } else { // Object not found, let's remove it from the changes - if (staged) - file.hasStagedChanges = NO; - else if (tracked && file.status != NEW) // Only remove it if it's not an untracked file. We handle that with the other thing - file.hasUnstagedChanges = NO; - else if (!tracked && file.status == NEW) - file.hasUnstagedChanges = NO; - } - } - - // Do new files - if (![[dictionary allKeys] count]) - return; - - [self willChangeValueForKey:@"files"]; - for (NSString *path in [dictionary allKeys]) { - NSArray *fileStatus = [dictionary objectForKey:path]; - - PBChangedFile *file = [[PBChangedFile alloc] initWithPath:path]; - if ([[fileStatus objectAtIndex:4] isEqualToString:@"D"]) - file.status = DELETED; - else if([[fileStatus objectAtIndex:0] isEqualToString:@":000000"]) - file.status = NEW; - else - file.status = MODIFIED; - - if (tracked) { - file.commitBlobMode = [[fileStatus objectAtIndex:0] substringFromIndex:1]; - file.commitBlobSHA = [fileStatus objectAtIndex:2]; - } - - file.hasStagedChanges = staged; - file.hasUnstagedChanges = !staged; - - [files addObject: file]; - } - [self didChangeValueForKey:@"files"]; -} - -- (void) readUnstagedFiles:(NSNotification *)notification -{ - NSArray *lines = [self linesFromNotification:notification]; - NSMutableDictionary *dic = [self dictionaryForLines:lines]; - [self addFilesFromDictionary:dic staged:NO tracked:YES]; - [self doneProcessingIndex]; -} - -- (void) readCachedFiles:(NSNotification *)notification -{ - NSArray *lines = [self linesFromNotification:notification]; - NSMutableDictionary *dic = [self dictionaryForLines:lines]; - [self addFilesFromDictionary:dic staged:YES tracked:YES]; - [self doneProcessingIndex]; -} - - (void) commitFailedBecause:(NSString *)reason { - self.busy--; + //self.busy--; self.status = [@"Commit failed: " stringByAppendingString:reason]; [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason]; return; @@ -360,7 +135,7 @@ [commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil]; - self.busy++; + //self.busy++; self.status = @"Creating tree.."; NSString *tree = [repository outputForCommand:@"write-tree"]; if ([tree length] != 40) @@ -369,7 +144,7 @@ int ret; NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"commit-tree", tree, nil]; - NSString *parent = amend ? @"HEAD^" : @"HEAD"; + NSString *parent = index.amend ? @"HEAD^" : @"HEAD"; if ([repository parseReference:parent]) { [arguments addObject:@"-p"]; [arguments addObject:parent]; @@ -400,12 +175,10 @@ [webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit %@", commit]]; repository.hasChanged = YES; - self.busy--; + //self.busy--; [commitMessageView setString:@""]; - amend = NO; amendEnvironment = nil; - [self refresh:self]; - self.amend = NO; + index.amend = NO; } - (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse diff --git a/PBGitCommitView.xib b/PBGitCommitView.xib index 643bfa3..49beeb5 100644 --- a/PBGitCommitView.xib +++ b/PBGitCommitView.xib @@ -2,15 +2,14 @@ 1050 - 9J61 + 9L31a 677 - 949.46 + 949.54 353.00 YES + - - YES @@ -127,7 +126,7 @@ YES - + @@ -963,38 +962,6 @@ 139 - - - contentArray: files - - - - - - contentArray: files - contentArray - files - 2 - - - 149 - - - - contentArray: files - - - - - - contentArray: files - contentArray - files - 2 - - - 150 - cachedFilesController @@ -1067,22 +1034,6 @@ 241 - - - value: amend - - - - - - value: amend - value - amend - 2 - - - 252 - webController @@ -1219,6 +1170,54 @@ 280 + + + contentArray: index.indexChanges + + + + + + contentArray: index.indexChanges + contentArray + index.indexChanges + 2 + + + 281 + + + + contentArray: index.indexChanges + + + + + + contentArray: index.indexChanges + contentArray + index.indexChanges + 2 + + + 282 + + + + value: index.amend + + + + + + value: index.amend + value + index.amend + 2 + + + 283 + @@ -1616,7 +1615,7 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilderKit com.apple.InterfaceBuilderKit - {{59, 63}, {852, 432}} + {{428, 510}, {852, 432}} com.apple.InterfaceBuilder.CocoaPlugin @@ -1680,7 +1679,7 @@ - 280 + 283 diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 21c7076..a03b3a2 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -136,7 +136,7 @@ if (file.status == NEW) return [commitController.repository outputForArguments:[NSArray arrayWithObjects:@"show", indexPath, nil]]; - return [commitController.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-index", [self contextParameter], @"--cached", [commitController parentTree], @"--", file.path, nil]]; + return [commitController.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-index", [self contextParameter], @"--cached", [commitController.index parentTree], @"--", file.path, nil]]; } - (NSString *)unstagedChangesForFile:(PBChangedFile *)file diff --git a/PBWebChangesController.m b/PBWebChangesController.m index d24a8af..697307d 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -8,6 +8,7 @@ #import "PBWebChangesController.h" #import "PBGitIndexController.h" +#import "PBGitIndex.h" @implementation PBWebChangesController @@ -31,7 +32,7 @@ - (BOOL) amend { - return controller.amend; + return controller.index.amend; } - (void)observeValueForKeyPath:(NSString *)keyPath @@ -83,7 +84,8 @@ - (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse { - [controller stageHunk: hunk reverse:reverse]; + //[controller stageHunk: hunk reverse:reverse]; + // FIXME: Don't need a hard refresh [self refresh]; } @@ -99,7 +101,7 @@ } if (ret == NSAlertDefaultReturn) { - [controller discardHunk:hunk]; + // [controller discardHunk:hunk]; [self refresh]; } } From 07417acd51d5eb4b8109c93d6b58b38485de0989 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:15:17 +0200 Subject: [PATCH 17/42] GitIndex: add support for retrieving diffs --- PBGitIndex.h | 2 ++ PBGitIndex.m | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/PBGitIndex.h b/PBGitIndex.h index 9fc784e..548983f 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -9,6 +9,7 @@ #import @class PBGitRepository; +@class PBChangedFile; // Represents a git index for a given work tree. // As a single git repository can have multiple trees, @@ -48,5 +49,6 @@ // Intra-file changes //- (void)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; +- (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context; @end diff --git a/PBGitIndex.m b/PBGitIndex.m index 29e9ff8..cfc3166 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -118,6 +118,42 @@ return parent; } +- (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context +{ + NSString *parameter = [NSString stringWithFormat:@"-U%u", context]; + if (staged) { + NSString *indexPath = [@":0:" stringByAppendingString:file.path]; + + if (file.status == NEW) + return [repository outputForArguments:[NSArray arrayWithObjects:@"show", indexPath, nil]]; + + return [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]; + if (error) + return nil; + + return contents; + } + + return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", parameter, @"--", file.path, nil]]; +} + +# pragma mark WebKit Accessibility + ++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector +{ + return NO; +} + @end @implementation PBGitIndex (IndexRefreshMethods) From 64a52ad9e0292dcceabecdd716ca463dbc8f3a93 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:16:31 +0200 Subject: [PATCH 18/42] CommitView: Migrate diff displaying away from IndexController --- PBGitCommitController.h | 2 ++ PBGitIndexController.h | 3 --- PBGitIndexController.m | 27 --------------------------- PBWebChangesController.m | 2 +- html/views/commit/commit.js | 21 ++++++++------------- 5 files changed, 11 insertions(+), 44 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index f96e986..a8b2802 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -12,6 +12,8 @@ @class PBGitIndexController, PBIconAndTextCell, PBWebChangesController, PBGitIndex; @interface PBGitCommitController : PBViewController { + // This might have to transfer over to the PBGitRepository + // object sometime PBGitIndex *index; IBOutlet NSTextView *commitMessageView; diff --git a/PBGitIndexController.h b/PBGitIndexController.h index a3bc191..87b3cab 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -33,8 +33,5 @@ - (IBAction) rowClicked:(NSCell *) sender; - (IBAction) tableClicked:(NSTableView *)tableView; -- (NSString *) stagedChangesForFile:(PBChangedFile *)file; -- (NSString *) unstagedChangesForFile:(PBChangedFile *)file; - - (NSMenu *) menuForTable:(NSTableView *)table; @end diff --git a/PBGitIndexController.m b/PBGitIndexController.m index a03b3a2..0517a0b 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -129,33 +129,6 @@ # pragma mark Displaying diffs -- (NSString *) stagedChangesForFile:(PBChangedFile *)file -{ - NSString *indexPath = [@":0:" stringByAppendingString:file.path]; - - if (file.status == NEW) - return [commitController.repository outputForArguments:[NSArray arrayWithObjects:@"show", indexPath, nil]]; - - return [commitController.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-index", [self contextParameter], @"--cached", [commitController.index parentTree], @"--", file.path, nil]]; -} - -- (NSString *)unstagedChangesForFile:(PBChangedFile *)file -{ - if (file.status == NEW) { - NSStringEncoding encoding; - NSError *error = nil; - NSString *path = [[commitController.repository workingDirectory] stringByAppendingPathComponent:file.path]; - NSString *contents = [NSString stringWithContentsOfFile:path - usedEncoding:&encoding - error:&error]; - if (error) - return nil; - - return contents; - } - - return [commitController.repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", [self contextParameter], @"--", file.path, nil]]; -} - (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force { diff --git a/PBWebChangesController.m b/PBWebChangesController.m index 697307d..96b9a5c 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -26,7 +26,7 @@ - (void) didLoad { - [[self script] setValue:indexController forKey:@"IndexController"]; + [[self script] setValue:controller.index forKey:@"Index"]; [self refresh]; } diff --git a/html/views/commit/commit.js b/html/views/commit/commit.js index df0cb42..cdec998 100644 --- a/html/views/commit/commit.js +++ b/html/views/commit/commit.js @@ -1,11 +1,13 @@ /* Commit: Interface for selecting, staging, discarding, and unstaging hunks, individual lines, or ranges of lines. */ +var contextLines = 5; + var showNewFile = function(file) { setTitle("New file: " + file.path); - var contents = IndexController.unstagedChangesForFile_(file); + var contents = Index.diffForFile_staged_contextLines_(file, false, contextLines); if (!contents) { notify("Can not display changes (Binary file?)", -1); diff.innerHTML = ""; @@ -49,23 +51,16 @@ var showFileChanges = function(file, cached) { hideState(); $("contextSize").oninput = function(element) { - Controller.setContextSize_($("contextSize").value); + contextSize = $("contextSize").value; } if (file.status == 0) // New file? return showNewFile(file); - var changes; - if (cached) { - setTitle("Staged changes for " + file.path); - displayContext(); - changes = IndexController.stagedChangesForFile_(file); - } - else { - setTitle("Unstaged changes for " + file.path); - displayContext(); - changes = IndexController.unstagedChangesForFile_(file); - } + setTitle((cached ? "Staged": "Unstaged") + " changes for" + file.path); + displayContext(); + var changes = Index.diffForFile_staged_contextLines_(file, cached, contextLines); + if (changes == "") { notify("This file has no more changes", 1); From 35a4dc37e2181a029a5326085f421f8fec849951 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:33:26 +0200 Subject: [PATCH 19/42] GitIndex: Add methods to stage and unstage files These are mostly copies from PBGitIndexController, and they can be refactored to a common method. I'm not sure of a name for that yet, so I'll keep it like this for now :) --- PBGitIndex.h | 4 ++-- PBGitIndex.m | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/PBGitIndex.h b/PBGitIndex.h index 548983f..19bfe43 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -44,8 +44,8 @@ //- (void)commit; // Inter-file changes: -//- (void)stageFiles:(NSArray *)files; -//- (void)unstageFiles:(NSArray *)files; +- (BOOL)stageFiles:(NSArray *)stageFiles; +- (BOOL)unstageFiles:(NSArray *)unstageFiles; // Intra-file changes //- (void)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; diff --git a/PBGitIndex.m b/PBGitIndex.m index cfc3166..1109140 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -118,6 +118,71 @@ return parent; } +- (BOOL)stageFiles:(NSArray *)stageFiles +{ + // Input string for update-index + // This will be a list of filenames that + // should be updated. It's similar to + // "git add -- + NSMutableString *input = [NSMutableString string]; + + for (PBChangedFile *file in stageFiles) { + [input appendFormat:@"%@\0", file.path]; + } + + int ret = 1; + [repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil] + inputString:input + retValue:&ret]; + + if (ret) { + // FIXME: failed notification? + NSLog(@"Error when updating index. Retvalue: %i", ret); + return NO; + } + + // TODO: Stop Tracking + for (PBChangedFile *file in stageFiles) + { + file.hasUnstagedChanges = NO; + file.hasStagedChanges = YES; + } + // TODO: Resume tracking + return YES; +} + +// TODO: Refactor with above. What's a better name for this? +- (BOOL)unstageFiles:(NSArray *)unstageFiles +{ + NSMutableString *input = [NSMutableString string]; + + for (PBChangedFile *file in unstageFiles) { + [input appendString:[file indexInfo]]; + } + + int ret = 1; + [repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil] + inputString:input + retValue:&ret]; + + if (ret) + { + // FIXME: Failed notification + NSLog(@"Error when updating index. Retvalue: %i", ret); + return NO; + } + + // TODO: stop tracking + for (PBChangedFile *file in unstageFiles) + { + file.hasUnstagedChanges = YES; + file.hasStagedChanges = NO; + } + // TODO: resume tracking + + return YES; +} + - (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context { NSString *parameter = [NSString stringWithFormat:@"-U%u", context]; @@ -147,6 +212,7 @@ return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", parameter, @"--", file.path, nil]]; } + # pragma mark WebKit Accessibility + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector From f51fd6c21478b6d7e0677f613a83b153faee6b11 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:33:53 +0200 Subject: [PATCH 20/42] GitIndexController: Migrate stageFiles functions to GitIndex --- PBGitIndexController.h | 3 -- PBGitIndexController.m | 66 +++++------------------------------------- 2 files changed, 7 insertions(+), 62 deletions(-) diff --git a/PBGitIndexController.h b/PBGitIndexController.h index 87b3cab..7b718ac 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -27,9 +27,6 @@ - (NSString *) contextParameter; -- (void) stageFiles:(NSArray *)files; -- (void) unstageFiles:(NSArray *)files; - - (IBAction) rowClicked:(NSCell *) sender; - (IBAction) tableClicked:(NSTableView *)tableView; diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 0517a0b..148c8e1 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -9,6 +9,7 @@ #import "PBGitIndexController.h" #import "PBChangedFile.h" #import "PBGitRepository.h" +#import "PBGitIndex.h" #define FileChangesTableViewType @"GitFileChangedType" @@ -36,59 +37,6 @@ } -- (void) stageFiles:(NSArray *)files -{ - NSMutableString *input = [NSMutableString string]; - - for (PBChangedFile *file in files) { - [input appendFormat:@"%@\0", file.path]; - } - - int ret = 1; - [commitController.repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"--add", @"--remove", @"-z", @"--stdin", nil] - inputString:input retValue:&ret]; - - if (ret) - { - NSLog(@"Error when updating index. Retvalue: %i", ret); - return; - } - - [self stopTrackingIndex]; - for (PBChangedFile *file in files) - { - file.hasUnstagedChanges = NO; - file.hasStagedChanges = YES; - } - [self resumeTrackingIndex]; -} - -- (void) unstageFiles:(NSArray *)files -{ - NSMutableString *input = [NSMutableString string]; - - for (PBChangedFile *file in files) { - [input appendString:[file indexInfo]]; - } - - int ret = 1; - [commitController.repository outputForArguments:[NSArray arrayWithObjects:@"update-index", @"-z", @"--index-info", nil] - inputString:input retValue:&ret]; - - if (ret) - { - NSLog(@"Error when updating index. Retvalue: %i", ret); - return; - } - - [self stopTrackingIndex]; - for (PBChangedFile *file in files) - { - file.hasUnstagedChanges = YES; - file.hasStagedChanges = NO; - } - [self resumeTrackingIndex]; -} - (void) ignoreFiles:(NSArray *)files { @@ -233,12 +181,12 @@ - (void) stageFilesAction:(id) sender { - [self stageFiles:[sender representedObject]]; + [commitController.index stageFiles:[sender representedObject]]; } - (void) unstageFilesAction:(id) sender { - [self unstageFiles:[sender representedObject]]; + [commitController.index unstageFiles:[sender representedObject]]; } - (void) openFilesAction:(id) sender @@ -298,9 +246,9 @@ NSIndexSet *selectionIndexes = [tableView selectedRowIndexes]; NSArray *files = [[controller arrangedObjects] objectsAtIndexes:selectionIndexes]; if ([tableView tag] == 0) - [self stageFiles:files]; + [commitController.index stageFiles:files]; else - [self unstageFiles:files]; + [commitController.index unstageFiles:files]; } - (void) rowClicked:(NSCell *)sender @@ -360,9 +308,9 @@ writeRowsWithIndexes:(NSIndexSet *)rowIndexes NSArray *files = [[controller arrangedObjects] objectsAtIndexes:rowIndexes]; if ([aTableView tag] == 0) - [self unstageFiles:files]; + [commitController.index unstageFiles:files]; else - [self stageFiles:files]; + [commitController.index stageFiles:files]; return YES; } From 8df614cb53deb9f1fe7e66e6a9db82ff69cbc155 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:47:39 +0200 Subject: [PATCH 21/42] GitIndex: add basic commit method --- PBGitIndex.h | 2 +- PBGitIndex.m | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/PBGitIndex.h b/PBGitIndex.h index 19bfe43..261b226 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -41,7 +41,7 @@ // Refresh the index - (void)refresh; -//- (void)commit; +- (void)commitWithMessage:(NSString *)commitMessage; // Inter-file changes: - (BOOL)stageFiles:(NSArray *)stageFiles; diff --git a/PBGitIndex.m b/PBGitIndex.m index 1109140..5097158 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -118,6 +118,69 @@ return parent; } +- (void)commitWithMessage:(NSString *)commitMessage +{ + NSMutableString *commitSubject = [@"commit: " mutableCopy]; + NSRange newLine = [commitMessage rangeOfString:@"\n"]; + if (newLine.location == NSNotFound) + [commitSubject appendString:commitMessage]; + else + [commitSubject appendString:[commitMessage substringToIndex:newLine.location]]; + + NSString *commitMessageFile; + commitMessageFile = [repository.fileURL.path stringByAppendingPathComponent:@"COMMIT_EDITMSG"]; + + [commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil]; + + // TODO: Notification: @"Creating tree.."; + NSString *tree = [repository outputForCommand:@"write-tree"]; + if ([tree length] != 40) + return; //TODO: commitFailedBecause:@"Could not create a tree"; + + + NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"commit-tree", tree, nil]; + NSString *parent = amend ? @"HEAD^" : @"HEAD"; + if ([repository parseReference:parent]) { + [arguments addObject:@"-p"]; + [arguments addObject:parent]; + } + + int ret = 1; + NSString *commit = [repository outputForArguments:arguments + inputString:commitMessage + byExtendingEnvironment:amendEnvironment + retValue: &ret]; + + if (ret || [commit length] != 40) + return; // TODO: [self commitFailedBecause:@"Could not create a commit object"]; + + if (![repository executeHook:@"pre-commit" output:nil]) + return; // TODO: [self commitFailedBecause:@"Pre-commit hook failed"]; + + if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) + return; // TODO: [self commitFailedBecause:@"Commit-msg hook failed"]; + + [repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] + retValue: &ret]; + if (ret) + return; // TODO: [self commitFailedBecause:@"Could not update HEAD"]; + + if (![repository executeHook:@"post-commit" output:nil]) + return; // [webController setStateMessage:[NSString stringWithFormat:@"Post-commit hook failed, however, successfully created commit %@", commit]]; + else + //[webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit %@", commit]]; + ; + + repository.hasChanged = YES; + + amendEnvironment = nil; + if (amend) + self.amend = NO; + else + [self refresh]; + +} + - (BOOL)stageFiles:(NSArray *)stageFiles { // Input string for update-index From 87dfb47f4f6aa0f4a547fbf6819ba8b983f0e7aa Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:47:59 +0200 Subject: [PATCH 22/42] CommitController: Replace commit method with the one from GitIndex --- PBGitCommitController.m | 58 ++--------------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index be3f309..d1b29ec 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -120,65 +120,11 @@ [cachedFilesController setSelectionIndexes:[NSIndexSet indexSet]]; [unstagedFilesController setSelectionIndexes:[NSIndexSet indexSet]]; - NSString *commitSubject; - NSRange newLine = [commitMessage rangeOfString:@"\n"]; - if (newLine.location == NSNotFound) - commitSubject = commitMessage; - else - commitSubject = [commitMessage substringToIndex:newLine.location]; - - commitSubject = [@"commit: " stringByAppendingString:commitSubject]; + [index commitWithMessage:commitMessage]; - NSString *commitMessageFile; - commitMessageFile = [repository.fileURL.path - stringByAppendingPathComponent:@"COMMIT_EDITMSG"]; + [webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit"]]; - [commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil]; - - //self.busy++; - self.status = @"Creating tree.."; - NSString *tree = [repository outputForCommand:@"write-tree"]; - if ([tree length] != 40) - return [self commitFailedBecause:@"Could not create a tree"]; - - int ret; - - NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"commit-tree", tree, nil]; - NSString *parent = index.amend ? @"HEAD^" : @"HEAD"; - if ([repository parseReference:parent]) { - [arguments addObject:@"-p"]; - [arguments addObject:parent]; - } - - NSString *commit = [repository outputForArguments:arguments - inputString:commitMessage - byExtendingEnvironment:amendEnvironment - retValue: &ret]; - - if (ret || [commit length] != 40) - return [self commitFailedBecause:@"Could not create a commit object"]; - - if (![repository executeHook:@"pre-commit" output:nil]) - return [self commitFailedBecause:@"Pre-commit hook failed"]; - - if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) - return [self commitFailedBecause:@"Commit-msg hook failed"]; - - [repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] - retValue: &ret]; - if (ret) - return [self commitFailedBecause:@"Could not update HEAD"]; - - if (![repository executeHook:@"post-commit" output:nil]) - [webController setStateMessage:[NSString stringWithFormat:@"Post-commit hook failed, however, successfully created commit %@", commit]]; - else - [webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit %@", commit]]; - - repository.hasChanged = YES; - //self.busy--; [commitMessageView setString:@""]; - amendEnvironment = nil; - index.amend = NO; } - (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse From 57dc38f58786f194e4cfe990d6bd6be1e4565de9 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:57:48 +0200 Subject: [PATCH 23/42] GitIndex: Add support for applying patches --- PBGitIndex.h | 2 +- PBGitIndex.m | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/PBGitIndex.h b/PBGitIndex.h index 261b226..a358f5a 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -48,7 +48,7 @@ - (BOOL)unstageFiles:(NSArray *)unstageFiles; // Intra-file changes -//- (void)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; +- (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; - (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context; @end diff --git a/PBGitIndex.m b/PBGitIndex.m index 5097158..717ceff 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -246,6 +246,31 @@ return YES; } +- (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; +{ + NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", nil]; + if (stage) + [array addObject:@"--cached"]; + if (reverse) + [array addObject:@"--reverse"]; + + int ret = 1; + NSString *error = [repository outputForArguments:array + inputString:hunk + retValue:&ret]; + + // FIXME: show this error, rather than just logging it + if (ret) { + NSLog(@"Error: %@", error); + return NO; + } + + // TODO: Try to be smarter about what to refresh + [self refresh]; + return YES; +} + + - (NSString *)diffForFile:(PBChangedFile *)file staged:(BOOL)staged contextLines:(NSUInteger)context { NSString *parameter = [NSString stringWithFormat:@"-U%u", context]; From cdae809f4132a95459933bf2e5333e03cd7959a5 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 02:58:05 +0200 Subject: [PATCH 24/42] CommitView: Migrate patch apply stuff to GitIndex --- PBGitCommitController.m | 30 ------------------------------ PBWebChangesController.m | 7 ++++--- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index d1b29ec..38ecc13 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -127,35 +127,5 @@ [commitMessageView setString:@""]; } -- (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse -{ - [self processHunk:hunk stage:TRUE reverse:reverse]; -} - -- (void)discardHunk:(NSString *)hunk -{ - [self processHunk:hunk stage:FALSE reverse:TRUE]; -} - -- (void)processHunk:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse -{ - NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", nil]; - if (stage) - [array addObject:@"--cached"]; - if (reverse) - [array addObject:@"--reverse"]; - - int ret = 1; - NSString *error = [repository outputForArguments:array - inputString:hunk - retValue:&ret]; - - // FIXME: show this error, rather than just logging it - if (ret) - NSLog(@"Error: %@", error); - - // TODO: We should do this smarter by checking if the file diff is empty, which is faster. - [self refresh:self]; -} @end diff --git a/PBWebChangesController.m b/PBWebChangesController.m index 96b9a5c..592e596 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -82,10 +82,11 @@ [NSNumber numberWithBool:selectedFileIsCached], nil]]; } -- (void) stageHunk:(NSString *)hunk reverse:(BOOL)reverse +- (void)stageHunk:(NSString *)hunk reverse:(BOOL)reverse { - //[controller stageHunk: hunk reverse:reverse]; + [controller.index applyPatch:hunk stage:YES reverse:reverse]; // FIXME: Don't need a hard refresh + [self refresh]; } @@ -101,7 +102,7 @@ } if (ret == NSAlertDefaultReturn) { - // [controller discardHunk:hunk]; + [controller.index applyPatch:hunk stage:NO reverse:YES]; [self refresh]; } } From ff263c6717cc3cf13f26669ff923634157b8873c Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:20:12 +0200 Subject: [PATCH 25/42] GitIndex: Add a few notifications --- PBGitIndex.h | 6 ++++++ PBGitIndex.m | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/PBGitIndex.h b/PBGitIndex.h index a358f5a..7dd0e93 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -11,6 +11,12 @@ @class PBGitRepository; @class PBChangedFile; +extern NSString *PBGitIndexIndexRefreshStatus; +extern NSString *PBGitIndexIndexRefreshFailed; +extern NSString *PBGitIndexFinishedIndexRefresh; +extern NSString *PBGitIndexCommitFailed; +extern NSString *PBGitIndexFinishedCommit; + // Represents a git index for a given work tree. // As a single git repository can have multiple trees, // the tree has to be given explicitly, even though diff --git a/PBGitIndex.m b/PBGitIndex.m index 717ceff..2ce84ab 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -13,6 +13,13 @@ #import "NSString_RegEx.h" #import "PBChangedFile.h" +NSString *PBGitIndexIndexRefreshStatus = @"PBGitIndexIndexRefreshStatus"; +NSString *PBGitIndexIndexRefreshFailed = @"PBGitIndexIndexRefreshFailed"; +NSString *PBGitIndexFinishedIndexRefresh = @"PBGitIndexFinishedIndexRefresh"; +NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed"; +NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; + + @interface PBGitIndex (IndexRefreshMethods) - (NSArray *)linesFromNotification:(NSNotification *)notification; @@ -316,10 +323,16 @@ { if ([(NSNumber *)[(NSDictionary *)[notification userInfo] objectForKey:@"NSFileHandleError"] intValue]) { - // TODO: send updatefailed notification? + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexIndexRefreshFailed + object:self + userInfo:[NSDictionary dictionaryWithObject:@"update-index failed" forKey:@"description"]]; return; } + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexIndexRefreshStatus + object:self + userInfo:[NSDictionary dictionaryWithObject:@"update-index success" forKey:@"description"]]; + // Now that the index is refreshed, we need to read the information from the index NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; @@ -529,7 +542,8 @@ [self didChangeValueForKey:@"indexChanges"]; } - // TODO: Sent index refresh finished operation + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexFinishedIndexRefresh + object:self]; } @end From c6d2b61020455875fabe45a6f7e97d369e916858 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:20:42 +0200 Subject: [PATCH 26/42] CommitController: Add status messages for index operations --- PBGitCommitController.h | 2 ++ PBGitCommitController.m | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index a8b2802..78ce470 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -24,6 +24,7 @@ IBOutlet PBWebChangesController *webController; NSString *status; + BOOL busy; NSDictionary *amendEnvironment; @@ -31,6 +32,7 @@ @property(copy) NSString *status; @property(readonly) PBGitIndex *index; +@property(assign) BOOL busy; // FIXME: redo 0823ff859dc65db238951c16e49293ea411c2b5a - (IBAction) refresh:(id) sender; diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 38ecc13..0643402 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -14,13 +14,13 @@ #import "NSString_RegEx.h" -@interface PBGitCommitController (PrivateMethods) -- (void)processHunk:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; +@interface PBGitCommitController () +- (void)refreshFinished:(NSNotification *)notification; @end @implementation PBGitCommitController -@synthesize status, index; +@synthesize status, index, busy; - (id)initWithRepository:(PBGitRepository *)theRepository superController:(PBGitWindowController *)controller { @@ -29,14 +29,10 @@ index = [[PBGitIndex alloc] initWithRepository:theRepository workingDirectory:[NSURL fileURLWithPath:[theRepository workingDirectory]]]; [index refresh]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshFinished:) name:PBGitIndexFinishedIndexRefresh object:index]; return self; } -- (BOOL)busy -{ - return NO; -} - - (void)awakeFromNib { [super awakeFromNib]; @@ -80,6 +76,8 @@ - (void) refresh:(id) sender { + self.busy = YES; + self.status = @"Refreshing index…"; [index refresh]; // Reload refs (in case HEAD changed) @@ -128,4 +126,9 @@ } +- (void)refreshFinished:(NSNotification *)notification +{ + self.busy = NO; + self.status = @"Index refresh finished"; +} @end From 4192d6a03f08fa347d4600071eb08042cca594a5 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:37:30 +0200 Subject: [PATCH 27/42] GitIndex: add commit notifications --- PBGitCommitController.m | 28 ++++++++++++++++++++++++---- PBGitIndex.h | 2 ++ PBGitIndex.m | 39 +++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 0643402..b5163be 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -16,6 +16,8 @@ @interface PBGitCommitController () - (void)refreshFinished:(NSNotification *)notification; +- (void)commitStatusUpdated:(NSNotification *)notification; +- (void)commitFinished:(NSNotification *)notification; @end @implementation PBGitCommitController @@ -29,7 +31,11 @@ index = [[PBGitIndex alloc] initWithRepository:theRepository workingDirectory:[NSURL fileURLWithPath:[theRepository workingDirectory]]]; [index refresh]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshFinished:) name:PBGitIndexFinishedIndexRefresh object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index]; + return self; } @@ -118,11 +124,10 @@ [cachedFilesController setSelectionIndexes:[NSIndexSet indexSet]]; [unstagedFilesController setSelectionIndexes:[NSIndexSet indexSet]]; + self.busy = YES; + [index commitWithMessage:commitMessage]; - - [webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit"]]; - - [commitMessageView setString:@""]; + [commitMessageView setEditable:NO]; } @@ -131,4 +136,19 @@ self.busy = NO; self.status = @"Index refresh finished"; } + +- (void)commitStatusUpdated:(NSNotification *)notification +{ + self.status = [[notification userInfo] objectForKey:@"description"]; +} + +- (void)commitFinished:(NSNotification *)notification +{ + [webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]]; + + BOOL success = [[[notification userInfo] objectForKey:@"success"] boolValue]; + if (success) + [commitMessageView setString:@""]; + [commitMessageView setEditable:YES]; +} @end diff --git a/PBGitIndex.h b/PBGitIndex.h index 7dd0e93..f1fc8c9 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -14,6 +14,8 @@ extern NSString *PBGitIndexIndexRefreshStatus; extern NSString *PBGitIndexIndexRefreshFailed; extern NSString *PBGitIndexFinishedIndexRefresh; + +extern NSString *PBGitIndexCommitStatus; extern NSString *PBGitIndexCommitFailed; extern NSString *PBGitIndexFinishedCommit; diff --git a/PBGitIndex.m b/PBGitIndex.m index 2ce84ab..e641102 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -16,6 +16,8 @@ NSString *PBGitIndexIndexRefreshStatus = @"PBGitIndexIndexRefreshStatus"; NSString *PBGitIndexIndexRefreshFailed = @"PBGitIndexIndexRefreshFailed"; NSString *PBGitIndexFinishedIndexRefresh = @"PBGitIndexFinishedIndexRefresh"; + +NSString *PBGitIndexCommitStatus = @"PBGitIndexCommitStatus"; NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed"; NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; @@ -40,6 +42,7 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; // Returns the tree to compare the index to, based // on whether amend is set or not. - (NSString *) parentTree; +- (void)postCommitUpdate:(NSString *)update; @end @@ -138,8 +141,9 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; commitMessageFile = [repository.fileURL.path stringByAppendingPathComponent:@"COMMIT_EDITMSG"]; [commitMessage writeToFile:commitMessageFile atomically:YES encoding:NSUTF8StringEncoding error:nil]; + - // TODO: Notification: @"Creating tree.."; + [self postCommitUpdate:@"Creating tree"]; NSString *tree = [repository outputForCommand:@"write-tree"]; if ([tree length] != 40) return; //TODO: commitFailedBecause:@"Could not create a tree"; @@ -152,6 +156,7 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; [arguments addObject:parent]; } + [self postCommitUpdate:@"Creating commit"]; int ret = 1; NSString *commit = [repository outputForArguments:arguments inputString:commitMessage @@ -161,23 +166,38 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; if (ret || [commit length] != 40) return; // TODO: [self commitFailedBecause:@"Could not create a commit object"]; + [self postCommitUpdate:@"Running hooks"]; if (![repository executeHook:@"pre-commit" output:nil]) return; // TODO: [self commitFailedBecause:@"Pre-commit hook failed"]; if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) return; // TODO: [self commitFailedBecause:@"Commit-msg hook failed"]; + [self postCommitUpdate:@"Updating HEAD"]; [repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] retValue: &ret]; if (ret) return; // TODO: [self commitFailedBecause:@"Could not update HEAD"]; - if (![repository executeHook:@"post-commit" output:nil]) - return; // [webController setStateMessage:[NSString stringWithFormat:@"Post-commit hook failed, however, successfully created commit %@", commit]]; - else - //[webController setStateMessage:[NSString stringWithFormat:@"Successfully created commit %@", commit]]; - ; + [self postCommitUpdate:@"Running post-commit hook"]; + BOOL success = [repository executeHook:@"post-commit" output:nil]; + NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:[NSNumber numberWithBool:success] forKey:@"success"]; + NSString *description; + if (success) + description = [NSString stringWithFormat:@"Successfull created commit %@", commit]; + else + description = [NSString stringWithFormat:@"Post-commit hook failed, but successfully created commit %@", commit]; + + [userInfo setObject:description forKey:@"description"]; + [userInfo setObject:commit forKey:@"sha"]; + + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexFinishedCommit + object:self + userInfo:userInfo]; + if (!success) + return; + repository.hasChanged = YES; amendEnvironment = nil; @@ -188,6 +208,13 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; } +- (void)postCommitUpdate:(NSString *)update +{ + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexCommitStatus + object:self + userInfo:[NSDictionary dictionaryWithObject:update forKey:@"description"]]; +} + - (BOOL)stageFiles:(NSArray *)stageFiles { // Input string for update-index From 5323b9159686b2d40f5a50077e704f6880b3aff3 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:44:00 +0200 Subject: [PATCH 28/42] Add failed commit notifications --- PBGitCommitController.m | 24 ++++++++++++------------ PBGitIndex.m | 20 ++++++++++++++------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index b5163be..861f8b7 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -18,6 +18,7 @@ - (void)refreshFinished:(NSNotification *)notification; - (void)commitStatusUpdated:(NSNotification *)notification; - (void)commitFinished:(NSNotification *)notification; +- (void)commitFailed:(NSNotification *)notification; @end @implementation PBGitCommitController @@ -35,6 +36,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshFinished:) name:PBGitIndexFinishedIndexRefresh object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index]; return self; } @@ -95,14 +97,6 @@ [self refresh:nil]; } -- (void) commitFailedBecause:(NSString *)reason -{ - //self.busy--; - self.status = [@"Commit failed: " stringByAppendingString:reason]; - [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason]; - return; -} - - (IBAction) commit:(id) sender { if ([[NSFileManager defaultManager] fileExistsAtPath:[repository.fileURL.path stringByAppendingPathComponent:@"MERGE_HEAD"]]) { @@ -145,10 +139,16 @@ - (void)commitFinished:(NSNotification *)notification { [webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]]; - - BOOL success = [[[notification userInfo] objectForKey:@"success"] boolValue]; - if (success) - [commitMessageView setString:@""]; [commitMessageView setEditable:YES]; } + +- (void)commitFailed:(NSNotification *)notification +{ + self.busy = NO; + NSString *reason = [[notification userInfo] objectForKey:@"description"]; + self.status = [@"Commit failed: " stringByAppendingString:reason]; + [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason]; +} + + @end diff --git a/PBGitIndex.m b/PBGitIndex.m index e641102..13c82a6 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -43,7 +43,7 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; // on whether amend is set or not. - (NSString *) parentTree; - (void)postCommitUpdate:(NSString *)update; - +- (void)postCommitFailure:(NSString *)reason; @end @implementation PBGitIndex @@ -146,7 +146,7 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; [self postCommitUpdate:@"Creating tree"]; NSString *tree = [repository outputForCommand:@"write-tree"]; if ([tree length] != 40) - return; //TODO: commitFailedBecause:@"Could not create a tree"; + return [self postCommitFailure:@"Creating tree failed"]; NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"commit-tree", tree, nil]; @@ -164,20 +164,20 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; retValue: &ret]; if (ret || [commit length] != 40) - return; // TODO: [self commitFailedBecause:@"Could not create a commit object"]; + return [self postCommitFailure:@"Could not create a commit object"]; [self postCommitUpdate:@"Running hooks"]; if (![repository executeHook:@"pre-commit" output:nil]) - return; // TODO: [self commitFailedBecause:@"Pre-commit hook failed"]; + return [self postCommitFailure:@"Pre-commit hook failed"]; if (![repository executeHook:@"commit-msg" withArgs:[NSArray arrayWithObject:commitMessageFile] output:nil]) - return; // TODO: [self commitFailedBecause:@"Commit-msg hook failed"]; + return [self postCommitFailure:@"Commit-msg hook failed"]; [self postCommitUpdate:@"Updating HEAD"]; [repository outputForArguments:[NSArray arrayWithObjects:@"update-ref", @"-m", commitSubject, @"HEAD", commit, nil] retValue: &ret]; if (ret) - return; // TODO: [self commitFailedBecause:@"Could not update HEAD"]; + return [self postCommitFailure:@"Could not update HEAD"]; [self postCommitUpdate:@"Running post-commit hook"]; @@ -215,6 +215,14 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; userInfo:[NSDictionary dictionaryWithObject:update forKey:@"description"]]; } +- (void)postCommitFailure:(NSString *)reason +{ + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexCommitFailed + object:self + userInfo:[NSDictionary dictionaryWithObject:reason forKey:@"description"]]; +} + + - (BOOL)stageFiles:(NSArray *)stageFiles { // Input string for update-index From 6265c774ac8893c38ef462a057fd0e111604bf37 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:51:36 +0200 Subject: [PATCH 29/42] CommitView: Remove cruft --- PBGitCommitController.h | 3 --- PBGitIndexController.h | 4 ---- PBGitIndexController.m | 9 --------- PBWebChangesController.h | 1 - PBWebChangesController.m | 8 -------- 5 files changed, 25 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index 78ce470..135e581 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -25,9 +25,6 @@ NSString *status; BOOL busy; - - NSDictionary *amendEnvironment; - } @property(copy) NSString *status; diff --git a/PBGitIndexController.h b/PBGitIndexController.h index 7b718ac..49454cc 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -23,10 +23,6 @@ IBOutlet NSTableView *stagedTable; } -@property (assign) int contextSize; - -- (NSString *) contextParameter; - - (IBAction) rowClicked:(NSCell *) sender; - (IBAction) tableClicked:(NSTableView *)tableView; diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 148c8e1..1637fc5 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -20,12 +20,8 @@ @implementation PBGitIndexController -@synthesize contextSize; - - (void)awakeFromNib { - contextSize = 3; - [unstagedTable setDoubleAction:@selector(tableClicked:)]; [stagedTable setDoubleAction:@selector(tableClicked:)]; @@ -315,11 +311,6 @@ writeRowsWithIndexes:(NSIndexSet *)rowIndexes return YES; } -- (NSString *) contextParameter -{ - return [[NSString alloc] initWithFormat:@"-U%i", contextSize]; -} - # pragma mark WebKit Accessibility + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector diff --git a/PBWebChangesController.h b/PBWebChangesController.h index 0b0ec13..069f6fc 100644 --- a/PBWebChangesController.h +++ b/PBWebChangesController.h @@ -27,5 +27,4 @@ - (void) setStateMessage:(NSString *)state; - (void) showMultiple:(NSArray *)files; -- (void) setContextSize:(int)size; @end diff --git a/PBWebChangesController.m b/PBWebChangesController.m index 592e596..2aa96e3 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -113,12 +113,4 @@ [script callWebScriptMethod:@"setState" withArguments: [NSArray arrayWithObject:state]]; } -- (void) setContextSize:(int)size -{ - if (size == indexController.contextSize) - return; - - indexController.contextSize = size; - [self refresh]; -} @end From 2b317eee5c42fb93ba5f44a83d451f06ab9fe178 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 03:52:18 +0200 Subject: [PATCH 30/42] CommitController: Empty commit title when commit is successful --- PBGitCommitController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 861f8b7..11b470d 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -138,6 +138,7 @@ - (void)commitFinished:(NSNotification *)notification { + [commitMessageView setString:@""]; [webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]]; [commitMessageView setEditable:YES]; } From 249233114dbb4653fbac2821de68d066f2cbc09a Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 04:02:52 +0200 Subject: [PATCH 31/42] Show previous commit message when amending --- PBGitCommitController.m | 15 +++++++++++++++ PBGitIndex.h | 1 + PBGitIndex.m | 11 +++++++++++ 3 files changed, 27 insertions(+) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 11b470d..9520056 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -19,6 +19,7 @@ - (void)commitStatusUpdated:(NSNotification *)notification; - (void)commitFinished:(NSNotification *)notification; - (void)commitFailed:(NSNotification *)notification; +- (void)amendCommit:(NSNotification *)notification; @end @implementation PBGitCommitController @@ -37,6 +38,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitStatusUpdated:) name:PBGitIndexCommitStatus object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index]; return self; } @@ -56,11 +58,13 @@ [cachedFilesController setSortDescriptors:[NSArray arrayWithObject: [[NSSortDescriptor alloc] initWithKey:@"path" ascending:true]]]; } + - (void) removeView { [webController closeView]; [super finalize]; } + - (NSResponder *)firstResponder; { return commitMessageView; @@ -151,5 +155,16 @@ [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason]; } +- (void)amendCommit:(NSNotification *)notification +{ + // Replace commit message with the old one if it's less than 3 characters long. + // This is just a random number. + if ([[commitMessageView string] length] > 3) + return; + + NSString *message = [[notification userInfo] objectForKey:@"message"]; + commitMessageView.string = message; +} + @end diff --git a/PBGitIndex.h b/PBGitIndex.h index f1fc8c9..cc4ae77 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -19,6 +19,7 @@ extern NSString *PBGitIndexCommitStatus; extern NSString *PBGitIndexCommitFailed; extern NSString *PBGitIndexFinishedCommit; +extern NSString *PBGitIndexAmendMessageAvailable; // Represents a git index for a given work tree. // As a single git repository can have multiple trees, // the tree has to be given explicitly, even though diff --git a/PBGitIndex.m b/PBGitIndex.m index 13c82a6..2b45988 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -21,6 +21,7 @@ NSString *PBGitIndexCommitStatus = @"PBGitIndexCommitStatus"; NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed"; NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; +NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; @interface PBGitIndex (IndexRefreshMethods) @@ -93,6 +94,16 @@ NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; [match objectAtIndex:2], @"GIT_AUTHOR_EMAIL", [match objectAtIndex:3], @"GIT_AUTHOR_DATE", nil]; + + // Find the commit message + NSRange r = [message rangeOfString:@"\n\n"]; + if (r.location != NSNotFound) { + NSString *commitMessage = [message substringFromIndex:r.location + 2]; + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexAmendMessageAvailable + object: self + userInfo:[NSDictionary dictionaryWithObject:commitMessage forKey:@"message"]]; + } + } - (void)refresh From 9b1fcd76280fe5e3e71cf4445379877b521735b0 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 04:07:52 +0200 Subject: [PATCH 32/42] Remove cruft --- PBGitCommitController.h | 1 - PBGitCommitController.m | 2 -- PBGitIndexController.h | 2 -- PBGitIndexController.m | 2 -- PBWebChangesController.m | 5 ----- 5 files changed, 12 deletions(-) diff --git a/PBGitCommitController.h b/PBGitCommitController.h index 135e581..f29f884 100644 --- a/PBGitCommitController.h +++ b/PBGitCommitController.h @@ -31,7 +31,6 @@ @property(readonly) PBGitIndex *index; @property(assign) BOOL busy; -// FIXME: redo 0823ff859dc65db238951c16e49293ea411c2b5a - (IBAction) refresh:(id) sender; - (IBAction) commit:(id) sender; - (IBAction)signOff:(id)sender; diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 9520056..0e1fdfd 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -11,8 +11,6 @@ #import "PBChangedFile.h" #import "PBWebChangesController.h" #import "PBGitIndex.h" -#import "NSString_RegEx.h" - @interface PBGitCommitController () - (void)refreshFinished:(NSNotification *)notification; diff --git a/PBGitIndexController.h b/PBGitIndexController.h index 49454cc..4bd969f 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -11,8 +11,6 @@ #import "PBChangedFile.h" @interface PBGitIndexController : NSObject { - int contextSize; - IBOutlet NSArrayController *stagedFilesController, *unstagedFilesController; IBOutlet PBGitCommitController *commitController; diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 1637fc5..21429f6 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -30,10 +30,8 @@ [unstagedTable registerForDraggedTypes: [NSArray arrayWithObject:FileChangesTableViewType]]; [stagedTable registerForDraggedTypes: [NSArray arrayWithObject:FileChangesTableViewType]]; - } - - (void) ignoreFiles:(NSArray *)files { // Build output string diff --git a/PBWebChangesController.m b/PBWebChangesController.m index 2aa96e3..933fecc 100644 --- a/PBWebChangesController.m +++ b/PBWebChangesController.m @@ -30,11 +30,6 @@ [self refresh]; } -- (BOOL) amend -{ - return controller.index.amend; -} - - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change From 029b42c5401a868078271132c49b813928e398ce Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 04:16:51 +0200 Subject: [PATCH 33/42] GitIndex: explicitly tell when stuff is updated --- PBGitCommitController.m | 11 ++++++++++- PBGitIndex.h | 5 +++++ PBGitIndex.m | 21 ++++++++++++++++----- PBGitIndexController.m | 22 ++++------------------ 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index 0e1fdfd..c0af324 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -18,6 +18,7 @@ - (void)commitFinished:(NSNotification *)notification; - (void)commitFailed:(NSNotification *)notification; - (void)amendCommit:(NSNotification *)notification; +- (void)indexChanged:(NSNotification *)notification; @end @implementation PBGitCommitController @@ -37,6 +38,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFinished:) name:PBGitIndexFinishedCommit object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexChanged:) name:PBGitIndexIndexUpdated object:index]; return self; } @@ -55,6 +57,9 @@ [[NSSortDescriptor alloc] initWithKey:@"path" ascending:true], nil]]; [cachedFilesController setSortDescriptors:[NSArray arrayWithObject: [[NSSortDescriptor alloc] initWithKey:@"path" ascending:true]]]; + + [cachedFilesController setAutomaticallyRearrangesObjects:NO]; + [unstagedFilesController setAutomaticallyRearrangesObjects:NO]; } - (void) removeView @@ -164,5 +169,9 @@ commitMessageView.string = message; } - +- (void)indexChanged:(NSNotification *)notification +{ + [cachedFilesController rearrangeObjects]; + [unstagedFilesController rearrangeObjects]; +} @end diff --git a/PBGitIndex.h b/PBGitIndex.h index cc4ae77..ee57245 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -15,11 +15,16 @@ extern NSString *PBGitIndexIndexRefreshStatus; extern NSString *PBGitIndexIndexRefreshFailed; extern NSString *PBGitIndexFinishedIndexRefresh; +// The "Files" array has changed +extern NSString *PBGitIndexIndexUpdated; + extern NSString *PBGitIndexCommitStatus; extern NSString *PBGitIndexCommitFailed; extern NSString *PBGitIndexFinishedCommit; extern NSString *PBGitIndexAmendMessageAvailable; + + // Represents a git index for a given work tree. // As a single git repository can have multiple trees, // the tree has to be given explicitly, even though diff --git a/PBGitIndex.m b/PBGitIndex.m index 2b45988..fb4ef3f 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -17,6 +17,8 @@ NSString *PBGitIndexIndexRefreshStatus = @"PBGitIndexIndexRefreshStatus"; NSString *PBGitIndexIndexRefreshFailed = @"PBGitIndexIndexRefreshFailed"; NSString *PBGitIndexFinishedIndexRefresh = @"PBGitIndexFinishedIndexRefresh"; +NSString *PBGitIndexIndexUpdated = @"GBGitIndexIndexUpdated"; + NSString *PBGitIndexCommitStatus = @"PBGitIndexCommitStatus"; NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed"; NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; @@ -45,6 +47,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; - (NSString *) parentTree; - (void)postCommitUpdate:(NSString *)update; - (void)postCommitFailure:(NSString *)reason; +- (void)postIndexChange; @end @implementation PBGitIndex @@ -257,13 +260,13 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return NO; } - // TODO: Stop Tracking for (PBChangedFile *file in stageFiles) { file.hasUnstagedChanges = NO; file.hasStagedChanges = YES; } - // TODO: Resume tracking + + [self postIndexChange]; return YES; } @@ -288,14 +291,13 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return NO; } - // TODO: stop tracking for (PBChangedFile *file in unstageFiles) { file.hasUnstagedChanges = YES; file.hasStagedChanges = NO; } - // TODO: resume tracking + [self postIndexChange]; return YES; } @@ -353,6 +355,11 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return [repository outputInWorkdirForArguments:[NSArray arrayWithObjects:@"diff-files", parameter, @"--", file.path, nil]]; } +- (void)postIndexChange +{ + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexIndexUpdated + object:self]; +} # pragma mark WebKit Accessibility @@ -568,8 +575,10 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; - (void)indexStepComplete { // if we're still busy, do nothing :) - if (--refreshStatus) + if (--refreshStatus) { + [self postIndexChange]; return; + } // At this point, all index operations have finished. // We need to find all files that don't have either @@ -590,6 +599,8 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexFinishedIndexRefresh object:self]; + [self postIndexChange]; + } @end diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 21429f6..8ab9033 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -13,11 +13,6 @@ #define FileChangesTableViewType @"GitFileChangedType" -@interface PBGitIndexController (PrivateMethods) -- (void)stopTrackingIndex; -- (void)resumeTrackingIndex; -@end - @implementation PBGitIndexController - (void)awakeFromNib @@ -67,6 +62,8 @@ [ignoreFile writeToFile:gitIgnoreName atomically:YES encoding:enc error:&error]; if (error) [[commitController.repository windowController] showErrorSheet:error]; + + // TODO: Post index change } # pragma mark Displaying diffs @@ -97,6 +94,8 @@ for (PBChangedFile *file in files) file.hasUnstagedChanges = NO; + + // TODO: Post index update } # pragma mark Context Menu methods @@ -316,17 +315,4 @@ writeRowsWithIndexes:(NSIndexSet *)rowIndexes return NO; } -#pragma mark Private Methods -- (void)stopTrackingIndex -{ - [stagedFilesController setAutomaticallyRearrangesObjects:NO]; - [unstagedFilesController setAutomaticallyRearrangesObjects:NO]; -} -- (void)resumeTrackingIndex -{ - [stagedFilesController setAutomaticallyRearrangesObjects:YES]; - [unstagedFilesController setAutomaticallyRearrangesObjects:YES]; - [stagedFilesController rearrangeObjects]; - [unstagedFilesController rearrangeObjects]; -} @end From 59d4a159a47945543398599f70d7de2db1e0a7cd Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 16:14:11 +0200 Subject: [PATCH 34/42] GitIndex: Fix a few comments --- PBGitIndex.m | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/PBGitIndex.m b/PBGitIndex.m index fb4ef3f..47a0986 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -142,6 +142,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return parent; } +// TODO: make Asynchronous - (void)commitWithMessage:(NSString *)commitMessage { NSMutableString *commitSubject = [@"commit: " mutableCopy]; @@ -419,8 +420,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; NSArray *lines = [self linesFromNotification:notification]; NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithCapacity:[lines count]]; // Other files are untracked, so we don't have any real index information. Instead, we can just fake it. - // The line below is used to add the file to the index - // FIXME: request the real file mode + // The line below is not used at all, as for these files the commitBlob isn't set NSArray *fileStatus = [NSArray arrayWithObjects:@":000000", @"100644", @"0000000000000000000000000000000000000000", @"0000000000000000000000000000000000000000", @"A", nil]; for (NSString *path in lines) { if ([path length] == 0) @@ -450,7 +450,6 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; - (void) addFilesFromDictionary:(NSMutableDictionary *)dictionary staged:(BOOL)staged tracked:(BOOL)tracked { - // TODO: Stop tracking files // Iterate over all existing files for (PBChangedFile *file in files) { NSArray *fileStatus = [dictionary objectForKey:file.path]; @@ -494,7 +493,6 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; file.hasUnstagedChanges = NO; } } - // TODO: Finish tracking files // Do new files only if necessary if (![[dictionary allKeys] count]) @@ -535,7 +533,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return [NSArray array]; NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - // FIXME: Return an error? + // FIXME: throw an error? if (!string) return [NSArray array]; From e17b454c39d7556f2d676d424496e3f68b7f16fe Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 16:15:23 +0200 Subject: [PATCH 35/42] CommitController: Make commit message editable after commit failed --- PBGitCommitController.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index c0af324..a6200dc 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -126,9 +126,9 @@ [unstagedFilesController setSelectionIndexes:[NSIndexSet indexSet]]; self.busy = YES; + [commitMessageView setEditable:NO]; [index commitWithMessage:commitMessage]; - [commitMessageView setEditable:NO]; } @@ -145,9 +145,9 @@ - (void)commitFinished:(NSNotification *)notification { + [commitMessageView setEditable:YES]; [commitMessageView setString:@""]; [webController setStateMessage:[NSString stringWithFormat:[[notification userInfo] objectForKey:@"description"]]]; - [commitMessageView setEditable:YES]; } - (void)commitFailed:(NSNotification *)notification @@ -155,6 +155,7 @@ self.busy = NO; NSString *reason = [[notification userInfo] objectForKey:@"description"]; self.status = [@"Commit failed: " stringByAppendingString:reason]; + [commitMessageView setEditable:YES]; [[repository windowController] showMessageSheet:@"Commit failed" infoText:reason]; } From 3dc312ff2e5971e528c89da63946cc2f67820558 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 16:16:53 +0200 Subject: [PATCH 36/42] PBGitIndex: Migrate discardChanges to the GitIndex --- PBGitIndex.h | 1 + PBGitIndex.m | 22 ++++++++++++++++++++++ PBGitIndexController.m | 18 ++---------------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/PBGitIndex.h b/PBGitIndex.h index ee57245..67a474a 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -60,6 +60,7 @@ extern NSString *PBGitIndexAmendMessageAvailable; // Inter-file changes: - (BOOL)stageFiles:(NSArray *)stageFiles; - (BOOL)unstageFiles:(NSArray *)unstageFiles; +- (void)discardChangesForFiles:(NSArray *)discardFiles; // Intra-file changes - (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; diff --git a/PBGitIndex.m b/PBGitIndex.m index 47a0986..d3d0263 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -302,6 +302,28 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; return YES; } +- (void)discardChangesForFiles:(NSArray *)discardFiles +{ + NSArray *paths = [discardFiles valueForKey:@"path"]; + NSString *input = [paths componentsJoinedByString:@"\0"]; + + 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]; + + if (ret) { + // TODO: Post failed notification + // [[commitController.repository windowController] showMessageSheet:@"Discarding changes failed" infoText:[NSString stringWithFormat:@"Discarding changes failed with error code %i", ret]]; + return; + } + + for (PBChangedFile *file in discardFiles) + file.hasUnstagedChanges = NO; + + [self postIndexChange]; +} + - (BOOL)applyPatch:(NSString *)hunk stage:(BOOL)stage reverse:(BOOL)reverse; { NSMutableArray *array = [NSMutableArray arrayWithObjects:@"apply", nil]; diff --git a/PBGitIndexController.m b/PBGitIndexController.m index 8ab9033..a19c6b9 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -71,7 +71,7 @@ - (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force { - if(!force) { + if (!force) { int ret = [[NSAlert alertWithMessageText:@"Discard changes" defaultButton:nil alternateButton:@"Cancel" @@ -81,21 +81,7 @@ return; } - NSArray *paths = [files valueForKey:@"path"]; - NSString *input = [paths componentsJoinedByString:@"\0"]; - - NSArray *arguments = [NSArray arrayWithObjects:@"checkout-index", @"--index", @"--quiet", @"--force", @"-z", @"--stdin", nil]; - int ret = 1; - [commitController.repository outputForArguments:arguments inputString:input retValue:&ret]; - if (ret) { - [[commitController.repository windowController] showMessageSheet:@"Discarding changes failed" infoText:[NSString stringWithFormat:@"Discarding changes failed with error code %i", ret]]; - return; - } - - for (PBChangedFile *file in files) - file.hasUnstagedChanges = NO; - - // TODO: Post index update + [commitController.index discardChangesForFiles:files]; } # pragma mark Context Menu methods From 438a3f808dede8589d47ea36f695727522d8b6dc Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 16:32:35 +0200 Subject: [PATCH 37/42] GitIndexController: reorder methods a bit, remove unnecessary stuff --- PBGitCommitView.xib | 20 --------------- PBGitIndexController.h | 3 --- PBGitIndexController.m | 57 ++++++++++++++++++------------------------ 3 files changed, 25 insertions(+), 55 deletions(-) diff --git a/PBGitCommitView.xib b/PBGitCommitView.xib index 49beeb5..5b8021f 100644 --- a/PBGitCommitView.xib +++ b/PBGitCommitView.xib @@ -1114,22 +1114,6 @@ 264 - - - stagedButtonCell - - - - 265 - - - - unstagedButtonCell - - - - 266 - rowClicked: @@ -1763,20 +1747,16 @@ YES commitController - stagedButtonCell stagedFilesController stagedTable - unstagedButtonCell unstagedFilesController unstagedTable YES PBGitCommitController - PBIconAndTextCell NSArrayController NSTableView - PBIconAndTextCell NSArrayController NSTableView diff --git a/PBGitIndexController.h b/PBGitIndexController.h index 4bd969f..1a455e6 100644 --- a/PBGitIndexController.h +++ b/PBGitIndexController.h @@ -14,9 +14,6 @@ IBOutlet NSArrayController *stagedFilesController, *unstagedFilesController; IBOutlet PBGitCommitController *commitController; - IBOutlet PBIconAndTextCell* unstagedButtonCell; - IBOutlet PBIconAndTextCell* stagedButtonCell; - IBOutlet NSTableView *unstagedTable; IBOutlet NSTableView *stagedTable; } diff --git a/PBGitIndexController.m b/PBGitIndexController.m index a19c6b9..5d2a949 100644 --- a/PBGitIndexController.m +++ b/PBGitIndexController.m @@ -13,6 +13,10 @@ #define FileChangesTableViewType @"GitFileChangedType" +@interface PBGitIndexController () +- (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force; +@end + @implementation PBGitIndexController - (void)awakeFromNib @@ -27,7 +31,8 @@ [stagedTable registerForDraggedTypes: [NSArray arrayWithObject:FileChangesTableViewType]]; } -- (void) ignoreFiles:(NSArray *)files +// FIXME: Find a proper place for this method -- this is not it. +- (void)ignoreFiles:(NSArray *)files { // Build output string NSMutableArray *fileList = [NSMutableArray array]; @@ -62,26 +67,6 @@ [ignoreFile writeToFile:gitIgnoreName atomically:YES encoding:enc error:&error]; if (error) [[commitController.repository windowController] showErrorSheet:error]; - - // TODO: Post index change -} - -# pragma mark Displaying diffs - - -- (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force -{ - if (!force) { - int ret = [[NSAlert alertWithMessageText:@"Discard changes" - defaultButton:nil - alternateButton:@"Cancel" - otherButton:nil - informativeTextWithFormat:@"Are you sure you wish to discard the changes to this file?\n\nYou cannot undo this operation."] runModal]; - if (ret != NSAlertDefaultReturn) - return; - } - - [commitController.index discardChangesForFiles:files]; } # pragma mark Context Menu methods @@ -179,10 +164,11 @@ - (void) ignoreFilesAction:(id) sender { NSArray *selectedFiles = [sender representedObject]; - if ([selectedFiles count] > 0) { - [self ignoreFiles:selectedFiles]; - } - [commitController refresh:NULL]; + if ([selectedFiles count] == 0) + return; + + [self ignoreFiles:selectedFiles]; + [commitController.index refresh]; } - (void)discardFilesAction:(id) sender @@ -210,6 +196,20 @@ [ws selectFile: path inFileViewerRootedAtPath:nil]; } +- (void)discardChangesForFiles:(NSArray *)files force:(BOOL)force +{ + if (!force) { + int ret = [[NSAlert alertWithMessageText:@"Discard changes" + defaultButton:nil + alternateButton:@"Cancel" + otherButton:nil + informativeTextWithFormat:@"Are you sure you wish to discard the changes to this file?\n\nYou cannot undo this operation."] runModal]; + if (ret != NSAlertDefaultReturn) + return; + } + + [commitController.index discardChangesForFiles:files]; +} # pragma mark TableView icon delegate - (void)tableView:(NSTableView*)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)rowIndex @@ -294,11 +294,4 @@ writeRowsWithIndexes:(NSIndexSet *)rowIndexes return YES; } -# pragma mark WebKit Accessibility - -+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector -{ - return NO; -} - @end From a2b3bf3d1e05c581468c32b41008223322f2a718 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Sun, 13 Sep 2009 16:47:30 +0200 Subject: [PATCH 38/42] PBGitIndex: post notifications when index stuff fails We use notifications so that we can make all these methods async later on --- PBGitCommitController.m | 9 +++++++++ PBGitIndex.h | 13 ++++++++++++- PBGitIndex.m | 20 ++++++++++++-------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/PBGitCommitController.m b/PBGitCommitController.m index a6200dc..6a77348 100644 --- a/PBGitCommitController.m +++ b/PBGitCommitController.m @@ -19,6 +19,7 @@ - (void)commitFailed:(NSNotification *)notification; - (void)amendCommit:(NSNotification *)notification; - (void)indexChanged:(NSNotification *)notification; +- (void)indexOperationFailed:(NSNotification *)notification; @end @implementation PBGitCommitController @@ -39,6 +40,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitFailed:) name:PBGitIndexCommitFailed object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(amendCommit:) name:PBGitIndexAmendMessageAvailable object:index]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexChanged:) name:PBGitIndexIndexUpdated object:index]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(indexOperationFailed:) name:PBGitIndexOperationFailed object:index]; return self; } @@ -132,6 +134,7 @@ } +# pragma mark PBGitIndex Notification handling - (void)refreshFinished:(NSNotification *)notification { self.busy = NO; @@ -175,4 +178,10 @@ [cachedFilesController rearrangeObjects]; [unstagedFilesController rearrangeObjects]; } + +- (void)indexOperationFailed:(NSNotification *)notification +{ + [[repository windowController] showMessageSheet:@"Index operation failed" infoText:[[notification userInfo] objectForKey:@"description"]]; +} + @end diff --git a/PBGitIndex.h b/PBGitIndex.h index 67a474a..7ca1db7 100644 --- a/PBGitIndex.h +++ b/PBGitIndex.h @@ -11,19 +11,30 @@ @class PBGitRepository; @class PBChangedFile; +/* + * Notifications this class will send + */ + +// Refreshing index extern NSString *PBGitIndexIndexRefreshStatus; extern NSString *PBGitIndexIndexRefreshFailed; extern NSString *PBGitIndexFinishedIndexRefresh; -// The "Files" array has changed +// The "indexChanges" array has changed extern NSString *PBGitIndexIndexUpdated; +// Committing files extern NSString *PBGitIndexCommitStatus; extern NSString *PBGitIndexCommitFailed; extern NSString *PBGitIndexFinishedCommit; +// Changing to amend extern NSString *PBGitIndexAmendMessageAvailable; +// This is for general operations, like applying a patch +extern NSString *PBGitIndexOperationFailed; + + // Represents a git index for a given work tree. // As a single git repository can have multiple trees, diff --git a/PBGitIndex.m b/PBGitIndex.m index d3d0263..4174d49 100644 --- a/PBGitIndex.m +++ b/PBGitIndex.m @@ -24,6 +24,7 @@ NSString *PBGitIndexCommitFailed = @"PBGitIndexCommitFailed"; NSString *PBGitIndexFinishedCommit = @"PBGitIndexFinishedCommit"; NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; +NSString *PBGitIndexOperationFailed = @"PBGitIndexOperationFailed"; @interface PBGitIndex (IndexRefreshMethods) @@ -48,6 +49,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; - (void)postCommitUpdate:(NSString *)update; - (void)postCommitFailure:(NSString *)reason; - (void)postIndexChange; +- (void)postOperationFailed:(NSString *)description; @end @implementation PBGitIndex @@ -237,6 +239,12 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; userInfo:[NSDictionary dictionaryWithObject:reason forKey:@"description"]]; } +- (void)postOperationFailed:(NSString *)description +{ + [[NSNotificationCenter defaultCenter] postNotificationName:PBGitIndexOperationFailed + object:self + userInfo:[NSDictionary dictionaryWithObject:description forKey:@"description"]]; +} - (BOOL)stageFiles:(NSArray *)stageFiles { @@ -256,8 +264,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; retValue:&ret]; if (ret) { - // FIXME: failed notification? - NSLog(@"Error when updating index. Retvalue: %i", ret); + [self postOperationFailed:[NSString stringWithFormat:@"Error in staging files. Return value: %i", ret]]; return NO; } @@ -287,8 +294,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; if (ret) { - // FIXME: Failed notification - NSLog(@"Error when updating index. Retvalue: %i", ret); + [self postOperationFailed:[NSString stringWithFormat:@"Error in unstaging files. Return value: %i", ret]]; return NO; } @@ -313,8 +319,7 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; [PBEasyPipe outputForCommand:[PBGitBinary path] withArgs:arguments inDir:[workingDirectory path] inputString:input retValue:&ret]; if (ret) { - // TODO: Post failed notification - // [[commitController.repository windowController] showMessageSheet:@"Discarding changes failed" infoText:[NSString stringWithFormat:@"Discarding changes failed with error code %i", ret]]; + [self postOperationFailed:[NSString stringWithFormat:@"Discarding changes failed with return value %i", ret]]; return; } @@ -337,9 +342,8 @@ NSString *PBGitIndexAmendMessageAvailable = @"PBGitIndexAmendMessageAvailable"; inputString:hunk retValue:&ret]; - // FIXME: show this error, rather than just logging it if (ret) { - NSLog(@"Error: %@", error); + [self postOperationFailed:[NSString stringWithFormat:@"Applying patch failed with return value %i. Error: %@", ret, error]]; return NO; } From 3324591e6cb3af729bad654b1772e3bc34d2986e Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Mon, 14 Sep 2009 13:02:36 +0200 Subject: [PATCH 39/42] Fix UTF-8 bug in NSString_RegEx This class would use the location information provided by regex(3) as range for for a substring. However, the information regex(3) returns is a byte-based, while NSString works on characters. This can cause a problem when there are UTF-8 characters in the string, as the wrong subsstring will be returned. This is fixed by taking the UTF bytesequence, and extracting a substring from that, rather than using NSString's own substring method --- NSString_RegEx.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NSString_RegEx.m b/NSString_RegEx.m index ee0e9bd..38d3848 100644 --- a/NSString_RegEx.m +++ b/NSString_RegEx.m @@ -57,7 +57,9 @@ break; NSRange range = NSMakeRange(pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so); - NSString * substring = [self substringWithRange:range]; + NSString * substring = [[[NSString alloc] initWithBytes:[self UTF8String] + range.location + length:range.length + encoding:NSUTF8StringEncoding] autorelease]; [outMatches addObject:substring]; if (ranges) From 0363eea494602e3002f45f1790eaff3435151949 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 17 Sep 2009 23:29:06 +0200 Subject: [PATCH 40/42] HistoryView: don't load in commit information in a separate thread anymore I've seen this hang or crash a few times, so I hope this works better. Instead of running a task in a separate thread, we just let it go through the run loop and catch it when the task is done. This ruins the second subview in the history view, but I don't think anybody ever used that, so I'm going to remove it. --- PBGitCommit.m | 14 ++------------ PBWebHistoryController.m | 32 ++++++++++++++++++++++++++++++++ html/views/history/history.js | 22 ++++++++++++++++------ 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/PBGitCommit.m b/PBGitCommit.m index b883c95..9ebe3b5 100644 --- a/PBGitCommit.m +++ b/PBGitCommit.m @@ -66,20 +66,10 @@ return str; } -// NOTE: This method should remain threadsafe, as we load it in async -// from the web view. +// FIXME: Remove this method once it's unused. - (NSString*) details { - if (details != nil) - return details; - - NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", [self realSha], nil]; - if (![PBGitDefaults showWhitespaceDifferences]) - [arguments insertObject:@"-w" atIndex:1]; - - details = [self.repository outputForArguments:arguments]; - - return details; + return @""; } - (NSString *) patch diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m index 35979a4..1934b73 100644 --- a/PBWebHistoryController.m +++ b/PBWebHistoryController.m @@ -7,6 +7,7 @@ // #import "PBWebHistoryController.h" +#import "PBGitDefaults.h" @implementation PBWebHistoryController @@ -49,6 +50,37 @@ NSArray *arguments = [NSArray arrayWithObjects:content, [[[historyController repository] headRef] simpleRef], nil]; [[self script] callWebScriptMethod:@"loadCommit" withArguments: arguments]; + + // 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, nil]; + if (![PBGitDefaults showWhitespaceDifferences]) + [taskArguments insertObject:@"-w" atIndex:1]; + + NSFileHandle *handle = [repository handleForArguments:taskArguments]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + // Remove notification, in case we have another one running + [nc removeObserver:self]; + [nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; + [handle readToEndOfFileInBackgroundAndNotify]; +} + +- (void)commitDetailsLoaded:(NSNotification *)notification +{ + NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem]; + if (!data) + return; + + NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (!details) + details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; + + if (!details) + return; + + [[view windowScriptObject] callWebScriptMethod:@"loadCommitDetails" withArguments:[NSArray arrayWithObject:details]]; } - (void) selectCommit: (NSString*) sha diff --git a/html/views/history/history.js b/html/views/history/history.js index df2a2b0..47d72b7 100644 --- a/html/views/history/history.js +++ b/html/views/history/history.js @@ -1,4 +1,7 @@ var commit; + +// Create a new Commit object +// obj: PBGitCommit object var Commit = function(obj) { this.object = obj; @@ -11,8 +14,9 @@ var Commit = function(obj) { // TODO: // this.author_date instant - // This all needs to be async - this.loadedRaw = function(details) { + // This can be called later with the output of + // 'git show' to fill in missing commit details (such as a diff) + this.parseDetails = function(details) { this.raw = details; var diffStart = this.raw.indexOf("\ndiff "); @@ -138,6 +142,7 @@ var selectCommit = function(a) { Controller.selectCommit_(a); } +// Relead only refs var reload = function() { $("notification").style.display = "none"; commit.reloadRefs(); @@ -159,10 +164,11 @@ var showRefs = function() { var loadCommit = function(commitObject, currentRef) { // These are only the things we can do instantly. - // Other information will be loaded later by loadExtendedCommit + // Other information will be loaded later by loadCommitDetails, + // Which will be called from the controller once + // the commit details are in. + commit = new Commit(commitObject); - Controller.callSelector_onObject_callBack_("details", commitObject, - function(data) { commit.loadedRaw(data); loadExtendedCommit(commit); }); commit.currentRef = currentRef; notify("Loading commit…", 0); @@ -199,6 +205,8 @@ var loadCommit = function(commitObject, currentRef) { } var showDiff = function() { + + // Callback for the diff highlighter. Used to generate a filelist var newfile = function(name1, name2, id, mode_change, old_mode, new_mode) { var button = document.createElement("div"); var p = document.createElement("p"); @@ -270,8 +278,10 @@ var enableFeatures = function() enableFeature("gravatar", $("gravatar")) } -var loadExtendedCommit = function(commit) +var loadCommitDetails = function(data) { + commit.parseDetails(data); + var formatEmail = function(name, email) { return email ? name + " <" + email + ">" : name; } From 34394d056b5ff0a4620a79c606f26ff4870c67f3 Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 17 Sep 2009 23:32:35 +0200 Subject: [PATCH 41/42] HistoryView: Remove raw view I don't think anybody has ever used this, so let's just remove it. --- PBGitHistoryController.m | 3 +- PBGitHistoryView.xib | 506 ++++++++++++--------------------------- 2 files changed, 149 insertions(+), 360 deletions(-) diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index f8ad04a..a9fde36 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -66,8 +66,7 @@ switch (self.selectedTab) { case 0: self.webCommit = realCommit; break; - case 1: self.rawCommit = realCommit; break; - case 2: self.gitTree = realCommit.tree; break; + case 1: self.gitTree = realCommit.tree; break; } } diff --git a/PBGitHistoryView.xib b/PBGitHistoryView.xib index b8c820e..68b7789 100644 --- a/PBGitHistoryView.xib +++ b/PBGitHistoryView.xib @@ -2,14 +2,14 @@ 1050 - 9L30 + 9L31a 677 949.54 353.00 YES - + YES @@ -98,7 +98,7 @@ 293 - {{376, 6}, {99, 25}} + {{376, 6}, {71, 25}} YES @@ -124,23 +124,14 @@ 2 - - NSImage - NSListViewTemplate - - - Raw View - 1 - 2 - - - 3.200000e+01 NSImage NSPathTemplate + Tree View - 0 + 9 + 2 2 @@ -320,7 +311,6 @@ 3 YES - NO YES @@ -410,7 +400,7 @@ 1 - + 274 YES @@ -477,268 +467,10 @@ - - 2 - - - 256 - - YES - - - 274 - - YES - - - 2304 - - YES - - - 2322 - {835, 70} - - - - - - Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum Et harumd und lookum like Greek to me, dereud facilis est er expedit distinct. Nam liber te conscient to factor tum poen legum odioque civiuda - - - YES - - YES - NSFont - NSParagraphStyle - - - YES - - Monaco - 1.000000e+01 - 16 - - - 3 - - YES - - 0.000000e+00 - - - 5.600000e+01 - - - 1.120000e+02 - - - 1.680000e+02 - - - 2.240000e+02 - - - 2.800000e+02 - - - 3.360000e+02 - - - 3.920000e+02 - - - 4.480000e+02 - - - 5.040000e+02 - - - 5.600000e+02 - - - 6.160000e+02 - - - 6.720000e+02 - - - 7.280000e+02 - - - 7.840000e+02 - - - 8.400000e+02 - - - 8.960000e+02 - - - 9.520000e+02 - - - 1.008000e+03 - - - 1.064000e+03 - - - 1.120000e+03 - - - 1.176000e+03 - - - 1.232000e+03 - - - 1.288000e+03 - - - 1.344000e+03 - - - 1.400000e+03 - - - 1.456000e+03 - - - 1.512000e+03 - - - 1.568000e+03 - - - 1.624000e+03 - - - 1.680000e+03 - - - 1.736000e+03 - - - - - - - - - YES - - - 6 - - - - 8.350000e+02 - 1 - - - 2369 - - - - YES - - YES - NSBackgroundColor - NSColor - - - YES - - 6 - System - selectedTextBackgroundColor - - - - 6 - System - selectedTextColor - - - - - - - YES - - YES - NSColor - NSUnderline - - - YES - - 1 - MCAwIDEAA - - - - - - - 6 - {1687, 1e+07} - {83, 0} - - - - {{1, 1}, {835, 185}} - - - - - - {4, -5} - 1 - - 4 - - - - 256 - {{836, 1}, {15, 185}} - - - _doScroller: - 2.240493e-01 - - - - 256 - {{-100, -100}, {87, 18}} - - 1 - - _doScroller: - 1.000000e+00 - 9.456522e-01 - - - {852, 187} - - - 18 - - - - - - {852, 186} - - Raw - - - Item 2 - + 256 YES @@ -869,7 +601,124 @@ Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum Et harumd und lookum like Greek to me, dereud facilis est er expedit distinct. Nam liber te conscient to factor tum poen legum odioque civiuda - + + YES + + YES + NSFont + NSParagraphStyle + + + YES + + Monaco + 1.000000e+01 + 16 + + + 3 + + YES + + 0.000000e+00 + + + 5.600000e+01 + + + 1.120000e+02 + + + 1.680000e+02 + + + 2.240000e+02 + + + 2.800000e+02 + + + 3.360000e+02 + + + 3.920000e+02 + + + 4.480000e+02 + + + 5.040000e+02 + + + 5.600000e+02 + + + 6.160000e+02 + + + 6.720000e+02 + + + 7.280000e+02 + + + 7.840000e+02 + + + 8.400000e+02 + + + 8.960000e+02 + + + 9.520000e+02 + + + 1.008000e+03 + + + 1.064000e+03 + + + 1.120000e+03 + + + 1.176000e+03 + + + 1.232000e+03 + + + 1.288000e+03 + + + 1.344000e+03 + + + 1.400000e+03 + + + 1.456000e+03 + + + 1.512000e+03 + + + 1.568000e+03 + + + 1.624000e+03 + + + 1.680000e+03 + + + 1.736000e+03 + + + + + @@ -896,8 +745,18 @@ YES - - + + 6 + System + selectedTextBackgroundColor + + + + 6 + System + selectedTextColor + + @@ -910,7 +769,10 @@ YES - + + 1 + MCAwIDEAA + @@ -927,7 +789,10 @@ - + + {4, -5} + 1 + 4 @@ -967,21 +832,20 @@ {852, 186} - Tree - + 6 YES YES YES - + @@ -1936,22 +1800,6 @@ 217 - - - value: rawCommit.details - - - - - - value: rawCommit.details - value - rawCommit.details - 2 - - - 230 - commitController @@ -2221,23 +2069,12 @@ YES - Bottom View - - 5 - - - YES - - - - Raw View - 6 @@ -2360,41 +2197,6 @@ - - 22 - - - YES - - - - - - 23 - - - YES - - - - - - - - 24 - - - - - 25 - - - - - 26 - - - 47 @@ -2819,11 +2621,9 @@ 20.IBPluginDependency 21.IBAttributePlaceholdersKey 21.IBPluginDependency - 22.IBPluginDependency 223.IBPluginDependency 224.IBPluginDependency 225.IBPluginDependency - 23.IBPluginDependency 231.IBPluginDependency 236.IBEditorWindowLastContentRect 236.IBWindowTemplateEditedContentRect @@ -2835,15 +2635,12 @@ 237.IBPluginDependency 238.IBPluginDependency 239.IBPluginDependency - 24.IBPluginDependency 240.IBPluginDependency 242.IBPluginDependency 243.IBPluginDependency 245.IBPluginDependency 246.IBPluginDependency 247.IBPluginDependency - 25.IBPluginDependency - 26.IBPluginDependency 261.IBAttributePlaceholdersKey 261.IBPluginDependency 262.IBPluginDependency @@ -2890,7 +2687,6 @@ 47.IBPluginDependency 48.IBPluginDependency 49.IBPluginDependency - 5.IBPluginDependency 50.IBPluginDependency 51.IBPluginDependency 52.IBPluginDependency @@ -2949,8 +2745,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin {{504, 612}, {346, 102}} {{504, 612}, {346, 102}} @@ -2967,9 +2761,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin ToolTip @@ -3038,7 +2829,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin From 5972bd4f7f194fce53f84c45ba68a4b63de22ffa Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Thu, 17 Sep 2009 23:40:38 +0200 Subject: [PATCH 42/42] HistoryView: Don't show the 'loading commit' thing until after 500 ms. This was annoying me a lot, so it's in stable :) Signed-off-by: Pieter de Bie --- html/views/history/history.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/html/views/history/history.js b/html/views/history/history.js index 47d72b7..6cd7540 100644 --- a/html/views/history/history.js +++ b/html/views/history/history.js @@ -10,6 +10,7 @@ var Commit = function(obj) { this.sha = obj.realSha(); this.parents = obj.parents; this.subject = obj.subject; + this.notificationID = null; // TODO: // this.author_date instant @@ -168,11 +169,12 @@ var loadCommit = function(commitObject, currentRef) { // Which will be called from the controller once // the commit details are in. + if (commit && commit.notificationID) + clearTimeout(commit.notificationID); + commit = new Commit(commitObject); commit.currentRef = currentRef; - notify("Loading commit…", 0); - $("commitID").innerHTML = commit.sha; $("authorID").innerHTML = commit.author_name; $("subjectID").innerHTML = commit.subject.escapeHTML(); @@ -202,6 +204,13 @@ var loadCommit = function(commitObject, currentRef) { "" + commit.parents[i] + ""; } + + commit.notificationID = setTimeout(function() { + if (!commit.fullyLoaded) + notify("Loading commit…", 0); + commit.notificationID = null; + }, 500); + } var showDiff = function() { @@ -282,6 +291,11 @@ var loadCommitDetails = function(data) { commit.parseDetails(data); + if (commit.notificationID) + clearTimeout(commit.notificationID) + else + $("notification").style.display = "none"; + var formatEmail = function(name, email) { return email ? name + " <" + email + ">" : name; }