Skip to content

Commit 8da3bfa

Browse files
committed
Speedups for reloading refs when there are lots of tags.
This change uses GCD to schedule certain git commands for background execution. All background commands occur on the queue returned by PBGetWorkQueue(), and the results are executed on the main queue. This results in a dramatic improvement in the performance of reloadRefs when there are lots of tags. More improvements are possible with this approach, this is just something to get things rolling.
1 parent 0cec363 commit 8da3bfa

File tree

3 files changed

+55
-16
lines changed

3 files changed

+55
-16
lines changed

PBGitRepository.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
4242
@class PBStashController;
4343
@class PBSubmoduleController;
4444

45+
dispatch_queue_t PBGetWorkQueue();
46+
4547
@interface PBGitRepository : NSDocument {
4648
PBGitHistoryList* revisionList;
4749
PBGitConfig *config;
@@ -58,6 +60,10 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) {
5860
PBStashController *stashController;
5961
PBSubmoduleController *submoduleController;
6062
PBGitResetController *resetController;
63+
64+
BOOL didCheckBareRepository;
65+
BOOL bareRepository;
66+
NSString* workingDirectory;
6167
}
6268
@property (nonatomic, retain, readonly) PBStashController *stashController;
6369
@property (nonatomic, retain, readonly) PBSubmoduleController *submoduleController;

PBGitRepository.m

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@
3232
@interface PBGitRepository()
3333
@end
3434

35+
dispatch_queue_t PBGetWorkQueue() {
36+
#if 1
37+
static dispatch_queue_t work_queue;
38+
static dispatch_once_t onceToken;
39+
dispatch_once(&onceToken, ^{
40+
work_queue = dispatch_queue_create("PBWorkQueue", 0);
41+
});
42+
return work_queue;
43+
#else
44+
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
45+
#endif
46+
}
3547

3648

3749
@implementation PBGitRepository
@@ -250,11 +262,13 @@ - (NSString*)gitIgnoreFilename
250262

251263
- (BOOL)isBareRepository
252264
{
253-
if([self workingDirectory]) {
254-
return [PBGitRepository isBareRepository:[self workingDirectory]];
255-
} else {
256-
return true;
265+
if(!didCheckBareRepository) {
266+
if([self workingDirectory])
267+
bareRepository = [PBGitRepository isBareRepository:[self workingDirectory]];
268+
else
269+
bareRepository = YES;
257270
}
271+
return bareRepository;
258272
}
259273

260274
// Overridden to create our custom window controller
@@ -358,11 +372,16 @@ - (void) reloadRefs
358372

359373
PBGitRef *newRef = [PBGitRef refFromString:[components objectAtIndex:0]];
360374
PBGitRevSpecifier *revSpec = [[PBGitRevSpecifier alloc] initWithRef:newRef];
361-
362-
[revSpec setHelpText:[self helpTextForRef:newRef]];
363375
[self addBranch:revSpec];
364376
[self addRef:newRef fromParameters:components];
365377
[oldBranches removeObject:revSpec];
378+
379+
dispatch_async(PBGetWorkQueue(), ^{
380+
NSString* helpText = [self helpTextForRef:newRef];
381+
dispatch_async(dispatch_get_main_queue(), ^{
382+
[revSpec setHelpText:helpText];
383+
});
384+
});
366385
}
367386

368387
for (PBGitRevSpecifier *branch in oldBranches)
@@ -628,12 +647,14 @@ - (void) readCurrentBranch
628647

629648
- (NSString *) workingDirectory
630649
{
631-
if ([self.fileURL.path hasSuffix:@"/.git"])
632-
return [self.fileURL.path substringToIndex:[self.fileURL.path length] - 5];
633-
else if ([[self outputForCommand:@"rev-parse --is-inside-work-tree"] isEqualToString:@"true"])
634-
return [PBGitBinary path];
650+
if(!workingDirectory) {
651+
if ([self.fileURL.path hasSuffix:@"/.git"])
652+
workingDirectory = [[self.fileURL.path substringToIndex:[self.fileURL.path length] - 5] retain];
653+
else if ([[self outputForCommand:@"rev-parse --is-inside-work-tree"] isEqualToString:@"true"])
654+
workingDirectory = [PBGitBinary path];
655+
}
635656

636-
return nil;
657+
return workingDirectory;
637658
}
638659

639660
#pragma mark Remotes

PBGitSidebarController.m

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,15 @@ - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(
163163
for(PBGitSVBranchItem* branch in [branches children]){
164164
if([branch isKindOfClass:[PBGitSVBranchItem class]]){
165165
NSString *bName=[branch title];
166-
[branch setAhead:[self countCommintsOf:[NSString stringWithFormat:@"origin/%@..%@",bName,bName]]];
167-
[branch setBehind:[self countCommintsOf:[NSString stringWithFormat:@"%@..origin/%@",bName,bName]]];
168-
[branch setIsCheckedOut:[branch.revSpecifier isEqual:[repository headRef]]];
166+
dispatch_async(PBGetWorkQueue(),^{
167+
id ahead = [self countCommintsOf:[NSString stringWithFormat:@"origin/%@..%@",bName,bName]];
168+
id behind = [self countCommintsOf:[NSString stringWithFormat:@"%@..origin/%@",bName,bName]];
169+
dispatch_async(dispatch_get_main_queue(),^{
170+
[branch setAhead:ahead];
171+
[branch setBehind:behind];
172+
[branch setIsCheckedOut:[branch.revSpecifier isEqual:[repository headRef]]];
173+
});
174+
});
169175
}
170176
}
171177
}else{
@@ -178,8 +184,14 @@ - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(
178184
-(void)evaluateRemoteBadge:(PBGitSVRemoteItem *)remote
179185
{
180186
DLog(@"remote.title=%@",[remote title]);
181-
if([remote isKindOfClass:[PBGitSVRemoteItem class]])
182-
[remote setAlert:[self remoteNeedFetch:[remote title]]];
187+
if([remote isKindOfClass:[PBGitSVRemoteItem class]]) {
188+
dispatch_async(PBGetWorkQueue(), ^{
189+
bool needsFetch = [self remoteNeedFetch:[remote title]];
190+
dispatch_async(dispatch_get_main_queue(), ^{
191+
[remote setAlert:needsFetch];
192+
});
193+
});
194+
}
183195
}
184196

185197
-(NSNumber *)countCommintsOf:(NSString *)range

0 commit comments

Comments
 (0)