32
32
#import " GTRemote.h"
33
33
#import " GTRepository.h"
34
34
#import " NSError+Git.h"
35
+ #import " NSData+Git.h"
35
36
36
37
#import " git2/branch.h"
37
38
#import " git2/errors.h"
@@ -65,30 +66,32 @@ + (NSString *)remoteNamePrefix {
65
66
return @" refs/remotes/" ;
66
67
}
67
68
68
- + (instancetype )branchWithReference : (GTReference *)ref repository : (GTRepository *) repo {
69
- return [[self alloc ] initWithReference: ref repository: repo ];
69
+ + (instancetype )branchWithReference : (GTReference *)ref {
70
+ return [[self alloc ] initWithReference: ref];
70
71
}
71
72
72
73
- (instancetype )init {
73
74
NSAssert (NO , @" Call to an unavailable initializer." );
74
75
return nil ;
75
76
}
76
77
77
- - (instancetype )initWithReference : (GTReference *)ref repository : (GTRepository *) repo {
78
+ - (instancetype )initWithReference : (GTReference *)ref {
78
79
NSParameterAssert (ref != nil );
79
- NSParameterAssert (repo != nil );
80
80
81
81
self = [super init ];
82
82
if (self == nil ) return nil ;
83
83
84
- _repository = repo;
85
84
_reference = ref;
86
85
87
86
return self;
88
87
}
89
88
90
89
- (NSString *)name {
91
- return self.reference .name ;
90
+ const char *charName;
91
+ int gitError = git_branch_name (&charName, self.reference .git_reference );
92
+ if (gitError != GIT_OK || charName == NULL ) return nil ;
93
+
94
+ return @(charName);
92
95
}
93
96
94
97
- (NSString *)shortName {
@@ -112,36 +115,39 @@ - (GTOID *)OID {
112
115
}
113
116
114
117
- (NSString *)remoteName {
115
- if (self.branchType == GTBranchTypeLocal) return nil ;
116
-
117
- const char *name;
118
- int gitError = git_branch_name (&name, self.reference .git_reference );
118
+ git_buf remote_name = GIT_BUF_INIT_CONST (0 , NULL );
119
+ int gitError = git_branch_remote_name (&remote_name, self.repository .git_repository , self.reference .name .UTF8String );
119
120
if (gitError != GIT_OK) return nil ;
120
121
121
- // Find out where the remote name ends.
122
- const char *end = strchr (name, ' /' );
123
- if (end == NULL || end == name) return nil ;
124
-
125
- return [[NSString alloc ] initWithBytes: name length: end - name encoding: NSUTF8StringEncoding];
122
+ NSData *data = [NSData git_dataWithBuffer: &remote_name];
123
+ return [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
126
124
}
127
125
128
126
- (GTCommit *)targetCommitWithError : (NSError **)error {
129
- if (self.OID == nil ) {
127
+ GTOID *oid = self.OID ;
128
+ if (oid == nil ) {
130
129
if (error != NULL ) *error = GTReference.invalidReferenceError ;
131
130
return nil ;
132
131
}
133
132
134
- return [self .repository lookUpObjectByOID: self .OID objectType: GTObjectTypeCommit error: error];
133
+ return [self .repository lookUpObjectByOID: oid objectType: GTObjectTypeCommit error: error];
135
134
}
136
135
137
136
- (NSUInteger )numberOfCommitsWithError : (NSError **)error {
138
137
GTEnumerator *enumerator = [[GTEnumerator alloc ] initWithRepository: self .repository error: error];
139
138
if (enumerator == nil ) return NSNotFound ;
140
139
141
- if (![enumerator pushSHA: self .OID.SHA error: error]) return NSNotFound ;
140
+ GTOID *oid = self.OID ;
141
+ if (oid == nil ) return NSNotFound ;
142
+
143
+ if (![enumerator pushSHA: oid.SHA error: error]) return NSNotFound ;
142
144
return [enumerator countRemainingObjects: error];
143
145
}
144
146
147
+ - (GTRepository *)repository {
148
+ return self.reference .repository ;
149
+ }
150
+
145
151
- (GTBranchType)branchType {
146
152
if (self.reference .remote ) {
147
153
return GTBranchTypeRemote;
@@ -150,8 +156,14 @@ - (GTBranchType)branchType {
150
156
}
151
157
}
152
158
159
+ - (BOOL )isHEAD {
160
+ return (git_branch_is_head (self.reference .git_reference ) ? YES : NO );
161
+ }
162
+
153
163
- (NSArray *)uniqueCommitsRelativeToBranch : (GTBranch *)otherBranch error : (NSError **)error {
154
- GTEnumerator *enumerator = [self .repository enumeratorForUniqueCommitsFromOID: self .OID relativeToOID: otherBranch.OID error: error];
164
+ GTOID *oid = self.OID ;
165
+ GTOID *otherOID = otherBranch.OID ;
166
+ GTEnumerator *enumerator = [self .repository enumeratorForUniqueCommitsFromOID: oid relativeToOID: otherOID error: error];
155
167
return [enumerator allObjectsWithError: error];
156
168
}
157
169
@@ -165,9 +177,29 @@ - (BOOL)deleteWithError:(NSError **)error {
165
177
return YES ;
166
178
}
167
179
180
+ - (BOOL )rename : (NSString *)name force : (BOOL )force error : (NSError **)error {
181
+ git_reference *git_ref;
182
+ int gitError = git_branch_move (&git_ref, self.reference .git_reference , name.UTF8String , (force ? 1 : 0 ));
183
+ if (gitError != GIT_OK) {
184
+ if (error) *error = [NSError git_errorFor: gitError description: @" Rename branch failed" ];
185
+ return NO ;
186
+ }
187
+
188
+ GTReference *renamedRef = [[GTReference alloc ] initWithGitReference: git_ref repository: self .repository];
189
+ NSAssert (renamedRef, @" Unable to allocate renamed ref" );
190
+ _reference = renamedRef;
191
+
192
+ return YES ;
193
+ }
194
+
168
195
- (GTBranch *)trackingBranchWithError : (NSError **)error success : (BOOL *)success {
196
+ BOOL underSuccess = NO ;
197
+ if (success == NULL ) {
198
+ success = &underSuccess;
199
+ }
200
+
169
201
if (self.branchType == GTBranchTypeRemote) {
170
- if (success != NULL ) *success = YES ;
202
+ *success = YES ;
171
203
return self;
172
204
}
173
205
@@ -176,25 +208,32 @@ - (GTBranch *)trackingBranchWithError:(NSError **)error success:(BOOL *)success
176
208
177
209
// GIT_ENOTFOUND means no tracking branch found.
178
210
if (gitError == GIT_ENOTFOUND) {
179
- if (success != NULL ) *success = YES ;
211
+ *success = YES ;
180
212
return nil ;
181
213
}
182
214
183
215
if (gitError != GIT_OK) {
184
- if (success != NULL ) *success = NO ;
216
+ *success = NO ;
185
217
if (error != NULL ) *error = [NSError git_errorFor: gitError description: @" Failed to create reference to tracking branch from %@ " , self ];
186
218
return nil ;
187
219
}
188
220
189
221
if (trackingRef == NULL ) {
190
- if (success != NULL ) *success = NO ;
222
+ *success = NO ;
191
223
if (error != NULL ) *error = [NSError git_errorFor: gitError description: @" Got a NULL remote ref for %@ " , self ];
192
224
return nil ;
193
225
}
194
226
195
- if (success != NULL ) *success = YES ;
227
+ GTReference *upsteamRef = [[GTReference alloc ] initWithGitReference: trackingRef repository: self .repository];
228
+ if (upsteamRef == nil ) {
229
+ *success = NO ;
230
+ if (error != NULL ) *error = [NSError git_errorFor: GIT_ERROR description: @" Failed to allocate upstream ref" ];
231
+ return nil ;
232
+ }
233
+
234
+ *success = YES ;
196
235
197
- return [[self class ] branchWithReference: [[GTReference alloc ] initWithGitReference: trackingRef repository: self .repository] repository: self .repository ];
236
+ return [[self class ] branchWithReference: upsteamRef ];
198
237
}
199
238
200
239
- (BOOL )updateTrackingBranch : (GTBranch *)trackingBranch error : (NSError **)error {
@@ -216,11 +255,13 @@ - (GTBranch *)reloadedBranchWithError:(NSError **)error {
216
255
GTReference *reloadedRef = [self .reference reloadedReferenceWithError: error];
217
256
if (reloadedRef == nil ) return nil ;
218
257
219
- return [[self .class alloc ] initWithReference: reloadedRef repository: self .repository ];
258
+ return [[self .class alloc ] initWithReference: reloadedRef];
220
259
}
221
260
222
261
- (BOOL )calculateAhead : (size_t *)ahead behind : (size_t *)behind relativeTo : (GTBranch *)branch error : (NSError **)error {
223
- return [self .repository calculateAhead: ahead behind: behind ofOID: self .OID relativeToOID: branch.OID error: error];
262
+ GTOID *oid = self.OID ;
263
+ GTOID *branchOID = branch.OID ;
264
+ return [self .repository calculateAhead: ahead behind: behind ofOID: oid relativeToOID: branchOID error: error];
224
265
}
225
266
226
267
@end
0 commit comments