diff --git a/GLFileView.h b/GLFileView.h index 6cac193..dfeb15e 100644 --- a/GLFileView.h +++ b/GLFileView.h @@ -31,6 +31,8 @@ + (NSString *)parseHTML:(NSString *)txt; + (NSString *)parseDiff:(NSString *)txt; + (NSString *)parseDiffTree:(NSString *)txt withStats:(NSMutableDictionary *)stats; ++ (NSString *)getFileName:(NSString *)line; + +(BOOL)isStartDiff:(NSString *)line; +(BOOL)isStartBlock:(NSString *)line; diff --git a/GLFileView.m b/GLFileView.m index 0a0154b..3c114f2 100644 --- a/GLFileView.m +++ b/GLFileView.m @@ -225,7 +225,7 @@ + (NSString *)parseDiffTree:(NSString *)txt withStats:(NSMutableDictionary *)stats { - NSInteger granTotal=0; + NSInteger granTotal=1; for(NSArray *stat in [stats allValues]){ NSInteger add=[[stat objectAtIndex:0] integerValue]; NSInteger rem=[[stat objectAtIndex:1] integerValue]; @@ -330,6 +330,20 @@ [res appendString:[NSString stringWithFormat:@"

%@

",line]]; }else if(inDiff){ [res appendString:[NSString stringWithFormat:@"

%@

",line]]; + if([self isBinaryFile:line]){ + NSLog(@"line='%@'",line); + [res appendString:@""]; + NSArray *files=[self getFilesNames:line]; + NSLog(@"files='%@'",files); + if(![[files objectAtIndex:0] isAbsolutePath]){ + [res appendString:[NSString stringWithFormat:@"%@",[files objectAtIndex:0]]]; + [res appendString:[NSString stringWithFormat:@"",[files objectAtIndex:0]]]; + } + if(![[files objectAtIndex:1] isAbsolutePath]){ + [res appendString:[NSString stringWithFormat:@"%@",[files objectAtIndex:1]]]; + [res appendString:[NSString stringWithFormat:@"",[files objectAtIndex:1]]]; + } + } } } if(inDiff) @@ -337,12 +351,39 @@ return res; } -+(NSString *)getFileName:(NSString *)line{ ++(NSString *)getFileName:(NSString *)line +{ NSRange b = [line rangeOfString:@"b/"]; NSString *file=[line substringFromIndex:b.location+2]; return file; } ++(NSArray *)getFilesNames:(NSString *)line +{ + NSString *a; + NSString *b; + NSLog(@"line='%@'",line); + NSScanner *scanner=[NSScanner scannerWithString:line]; + if([scanner scanString:@"Binary files " intoString:NULL]){ + [scanner scanUpToString:@" and" intoString:&a]; + [scanner scanString:@"and" intoString:NULL]; + [scanner scanUpToString:@" differ" intoString:&b]; + } + if (![a isAbsolutePath]) { + a=[a substringFromIndex:2]; + } + if (![b isAbsolutePath]) { + b=[b substringFromIndex:2]; + } + + return [NSArray arrayWithObjects:a,b,nil]; +} + ++(BOOL)isBinaryFile:(NSString *)line +{ + return (([line length]>12) && [[line substringToIndex:12] isEqualToString:@"Binary files"]); +} + +(BOOL)isStartDiff:(NSString *)line { return (([line length]>10) && [[line substringToIndex:10] isEqualToString:@"diff --git"]); diff --git a/PBGitRepository.h b/PBGitRepository.h index 7599c6c..a16acc0 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -128,6 +128,9 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { // for the scripting bridge - (void)findInModeScriptCommand:(NSScriptCommand *)command; +-(NSNumber *)countCommintsOf:(NSString *)branchs; ++(bool)isLocalBranch:(NSString *)name; + @property (assign) BOOL hasChanged; @property (readonly) PBGitWindowController *windowController; diff --git a/PBGitRepository.m b/PBGitRepository.m index 3d4489b..edec8ec 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -269,6 +269,10 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; PBGitRef *newRef = [PBGitRef refFromString:[components objectAtIndex:0]]; PBGitRevSpecifier *revSpec = [[PBGitRevSpecifier alloc] initWithRef:newRef]; + if([PBGitRepository isLocalBranch:[components objectAtIndex:0]]){ + [revSpec setAhead:[self countCommintsOf:[NSString stringWithFormat:@"origin..%@",[components objectAtIndex:0]]]]; + [revSpec setBehind:[self countCommintsOf:[NSString stringWithFormat:@"%@..origin",[components objectAtIndex:0]]]]; + } [self addBranch:revSpec]; [self addRef:newRef fromParameters:components]; [oldBranches removeObject:revSpec]; @@ -284,6 +288,23 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; [[[self windowController] window] setTitle:[self displayName]]; } ++(bool)isLocalBranch:(NSString *)name +{ + NSScanner *scanner=[NSScanner scannerWithString:name]; + return [scanner scanString:@"refs/heads/" intoString:NULL]; +} + +-(NSNumber *)countCommintsOf:(NSString *)branchs +{ + NSArray *args = [NSArray arrayWithObjects:@"rev-list", branchs, nil]; + NSString *o = [self outputForArguments:args]; + if ([o length]==0) { + return NULL; + } + NSArray *commits = [o componentsSeparatedByString:@"\n"]; + return [NSNumber numberWithInt:[commits count]]; +} + - (void) lazyReload { if (!hasChanged) diff --git a/PBGitRevSpecifier.h b/PBGitRevSpecifier.h index a8d97f2..32e96c4 100644 --- a/PBGitRevSpecifier.h +++ b/PBGitRevSpecifier.h @@ -14,6 +14,8 @@ NSArray *parameters; NSURL *workingDirectory; BOOL isSimpleRef; + NSNumber *behind; + NSNumber *ahead; } - (id) initWithParameters:(NSArray *)params description:(NSString *)descrip; @@ -37,5 +39,7 @@ @property(readonly) NSArray *parameters; @property(retain) NSURL *workingDirectory; @property(readonly) BOOL isSimpleRef; +@property(assign) NSNumber *behind; +@property(assign) NSNumber *ahead; @end diff --git a/PBGitRevSpecifier.m b/PBGitRevSpecifier.m index 9e2b785..1adc9ed 100644 --- a/PBGitRevSpecifier.m +++ b/PBGitRevSpecifier.m @@ -13,6 +13,7 @@ @synthesize parameters, description, workingDirectory; @synthesize isSimpleRef; +@synthesize behind,ahead; // internal designated init diff --git a/PBGitSidebarController.m b/PBGitSidebarController.m index 89a04c3..301bf16 100644 --- a/PBGitSidebarController.m +++ b/PBGitSidebarController.m @@ -223,8 +223,14 @@ - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(PBSourceViewCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(PBSourceViewItem *)item { - cell.isCheckedOut = [item.revSpecifier isEqual:[repository headRef]]; - + if(item.revSpecifier!=NULL){ + cell.isCheckedOut = [item.revSpecifier isEqual:[repository headRef]]; + cell.behind=[item.revSpecifier behind]; + cell.ahead=[item.revSpecifier ahead]; + }else{ + cell.behind=nil; + cell.ahead=nil; + } [cell setImage:[item icon]]; } diff --git a/PBGitXProtocol.m b/PBGitXProtocol.m index dcffeea..7d1e1bc 100644 --- a/PBGitXProtocol.m +++ b/PBGitXProtocol.m @@ -25,22 +25,28 @@ { NSURL *url = [[self request] URL]; PBGitRepository *repo = [[self request] repository]; - + if(!repo) { [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:nil]]; return; } - - NSString *specifier = [NSString stringWithFormat:@"%@:%@", [url host], [[url path] substringFromIndex:1]]; + + NSString *path=[[url path] substringFromIndex:1]; + NSString *v=@""; + if ([[path substringToIndex:5] isEqualToString:@"prev/"]) { + path=[path substringFromIndex:5]; + v=@"^"; + } + NSString *specifier = [NSString stringWithFormat:@"%@%@:%@", [url host], v,path]; handle = [repo handleInWorkDirForArguments:[NSArray arrayWithObjects:@"cat-file", @"blob", specifier, nil]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishFileLoad:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; [handle readToEndOfFileInBackgroundAndNotify]; - + NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[[self request] URL] MIMEType:nil expectedContentLength:-1 textEncodingName:nil]; - + [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; diff --git a/PBSourceViewBadge.h b/PBSourceViewBadge.h index 1754000..3058458 100644 --- a/PBSourceViewBadge.h +++ b/PBSourceViewBadge.h @@ -13,6 +13,7 @@ } ++ (NSImage *) badge:(NSString *)badge forCell:(NSTextFieldCell *)cell; + (NSImage *) checkedOutBadgeForCell:(NSTextFieldCell *)cell; + (NSImage *) numericBadge:(NSInteger)number forCell:(NSTextFieldCell *)cell; diff --git a/PBSourceViewCell.h b/PBSourceViewCell.h index 5b88392..fb80ece 100644 --- a/PBSourceViewCell.h +++ b/PBSourceViewCell.h @@ -12,8 +12,13 @@ @interface PBSourceViewCell : PBIconAndTextCell { BOOL isCheckedOut; + NSNumber *behind; + NSNumber *ahead; } @property (assign) BOOL isCheckedOut; +@property (assign) NSNumber *behind; +@property (assign) NSNumber *ahead; + @end diff --git a/PBSourceViewCell.m b/PBSourceViewCell.m index eb60bca..f207e04 100644 --- a/PBSourceViewCell.m +++ b/PBSourceViewCell.m @@ -16,6 +16,7 @@ @implementation PBSourceViewCell @synthesize isCheckedOut; +@synthesize behind,ahead; # pragma mark context menu delegate methods @@ -23,9 +24,9 @@ { NSPoint point = [view convertPoint:[event locationInWindow] fromView:nil]; NSInteger row = [view rowAtPoint:point]; - + PBGitSidebarController *controller = [view delegate]; - + return [controller menuForRow:row]; } @@ -34,21 +35,25 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)outlineView { - if (isCheckedOut) { - NSImage *checkedOutImage = [PBSourceViewBadge checkedOutBadgeForCell:self]; + if(behind || ahead || isCheckedOut){ + NSMutableString *badge=[NSMutableString string]; + if(isCheckedOut) [badge appendString:@"✔ "]; + if(ahead) [badge appendFormat:@"+%@",ahead]; + if(behind) [badge appendFormat:@"-%@",behind]; + NSImage *checkedOutImage = [PBSourceViewBadge badge:badge forCell:self]; NSSize imageSize = [checkedOutImage size]; NSRect imageFrame; NSDivideRect(cellFrame, &imageFrame, &cellFrame, imageSize.width + 3, NSMaxXEdge); imageFrame.size = imageSize; - + if ([outlineView isFlipped]) imageFrame.origin.y += floor((cellFrame.size.height + imageFrame.size.height) / 2); else imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2); - + [checkedOutImage compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver]; } - + [super drawWithFrame:cellFrame inView:outlineView]; } diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m index 8c06a7f..d38a180 100644 --- a/PBWebHistoryController.m +++ b/PBWebHistoryController.m @@ -116,6 +116,8 @@ NSString *html=[NSString stringWithFormat:@"%@%@
%@
",header,fileList,diffs]; + html=[html stringByReplacingOccurrencesOfString:@"{SHA}" withString:[currentSha string]]; + [[view windowScriptObject] callWebScriptMethod:@"showCommit" withArguments:[NSArray arrayWithObject:html]]; #if 1