Skip to content

Commit 953f1e6

Browse files
committed
Provide a wrapper for annotated commits
1 parent 516ae18 commit 953f1e6

File tree

5 files changed

+295
-0
lines changed

5 files changed

+295
-0
lines changed

ObjectiveGit/GTAnnotatedCommit.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//
2+
// GTAnnotatedCommit.h
3+
// ObjectiveGitFramework
4+
//
5+
// Created by Etienne on 18/12/2016.
6+
// Copyright © 2016 GitHub, Inc. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
#import <git2/annotated_commit.h>
12+
13+
@class GTReference;
14+
@class GTRepository;
15+
@class GTOID;
16+
17+
NS_ASSUME_NONNULL_BEGIN
18+
19+
@interface GTAnnotatedCommit : NSObject
20+
21+
/// Make an annotated commit from a reference.
22+
///
23+
/// @param reference The reference the annotated commit should point to. Must not be nil.
24+
/// @param error An error if one occurred.
25+
///
26+
/// @return Return a newly initialized instance of the receiver.
27+
+ (nullable instancetype)annotatedCommitFromReference:(GTReference *)reference error:(NSError **)error;
28+
29+
/// Make an annotated commit from a fetch head.
30+
///
31+
/// @param branchName The branch name to use. Must not be nil.
32+
/// @param remoteURL The remote URL to use. Must not be nil.
33+
/// @param OID The OID the commit should point to. Must not be nil.
34+
/// @param repository The repository the OID belongs to. Must not be nil.
35+
/// @param error An error if one occurred.
36+
///
37+
/// @return Return a newly initialized instance of the receiver.
38+
+ (nullable instancetype)annotatedCommitFromFetchHead:(NSString *)branchName url:(NSString *)remoteURL oid:(GTOID *)OID inRepository:(GTRepository *)repository error:(NSError **)error;
39+
40+
/// Make an annotated commit from a OID.
41+
///
42+
/// @param OID The OID the commit should point to. Must not be nil.
43+
/// @param repository The repository the OID belongs to. Must not be nil.
44+
/// @param error An error if one occurred.
45+
///
46+
/// @return Return a newly initialized instance of the receiver.
47+
+ (nullable instancetype)annotatedCommitFromOID:(GTOID *)OID inRepository:(GTRepository *)repository error:(NSError **)error;
48+
49+
/// Make an annotated commit by resolving a revspec.
50+
///
51+
/// @param revSpec The revspec to resolve. Must not be nil.
52+
/// @param repository The repository to perform the resolution in. Must not be nil.
53+
/// @param error An error if one occurred.
54+
///
55+
/// @return Return a newly initialized instance of the receiver.
56+
+ (nullable instancetype)annotatedCommitFromRevSpec:(NSString *)revSpec inRepository:(GTRepository *)repository error:(NSError **)error;
57+
58+
- (instancetype)init NS_UNAVAILABLE;
59+
60+
/// Designated initializer
61+
///
62+
/// @param annotated_commit The annotated commit to wrap. Must not be nil.
63+
///
64+
/// @return Return a newly initialized instance of the receiver.
65+
- (nullable instancetype)initWithGitAnnotatedCommit:(git_annotated_commit *)annotated_commit NS_DESIGNATED_INITIALIZER;
66+
67+
/// The underlying `git_annotated_commit` object.
68+
- (git_annotated_commit *)git_annotated_commit __attribute__((objc_returns_inner_pointer));
69+
70+
/// The OID of the underlying commit.
71+
@property (nonatomic, copy, readonly) GTOID *OID;
72+
73+
@end
74+
75+
NS_ASSUME_NONNULL_END

ObjectiveGit/GTAnnotatedCommit.m

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//
2+
// GTAnnotatedCommit.m
3+
// ObjectiveGitFramework
4+
//
5+
// Created by Etienne on 18/12/2016.
6+
// Copyright © 2016 GitHub, Inc. All rights reserved.
7+
//
8+
9+
#import "GTAnnotatedCommit.h"
10+
11+
#import "GTReference.h"
12+
#import "GTRepository.h"
13+
#import "GTOID.h"
14+
#import "NSError+Git.h"
15+
16+
#import "git2/annotated_commit.h"
17+
18+
@interface GTAnnotatedCommit ()
19+
@property (nonatomic, readonly, assign) git_annotated_commit *annotated_commit;
20+
@end
21+
22+
@implementation GTAnnotatedCommit
23+
24+
+ (instancetype)annotatedCommitFromReference:(GTReference *)reference error:(NSError **)error {
25+
NSParameterAssert(reference != nil);
26+
27+
git_annotated_commit *commit;
28+
int gitError = git_annotated_commit_from_ref(&commit, reference.repository.git_repository, reference.git_reference);
29+
if (gitError != 0) {
30+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Annotated commit creation failed"];
31+
return nil;
32+
}
33+
34+
return [[self alloc] initWithGitAnnotatedCommit:commit];
35+
}
36+
37+
+ (instancetype)annotatedCommitFromFetchHead:(NSString *)branchName url:(NSString *)remoteURL oid:(GTOID *)OID inRepository:(GTRepository *)repository error:(NSError **)error {
38+
NSParameterAssert(branchName != nil);
39+
NSParameterAssert(remoteURL != nil);
40+
NSParameterAssert(OID != nil);
41+
NSParameterAssert(repository != nil);
42+
43+
git_annotated_commit *commit;
44+
int gitError = git_annotated_commit_from_fetchhead(&commit, repository.git_repository, branchName.UTF8String, remoteURL.UTF8String, OID.git_oid);
45+
if (gitError != 0) {
46+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Annotated commit creation failed"];
47+
return nil;
48+
}
49+
50+
return [[self alloc] initWithGitAnnotatedCommit:commit];
51+
}
52+
53+
+ (instancetype)annotatedCommitFromOID:(GTOID *)OID inRepository:(GTRepository *)repository error:(NSError **)error {
54+
NSParameterAssert(OID != nil);
55+
NSParameterAssert(repository != nil);
56+
57+
git_annotated_commit *commit;
58+
int gitError = git_annotated_commit_lookup(&commit, repository.git_repository, OID.git_oid);
59+
if (gitError != 0) {
60+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Annotated commit creation failed"];
61+
return nil;
62+
}
63+
64+
return [[self alloc] initWithGitAnnotatedCommit:commit];
65+
}
66+
67+
+ (instancetype)annotatedCommitFromRevSpec:(NSString *)revSpec inRepository:(GTRepository *)repository error:(NSError **)error {
68+
NSParameterAssert(revSpec != nil);
69+
NSParameterAssert(repository != nil);
70+
71+
git_annotated_commit *commit;
72+
int gitError = git_annotated_commit_from_revspec(&commit, repository.git_repository, revSpec.UTF8String);
73+
if (gitError != 0) {
74+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Annotated commit creation failed"];
75+
return nil;
76+
}
77+
78+
return [[self alloc] initWithGitAnnotatedCommit:commit];
79+
}
80+
81+
- (instancetype)initWithGitAnnotatedCommit:(git_annotated_commit *)annotated_commit {
82+
NSParameterAssert(annotated_commit != NULL);
83+
84+
self = [super init];
85+
if (!self) return nil;
86+
87+
_annotated_commit = annotated_commit;
88+
89+
return self;
90+
}
91+
92+
- (void)dealloc {
93+
git_annotated_commit_free(_annotated_commit);
94+
}
95+
96+
/// The underlying `git_annotated_commit` object.
97+
- (git_annotated_commit *)git_annotated_commit {
98+
return _annotated_commit;
99+
}
100+
101+
- (GTOID *)OID {
102+
return [GTOID oidWithGitOid:git_annotated_commit_id(self.git_annotated_commit)];
103+
}
104+
105+
@end

ObjectiveGit/ObjectiveGit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ FOUNDATION_EXPORT const unsigned char ObjectiveGitVersionString[];
7272
#import <ObjectiveGit/GTFetchHeadEntry.h>
7373
#import <ObjectiveGit/GTNote.h>
7474
#import <ObjectiveGit/GTCheckoutOptions.h>
75+
#import <ObjectiveGit/GTAnnotatedCommit.h>
7576

7677
#import <ObjectiveGit/GTObjectDatabase.h>
7778
#import <ObjectiveGit/GTOdbObject.h>

ObjectiveGitFramework.xcodeproj/project.pbxproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,14 @@
8989
30FDC08116835A8100654BF0 /* GTDiffLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 30FDC07E16835A8100654BF0 /* GTDiffLine.m */; };
9090
4D123240178E009E0048F785 /* GTRepositoryCommittingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D12323F178E009E0048F785 /* GTRepositoryCommittingSpec.m */; };
9191
4D1C40D8182C006D00BE2960 /* GTBlobSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1C40D7182C006D00BE2960 /* GTBlobSpec.m */; };
92+
4D2740CE1E06C048004C3A6F /* GTAnnotatedCommit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D2740CC1E06C048004C3A6F /* GTAnnotatedCommit.h */; settings = {ATTRIBUTES = (Public, ); }; };
93+
4D2740CF1E06C048004C3A6F /* GTAnnotatedCommit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D2740CC1E06C048004C3A6F /* GTAnnotatedCommit.h */; settings = {ATTRIBUTES = (Public, ); }; };
94+
4D2740D01E06C048004C3A6F /* GTAnnotatedCommit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D2740CD1E06C048004C3A6F /* GTAnnotatedCommit.m */; };
95+
4D2740D11E06C048004C3A6F /* GTAnnotatedCommit.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D2740CD1E06C048004C3A6F /* GTAnnotatedCommit.m */; };
9296
4D79C0EE17DF9F4D00997DE4 /* GTCredential.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D79C0EC17DF9F4D00997DE4 /* GTCredential.h */; settings = {ATTRIBUTES = (Public, ); }; };
9397
4D79C0EF17DF9F4D00997DE4 /* GTCredential.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D79C0ED17DF9F4D00997DE4 /* GTCredential.m */; };
98+
4D7BA1C3218531AD003CD3CE /* GTAnnotatedCommitSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BA1C2218531AD003CD3CE /* GTAnnotatedCommitSpec.m */; };
99+
4D7BA1C4218531AD003CD3CE /* GTAnnotatedCommitSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BA1C2218531AD003CD3CE /* GTAnnotatedCommitSpec.m */; };
94100
4D9BCD24206D84AD003CD3CE /* libgit2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D9BCD23206D84AD003CD3CE /* libgit2.a */; };
95101
4D9BCD25206D84B2003CD3CE /* libgit2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D9BCD23206D84AD003CD3CE /* libgit2.a */; };
96102
4DBA4A3217DA73CE006CD5F5 /* GTRemoteSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DBA4A3117DA73CE006CD5F5 /* GTRemoteSpec.m */; };
@@ -488,9 +494,12 @@
488494
30FDC07E16835A8100654BF0 /* GTDiffLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTDiffLine.m; sourceTree = "<group>"; };
489495
4D12323F178E009E0048F785 /* GTRepositoryCommittingSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTRepositoryCommittingSpec.m; sourceTree = "<group>"; };
490496
4D1C40D7182C006D00BE2960 /* GTBlobSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTBlobSpec.m; sourceTree = "<group>"; };
497+
4D2740CC1E06C048004C3A6F /* GTAnnotatedCommit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTAnnotatedCommit.h; sourceTree = "<group>"; };
498+
4D2740CD1E06C048004C3A6F /* GTAnnotatedCommit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTAnnotatedCommit.m; sourceTree = "<group>"; };
491499
4D79C0EC17DF9F4D00997DE4 /* GTCredential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTCredential.h; sourceTree = "<group>"; };
492500
4D79C0ED17DF9F4D00997DE4 /* GTCredential.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTCredential.m; sourceTree = "<group>"; };
493501
4D79C0F617DFAA7100997DE4 /* GTCredential+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTCredential+Private.h"; sourceTree = "<group>"; };
502+
4D7BA1C2218531AD003CD3CE /* GTAnnotatedCommitSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTAnnotatedCommitSpec.m; sourceTree = "<group>"; };
494503
4D9BCD23206D84AD003CD3CE /* libgit2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgit2.a; path = External/build/lib/libgit2.a; sourceTree = "<group>"; };
495504
4DBA4A3117DA73CE006CD5F5 /* GTRemoteSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTRemoteSpec.m; sourceTree = "<group>"; };
496505
4DC55AE31AD859AD0032563C /* GTCheckoutOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTCheckoutOptions.h; sourceTree = "<group>"; };
@@ -825,6 +834,7 @@
825834
88F05A7516011E5400B7AD1D /* ObjectiveGitTests */ = {
826835
isa = PBXGroup;
827836
children = (
837+
4D7BA1C2218531AD003CD3CE /* GTAnnotatedCommitSpec.m */,
828838
200578C418932A82001C06C3 /* GTBlameSpec.m */,
829839
4D1C40D7182C006D00BE2960 /* GTBlobSpec.m */,
830840
88A994B916FCE7D400402C7B /* GTBranchSpec.m */,
@@ -976,6 +986,8 @@
976986
6EEB51A0199D62B9001D72C0 /* GTFetchHeadEntry.m */,
977987
4DC55AE31AD859AD0032563C /* GTCheckoutOptions.h */,
978988
4DC55AE41AD859AD0032563C /* GTCheckoutOptions.m */,
989+
4D2740CC1E06C048004C3A6F /* GTAnnotatedCommit.h */,
990+
4D2740CD1E06C048004C3A6F /* GTAnnotatedCommit.m */,
979991
);
980992
path = ObjectiveGit;
981993
sourceTree = "<group>";
@@ -1090,6 +1102,7 @@
10901102
4DC55AE51AD859AD0032563C /* GTCheckoutOptions.h in Headers */,
10911103
BD441E08131ED0C300187010 /* GTReference.h in Headers */,
10921104
88F6D9D91320451F00CC0BA8 /* ObjectiveGit.h in Headers */,
1105+
4D2740CE1E06C048004C3A6F /* GTAnnotatedCommit.h in Headers */,
10931106
88B2131C1B20E785005CF2C5 /* GTRepository+References.h in Headers */,
10941107
88F6D9FA1320467100CC0BA8 /* GTCommit.h in Headers */,
10951108
88F6D9FB1320467500CC0BA8 /* GTObject.h in Headers */,
@@ -1179,6 +1192,7 @@
11791192
D01B6F6F19F82FB300D411BC /* GTDiffHunk.h in Headers */,
11801193
D01B6F4319F82F8700D411BC /* GTReference.h in Headers */,
11811194
D01B6F3F19F82F8700D411BC /* GTIndex.h in Headers */,
1195+
4D2740CF1E06C048004C3A6F /* GTAnnotatedCommit.h in Headers */,
11821196
D01B6F2719F82F8700D411BC /* GTRepository+Stashing.h in Headers */,
11831197
D01B6F5119F82FA600D411BC /* GTBlame.h in Headers */,
11841198
D01B6F1D19F82F7B00D411BC /* NSArray+StringArray.h in Headers */,
@@ -1435,6 +1449,7 @@
14351449
F8EFA03A1B4059ED000FF7D0 /* GTUtilityFunctions.m in Sources */,
14361450
30B1E8001703871900D0814D /* GTTimeAdditionsSpec.m in Sources */,
14371451
8870390B1975E3F2004118D7 /* GTDiffDeltaSpec.m in Sources */,
1452+
4D7BA1C3218531AD003CD3CE /* GTAnnotatedCommitSpec.m in Sources */,
14381453
88C0BC5917038CF3009E99AA /* GTConfigurationSpec.m in Sources */,
14391454
88215483171499BE00D76B76 /* GTReflogSpec.m in Sources */,
14401455
88948AC91779243600809CDA /* GTObjectDatabaseSpec.m in Sources */,
@@ -1517,6 +1532,7 @@
15171532
D03B57A418BFFF07007124F4 /* GTDiffPatch.m in Sources */,
15181533
D03B07F71965DAB0009E5624 /* NSData+Git.m in Sources */,
15191534
20F43DE618A2F668007D3621 /* GTRepository+Blame.m in Sources */,
1535+
4D2740D01E06C048004C3A6F /* GTAnnotatedCommit.m in Sources */,
15201536
5BE6128A1745EE3400266D8C /* GTTreeBuilder.m in Sources */,
15211537
D09C2E381755F16200065E36 /* GTSubmodule.m in Sources */,
15221538
4D79C0EF17DF9F4D00997DE4 /* GTCredential.m in Sources */,
@@ -1579,6 +1595,7 @@
15791595
D01B6F6219F82FA600D411BC /* GTFilterSource.m in Sources */,
15801596
D01B6F1C19F82F7B00D411BC /* NSDate+GTTimeAdditions.m in Sources */,
15811597
D01B6F1619F82F7B00D411BC /* NSData+Git.m in Sources */,
1598+
4D2740D11E06C048004C3A6F /* GTAnnotatedCommit.m in Sources */,
15821599
D01B6F1E19F82F7B00D411BC /* NSArray+StringArray.m in Sources */,
15831600
D01B6F5819F82FA600D411BC /* GTReflogEntry.m in Sources */,
15841601
D01B6F4A19F82F8700D411BC /* GTOdbObject.m in Sources */,
@@ -1615,6 +1632,7 @@
16151632
F8D007901B4FA03B009A8DAF /* GTDiffSpec.m in Sources */,
16161633
F8D007A71B4FA040009A8DAF /* QuickSpec+GTFixtures.m in Sources */,
16171634
F8D0079A1B4FA03B009A8DAF /* GTRepositoryCommittingSpec.m in Sources */,
1635+
4D7BA1C4218531AD003CD3CE /* GTAnnotatedCommitSpec.m in Sources */,
16181636
F8D0078E1B4FA03B009A8DAF /* GTCommitSpec.m in Sources */,
16191637
F86949AA1BF1B79E00A989D3 /* GTUtilityFunctions.m in Sources */,
16201638
F8D0078F1B4FA03B009A8DAF /* GTConfigurationSpec.m in Sources */,
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//
2+
// GTAnnotatedCommitSpec.m
3+
// ObjectiveGitFramework
4+
//
5+
// Created by Etienne Samson on 28/10/2019.
6+
// Copyright (c) 2019 GitHub, Inc. All rights reserved.
7+
//
8+
9+
@import ObjectiveGit;
10+
@import Nimble;
11+
@import Quick;
12+
13+
#import "QuickSpec+GTFixtures.h"
14+
15+
#define MASTER_OID @"a4bca6b67a5483169963572ee3da563da33712f7"
16+
17+
QuickSpecBegin(GTAnnotatedCommitSpec)
18+
19+
__block GTRepository *repository;
20+
__block GTIndex *index;
21+
22+
beforeEach(^{
23+
repository = self.testAppFixtureRepository;
24+
25+
index = [repository indexWithError:NULL];
26+
expect(index).notTo(beNil());
27+
28+
BOOL success = [index refresh:NULL];
29+
expect(@(success)).to(beTruthy());
30+
});
31+
32+
describe(@"initialization", ^{
33+
it(@"can be initialized from a reference", ^{
34+
NSError *error = nil;
35+
36+
GTReference *ref = [repository lookUpReferenceWithName:@"refs/heads/master" error:NULL];
37+
expect(ref).notTo(beNil());
38+
39+
GTAnnotatedCommit *commit = [GTAnnotatedCommit annotatedCommitFromReference:ref error:&error];
40+
expect(commit).notTo(beNil());
41+
expect(error).to(beNil());
42+
43+
expect(commit.OID.SHA).to(equal(MASTER_OID));
44+
});
45+
46+
it(@"can be initialized from a fetch head", ^{
47+
NSError *error = nil;
48+
49+
GTOID *oid = [GTOID oidWithSHA:MASTER_OID];
50+
51+
GTAnnotatedCommit *commit = [GTAnnotatedCommit annotatedCommitFromFetchHead:@"master"
52+
url:@"https://example.com/random.git"
53+
oid:oid
54+
inRepository:repository
55+
error:&error];
56+
expect(commit).notTo(beNil());
57+
expect(error).to(beNil());
58+
59+
expect(commit.OID.SHA).to(equal(MASTER_OID));
60+
});
61+
62+
it(@"can be initialized from an OID", ^{
63+
NSError *error = nil;
64+
65+
GTReference *ref = [repository headReferenceWithError:NULL];
66+
expect(ref).notTo(beNil());
67+
68+
GTAnnotatedCommit *commit = [GTAnnotatedCommit annotatedCommitFromOID:ref.OID
69+
inRepository:repository
70+
error:&error];
71+
expect(commit).notTo(beNil());
72+
expect(error).to(beNil());
73+
74+
expect(commit.OID.SHA).to(equal(MASTER_OID));
75+
76+
});
77+
78+
it(@"can be initialized from a revspec", ^{
79+
NSError *error = nil;
80+
81+
GTAnnotatedCommit *commit = [GTAnnotatedCommit annotatedCommitFromRevSpec:@"master^"
82+
inRepository:repository
83+
error:&error];
84+
expect(commit).notTo(beNil());
85+
expect(error).to(beNil());
86+
87+
expect(commit.OID.SHA).to(equal(@"6b0c1c8b8816416089c534e474f4c692a76ac14f"));
88+
});
89+
});
90+
91+
92+
afterEach(^{
93+
[self tearDown];
94+
});
95+
96+
QuickSpecEnd

0 commit comments

Comments
 (0)