Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OIDs for ahead/behind count and enumeration #450

Merged
merged 3 commits into from
Mar 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ObjectiveGit/GTBranch.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef NS_ENUM(NSInteger, GTBranchType) {

@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly) NSString *shortName;
@property (nonatomic, readonly) NSString *SHA;
@property (nonatomic, copy, readonly) GTOID *OID;
@property (nonatomic, readonly) NSString *remoteName;
@property (nonatomic, readonly) GTBranchType branchType;
@property (nonatomic, readonly, strong) GTRepository *repository;
Expand Down
55 changes: 15 additions & 40 deletions ObjectiveGit/GTBranch.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
//

#import "GTBranch.h"
#import "GTReference.h"
#import "GTEnumerator.h"
#import "GTRepository.h"

#import "GTCommit.h"
#import "GTEnumerator.h"
#import "GTOID.h"
#import "GTReference.h"
#import "GTRemote.h"
#import "GTRepository.h"
#import "NSError+Git.h"

#import "git2/branch.h"
Expand All @@ -38,18 +40,18 @@
@implementation GTBranch

- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p> name: %@, shortName: %@, sha: %@, remoteName: %@, repository: %@", NSStringFromClass([self class]), self, self.name, self.shortName, self.SHA, self.remoteName, self.repository];
return [NSString stringWithFormat:@"<%@: %p> name: %@, shortName: %@, sha: %@, remoteName: %@, repository: %@", NSStringFromClass([self class]), self, self.name, self.shortName, self.OID, self.remoteName, self.repository];
}

- (BOOL)isEqual:(GTBranch *)otherBranch {
if (otherBranch == self) return YES;
if (![otherBranch isKindOfClass:self.class]) return NO;

return [self.name isEqual:otherBranch.name] && [self.SHA isEqual:otherBranch.SHA];
return [self.name isEqual:otherBranch.name] && [self.OID isEqual:otherBranch.OID];
}

- (NSUInteger)hash {
return self.name.hash ^ self.SHA.hash;
return self.name.hash ^ self.OID.hash;
}


Expand Down Expand Up @@ -100,8 +102,8 @@ - (NSString *)shortName {
return @(name);
}

- (NSString *)SHA {
return self.reference.targetSHA;
- (GTOID *)OID {
return self.reference.targetOID;
}

- (NSString *)remoteName {
Expand All @@ -119,19 +121,19 @@ - (NSString *)remoteName {
}

- (GTCommit *)targetCommitAndReturnError:(NSError **)error {
if (self.SHA == nil) {
if (self.OID == nil) {
if (error != NULL) *error = GTReference.invalidReferenceError;
return nil;
}

return [self.repository lookUpObjectBySHA:self.SHA objectType:GTObjectTypeCommit error:error];
return [self.repository lookUpObjectByOID:self.OID objectType:GTObjectTypeCommit error:error];
}

- (NSUInteger)numberOfCommitsWithError:(NSError **)error {
GTEnumerator *enumerator = [[GTEnumerator alloc] initWithRepository:self.repository error:error];
if (enumerator == nil) return NSNotFound;

if (![enumerator pushSHA:self.SHA error:error]) return NSNotFound;
if (![enumerator pushSHA:self.OID.SHA error:error]) return NSNotFound;
return [enumerator countRemainingObjects:error];
}

Expand All @@ -144,22 +146,7 @@ - (GTBranchType)branchType {
}

- (NSArray *)uniqueCommitsRelativeToBranch:(GTBranch *)otherBranch error:(NSError **)error {
NSParameterAssert(otherBranch != nil);

GTCommit *mergeBase = [self.repository mergeBaseBetweenFirstOID:self.reference.OID secondOID:otherBranch.reference.OID error:error];
if (mergeBase == nil) return nil;

GTEnumerator *enumerator = [[GTEnumerator alloc] initWithRepository:self.repository error:error];
if (enumerator == nil) return nil;

[enumerator resetWithOptions:GTEnumeratorOptionsTimeSort];

BOOL success = [enumerator pushSHA:self.SHA error:error];
if (!success) return nil;

success = [enumerator hideSHA:mergeBase.SHA error:error];
if (!success) return nil;

GTEnumerator *enumerator = [self.repository enumerateUniqueCommitsUpToOID:self.OID relativeToOID:otherBranch.OID error:error];
return [enumerator allObjectsWithError:error];
}

Expand Down Expand Up @@ -223,19 +210,7 @@ - (GTBranch *)reloadedBranchWithError:(NSError **)error {
}

- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind relativeTo:(GTBranch *)branch error:(NSError **)error {
if (branch == nil) {
*ahead = 0;
*behind = 0;
return YES;
}

int errorCode = git_graph_ahead_behind(ahead, behind, self.repository.git_repository, self.reference.git_oid, branch.reference.git_oid);
if (errorCode != GIT_OK && error != NULL) {
*error = [NSError git_errorFor:errorCode description:@"Failed to calculate ahead/behind count of %@ relative to %@", self, branch];
return NO;
}

return YES;
return [self.repository calculateAhead:ahead behind:behind ofOID:self.OID relativeToOID:branch.OID error:error];
}

@end
4 changes: 2 additions & 2 deletions ObjectiveGit/GTReference.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ typedef NS_OPTIONS(NSInteger, GTReferenceType) {
/// The last direct reference in a chain
@property (nonatomic, readonly, copy) GTReference *resolvedReference;

/// The SHA of the target object
@property (nonatomic, readonly, copy) NSString *targetSHA;
/// The OID of the target object.
@property (nonatomic, readonly, copy) GTOID *targetOID;

/// Updates the on-disk reference to point to the target and returns the updated
/// reference.
Expand Down
4 changes: 2 additions & 2 deletions ObjectiveGit/GTReference.m
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ - (GTReference *)resolvedReference {
return [self.class referenceByResolvingSymbolicReference:self error:NULL];
}

- (NSString *)targetSHA {
return [self.resolvedTarget SHA];
- (GTOID *)targetOID {
return [self.resolvedTarget OID];
}

- (GTReference *)referenceByUpdatingTarget:(NSString *)newTarget message:(NSString *)message error:(NSError **)error {
Expand Down
12 changes: 12 additions & 0 deletions ObjectiveGit/GTRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,4 +498,16 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// distinguished using the value of `success`.
- (GTFilterList *)filterListWithPath:(NSString *)path blob:(GTBlob *)blob mode:(GTFilterSourceMode)mode options:(GTFilterListOptions)options success:(BOOL *)success error:(NSError **)error;

/// Creates an enumerator for finding all commits in the history of `headOID`
/// that do not exist in the history of `baseOID`.
///
/// Returns the created enumerator upon success, or `nil` if an error occurred.
- (GTEnumerator *)enumerateUniqueCommitsUpToOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error;

/// Calculates how far ahead/behind the commit represented by `headOID` is,
/// relative to the commit represented by `baseOID`.
///
/// Returns whether `ahead` and `behind` were successfully calculated.
- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind ofOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error;

@end
32 changes: 32 additions & 0 deletions ObjectiveGit/GTRepository.m
Original file line number Diff line number Diff line change
Expand Up @@ -885,4 +885,36 @@ - (GTFilterList *)filterListWithPath:(NSString *)path blob:(GTBlob *)blob mode:(
}
}

- (GTEnumerator *)enumerateUniqueCommitsUpToOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error {
NSParameterAssert(headOID != nil);
NSParameterAssert(baseOID != nil);

GTCommit *mergeBase = [self mergeBaseBetweenFirstOID:headOID secondOID:baseOID error:error];
if (mergeBase == nil) return nil;

GTEnumerator *enumerator = [[GTEnumerator alloc] initWithRepository:self error:error];
if (enumerator == nil) return nil;

[enumerator resetWithOptions:GTEnumeratorOptionsTimeSort];

if (![enumerator pushSHA:headOID.SHA error:error]) return nil;
if (![enumerator hideSHA:mergeBase.OID.SHA error:error]) return nil;

return enumerator;
}

- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind ofOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error {
NSParameterAssert(headOID != nil);
NSParameterAssert(baseOID != nil);

int errorCode = git_graph_ahead_behind(ahead, behind, self.git_repository, headOID.git_oid, baseOID.git_oid);
if (errorCode != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:errorCode description:@"Failed to calculate ahead/behind count of %@ relative to %@", headOID, baseOID];

return NO;
}

return YES;
}

@end
2 changes: 1 addition & 1 deletion ObjectiveGitTests/GTEnumeratorSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
GTReference *HEADRef = [repo headReferenceWithError:NULL];
expect(HEADRef).notTo(beNil());

[enumerator pushSHA:HEADRef.targetSHA error:NULL];
[enumerator pushSHA:HEADRef.targetOID.SHA error:NULL];
NSUInteger count = [enumerator allObjects].count;
expect(@(count)).to(equal(@3));
expect(error).to(beNil());
Expand Down
8 changes: 4 additions & 4 deletions ObjectiveGitTests/GTReferenceSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
reference = [repository createReferenceNamed:testRefName fromOID:testRefOID message:nil error:&error];
expect(reference).notTo(beNil());
expect(reference.name).to(equal(testRefName));
expect(reference.targetSHA).to(equal(testRefOID.SHA));
expect(reference.targetOID).to(equal(testRefOID));
});

it(@"should be able to be renamed", ^{
Expand All @@ -74,7 +74,7 @@
GTReference *renamedRef = [reference referenceByRenaming:newRefName error:NULL];
expect(renamedRef).notTo(beNil());
expect(renamedRef.name).to(equal(newRefName));
expect(renamedRef.targetSHA).to(equal(testRefOID.SHA));
expect(renamedRef.targetOID).to(equal(testRefOID));
});

it(@"should be able to change the target", ^{
Expand All @@ -83,7 +83,7 @@
GTReference *updatedRef = [reference referenceByUpdatingTarget:newRefTarget message:nil error:NULL];
expect(updatedRef).notTo(beNil());
expect(updatedRef.name).to(equal(testRefName));
expect(updatedRef.targetSHA).to(equal(newRefTarget));
expect(updatedRef.targetOID.SHA).to(equal(newRefTarget));
});
});

Expand Down Expand Up @@ -119,7 +119,7 @@

void (^expectValidReference)(GTReference *ref, NSString *SHA, GTReferenceType type, NSString *name) = ^(GTReference *ref, NSString *SHA, GTReferenceType type, NSString *name) {
expect(ref).notTo(beNil());
expect(ref.targetSHA).to(equal(SHA));
expect(ref.targetOID.SHA).to(equal(SHA));
expect(@(ref.referenceType)).to(equal(@(type)));
expect(ref.name).to(equal(name));
};
Expand Down
2 changes: 1 addition & 1 deletion ObjectiveGitTests/GTRemotePushSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
GTReference *headReference = [repo headReferenceWithError:nil];

GTEnumerator *commitEnum = [[GTEnumerator alloc] initWithRepository:repo error:nil];
[commitEnum pushSHA:[headReference targetSHA] error:nil];
[commitEnum pushSHA:[headReference targetOID].SHA error:nil];
GTCommit *parent = [commitEnum nextObject];

GTCommit *testCommit = [repo createCommitWithTree:testTree message:message parents:@[ parent ] updatingReferenceNamed:headReference.name error:nil];
Expand Down
2 changes: 1 addition & 1 deletion ObjectiveGitTests/GTRemoteSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
GTReference *headReference = [repo headReferenceWithError:nil];

GTEnumerator *commitEnum = [[GTEnumerator alloc] initWithRepository:repo error:nil];
[commitEnum pushSHA:[headReference targetSHA] error:nil];
[commitEnum pushSHA:headReference.targetOID.SHA error:nil];
GTCommit *parent = [commitEnum nextObject];

GTCommit *testCommit = [repo createCommitWithTree:testTree message:message parents:@[parent] updatingReferenceNamed:headReference.name error:nil];
Expand Down
6 changes: 3 additions & 3 deletions ObjectiveGitTests/GTRepositoryResetSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

GTCommit *commit = [repository lookUpObjectBySHA:resetTargetSHA error:NULL];
expect(commit).notTo(beNil());
GTCommit *originalHeadCommit = [repository lookUpObjectBySHA:originalHead.targetSHA error:NULL];
GTCommit *originalHeadCommit = [repository lookUpObjectByOID:originalHead.targetOID error:NULL];
expect(originalHeadCommit).notTo(beNil());

BOOL success = [repository resetToCommit:commit resetType:GTRepositoryResetTypeSoft error:&error];
Expand All @@ -77,14 +77,14 @@

GTReference *head = [repository headReferenceWithError:&error];
expect(head).notTo(beNil());
expect(head.targetSHA).to(equal(resetTargetSHA));
expect(head.targetOID.SHA).to(equal(resetTargetSHA));

success = [repository resetToCommit:originalHeadCommit resetType:GTRepositoryResetTypeSoft error:&error];
expect(@(success)).to(beTruthy());
expect(error).to(beNil());

head = [repository headReferenceWithError:&error];
expect(head.targetSHA).to(equal(originalHead.targetSHA));
expect(head.targetOID).to(equal(originalHead.targetOID));
});
});

Expand Down
16 changes: 8 additions & 8 deletions ObjectiveGitTests/GTRepositorySpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
GTReference *head = [repository headReferenceWithError:&error];
expect(head).notTo(beNil());
expect(error).to(beNil());
expect(head.targetSHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(head.targetOID.SHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(@(head.referenceType)).to(equal(@(GTReferenceTypeOid)));
});

Expand All @@ -120,7 +120,7 @@
GTReference *head = [repository headReferenceWithError:&error];
expect(head).notTo(beNil());
expect(error).to(beNil());
expect(head.targetSHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(head.targetOID.SHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(@(head.referenceType)).to(equal(@(GTReferenceTypeOid)));
});

Expand Down Expand Up @@ -183,7 +183,7 @@
GTReference *head = [self.bareFixtureRepository headReferenceWithError:&error];
expect(head).notTo(beNil());
expect(error).to(beNil());
expect(head.targetSHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(head.targetOID.SHA).to(equal(@"36060c58702ed4c2a40832c51758d5344201d89a"));
expect(@(head.referenceType)).to(equal(@(GTReferenceTypeOid)));
});

Expand Down Expand Up @@ -276,13 +276,13 @@
NSString *branchName = @"new-test-branch";

NSError *error = nil;
GTBranch *newBranch = [repository createBranchNamed:branchName fromOID:[[GTOID alloc] initWithSHA:currentBranch.SHA] message:nil error:&error];
GTBranch *newBranch = [repository createBranchNamed:branchName fromOID:currentBranch.OID message:nil error:&error];
expect(newBranch).notTo(beNil());
expect(error).to(beNil());

expect(newBranch.shortName).to(equal(branchName));
expect(@(newBranch.branchType)).to(equal(@(GTBranchTypeLocal)));
expect(newBranch.SHA).to(equal(currentBranch.SHA));
expect(newBranch.OID).to(equal(currentBranch.OID));
});
});

Expand Down Expand Up @@ -409,7 +409,7 @@

GTCommit *commit = [repository lookUpObjectBySHA:resetTargetSHA error:NULL];
expect(commit).notTo(beNil());
GTCommit *originalHeadCommit = [repository lookUpObjectBySHA:originalHead.targetSHA error:NULL];
GTCommit *originalHeadCommit = [repository lookUpObjectByOID:originalHead.targetOID error:NULL];
expect(originalHeadCommit).notTo(beNil());

BOOL success = [repository resetToCommit:commit resetType:GTRepositoryResetTypeSoft error:&error];
Expand All @@ -418,14 +418,14 @@

GTReference *head = [repository headReferenceWithError:&error];
expect(head).notTo(beNil());
expect(head.targetSHA).to(equal(resetTargetSHA));
expect(head.targetOID.SHA).to(equal(resetTargetSHA));

success = [repository resetToCommit:originalHeadCommit resetType:GTRepositoryResetTypeSoft error:&error];
expect(@(success)).to(beTruthy());
expect(error).to(beNil());

head = [repository headReferenceWithError:&error];
expect(head.targetSHA).to(equal(originalHead.targetSHA));
expect(head.targetOID).to(equal(originalHead.targetOID));
});
});

Expand Down