diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index c0f7d62..331d554 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -73,6 +73,7 @@ D8E105471157C18200FC28A4 /* PBQLTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E105461157C18200FC28A4 /* PBQLTextView.m */; }; D8E3B2B810DC9FB2001096A3 /* ScriptingBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E3B2B710DC9FB2001096A3 /* ScriptingBridge.framework */; }; D8E3B34D10DCA958001096A3 /* PBCreateTagSheet.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */; }; + D8FBCF19115FA20C0098676A /* PBGitSHA.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FBCF18115FA20C0098676A /* PBGitSHA.m */; }; D8FDD9F711432A12005647F6 /* PBCloneRepositoryPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = D8FDD9F511432A12005647F6 /* PBCloneRepositoryPanel.xib */; }; D8FDDA6A114335E8005647F6 /* PBGitSVBranchItem.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FDDA5D114335E8005647F6 /* PBGitSVBranchItem.m */; }; D8FDDA6B114335E8005647F6 /* PBGitSVFolderItem.m in Sources */ = {isa = PBXBuildFile; fileRef = D8FDDA5F114335E8005647F6 /* PBGitSVFolderItem.m */; }; @@ -293,6 +294,8 @@ D8E3B34B10DCA958001096A3 /* PBCreateTagSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBCreateTagSheet.h; sourceTree = ""; }; D8E3B34C10DCA958001096A3 /* PBCreateTagSheet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBCreateTagSheet.m; sourceTree = ""; }; D8E3B38110DD4E2C001096A3 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBCreateTagSheet.xib; sourceTree = ""; }; + D8FBCF17115FA20C0098676A /* PBGitSHA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSHA.h; sourceTree = ""; }; + D8FBCF18115FA20C0098676A /* PBGitSHA.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSHA.m; sourceTree = ""; }; D8FDD9F611432A12005647F6 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PBCloneRepositoryPanel.xib; sourceTree = ""; }; D8FDDA5C114335E8005647F6 /* PBGitSVBranchItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBGitSVBranchItem.h; sourceTree = ""; }; D8FDDA5D114335E8005647F6 /* PBGitSVBranchItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBGitSVBranchItem.m; sourceTree = ""; }; @@ -828,6 +831,8 @@ F56524EF0E02D45200F03B52 /* PBGitCommit.m */, F5C007730E731B48007B84B2 /* PBGitRef.h */, F5C007740E731B48007B84B2 /* PBGitRef.m */, + D8FBCF17115FA20C0098676A /* PBGitSHA.h */, + D8FBCF18115FA20C0098676A /* PBGitSHA.m */, D8295D281130A1DC00C838E8 /* PBGitHistoryList.h */, D8295D291130A1DC00C838E8 /* PBGitHistoryList.m */, F5FF4E160E0829C20006317A /* PBGitRevList.h */, @@ -1175,6 +1180,7 @@ D8295D2A1130A1DC00C838E8 /* PBGitHistoryList.m in Sources */, D8295DE01130E43900C838E8 /* PBGitHistoryGrapher.m in Sources */, D8E105471157C18200FC28A4 /* PBQLTextView.m in Sources */, + D8FBCF19115FA20C0098676A /* PBGitSHA.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PBGitCommit.h b/PBGitCommit.h index 9e4da8d..e77ee32 100644 --- a/PBGitCommit.h +++ b/PBGitCommit.h @@ -10,23 +10,21 @@ #import "PBGitRepository.h" #import "PBGitTree.h" #import "PBGitRefish.h" -#include "git/oid.h" +#import "PBGitSHA.h" extern NSString * const kGitXCommitType; @interface PBGitCommit : NSObject { - git_oid sha; - git_oid *parentShas; - int nParents; + PBGitSHA *sha; NSString* subject; NSString* author; NSString *committer; NSString* details; NSString *_patch; - NSArray* parents; + NSArray *parents; NSString *realSHA; int timestamp; @@ -35,8 +33,8 @@ extern NSString * const kGitXCommitType; PBGitRepository* repository; } -+ (id) commitWithRepository:(PBGitRepository*)repo andSha:(git_oid)newSha; -- (id) initWithRepository:(PBGitRepository *)repo andSha:(git_oid)sha; ++ (PBGitCommit *)commitWithRepository:(PBGitRepository*)repo andSha:(PBGitSHA *)newSha; +- (id)initWithRepository:(PBGitRepository *)repo andSha:(PBGitSHA *)newSha; - (void) addRef:(PBGitRef *)ref; - (void) removeRef:(id)ref; @@ -51,14 +49,13 @@ extern NSString * const kGitXCommitType; - (NSString *) shortName; - (NSString *) refishType; -@property (readonly) git_oid *sha; +@property (readonly) PBGitSHA *sha; @property (copy) NSString* subject; @property (copy) NSString* author; @property (copy) NSString *committer; -@property (readonly) NSArray* parents; // TODO: remove this and its uses +@property (retain) NSArray *parents; -@property (assign) git_oid *parentShas; -@property (assign) int nParents, timestamp; +@property (assign) int timestamp; @property (retain) NSMutableArray* refs; @property (readonly) NSDate *date; diff --git a/PBGitCommit.m b/PBGitCommit.m index 6bb9d56..ac2bd1f 100644 --- a/PBGitCommit.m +++ b/PBGitCommit.m @@ -7,6 +7,7 @@ // #import "PBGitCommit.h" +#import "PBGitSHA.h" #import "PBGitDefaults.h" @@ -15,24 +16,11 @@ NSString * const kGitXCommitType = @"commit"; @implementation PBGitCommit -@synthesize repository, subject, timestamp, author, parentShas, nParents, sign, lineInfo; +@synthesize repository, subject, timestamp, author, sign, lineInfo; +@synthesize sha; +@synthesize parents; @synthesize committer; -- (NSArray *) parents -{ - if (nParents == 0) - return NULL; - - int i; - NSMutableArray *p = [NSMutableArray arrayWithCapacity:nParents]; - for (i = 0; i < nParents; ++i) - { - char *s = git_oid_mkhex(parentShas + i); - [p addObject:[NSString stringWithUTF8String:s]]; - free(s); - } - return p; -} - (NSDate *)date { @@ -50,17 +38,12 @@ NSString * const kGitXCommitType = @"commit"; return self.tree.children; } -- (git_oid *)sha ++ (PBGitCommit *)commitWithRepository:(PBGitRepository*)repo andSha:(PBGitSHA *)newSha { - return &sha; + return [[self alloc] initWithRepository:repo andSha:newSha]; } -+ commitWithRepository:(PBGitRepository*)repo andSha:(git_oid)newSha -{ - return [[[self alloc] initWithRepository:repo andSha:newSha] autorelease]; -} - -- initWithRepository:(PBGitRepository*) repo andSha:(git_oid)newSha +- (id)initWithRepository:(PBGitRepository*) repo andSha:(PBGitSHA *)newSha { details = nil; repository = repo; @@ -70,27 +53,18 @@ NSString * const kGitXCommitType = @"commit"; - (NSString *)realSha { - if (!realSHA) { - char *hex = git_oid_mkhex(&sha); - realSHA = [NSString stringWithUTF8String:hex]; - free(hex); - } - - return realSHA; + return sha.string; } -- (BOOL) isOnSameBranchAs:(PBGitCommit *)other +- (BOOL) isOnSameBranchAs:(PBGitCommit *)otherCommit { - if (!other) + if (!otherCommit) return NO; - NSString *mySHA = [self realSha]; - NSString *otherSHA = [other realSha]; - - if ([otherSHA isEqualToString:mySHA]) + if ([self isEqual:otherCommit]) return YES; - return [repository isOnSameBranch:otherSHA asSHA:mySHA]; + return [repository isOnSameBranch:otherCommit.sha asSHA:self.sha]; } - (BOOL) isOnHeadBranch @@ -98,6 +72,19 @@ NSString * const kGitXCommitType = @"commit"; return [self isOnSameBranchAs:[repository headCommit]]; } +- (BOOL)isEqual:(id)otherCommit +{ + if (![otherCommit isMemberOfClass:[PBGitCommit class]]) + return NO; + + return [self.sha isEqual:[(PBGitCommit *)otherCommit sha]]; +} + +- (NSUInteger)hash +{ + return [self.sha hash]; +} + // FIXME: Remove this method once it's unused. - (NSString*) details { @@ -150,17 +137,16 @@ NSString * const kGitXCommitType = @"commit"; - (NSMutableArray *)refs { - return [[repository refs] objectForKey:[self realSha]]; + return [[repository refs] objectForKey:[self sha]]; } - (void) setRefs:(NSMutableArray *)refs { - [[repository refs] setObject:refs forKey:[self realSha]]; + [[repository refs] setObject:refs forKey:[self sha]]; } - (void)finalize { - free(parentShas); [super finalize]; } diff --git a/PBGitGrapher.mm b/PBGitGrapher.mm index f9daf84..abd6327 100644 --- a/PBGitGrapher.mm +++ b/PBGitGrapher.mm @@ -39,8 +39,10 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in int i = 0, newPos = -1; std::list *currentLanes = new std::list; std::list *previousLanes = (std::list *)pl; + NSArray *parents = [commit parents]; + int nParents = [parents count]; - int maxLines = (previousLanes->size() + commit.nParents + 2) * 2; + int maxLines = (previousLanes->size() + nParents + 2) * 2; struct PBGitGraphLine *lines = (struct PBGitGraphLine *)malloc(sizeof(struct PBGitGraphLine) * maxLines); int currentLine = 0; @@ -55,14 +57,14 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in i++; // This is our commit! We should do a "merge": move the line from // our upperMapping to their lowerMapping - if ((*it)->isCommit([commit sha])) { + if ((*it)->isCommit([[commit sha] oid])) { if (!didFirst) { didFirst = YES; currentLanes->push_back(*it); currentLane = currentLanes->back(); newPos = currentLanes->size(); add_line(lines, ¤tLine, 1, i, newPos,(*it)->index()); - if (commit.nParents) + if (nParents) add_line(lines, ¤tLine, 0, newPos, newPos,(*it)->index()); } else { @@ -84,8 +86,9 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in //Add your own parents // If we already did the first parent, don't do so again - if (!didFirst && currentLanes->size() < MAX_LANES && commit.nParents) { - PBGitLane *newLane = new PBGitLane(commit.parentShas); + if (!didFirst && currentLanes->size() < MAX_LANES && nParents) { + git_oid parentOID = [[parents objectAtIndex:0] oid]; + PBGitLane *newLane = new PBGitLane(&parentOID); currentLanes->push_back(newLane); newPos = currentLanes->size(); add_line(lines, ¤tLine, 0, newPos, newPos, newLane->index()); @@ -97,15 +100,15 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in // This boolean will tell us if that happened BOOL addedParent = NO; - int parentIndex; - for (parentIndex = 1; parentIndex < commit.nParents; ++parentIndex) { - git_oid *parent = commit.parentShas + parentIndex; + int parentIndex = 0; + for (parentIndex = 1; parentIndex < nParents; ++parentIndex) { + git_oid parentOID = [[parents objectAtIndex:parentIndex] oid]; int i = 0; BOOL was_displayed = NO; std::list::iterator it = currentLanes->begin(); for (; it != currentLanes->end(); ++it) { i++; - if ((*it)->isCommit(parent)) { + if ((*it)->isCommit(parentOID)) { add_line(lines, ¤tLine, 0, i, newPos,(*it)->index()); was_displayed = YES; break; @@ -119,7 +122,7 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in // Really add this parent addedParent = YES; - PBGitLane *newLane = new PBGitLane(parent); + PBGitLane *newLane = new PBGitLane(&parentOID); currentLanes->push_back(newLane); add_line(lines, ¤tLine, 0, currentLanes->size(), newPos, newLane->index()); } @@ -138,8 +141,8 @@ void add_line(struct PBGitGraphLine *lines, int *nLines, int upper, int from, in previous.numColumns = currentLanes->size(); // Update the current lane to point to the new parent - if (currentLane && commit.nParents > 0) - currentLane->setSha(commit.parentShas[0]); + if (currentLane && nParents > 0) + currentLane->setSha([[parents objectAtIndex:0] oid]); else currentLanes->remove(currentLane); diff --git a/PBGitHistoryController.h b/PBGitHistoryController.h index 3c92168..6489930 100644 --- a/PBGitHistoryController.h +++ b/PBGitHistoryController.h @@ -17,6 +17,7 @@ @class PBRefController; @class QLPreviewPanel; @class PBCommitList; +@class PBGitSHA; @interface PBGitHistoryController : PBViewController { IBOutlet PBRefController *refController; @@ -58,7 +59,7 @@ - (IBAction) setTreeView:(id)sender; - (IBAction) setBranchFilter:(id)sender; -- (void) selectCommit: (NSString*) commit; +- (void)selectCommit:(PBGitSHA *)commit; - (IBAction) refresh:(id)sender; - (IBAction) toggleQLPreviewPanel:(id)sender; - (IBAction) openSelectedFile:(id)sender; diff --git a/PBGitHistoryController.m b/PBGitHistoryController.m index 9e0fafb..9d5a428 100644 --- a/PBGitHistoryController.m +++ b/PBGitHistoryController.m @@ -236,7 +236,7 @@ if ([repository.currentBranch isSimpleRef]) [self selectCommit:[repository shaForRef:[repository.currentBranch ref]]]; else - [self selectCommit:[[self firstCommit] realSha]]; + [self selectCommit:[[self firstCommit] sha]]; return; } @@ -385,9 +385,9 @@ commitList.useAdjustScroll = NO; } -- (NSArray *) selectedObjectsForSHA:(NSString *)commitSHA +- (NSArray *) selectedObjectsForSHA:(PBGitSHA *)commitSHA { - NSPredicate *selection = [NSPredicate predicateWithFormat:@"realSha == %@", commitSHA]; + NSPredicate *selection = [NSPredicate predicateWithFormat:@"sha == %@", commitSHA]; NSArray *selectedCommits = [[commitController content] filteredArrayUsingPredicate:selection]; if (([selectedCommits count] == 0) && [self firstCommit]) @@ -396,9 +396,9 @@ return selectedCommits; } -- (void) selectCommit:(NSString *)commitSHA +- (void)selectCommit:(PBGitSHA *)commitSHA { - if (!forceSelectionUpdate && [[selectedCommit realSha] isEqualToString:commitSHA]) + if (!forceSelectionUpdate && [[selectedCommit sha] isEqual:commitSHA]) return; NSInteger oldIndex = [[commitController selectionIndexes] firstIndex]; @@ -521,7 +521,7 @@ PBGitRef *headRef = [[repository headRef] ref]; NSString *headRefName = [headRef shortName]; NSString *diffTitle = [NSString stringWithFormat:@"Diff %@ with %@", multiple ? @"files" : @"file", headRefName]; - BOOL isHead = [[selectedCommit realSha] isEqualToString:[repository headSHA]]; + BOOL isHead = [[selectedCommit sha] isEqual:[repository headSHA]]; NSMenuItem *diffItem = [[NSMenuItem alloc] initWithTitle:diffTitle action:isHead ? nil : @selector(diffFilesAction:) keyEquivalent:@""]; diff --git a/PBGitHistoryGrapher.m b/PBGitHistoryGrapher.m index 4769950..891d342 100644 --- a/PBGitHistoryGrapher.m +++ b/PBGitHistoryGrapher.m @@ -8,6 +8,7 @@ #import "PBGitHistoryGrapher.h" #import "PBGitGrapher.h" +#import "PBGitSHA.h" @implementation PBGitHistoryGrapher @@ -41,13 +42,13 @@ NSInteger counter = 0; for (PBGitCommit *commit in revList) { - NSString *commitSHA = [commit realSha]; + PBGitSHA *commitSHA = [commit sha]; if (viewAllBranches || [searchSHAs containsObject:commitSHA]) { [grapher decorateCommit:commit]; [commits addObject:commit]; if (!viewAllBranches) { [searchSHAs removeObject:commitSHA]; - [searchSHAs addObjectsFromArray:commit.parents]; + [searchSHAs addObjectsFromArray:[commit parents]]; } } if (++counter % 2000 == 0) { diff --git a/PBGitHistoryList.h b/PBGitHistoryList.h index 93fdcd3..9f00a66 100644 --- a/PBGitHistoryList.h +++ b/PBGitHistoryList.h @@ -14,6 +14,7 @@ @class PBGitRef; @class PBGitRevList; @class PBGitHistoryGrapher; +@class PBGitSHA; @interface PBGitHistoryList : NSObject { PBGitRepository *repository; @@ -21,7 +22,7 @@ PBGitRevList *projectRevList; PBGitRevList *currentRevList; - NSString *lastSHA; + PBGitSHA *lastSHA; NSSet *lastRefSHAs; NSInteger lastBranchFilter; PBGitRef *lastRemoteRef; diff --git a/PBGitHistoryList.m b/PBGitHistoryList.m index 59cb3c4..017a757 100644 --- a/PBGitHistoryList.m +++ b/PBGitHistoryList.m @@ -11,6 +11,7 @@ #import "PBGitRevList.h" #import "PBGitGrapher.h" #import "PBGitHistoryGrapher.h" +#import "PBGitSHA.h" @@ -158,7 +159,7 @@ NSMutableSet *baseCommitSHAs = [NSMutableSet set]; NSDictionary *refs = repository.refs; - for (NSString *sha in refs) + for (PBGitSHA *sha in refs) for (PBGitRef *ref in [refs objectForKey:sha]) if ([ref isBranch] || [ref isTag]) [baseCommitSHAs addObject:sha]; @@ -177,7 +178,7 @@ PBGitRef *remoteRef = [[repository.currentBranch ref] remoteRef]; - for (NSString *sha in refs) + for (PBGitSHA *sha in refs) for (PBGitRef *ref in [refs objectForKey:sha]) if ([remoteRef isEqualToRef:[ref remoteRef]]) [baseCommitSHAs addObject:sha]; @@ -193,7 +194,7 @@ return [NSMutableSet setWithObject:lastSHA]; else if ([repository.currentBranch isSimpleRef]) { PBGitRef *currentRef = [repository.currentBranch ref]; - NSString *sha = [repository shaForRef:currentRef]; + PBGitSHA *sha = [repository shaForRef:currentRef]; if (sha) return [NSMutableSet setWithObject:sha]; } @@ -267,8 +268,8 @@ return NO; } - NSString *revSHA = [repository shaForRef:[rev ref]]; - if ([revSHA isEqualToString:lastSHA] && (lastBranchFilter == repository.currentBranchFilter)) + PBGitSHA *revSHA = [repository shaForRef:[rev ref]]; + if ([revSHA isEqual:lastSHA] && (lastBranchFilter == repository.currentBranchFilter)) return NO; lastBranchFilter = repository.currentBranchFilter; @@ -341,6 +342,7 @@ - (void) removeObservers { [repository removeObserver:self forKeyPath:@"currentBranch"]; + [repository removeObserver:self forKeyPath:@"currentBranchFilter"]; [repository removeObserver:self forKeyPath:@"hasChanged"]; if (currentRevList) { diff --git a/PBGitLane.h b/PBGitLane.h index 57d59c8..94b59a2 100644 --- a/PBGitLane.h +++ b/PBGitLane.h @@ -33,9 +33,9 @@ public: d_index = s_colorIndex++; } - bool isCommit(git_oid *sha) const + bool isCommit(git_oid sha) const { - return !git_oid_cmp(&d_sha, sha); + return !git_oid_cmp(&d_sha, &sha); } void setSha(git_oid sha); diff --git a/PBGitRepository.h b/PBGitRepository.h index 0236a06..25176cd 100644 --- a/PBGitRepository.h +++ b/PBGitRepository.h @@ -38,6 +38,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { @class PBGitWindowController; @class PBGitCommit; +@class PBGitSHA; @interface PBGitRepository : NSDocument { PBGitHistoryList* revisionList; @@ -50,7 +51,7 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { NSMutableDictionary *refs; PBGitRevSpecifier *_headRef; // Caching - NSString* _headSha; + PBGitSHA* _headSha; } - (void) cloneRepositoryToPath:(NSString *)path bare:(BOOL)isBare; @@ -92,17 +93,17 @@ static NSString * PBStringFromBranchFilterType(PBGitXBranchFilterType type) { - (void) reloadRefs; - (void) addRef:(PBGitRef *)ref fromParameters:(NSArray *)params; - (void) lazyReload; -- (PBGitRevSpecifier*) headRef; -- (NSString *) headSHA; -- (PBGitCommit *) headCommit; -- (NSString *) shaForRef:(PBGitRef *)ref; -- (PBGitCommit *) commitForRef:(PBGitRef *)ref; -- (PBGitCommit *) commitForSHA:(NSString *)sha; -- (BOOL) isOnSameBranch:(NSString *)baseSHA asSHA:(NSString *)testSHA; -- (BOOL) isSHAOnHeadBranch:(NSString *)testSHA; -- (BOOL) isRefOnHeadBranch:(PBGitRef *)testRef; -- (BOOL) checkRefFormat:(NSString *)refName; -- (BOOL) refExists:(PBGitRef *)ref; +- (PBGitRevSpecifier*)headRef; +- (PBGitSHA *)headSHA; +- (PBGitCommit *)headCommit; +- (PBGitSHA *)shaForRef:(PBGitRef *)ref; +- (PBGitCommit *)commitForRef:(PBGitRef *)ref; +- (PBGitCommit *)commitForSHA:(PBGitSHA *)sha; +- (BOOL)isOnSameBranch:(PBGitSHA *)baseSHA asSHA:(PBGitSHA *)testSHA; +- (BOOL)isSHAOnHeadBranch:(PBGitSHA *)testSHA; +- (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef; +- (BOOL)checkRefFormat:(NSString *)refName; +- (BOOL)refExists:(PBGitRef *)ref; - (NSArray *) remotes; - (BOOL) hasRemotes; diff --git a/PBGitRepository.m b/PBGitRepository.m index f401aa6..f9f9175 100644 --- a/PBGitRepository.m +++ b/PBGitRepository.m @@ -218,11 +218,11 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; { NSString* type = [components objectAtIndex:1]; - NSString* sha; + PBGitSHA *sha; if ([type isEqualToString:@"tag"] && [components count] == 4) - sha = [components objectAtIndex:3]; + sha = [PBGitSHA shaWithString:[components objectAtIndex:3]]; else - sha = [components objectAtIndex:2]; + sha = [PBGitSHA shaWithString:[components objectAtIndex:2]]; NSMutableArray* curRefs; if (curRefs = [refs objectForKey:sha]) @@ -293,7 +293,7 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; return _headRef; } -- (NSString *) headSHA +- (PBGitSHA *)headSHA { if (! _headSha) [self headRef]; @@ -301,17 +301,17 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; return _headSha; } -- (PBGitCommit *) headCommit +- (PBGitCommit *)headCommit { return [self commitForSHA:[self headSHA]]; } -- (NSString *) shaForRef:(PBGitRef *)ref +- (PBGitSHA *)shaForRef:(PBGitRef *)ref { if (!ref) return nil; - for (NSString *sha in refs) + for (PBGitSHA *sha in refs) for (PBGitRef *existingRef in [refs objectForKey:sha]) if ([existingRef isEqualToRef:ref]) return sha; @@ -322,10 +322,10 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; if (retValue || [shaForRef isEqualToString:@""]) return nil; - return shaForRef; + return [PBGitSHA shaWithString:shaForRef]; } -- (PBGitCommit *) commitForRef:(PBGitRef *)ref +- (PBGitCommit *)commitForRef:(PBGitRef *)ref { if (!ref) return nil; @@ -333,7 +333,7 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; return [self commitForSHA:[self shaForRef:ref]]; } -- (PBGitCommit *) commitForSHA:(NSString *)sha +- (PBGitCommit *)commitForSHA:(PBGitSHA *)sha { if (!sha) return nil; @@ -344,18 +344,18 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; revList = revisionList.projectCommits; } for (PBGitCommit *commit in revList) - if ([[commit realSha] isEqualToString:sha]) + if ([[commit sha] isEqual:sha]) return commit; return nil; } -- (BOOL) isOnSameBranch:(NSString *)branchSHA asSHA:(NSString *)testSHA +- (BOOL)isOnSameBranch:(PBGitSHA *)branchSHA asSHA:(PBGitSHA *)testSHA { if (!branchSHA || !testSHA) return NO; - if ([testSHA isEqualToString:branchSHA]) + if ([testSHA isEqual:branchSHA]) return YES; NSArray *revList = revisionList.projectCommits; @@ -363,34 +363,34 @@ NSString* PBGitRepositoryErrorDomain = @"GitXErrorDomain"; NSMutableSet *searchSHAs = [NSMutableSet setWithObject:branchSHA]; for (PBGitCommit *commit in revList) { - NSString *commitSHA = [commit realSha]; + PBGitSHA *commitSHA = [commit sha]; if ([searchSHAs containsObject:commitSHA]) { - if ([testSHA isEqualToString:commitSHA]) + if ([testSHA isEqual:commitSHA]) return YES; [searchSHAs removeObject:commitSHA]; [searchSHAs addObjectsFromArray:commit.parents]; } - else if ([testSHA isEqualToString:commitSHA]) + else if ([testSHA isEqual:commitSHA]) return NO; } return NO; } -- (BOOL) isSHAOnHeadBranch:(NSString *)testSHA +- (BOOL)isSHAOnHeadBranch:(PBGitSHA *)testSHA { if (!testSHA) return NO; - NSString *headSHA = [self headSHA]; + PBGitSHA *headSHA = [self headSHA]; - if ([testSHA isEqualToString:headSHA]) + if ([testSHA isEqual:headSHA]) return YES; return [self isOnSameBranch:headSHA asSHA:testSHA]; } -- (BOOL) isRefOnHeadBranch:(PBGitRef *)testRef +- (BOOL)isRefOnHeadBranch:(PBGitRef *)testRef { if (!testRef) return NO; diff --git a/PBGitRevList.mm b/PBGitRevList.mm index 4a033fb..ea0933d 100644 --- a/PBGitRevList.mm +++ b/PBGitRevList.mm @@ -12,7 +12,6 @@ #import "PBGitGrapher.h" #import "PBGitRevSpecifier.h" -#include "git/oid.h" #include #include #include @@ -140,7 +139,7 @@ using namespace std; git_oid oid; git_oid_mkstr(&oid, sha.c_str()); - PBGitCommit* newCommit = [[PBGitCommit alloc] initWithRepository:repository andSha:oid]; + PBGitCommit *newCommit = [PBGitCommit commitWithRepository:repository andSha:[PBGitSHA shaWithOID:oid]]; string author; getline(stream, author, '\1'); @@ -160,13 +159,12 @@ using namespace std; continue; } int nParents = (parentString.size() + 1) / 41; - git_oid *parents = (git_oid *)malloc(sizeof(git_oid) * nParents); + NSMutableArray *parents = [NSMutableArray arrayWithCapacity:nParents]; int parentIndex; for (parentIndex = 0; parentIndex < nParents; ++parentIndex) - git_oid_mkstr(parents + parentIndex, parentString.substr(parentIndex * 41, 40).c_str()); - - newCommit.parentShas = parents; - newCommit.nParents = nParents; + [parents addObject:[PBGitSHA shaWithCString:parentString.substr(parentIndex * 41, 40).c_str()]]; + + [newCommit setParents:parents]; } int time; diff --git a/PBGitRevisionCell.m b/PBGitRevisionCell.m index abbf29c..17e5b16 100644 --- a/PBGitRevisionCell.m +++ b/PBGitRevisionCell.m @@ -59,12 +59,12 @@ - (BOOL) isCurrentCommit { - NSString* thisSha = [self.objectValue realSha]; + PBGitSHA *thisSha = [self.objectValue sha]; PBGitRepository* repository = [self.objectValue repository]; - NSString* currentSha = [repository headSHA]; + PBGitSHA *currentSha = [repository headSHA]; - return [ currentSha isEqualToString : thisSha ]; + return [currentSha isEqual:thisSha]; } - (void) drawCircleInRect: (NSRect) r diff --git a/PBGitSHA.h b/PBGitSHA.h new file mode 100644 index 0000000..f222911 --- /dev/null +++ b/PBGitSHA.h @@ -0,0 +1,28 @@ +// +// PBGitSHA.h +// GitX +// +// Created by BrotherBard on 3/28/10. +// Copyright 2010 BrotherBard. All rights reserved. +// + +#import +#include "git/oid.h" + + +@interface PBGitSHA : NSObject { + git_oid oid; + NSString *string; +} + + ++ (PBGitSHA *)shaWithOID:(git_oid)oid; ++ (PBGitSHA *)shaWithString:(NSString *)shaString; ++ (PBGitSHA *)shaWithCString:(const char *)shaCString; + +- (BOOL)isEqualToOID:(git_oid)other_oid; + +@property (readonly) git_oid oid; +@property (readonly) NSString *string; + +@end diff --git a/PBGitSHA.m b/PBGitSHA.m new file mode 100644 index 0000000..6aff86f --- /dev/null +++ b/PBGitSHA.m @@ -0,0 +1,139 @@ +// +// PBGitSHA.m +// GitX +// +// Created by BrotherBard on 3/28/10. +// Copyright 2010 BrotherBard. All rights reserved. +// + +#import "PBGitSHA.h" + + +@interface PBGitSHA () + +- (id)initWithOID:(git_oid)g_oid; + +@end + + +@implementation PBGitSHA + + +@synthesize oid; +@synthesize string; + + ++ (PBGitSHA *)shaWithOID:(git_oid)oid +{ + return [[PBGitSHA alloc] initWithOID:oid]; +} + + ++ (PBGitSHA *)shaWithString:(NSString *)shaString +{ + git_oid oid; + int err = git_oid_mkstr(&oid, [shaString UTF8String]); + if (err == GIT_ENOTOID) + return nil; + + return [self shaWithOID:oid]; +} + + ++ (PBGitSHA *)shaWithCString:(const char *)shaCString +{ + git_oid oid; + int err = git_oid_mkstr(&oid, shaCString); + if (err == GIT_ENOTOID) + return nil; + + return [self shaWithOID:oid]; +} + + ++ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector +{ + return NO; +} + + ++ (BOOL)isKeyExcludedFromWebScript:(const char *)name +{ + return NO; +} + + + +#pragma mark - +#pragma mark PBGitSHA + +- (id)initWithOID:(git_oid)g_oid +{ + self = [super init]; + if (!self) + return nil; + + oid = g_oid; + + return self; +} + + +- (NSString *)string +{ + if (!string) { + char *hex = git_oid_mkhex(&oid); + if (hex == NULL) + return nil; + string = [NSString stringWithUTF8String:hex]; + free(hex); + } + + return string; +} + + +- (BOOL)isEqual:(id)otherSHA +{ + if (self == otherSHA) + return YES; + + git_oid other_oid = [(PBGitSHA *)otherSHA oid]; + return git_oid_cmp(&oid, &other_oid) == 0; +} + + +- (BOOL)isEqualToOID:(git_oid)other_oid +{ + return git_oid_cmp(&oid, &other_oid) == 0; +} + + +- (NSUInteger)hash +{ + NSUInteger hash; + memcpy(&hash, &(oid.id), sizeof(NSUInteger)); + + return hash; +} + + +- (NSString *)description +{ + return [self string]; +} + + + +#pragma mark + +- (id)copyWithZone:(NSZone *)zone +{ + git_oid oidCopy; + git_oid_cpy(&oidCopy, &oid); + PBGitSHA *copy = [[[self class] allocWithZone:zone] initWithOID:oidCopy]; + + return copy; +} + +@end diff --git a/PBRefMenuItem.m b/PBRefMenuItem.m index 8a571d5..e7b7c0b 100644 --- a/PBRefMenuItem.m +++ b/PBRefMenuItem.m @@ -145,7 +145,7 @@ NSString *headBranchName = [[[commit.repository headRef] ref] shortName]; BOOL isOnHeadBranch = [commit isOnHeadBranch]; - BOOL isHead = [[commit realSha] isEqualToString:[commit.repository headSHA]]; + BOOL isHead = [[commit sha] isEqual:[commit.repository headSHA]]; [items addObject:[PBRefMenuItem itemWithTitle:@"Checkout Commit" action:@selector(checkout:) enabled:YES]]; [items addObject:[PBRefMenuItem separatorItem]]; diff --git a/PBWebHistoryController.h b/PBWebHistoryController.h index 749725a..f42a42e 100644 --- a/PBWebHistoryController.h +++ b/PBWebHistoryController.h @@ -13,11 +13,15 @@ #import "PBGitHistoryController.h" #import "PBRefContextDelegate.h" + +@class PBGitSHA; + + @interface PBWebHistoryController : PBWebController { IBOutlet PBGitHistoryController* historyController; IBOutlet id contextMenuDelegate; - NSString* currentSha; + PBGitSHA* currentSha; NSString* diff; } diff --git a/PBWebHistoryController.m b/PBWebHistoryController.m index 08279cf..f0c533d 100644 --- a/PBWebHistoryController.m +++ b/PBWebHistoryController.m @@ -8,6 +8,7 @@ #import "PBWebHistoryController.h" #import "PBGitDefaults.h" +#import "PBGitSHA.h" @implementation PBWebHistoryController @@ -23,7 +24,7 @@ - (void) didLoad { - currentSha = @""; + currentSha = nil; [self changeContentTo: historyController.webCommit]; } @@ -41,7 +42,7 @@ return; // The sha is the same, but refs may have changed.. reload it lazy - if ([currentSha isEqualToString: [content realSha]]) + if ([currentSha isEqual:[content sha]]) { [[self script] callWebScriptMethod:@"reload" withArguments: nil]; return; @@ -54,13 +55,13 @@ [self performSelector:_cmd withObject:content afterDelay:0.05]; return; } - currentSha = [content realSha]; + currentSha = [content sha]; // 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]; + NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", [currentSha string], nil]; if (![PBGitDefaults showWhitespaceDifferences]) [taskArguments insertObject:@"-w" atIndex:1]; @@ -90,9 +91,9 @@ [[view windowScriptObject] callWebScriptMethod:@"loadCommitDetails" withArguments:[NSArray arrayWithObject:details]]; } -- (void) selectCommit: (NSString*) sha +- (void)selectCommit:(NSString *)sha { - [historyController selectCommit:sha]; + [historyController selectCommit:[PBGitSHA shaWithString:sha]]; } - (void) sendKey: (NSString*) key diff --git a/html/views/history/history.js b/html/views/history/history.js index 4c9db52..c90c0c2 100644 --- a/html/views/history/history.js +++ b/html/views/history/history.js @@ -209,7 +209,7 @@ var loadCommit = function(commitObject, currentRef) { var newRow = $("commit_header").insertRow(-1); newRow.innerHTML = "Parent:" + "" + - commit.parents[i] + ""; + commit.parents[i].string + ""; } commit.notificationID = setTimeout(function() {