mirror of
https://github.com/kennethreitz-archive/gitx.git
synced 2026-06-05 23:40:18 +00:00
PBGitRepository: Abstract revision walking to new class PBGitRevList
The revision walking code made the PBGitRepository unclean. Especially if we want to keep multiple PBGitRepository objects around (e.g. persistent data store), it needs to be more simple. This neatly extracts the revision walking code from the repository code.
This commit is contained in:
+997
-997
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@
|
||||
F5945E170E02B0C200706420 /* PBGitRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = F5945E160E02B0C200706420 /* PBGitRepository.m */; };
|
||||
F5B721C40E05CF7E00AF29DC /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5B721C20E05CF7E00AF29DC /* MainMenu.xib */; };
|
||||
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */ = {isa = PBXBuildFile; fileRef = F5DFFA6B0E075D8800617813 /* PBEasyFS.m */; };
|
||||
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */ = {isa = PBXBuildFile; fileRef = F5FF4E170E0829C20006317A /* PBGitRevList.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -76,6 +77,8 @@
|
||||
F5B721C30E05CF7E00AF29DC /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
F5DFFA6A0E075D8800617813 /* PBEasyFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBEasyFS.h; sourceTree = "<group>"; };
|
||||
F5DFFA6B0E075D8800617813 /* PBEasyFS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBEasyFS.m; sourceTree = "<group>"; };
|
||||
F5FF4E160E0829C20006317A /* PBGitRevList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitRevList.h; sourceTree = "<group>"; };
|
||||
F5FF4E170E0829C20006317A /* PBGitRevList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitRevList.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -188,6 +191,8 @@
|
||||
F56524EF0E02D45200F03B52 /* PBGitCommit.m */,
|
||||
F56174550E058893001DCD79 /* PBGitTree.h */,
|
||||
F56174560E058893001DCD79 /* PBGitTree.m */,
|
||||
F5FF4E160E0829C20006317A /* PBGitRevList.h */,
|
||||
F5FF4E170E0829C20006317A /* PBGitRevList.m */,
|
||||
);
|
||||
name = Git;
|
||||
sourceTree = "<group>";
|
||||
@@ -311,6 +316,7 @@
|
||||
F513085B0E0740F2000C8BCD /* PBQLOutlineView.m in Sources */,
|
||||
F5DFFA6C0E075D8800617813 /* PBEasyFS.m in Sources */,
|
||||
F50FE0E30E07BE9600854FCD /* PBGitRevisionCell.m in Sources */,
|
||||
F5FF4E180E0829C20006317A /* PBGitRevList.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
+3
-2
@@ -7,10 +7,11 @@
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "PBGitRevList.h"
|
||||
|
||||
@interface PBGitRepository : NSObject {
|
||||
NSString* path;
|
||||
NSArray* commits;
|
||||
PBGitRevList* revisionList;
|
||||
}
|
||||
|
||||
+ (void) setGitPath;
|
||||
@@ -24,6 +25,6 @@
|
||||
- (void) addCommit: (id)obj;
|
||||
|
||||
@property (copy) NSString* path;
|
||||
@property (retain) NSArray* commits;
|
||||
@property (readonly) PBGitRevList* revisionList;
|
||||
|
||||
@end
|
||||
|
||||
+22
-89
@@ -14,12 +14,30 @@
|
||||
|
||||
@implementation PBGitRepository
|
||||
|
||||
@synthesize path, commits;
|
||||
static NSString* gitPath = @"/usr/bin/env";
|
||||
@synthesize path;
|
||||
static NSString* gitPath;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
// Try to find the path of the Git binary
|
||||
char* path = getenv("GIT_PATH");
|
||||
if (path != nil) {
|
||||
gitPath = [NSString stringWithCString:path];
|
||||
return;
|
||||
}
|
||||
|
||||
// No explicit path. Try it with "which"
|
||||
gitPath = [PBEasyPipe outputForCommand:@"/usr/bin/which" withArgs:[NSArray arrayWithObject:@"git"]];
|
||||
|
||||
if (gitPath.length == 0) {
|
||||
NSLog(@"Git path not found. Defaulting to /opt/pieter/bin/git");
|
||||
gitPath = @"/opt/pieter/bin/git";
|
||||
}
|
||||
}
|
||||
|
||||
+ (PBGitRepository*) repositoryWithPath:(NSString*) path
|
||||
{
|
||||
[self setGitPath];
|
||||
|
||||
PBGitRepository* repo = [[PBGitRepository alloc] initWithPath: path];
|
||||
return repo;
|
||||
}
|
||||
@@ -37,96 +55,11 @@ static NSString* gitPath = @"/usr/bin/env";
|
||||
}
|
||||
|
||||
NSLog(@"Git path is: %@", self.path);
|
||||
|
||||
NSThread * commitThread = [[NSThread alloc] initWithTarget: self selector: @selector(initializeCommits) object:nil];
|
||||
[commitThread start];
|
||||
revisionList = [[PBGitRevList alloc] initWithRepository:self andRevListParameters:[NSArray array]];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ (void) setGitPath
|
||||
{
|
||||
char* path = getenv("GIT_PATH");
|
||||
if (path != nil) {
|
||||
gitPath = [NSString stringWithCString:path];
|
||||
return;
|
||||
}
|
||||
|
||||
// No explicit path. Try it with "which"
|
||||
gitPath = [PBEasyPipe outputForCommand:@"/usr/bin/which" withArgs:[NSArray arrayWithObject:@"git"]];
|
||||
|
||||
if (gitPath.length == 0) {
|
||||
NSLog(@"Git path not found. Defaulting to /opt/pieter/bin/git");
|
||||
gitPath = @"/opt/pieter/bin/git";
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addCommit: (id) obj
|
||||
{
|
||||
self.commits = [self.commits arrayByAddingObject:obj];
|
||||
}
|
||||
|
||||
- (void) setCommits:(NSArray*) obj
|
||||
{
|
||||
commits = obj;
|
||||
}
|
||||
|
||||
- (void) initializeCommits
|
||||
{
|
||||
|
||||
NSMutableArray * newArray = [NSMutableArray array];
|
||||
NSDate* start = [NSDate date];
|
||||
NSFileHandle* handle = [self handleForCommand:@"log --pretty=format:%H\01%an\01%s\01%P\01%at HEAD"];
|
||||
|
||||
int fd = [handle fileDescriptor];
|
||||
FILE* f = fdopen(fd, "r");
|
||||
int BUFFERSIZE = 2048;
|
||||
char buffer[BUFFERSIZE];
|
||||
buffer[BUFFERSIZE - 2] = 0;
|
||||
|
||||
char* l;
|
||||
int num = 0;
|
||||
NSMutableString* currentLine = [NSMutableString string];
|
||||
while (l = fgets(buffer, BUFFERSIZE, f)) {
|
||||
NSString *s = [NSString stringWithCString:(const char *)l encoding:NSUTF8StringEncoding];
|
||||
if ([s length] == 0)
|
||||
s = [NSString stringWithCString:(const char *)l encoding:NSASCIIStringEncoding];
|
||||
[currentLine appendString: s];
|
||||
|
||||
// If buffer is full, we go for another round
|
||||
if (buffer[BUFFERSIZE - 2] != 0) {
|
||||
//NSLog(@"Line too long!");
|
||||
buffer[BUFFERSIZE - 2] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we are here, we currentLine is a full line.
|
||||
NSArray* components = [currentLine componentsSeparatedByString:@"\01"];
|
||||
if ([components count] < 5) {
|
||||
NSLog(@"Can't split string: %@", currentLine);
|
||||
continue;
|
||||
}
|
||||
PBGitCommit* newCommit = [[PBGitCommit alloc] initWithRepository: self andSha: [components objectAtIndex:0]];
|
||||
NSArray* parents = [[components objectAtIndex:3] componentsSeparatedByString:@" "];
|
||||
newCommit.parents = parents;
|
||||
newCommit.subject = [components objectAtIndex:2];
|
||||
newCommit.author = [components objectAtIndex:1];
|
||||
newCommit.date = [NSDate dateWithTimeIntervalSince1970:[[components objectAtIndex:3] intValue]];
|
||||
|
||||
[newArray addObject: newCommit];
|
||||
num++;
|
||||
if (num % 10000 == 0)
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:NO];
|
||||
currentLine = [NSMutableString string];
|
||||
}
|
||||
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
|
||||
NSLog(@"Loaded %i commits in %f seconds", num, duration);
|
||||
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
- (NSFileHandle*) handleForArguments:(NSArray *)args
|
||||
{
|
||||
NSString* gitDirArg = [@"--git-dir=" stringByAppendingString:path];
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// PBGitRevList.h
|
||||
// GitX
|
||||
//
|
||||
// Created by Pieter de Bie on 17-06-08.
|
||||
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface PBGitRevList : NSObject {
|
||||
NSArray* commits;
|
||||
NSArray* parameters;
|
||||
id repository;
|
||||
}
|
||||
|
||||
- initWithRepository:(id)repo andRevListParameters:(NSArray*) params;
|
||||
|
||||
@property(retain) NSArray* commits;
|
||||
@end
|
||||
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// PBGitRevList.m
|
||||
// GitX
|
||||
//
|
||||
// Created by Pieter de Bie on 17-06-08.
|
||||
// Copyright 2008 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PBGitRevList.h"
|
||||
#import "PBGitRepository.h"
|
||||
#import "PBGitCommit.h"
|
||||
|
||||
@implementation PBGitRevList
|
||||
|
||||
@synthesize commits;
|
||||
- initWithRepository: (id) repo andRevListParameters: (NSArray*) params
|
||||
{
|
||||
parameters = params;
|
||||
repository = repo;
|
||||
NSThread * commitThread = [[NSThread alloc] initWithTarget: self selector: @selector(walkRevisionList) object:nil];
|
||||
[commitThread start];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) walkRevisionList
|
||||
{
|
||||
|
||||
NSMutableArray * newArray = [NSMutableArray array];
|
||||
NSDate* start = [NSDate date];
|
||||
NSFileHandle* handle = [repository handleForCommand:@"log --pretty=format:%H\01%an\01%s\01%P\01%at HEAD"];
|
||||
|
||||
int fd = [handle fileDescriptor];
|
||||
FILE* f = fdopen(fd, "r");
|
||||
int BUFFERSIZE = 2048;
|
||||
char buffer[BUFFERSIZE];
|
||||
buffer[BUFFERSIZE - 2] = 0;
|
||||
|
||||
char* l;
|
||||
int num = 0;
|
||||
NSMutableString* currentLine = [NSMutableString string];
|
||||
while (l = fgets(buffer, BUFFERSIZE, f)) {
|
||||
NSString *s = [NSString stringWithCString:(const char *)l encoding:NSUTF8StringEncoding];
|
||||
if ([s length] == 0)
|
||||
s = [NSString stringWithCString:(const char *)l encoding:NSASCIIStringEncoding];
|
||||
[currentLine appendString: s];
|
||||
|
||||
// If buffer is full, we go for another round
|
||||
if (buffer[BUFFERSIZE - 2] != 0) {
|
||||
//NSLog(@"Line too long!");
|
||||
buffer[BUFFERSIZE - 2] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we are here, we currentLine is a full line.
|
||||
NSArray* components = [currentLine componentsSeparatedByString:@"\01"];
|
||||
if ([components count] < 5) {
|
||||
NSLog(@"Can't split string: %@", currentLine);
|
||||
continue;
|
||||
}
|
||||
PBGitCommit* newCommit = [[PBGitCommit alloc] initWithRepository: repository andSha: [components objectAtIndex:0]];
|
||||
NSArray* parents = [[components objectAtIndex:3] componentsSeparatedByString:@" "];
|
||||
newCommit.parents = parents;
|
||||
newCommit.subject = [components objectAtIndex:2];
|
||||
newCommit.author = [components objectAtIndex:1];
|
||||
newCommit.date = [NSDate dateWithTimeIntervalSince1970:[[components objectAtIndex:3] intValue]];
|
||||
|
||||
[newArray addObject: newCommit];
|
||||
num++;
|
||||
if (num % 10000 == 0)
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:NO];
|
||||
currentLine = [NSMutableString string];
|
||||
}
|
||||
|
||||
[self performSelectorOnMainThread:@selector(setCommits:) withObject:newArray waitUntilDone:YES];
|
||||
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:start];
|
||||
NSLog(@"Loaded %i commits in %f seconds", num, duration);
|
||||
|
||||
[NSThread exit];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -65,7 +65,7 @@
|
||||
- (void) selectCommit: (NSString*) sha
|
||||
{
|
||||
NSPredicate* selection = [NSPredicate predicateWithFormat:@"sha == %@", sha];
|
||||
NSArray* selectedCommits = [controller.repository.commits filteredArrayUsingPredicate:selection];
|
||||
NSArray* selectedCommits = [controller.repository.revisionList.commits filteredArrayUsingPredicate:selection];
|
||||
// TODO: reimplement this. How can we set the new commit? Our detailscontroller is read-only
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user