Merge branch 'master' into experimental

Conflicts:
	PBGitRepository.h
	PBGitSidebarController.m
	PBSourceViewCell.h
	PBSourceViewCell.m
This commit is contained in:
German Laullon
2011-01-07 12:27:45 -08:00
15 changed files with 171 additions and 97 deletions
+5
View File
@@ -36,6 +36,11 @@
+(BOOL)isStartDiff:(NSString *)line;
+(BOOL)isStartBlock:(NSString *)line;
+(NSArray *)getFilesNames:(NSString *)line;
+(BOOL)isBinaryFile:(NSString *)line;
+(NSString*)mimeTypeForFileName:(NSString*)file;
+(BOOL)isImage:(NSString*)file;
@property(retain) NSMutableArray *groups;
@property(retain) NSString *logFormat;
+35 -12
View File
@@ -181,7 +181,6 @@
- (void)scopeBar:(MGScopeBar *)theScopeBar selectedStateChanged:(BOOL)selected forItem:(NSString *)identifier inGroup:(int)groupNumber
{
NSLog(@"startFile=%@ identifier=%@ groupNumber=%d",startFile,identifier,groupNumber);
if((groupNumber==0) && (startFile!=identifier)){
NSString *path = [NSString stringWithFormat:@"html/views/%@", identifier];
NSString *html = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:path];
@@ -238,11 +237,10 @@
NSArray *lines = [txt componentsSeparatedByString:@"\n"];
NSMutableString *res=[NSMutableString string];
[res appendString:@"<table id='filelist'>"];
int i;
for (i=1; i<[lines count]; i++) {
NSString *line=[lines objectAtIndex:i];
NSArray *fields=[line componentsSeparatedByString:@" "];
NSArray *fileStatus=[[fields objectAtIndex:4] componentsSeparatedByString:@"\t"];
for (NSString *line in lines) {
if([line length]<98) continue;
line=[line substringFromIndex:97];
NSArray *fileStatus=[line componentsSeparatedByString:@"\t"];
NSString *status=[[fileStatus objectAtIndex:0] substringToIndex:1]; // ignore the score
NSString *file=[fileStatus objectAtIndex:1];
NSString *txt=file;
@@ -331,17 +329,19 @@
}else if(inDiff){
[res appendString:[NSString stringWithFormat:@"<p>%@</p>",line]];
if([self isBinaryFile:line]){
NSLog(@"line='%@'",line);
[res appendString:@"</td></tr></thead><tbody>"];
NSArray *files=[self getFilesNames:line];
NSLog(@"files='%@'",files);
if(![[files objectAtIndex:0] isAbsolutePath]){
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'>%@</td></tr>",[files objectAtIndex:0]]];
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'><img src='GitX://{SHA}:/prev/%@'/></td></tr>",[files objectAtIndex:0]]];
if([GLFileView isImage:[files objectAtIndex:0]]){
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'><img src='GitX://{SHA}:/prev/%@'/></td></tr>",[files objectAtIndex:0]]];
}
}
if(![[files objectAtIndex:1] isAbsolutePath]){
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'>%@</td></tr>",[files objectAtIndex:1]]];
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'><img src='GitX://{SHA}/%@'/></td></tr>",[files objectAtIndex:1]]];
if([GLFileView isImage:[files objectAtIndex:1]]){
[res appendString:[NSString stringWithFormat:@"<tr><td colspan='3'><img src='GitX://{SHA}/%@'/></td></tr>",[files objectAtIndex:1]]];
}
}
}
}
@@ -362,7 +362,6 @@
{
NSString *a;
NSString *b;
NSLog(@"line='%@'",line);
NSScanner *scanner=[NSScanner scannerWithString:line];
if([scanner scanString:@"Binary files " intoString:NULL]){
[scanner scanUpToString:@" and" intoString:&a];
@@ -375,10 +374,34 @@
if (![b isAbsolutePath]) {
b=[b substringFromIndex:2];
}
return [NSArray arrayWithObjects:a,b,nil];
}
+(NSString*)mimeTypeForFileName:(NSString*)name
{
NSString *mimeType = nil;
NSInteger i=[name rangeOfString:@"." options:NSBackwardsSearch].location;
if(i!=NSNotFound){
NSString *ext=[name substringFromIndex:i+1];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (CFStringRef)ext, NULL);
if(UTI){
CFStringRef registeredType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
if(registeredType){
mimeType = NSMakeCollectable(registeredType);
}
CFRelease(UTI);
}
}
return mimeType;
}
+(BOOL)isImage:(NSString*)file
{
NSString *mimeType=[GLFileView mimeTypeForFileName:file];
return (mimeType!=nil) && ([mimeType rangeOfString:@"image/" options:NSCaseInsensitiveSearch].location!=NSNotFound);
}
+(BOOL)isBinaryFile:(NSString *)line
{
return (([line length]>12) && [[line substringToIndex:12] isEqualToString:@"Binary files"]);
+1 -1
View File
@@ -287,7 +287,7 @@
- (BOOL) haveRefsBeenModified
{
[repository reloadRefs];
//[repository reloadRefs];
NSMutableSet *currentRefSHAs = [NSMutableSet setWithArray:[repository.refs allKeys]];
[currentRefSHAs minusSet:lastRefSHAs];
+1 -2
View File
@@ -146,8 +146,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
- (void)findInModeScriptCommand:(NSScriptCommand *)command;
-(NSNumber *)countCommintsOf:(NSString *)branchs;
+(bool)isLocalBranch:(NSString *)name;
- (NSMenu *) menu;
+(bool)isLocalBranch:(NSString *)branch branchNameInto:(NSString **)name;
@property (assign) BOOL hasChanged;
@property (readonly) PBGitWindowController *windowController;
+6 -17
View File
@@ -300,10 +300,6 @@ 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];
@@ -322,21 +318,14 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain";
[[[self windowController] window] setTitle:[self displayName]];
}
+(bool)isLocalBranch:(NSString *)name
+(bool)isLocalBranch:(NSString *)branch branchNameInto:(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;
NSScanner *scanner=[NSScanner scannerWithString:branch];
bool is=[scanner scanString:@"refs/heads/" intoString:NULL];
if(is && (name)){
*name=[branch substringFromIndex:[scanner scanLocation]];
}
NSArray *commits = [o componentsSeparatedByString:@"\n"];
return [NSNumber numberWithInt:[commits count]];
return is;
}
- (void) lazyReload
+7 -1
View File
@@ -11,9 +11,15 @@
@interface PBGitSVBranchItem : PBSourceViewItem {
BOOL isCheckedOut;
NSNumber *behind;
NSNumber *ahead;
}
+ (id)branchItemWithRevSpec:(PBGitRevSpecifier *)revSpecifier;
@property (assign) BOOL isCheckedOut;
@property (assign) NSNumber *behind;
@property (assign) NSNumber *ahead;
@end
+15
View File
@@ -11,6 +11,8 @@
@implementation PBGitSVBranchItem
@synthesize isCheckedOut;
@synthesize behind,ahead;
+ (id)branchItemWithRevSpec:(PBGitRevSpecifier *)revSpecifier
{
@@ -30,4 +32,17 @@
return branchImage;
}
- (NSString *) badge{
NSMutableString *badge=nil;
if(isCheckedOut || ahead || behind){
badge=[NSMutableString string];
if(isCheckedOut) [badge appendString:@""];
if(ahead) [badge appendFormat:@"+%@",ahead];
if(behind) [badge appendFormat:@"-%@",behind];
}
return badge;
}
@end
+3 -1
View File
@@ -11,9 +11,11 @@
@interface PBGitSVRemoteItem : PBSourceViewItem {
BOOL alert;
}
@property (assign) BOOL alert;
+ (id)remoteItemWithTitle:(NSString *)title;
@end
+5
View File
@@ -12,6 +12,7 @@
@implementation PBGitSVRemoteItem
@synthesize alert;
+ (id)remoteItemWithTitle:(NSString *)title
{
@@ -38,4 +39,8 @@
return [PBGitRef refFromString:[kGitXRemoteRefPrefix stringByAppendingString:self.title]];
}
- (NSString *)badge
{
return (alert ? @"!" : nil);
}
@end
+3
View File
@@ -47,6 +47,9 @@
- (void)setHistorySearch:(NSString *)searchString mode:(NSInteger)mode;
-(NSNumber *)countCommintsOf:(NSString *)range;
-(bool)remoteNeedFetch:(NSString *)remote;
@property(readonly) NSMutableArray *items;
@property(readonly) NSView *sourceListControlsView;
@property(readonly) PBGitHistoryController *historyViewController;
+79 -47
View File
@@ -48,7 +48,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
self = [super initWithRepository:theRepository superController:controller];
[sourceView setDelegate:self];
items = [NSMutableArray array];
return self;
}
@@ -57,18 +57,19 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
[super awakeFromNib];
window.contentView = self.view;
[self populateList];
historyViewController = [[PBGitHistoryController alloc] initWithRepository:repository superController:superController];
commitViewController = [[PBGitCommitController alloc] initWithRepository:repository superController:superController];
[repository addObserver:self forKeyPath:@"refs" options:0 context:@"updateRefs"];
[repository addObserver:self forKeyPath:@"currentBranch" options:0 context:@"currentBranchChange"];
[repository addObserver:self forKeyPath:@"branches" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:@"branchesModified"];
[repository addObserver:self forKeyPath:@"stashController.stashes" options:NSKeyValueObservingOptionNew context:kObservingContextStashes];
[repository addObserver:self forKeyPath:@"submoduleController.submodules" options:NSKeyValueObservingOptionNew context:kObservingContextSubmodules];
[self menuNeedsUpdate:[actionButton menu]];
if ([PBGitDefaults showStageView])
[self selectStage];
else
@@ -82,12 +83,12 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
[historyViewController closeView];
[commitViewController closeView];
[repository removeObserver:self forKeyPath:@"currentBranch"];
[repository removeObserver:self forKeyPath:@"branches"];
[repository removeObserver:self forKeyPath:@"stashController.stashes"];
[repository removeObserver:self forKeyPath:@"submoduleController.submodules"];
[super closeView];
}
@@ -96,9 +97,9 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
if ([@"currentBranchChange" isEqualToString:context]) {
[sourceView reloadData];
[self selectCurrentBranch];
} else if ([@"branchesModified" isEqualToString:context]) {
}else if ([@"branchesModified" isEqualToString:context]) {
NSInteger changeKind = [(NSNumber *)[change objectForKey:NSKeyValueChangeKindKey] intValue];
if (changeKind == NSKeyValueChangeInsertion) {
NSArray *newRevSpecs = [change objectForKey:NSKeyValueChangeNewKey];
for (PBGitRevSpecifier *rev in newRevSpecs) {
@@ -147,16 +148,54 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
[sourceView PBExpandItem:item expandParents:YES];
}
[sourceView reloadData];
} else {
}else if ([@"updateRefs" isEqualToString:context]) {
for(PBGitSVRemoteItem* remote in [remotes children]){
NSLog(@"remote.title=%@",[remote title]);
[remote setAlert:[self remoteNeedFetch:[remote title]]];
}
for(PBGitSVBranchItem* branch in [branches children]){
NSString *bName=[branch title];
[branch setAhead:[self countCommintsOf:[NSString stringWithFormat:@"origin/%@..%@",bName,bName]]];
[branch setBehind:[self countCommintsOf:[NSString stringWithFormat:@"%@..origin/%@",bName,bName]]];
[branch setIsCheckedOut:[branch.revSpecifier isEqual:[repository headRef]]];
}
}else{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark Badges Methods
-(NSNumber *)countCommintsOf:(NSString *)range
{
NSArray *args = [NSArray arrayWithObjects:@"rev-list", range, nil];
int ret;
NSString *o = [repository outputForArguments:args retValue:&ret];
if ((ret!=0) || ([o length]==0)) {
return NULL;
}
NSArray *commits = [o componentsSeparatedByString:@"\n"];
return [NSNumber numberWithInt:[commits count]];
}
-(bool)remoteNeedFetch:(NSString *)remote
{
int ret;
NSArray *args = [NSArray arrayWithObjects:@"fetch", @"--dry-run", remote, nil];
NSString *o = [repository outputForArguments:args retValue:&ret];
return ((ret==0) && ([o length]!=0));
}
#pragma mark -----
- (PBSourceViewItem *) selectedItem
{
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
return item;
}
@@ -222,7 +261,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
[sourceView reloadData];
return;
}
NSArray *pathComponents = [[rev simpleRef] componentsSeparatedByString:@"/"];
if ([pathComponents count] < 2)
[branches addChild:[PBSourceViewItem itemWithRevSpec:rev]];
@@ -232,17 +271,17 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
[tags addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]];
else if ([[rev simpleRef] hasPrefix:@"refs/remotes/"])
[remotes addRev:rev toPath:[pathComponents subarrayWithRange:NSMakeRange(2, [pathComponents count] - 2)]];
[sourceView reloadData];
}
- (void) removeRevSpec:(PBGitRevSpecifier *)rev
{
PBSourceViewItem *item = [self itemForRev:rev];
if (!item)
return;
PBSourceViewItem *parent = item.parent;
[parent removeChild:item];
[sourceView reloadData];
@@ -259,19 +298,19 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
if ([item revSpecifier]) {
if (![repository.currentBranch isEqual:[item revSpecifier]])
repository.currentBranch = [item revSpecifier];
[superController changeContentController:historyViewController];
[PBGitDefaults setShowStageView:NO];
}
if (item == stage) {
[superController changeContentController:commitViewController];
[PBGitDefaults setShowStageView:YES];
}
[self updateActionMenu];
[self updateRemoteControls];
}
@@ -284,15 +323,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(PBSourceViewCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(PBSourceViewItem *)item
{
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;
}
BOOL showsActionButton = NO;
if ([item respondsToSelector:@selector(showsActionButton)]) {
showsActionButton = [item showsActionButton];
@@ -301,6 +332,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
}
cell.showsActionButton = showsActionButton;
[cell setBadge:[item badge]];
[cell setImage:[item icon]];
}
@@ -327,7 +359,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
PBSourceViewItem *project = [PBSourceViewItem groupItemWithTitle:[repository projectName]];
project.showsActionButton = YES;
project.isUncollapsible = YES;
stage = [PBGitSVStageItem stageItem];
[project addChild:stage];
@@ -338,10 +370,10 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
others = [PBSourceViewItem groupItemWithTitle:@"Other"];
stashes = [PBSourceViewItem groupItemWithTitle:@"Stashes"];
submodules = [PBSourceViewItem groupItemWithTitle:@"Submodules"];
for (PBGitRevSpecifier *rev in repository.branches)
[self addRevSpec:rev];
[items addObject:project];
[items addObject:branches];
[items addObject:remotes];
@@ -349,7 +381,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
[items addObject:others];
[items addObject:stashes];
[items addObject:submodules];
[sourceView reloadData];
[sourceView expandItem:project];
[sourceView expandItem:branches expandChildren:YES];
@@ -365,7 +397,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
if (!item)
return [items objectAtIndex:index];
return [[(PBSourceViewItem *)item children] objectAtIndex:index];
}
@@ -378,7 +410,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
if (!item)
return [items count];
return [[(PBSourceViewItem *)item children] count];
}
@@ -399,7 +431,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
if (!ref)
return;
for (NSMenuItem *menuItem in [historyViewController.refController menuItemsForRef:ref])
[menu addItem:menuItem];
}
@@ -410,7 +442,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
NSImage *actionIcon = [NSImage imageNamed:@"NSActionTemplate"];
[actionIcon setSize:NSMakeSize(12, 12)];
[actionIconItem setImage:actionIcon];
return actionIconItem;
}
@@ -441,11 +473,11 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
PBGitRef *ref = [viewItem ref];
if (!ref)
return nil;
NSMenu *menu = [[NSMenu alloc] init];
[menu setAutoenablesItems:NO];
[self addMenuItemsForRef:ref toMenu:menu];
return menu;
}
@@ -454,7 +486,7 @@ static NSString * const kObservingContextSubmodules = @"submodulesChanged";
{
[actionButton removeAllItems];
[menu addItem:[self actionIconItem]];
PBGitRef *ref = [[self selectedItem] ref];
[self addMenuItemsForRef:ref toMenu:menu];
}
@@ -472,11 +504,11 @@ enum {
- (void) updateRemoteControls
{
BOOL hasRemote = NO;
PBGitRef *ref = [[self selectedItem] ref];
if ([ref isRemote] || ([ref isBranch] && [[repository remoteRefForBranch:ref error:NULL] remoteName]))
hasRemote = YES;
[remoteControls setEnabled:hasRemote forSegment:kFetchSegment];
[remoteControls setEnabled:hasRemote forSegment:kPullSegment];
[remoteControls setEnabled:hasRemote forSegment:kPushSegment];
@@ -491,26 +523,26 @@ enum {
- (IBAction) fetchPullPushAction:(id)sender
{
NSInteger selectedSegment = [sender selectedSegment];
if (selectedSegment == kAddRemoteSegment) {
[PBAddRemoteSheet beginAddRemoteSheetForRepository:repository];
return;
}
NSInteger index = [sourceView selectedRow];
PBSourceViewItem *item = [sourceView itemAtRow:index];
PBGitRef *ref = [[item revSpecifier] ref];
if (!ref && (item.parent == remotes))
ref = [PBGitRef refFromString:[kGitXRemoteRefPrefix stringByAppendingString:[item title]]];
if (![ref isRemote] && ![ref isBranch])
return;
PBGitRef *remoteRef = [repository remoteRefForBranch:ref error:NULL];
if (!remoteRef)
return;
if (selectedSegment == kFetchSegment)
[repository beginFetchFromRemoteForRef:ref];
else if (selectedSegment == kPullSegment)
+2 -8
View File
@@ -9,11 +9,8 @@
#import <Cocoa/Cocoa.h>
#import "PBIconAndTextCell.h"
@interface PBSourceViewCell : PBIconAndTextCell {
BOOL isCheckedOut;
NSNumber *behind;
NSNumber *ahead;
NSString *badge;
BOOL showsActionButton;
BOOL iMouseDownInInfoButton;
@@ -22,9 +19,6 @@
}
@property (nonatomic) BOOL showsActionButton;
@property (nonatomic) SEL iInfoButtonAction;
@property (assign) BOOL isCheckedOut;
@property (assign) NSNumber *behind;
@property (assign) NSNumber *ahead;
@property (assign) NSString *badge;
@end
+2 -8
View File
@@ -14,12 +14,10 @@
- (NSRect)infoButtonRectForBounds:(NSRect)bounds;
@end
@implementation PBSourceViewCell
@synthesize iInfoButtonAction;
@synthesize isCheckedOut;
@synthesize behind,ahead;
@synthesize showsActionButton;
@synthesize badge;
# pragma mark context menu delegate methods
@@ -45,11 +43,7 @@
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)outlineView
{
if(behind || ahead || isCheckedOut){
NSMutableString *badge=[NSMutableString string];
if(isCheckedOut) [badge appendString:@""];
if(ahead) [badge appendFormat:@"+%@",ahead];
if(behind) [badge appendFormat:@"-%@",behind];
if(badge){
NSImage *checkedOutImage = [PBSourceViewBadge badge:badge forCell:self];
NSSize imageSize = [checkedOutImage size];
NSRect imageFrame;
+2
View File
@@ -29,6 +29,8 @@
+ (id)itemWithRevSpec:(PBGitRevSpecifier *)revSpecifier;
+ (id)itemWithTitle:(NSString *)title;
- (NSString *)badge;
- (void)addChild:(PBSourceViewItem *)child;
- (void)removeChild:(PBSourceViewItem *)child;
+5
View File
@@ -110,6 +110,11 @@
return nil;
}
- (NSString *)badge
{
return nil;
}
- (NSImage *) icon
{
return nil;