Skip to content

Commit 3503fc0

Browse files
committed
Merge pull request #450 from libgit2/oid-ahead-behind
Support OIDs for ahead/behind count and enumeration
2 parents 2811537 + 7301dd3 commit 3503fc0

12 files changed

+82
-63
lines changed

ObjectiveGit/GTBranch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef NS_ENUM(NSInteger, GTBranchType) {
4343

4444
@property (nonatomic, readonly) NSString *name;
4545
@property (nonatomic, readonly) NSString *shortName;
46-
@property (nonatomic, readonly) NSString *SHA;
46+
@property (nonatomic, copy, readonly) GTOID *OID;
4747
@property (nonatomic, readonly) NSString *remoteName;
4848
@property (nonatomic, readonly) GTBranchType branchType;
4949
@property (nonatomic, readonly, strong) GTRepository *repository;

ObjectiveGit/GTBranch.m

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
//
2525

2626
#import "GTBranch.h"
27-
#import "GTReference.h"
28-
#import "GTEnumerator.h"
29-
#import "GTRepository.h"
27+
3028
#import "GTCommit.h"
29+
#import "GTEnumerator.h"
30+
#import "GTOID.h"
31+
#import "GTReference.h"
3132
#import "GTRemote.h"
33+
#import "GTRepository.h"
3234
#import "NSError+Git.h"
3335

3436
#import "git2/branch.h"
@@ -38,18 +40,18 @@
3840
@implementation GTBranch
3941

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

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

48-
return [self.name isEqual:otherBranch.name] && [self.SHA isEqual:otherBranch.SHA];
50+
return [self.name isEqual:otherBranch.name] && [self.OID isEqual:otherBranch.OID];
4951
}
5052

5153
- (NSUInteger)hash {
52-
return self.name.hash ^ self.SHA.hash;
54+
return self.name.hash ^ self.OID.hash;
5355
}
5456

5557

@@ -100,8 +102,8 @@ - (NSString *)shortName {
100102
return @(name);
101103
}
102104

103-
- (NSString *)SHA {
104-
return self.reference.targetSHA;
105+
- (GTOID *)OID {
106+
return self.reference.targetOID;
105107
}
106108

107109
- (NSString *)remoteName {
@@ -119,19 +121,19 @@ - (NSString *)remoteName {
119121
}
120122

121123
- (GTCommit *)targetCommitAndReturnError:(NSError **)error {
122-
if (self.SHA == nil) {
124+
if (self.OID == nil) {
123125
if (error != NULL) *error = GTReference.invalidReferenceError;
124126
return nil;
125127
}
126128

127-
return [self.repository lookUpObjectBySHA:self.SHA objectType:GTObjectTypeCommit error:error];
129+
return [self.repository lookUpObjectByOID:self.OID objectType:GTObjectTypeCommit error:error];
128130
}
129131

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

134-
if (![enumerator pushSHA:self.SHA error:error]) return NSNotFound;
136+
if (![enumerator pushSHA:self.OID.SHA error:error]) return NSNotFound;
135137
return [enumerator countRemainingObjects:error];
136138
}
137139

@@ -144,22 +146,7 @@ - (GTBranchType)branchType {
144146
}
145147

146148
- (NSArray *)uniqueCommitsRelativeToBranch:(GTBranch *)otherBranch error:(NSError **)error {
147-
NSParameterAssert(otherBranch != nil);
148-
149-
GTCommit *mergeBase = [self.repository mergeBaseBetweenFirstOID:self.reference.OID secondOID:otherBranch.reference.OID error:error];
150-
if (mergeBase == nil) return nil;
151-
152-
GTEnumerator *enumerator = [[GTEnumerator alloc] initWithRepository:self.repository error:error];
153-
if (enumerator == nil) return nil;
154-
155-
[enumerator resetWithOptions:GTEnumeratorOptionsTimeSort];
156-
157-
BOOL success = [enumerator pushSHA:self.SHA error:error];
158-
if (!success) return nil;
159-
160-
success = [enumerator hideSHA:mergeBase.SHA error:error];
161-
if (!success) return nil;
162-
149+
GTEnumerator *enumerator = [self.repository enumerateUniqueCommitsUpToOID:self.OID relativeToOID:otherBranch.OID error:error];
163150
return [enumerator allObjectsWithError:error];
164151
}
165152

@@ -223,19 +210,7 @@ - (GTBranch *)reloadedBranchWithError:(NSError **)error {
223210
}
224211

225212
- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind relativeTo:(GTBranch *)branch error:(NSError **)error {
226-
if (branch == nil) {
227-
*ahead = 0;
228-
*behind = 0;
229-
return YES;
230-
}
231-
232-
int errorCode = git_graph_ahead_behind(ahead, behind, self.repository.git_repository, self.reference.git_oid, branch.reference.git_oid);
233-
if (errorCode != GIT_OK && error != NULL) {
234-
*error = [NSError git_errorFor:errorCode description:@"Failed to calculate ahead/behind count of %@ relative to %@", self, branch];
235-
return NO;
236-
}
237-
238-
return YES;
213+
return [self.repository calculateAhead:ahead behind:behind ofOID:self.OID relativeToOID:branch.OID error:error];
239214
}
240215

241216
@end

ObjectiveGit/GTReference.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ typedef NS_OPTIONS(NSInteger, GTReferenceType) {
7979
/// The last direct reference in a chain
8080
@property (nonatomic, readonly, copy) GTReference *resolvedReference;
8181

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

8585
/// Updates the on-disk reference to point to the target and returns the updated
8686
/// reference.

ObjectiveGit/GTReference.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ - (GTReference *)resolvedReference {
169169
return [self.class referenceByResolvingSymbolicReference:self error:NULL];
170170
}
171171

172-
- (NSString *)targetSHA {
173-
return [self.resolvedTarget SHA];
172+
- (GTOID *)targetOID {
173+
return [self.resolvedTarget OID];
174174
}
175175

176176
- (GTReference *)referenceByUpdatingTarget:(NSString *)newTarget message:(NSString *)message error:(NSError **)error {

ObjectiveGit/GTRepository.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,16 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
498498
/// distinguished using the value of `success`.
499499
- (GTFilterList *)filterListWithPath:(NSString *)path blob:(GTBlob *)blob mode:(GTFilterSourceMode)mode options:(GTFilterListOptions)options success:(BOOL *)success error:(NSError **)error;
500500

501+
/// Creates an enumerator for finding all commits in the history of `headOID`
502+
/// that do not exist in the history of `baseOID`.
503+
///
504+
/// Returns the created enumerator upon success, or `nil` if an error occurred.
505+
- (GTEnumerator *)enumerateUniqueCommitsUpToOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error;
506+
507+
/// Calculates how far ahead/behind the commit represented by `headOID` is,
508+
/// relative to the commit represented by `baseOID`.
509+
///
510+
/// Returns whether `ahead` and `behind` were successfully calculated.
511+
- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind ofOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error;
512+
501513
@end

ObjectiveGit/GTRepository.m

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,4 +885,36 @@ - (GTFilterList *)filterListWithPath:(NSString *)path blob:(GTBlob *)blob mode:(
885885
}
886886
}
887887

888+
- (GTEnumerator *)enumerateUniqueCommitsUpToOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error {
889+
NSParameterAssert(headOID != nil);
890+
NSParameterAssert(baseOID != nil);
891+
892+
GTCommit *mergeBase = [self mergeBaseBetweenFirstOID:headOID secondOID:baseOID error:error];
893+
if (mergeBase == nil) return nil;
894+
895+
GTEnumerator *enumerator = [[GTEnumerator alloc] initWithRepository:self error:error];
896+
if (enumerator == nil) return nil;
897+
898+
[enumerator resetWithOptions:GTEnumeratorOptionsTimeSort];
899+
900+
if (![enumerator pushSHA:headOID.SHA error:error]) return nil;
901+
if (![enumerator hideSHA:mergeBase.OID.SHA error:error]) return nil;
902+
903+
return enumerator;
904+
}
905+
906+
- (BOOL)calculateAhead:(size_t *)ahead behind:(size_t *)behind ofOID:(GTOID *)headOID relativeToOID:(GTOID *)baseOID error:(NSError **)error {
907+
NSParameterAssert(headOID != nil);
908+
NSParameterAssert(baseOID != nil);
909+
910+
int errorCode = git_graph_ahead_behind(ahead, behind, self.git_repository, headOID.git_oid, baseOID.git_oid);
911+
if (errorCode != GIT_OK) {
912+
if (error != NULL) *error = [NSError git_errorFor:errorCode description:@"Failed to calculate ahead/behind count of %@ relative to %@", headOID, baseOID];
913+
914+
return NO;
915+
}
916+
917+
return YES;
918+
}
919+
888920
@end

ObjectiveGitTests/GTEnumeratorSpec.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
GTReference *HEADRef = [repo headReferenceWithError:NULL];
3232
expect(HEADRef).notTo(beNil());
3333

34-
[enumerator pushSHA:HEADRef.targetSHA error:NULL];
34+
[enumerator pushSHA:HEADRef.targetOID.SHA error:NULL];
3535
NSUInteger count = [enumerator allObjects].count;
3636
expect(@(count)).to(equal(@3));
3737
expect(error).to(beNil());

ObjectiveGitTests/GTReferenceSpec.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
reference = [repository createReferenceNamed:testRefName fromOID:testRefOID message:nil error:&error];
6666
expect(reference).notTo(beNil());
6767
expect(reference.name).to(equal(testRefName));
68-
expect(reference.targetSHA).to(equal(testRefOID.SHA));
68+
expect(reference.targetOID).to(equal(testRefOID));
6969
});
7070

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

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

@@ -119,7 +119,7 @@
119119

120120
void (^expectValidReference)(GTReference *ref, NSString *SHA, GTReferenceType type, NSString *name) = ^(GTReference *ref, NSString *SHA, GTReferenceType type, NSString *name) {
121121
expect(ref).notTo(beNil());
122-
expect(ref.targetSHA).to(equal(SHA));
122+
expect(ref.targetOID.SHA).to(equal(SHA));
123123
expect(@(ref.referenceType)).to(equal(@(type)));
124124
expect(ref.name).to(equal(name));
125125
};

ObjectiveGitTests/GTRemotePushSpec.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
GTReference *headReference = [repo headReferenceWithError:nil];
2424

2525
GTEnumerator *commitEnum = [[GTEnumerator alloc] initWithRepository:repo error:nil];
26-
[commitEnum pushSHA:[headReference targetSHA] error:nil];
26+
[commitEnum pushSHA:[headReference targetOID].SHA error:nil];
2727
GTCommit *parent = [commitEnum nextObject];
2828

2929
GTCommit *testCommit = [repo createCommitWithTree:testTree message:message parents:@[ parent ] updatingReferenceNamed:headReference.name error:nil];

ObjectiveGitTests/GTRemoteSpec.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
GTReference *headReference = [repo headReferenceWithError:nil];
145145

146146
GTEnumerator *commitEnum = [[GTEnumerator alloc] initWithRepository:repo error:nil];
147-
[commitEnum pushSHA:[headReference targetSHA] error:nil];
147+
[commitEnum pushSHA:headReference.targetOID.SHA error:nil];
148148
GTCommit *parent = [commitEnum nextObject];
149149

150150
GTCommit *testCommit = [repo createCommitWithTree:testTree message:message parents:@[parent] updatingReferenceNamed:headReference.name error:nil];

0 commit comments

Comments
 (0)