Skip to content

Commit a2de081

Browse files
committed
Merge pull request #458 from sagmor/index_add_frombuffer
Add/Fetch NSData from index
2 parents 30219e2 + a64e915 commit a2de081

File tree

6 files changed

+139
-12
lines changed

6 files changed

+139
-12
lines changed

External/libgit2

Submodule libgit2 updated 148 files

ObjectiveGit/GTIndex.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@
135135
/// Returns YES if successful, NO otherwise.
136136
- (BOOL)addFile:(NSString *)file error:(NSError **)error;
137137

138+
/// Add an entry (with the provided data and name) to the index.
139+
/// Will fail if the receiver's repository is nil.
140+
///
141+
/// data - The content of the entry to add. Cannot be nil.
142+
/// name - The name of the entry to add. Cannot be nil.
143+
/// error - The error if one occurred.
144+
- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error;
145+
138146
/// Reads the contents of the given tree into the index.
139147
///
140148
/// tree - The tree to add to the index. This must not be nil.

ObjectiveGit/GTIndex.m

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#import "GTRepository+Private.h"
3737
#import "GTRepository.h"
3838
#import "GTTree.h"
39+
#import "GTBlob.h"
3940
#import "NSArray+StringArray.h"
4041
#import "NSError+Git.h"
4142

@@ -76,6 +77,7 @@ - (void)dealloc {
7677

7778
+ (instancetype)inMemoryIndexWithRepository:(GTRepository *)repository error:(NSError **)error {
7879
git_index *index = NULL;
80+
7981
int status = git_index_new(&index);
8082
if (status != GIT_OK) {
8183
if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to initialize in-memory index"];
@@ -141,7 +143,7 @@ - (GTIndexEntry *)entryAtIndex:(NSUInteger)index {
141143
const git_index_entry *entry = git_index_get_byindex(self.git_index, (unsigned int)index);
142144
if (entry == NULL) return nil;
143145

144-
return [[GTIndexEntry alloc] initWithGitIndexEntry:entry];
146+
return [[GTIndexEntry alloc] initWithGitIndexEntry:entry index:self error:NULL];
145147
}
146148

147149
- (GTIndexEntry *)entryWithName:(NSString *)name {
@@ -180,6 +182,25 @@ - (BOOL)addFile:(NSString *)file error:(NSError **)error {
180182
return YES;
181183
}
182184

185+
- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error {
186+
NSParameterAssert(data != nil);
187+
NSParameterAssert(name != nil);
188+
189+
git_index_entry entry;
190+
memset(&entry, 0x0, sizeof(git_index_entry));
191+
entry.path = [name cStringUsingEncoding:NSUTF8StringEncoding];
192+
entry.mode = GIT_FILEMODE_BLOB;
193+
194+
int status = git_index_add_frombuffer(self.git_index, &entry, [data bytes], [data length]);
195+
196+
if (status != GIT_OK) {
197+
if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to add data with name %@ into index.", name];
198+
return NO;
199+
}
200+
201+
return YES;
202+
}
203+
183204
- (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error {
184205
NSParameterAssert(tree != nil);
185206

ObjectiveGit/GTIndexEntry.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929

3030
#import <Foundation/Foundation.h>
3131
#include "git2/index.h"
32+
#import "GTObject.h"
33+
34+
@class GTIndex;
3235

3336
typedef NS_ENUM(NSInteger, GTIndexEntryStatus) {
3437
GTIndexEntryStatusUpdated = 0,
@@ -40,6 +43,22 @@ typedef NS_ENUM(NSInteger, GTIndexEntryStatus) {
4043

4144
@interface GTIndexEntry : NSObject
4245

46+
/// Initializes the receiver with the given libgit2 index entry.
47+
///
48+
/// entry - The libgit2 index entry. Cannot be NULL.
49+
/// index - The index this entry belongs to.
50+
/// error - will be filled if an error occurs
51+
///
52+
/// Returns the initialized object.
53+
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry index:(GTIndex *)index error:(NSError **)error NS_DESIGNATED_INITIALIZER;
54+
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry;
55+
56+
/// The underlying `git_index_entry` object.
57+
- (const git_index_entry *)git_index_entry __attribute__((objc_returns_inner_pointer));
58+
59+
/// The entry's index. This may be nil if nil is passed in to -initWithGitIndexEntry:
60+
@property (nonatomic, strong, readonly) GTIndex *index;
61+
4362
/// The repository-relative path for the entry.
4463
@property (nonatomic, readonly, copy) NSString *path;
4564

@@ -49,14 +68,21 @@ typedef NS_ENUM(NSInteger, GTIndexEntryStatus) {
4968
/// What is the entry's status?
5069
@property (nonatomic, readonly) GTIndexEntryStatus status;
5170

52-
/// Initializes the receiver with the given libgit2 index entry.
71+
/// The OID of the entry.
72+
@property (nonatomic, strong, readonly) GTOID *OID;
73+
74+
/// Convert the entry into an GTObject
5375
///
54-
/// entry - The libgit2 index entry. Cannot be NULL.
76+
/// error - will be filled if an error occurs
5577
///
56-
/// Returns the initialized object.
57-
- (id)initWithGitIndexEntry:(const git_index_entry *)entry NS_DESIGNATED_INITIALIZER;
78+
/// Returns this entry as a GTObject or nil if an error occurred.
79+
- (GTObject *)GTObject:(NSError **)error;
5880

59-
/// The underlying `git_index_entry` object.
60-
- (const git_index_entry *)git_index_entry __attribute__((objc_returns_inner_pointer));
81+
@end
82+
83+
@interface GTObject (GTIndexEntry)
84+
85+
+ (instancetype)objectWithIndexEntry:(GTIndexEntry *)treeEntry error:(NSError **)error;
86+
- (instancetype)initWithIndexEntry:(GTIndexEntry *)treeEntry error:(NSError **)error;
6187

6288
@end

ObjectiveGit/GTIndexEntry.m

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
#import "GTIndexEntry.h"
3131
#import "NSError+Git.h"
3232
#import "NSString+Git.h"
33+
#import "GTOID.h"
34+
#import "GTRepository.h"
35+
#import "GTIndex.h"
36+
37+
#import "git2.h"
3338

3439
@interface GTIndexEntry ()
3540
@property (nonatomic, assign, readonly) const git_index_entry *git_index_entry;
@@ -40,22 +45,27 @@ @implementation GTIndexEntry
4045
#pragma mark NSObject
4146

4247
- (NSString *)description {
43-
return [NSString stringWithFormat:@"<%@: %p> path: %@", self.class, self, self.path];
48+
return [NSString stringWithFormat:@"<%@: %p> path: %@", self.class, self, self.path];
4449
}
4550

4651
#pragma mark Lifecycle
4752

48-
- (id)initWithGitIndexEntry:(const git_index_entry *)entry {
53+
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry index:(GTIndex *)index error:(NSError **)error {
4954
NSParameterAssert(entry != NULL);
5055

5156
self = [super init];
5257
if (self == nil) return nil;
5358

5459
_git_index_entry = entry;
55-
60+
_index = index;
61+
5662
return self;
5763
}
5864

65+
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry {
66+
return [self initWithGitIndexEntry:entry index:nil error:NULL];
67+
}
68+
5969
#pragma mark Properties
6070

6171
- (NSString *)path {
@@ -82,8 +92,45 @@ - (GTIndexEntryStatus)status {
8292
} else if ((self.flags & GIT_IDXENTRY_REMOVE) != 0) {
8393
return GTIndexEntryStatusRemoved;
8494
}
85-
95+
8696
return GTIndexEntryStatusUpToDate;
8797
}
8898

99+
- (GTOID *)OID {
100+
return [GTOID oidWithGitOid:&self.git_index_entry->id];
101+
}
102+
103+
#pragma mark API
104+
105+
- (GTRepository *)repository {
106+
return self.index.repository;
107+
}
108+
109+
- (GTObject *)GTObject:(NSError **)error {
110+
return [GTObject objectWithIndexEntry:self error:error];
111+
}
112+
113+
@end
114+
115+
@implementation GTObject (GTIndexEntry)
116+
117+
+ (instancetype)objectWithIndexEntry:(GTIndexEntry *)indexEntry error:(NSError **)error {
118+
return [[self alloc] initWithIndexEntry:indexEntry error:error];
119+
}
120+
121+
- (instancetype)initWithIndexEntry:(GTIndexEntry *)indexEntry error:(NSError **)error {
122+
git_object *obj;
123+
int gitError = git_object_lookup(&obj, indexEntry.repository.git_repository, indexEntry.OID.git_oid, (git_otype)GTObjectTypeAny);
124+
125+
if (gitError < GIT_OK) {
126+
if (error != NULL) {
127+
*error = [NSError git_errorFor:gitError description:@"Failed to get object for index entry."];
128+
}
129+
130+
return nil;
131+
}
132+
133+
return [self initWithObj:obj inRepository:indexEntry.repository];
134+
}
135+
89136
@end

ObjectiveGitTests/GTIndexSpec.m

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,31 @@
276276
});
277277
});
278278

279+
describe(@"adding data", ^{
280+
__block GTRepository *repo;
281+
__block GTIndex *index;
282+
__block NSError *error;
283+
284+
beforeEach(^{
285+
error = nil;
286+
repo = self.testUnicodeFixtureRepository;
287+
// Not sure why but it doesn't work with an in memory index
288+
// index = [GTIndex inMemoryIndexWithRepository:repo error:&error];
289+
index = [repo indexWithError:&error];
290+
expect(error).to(beNil());
291+
});
292+
293+
it(@"should store data at given path", ^{
294+
NSData *data = [NSData dataWithBytes:"foo" length:4];
295+
[index addData:data withName:@"bar/foo" error:&error];
296+
expect(error).to(beNil());
297+
298+
GTIndexEntry *entry = [index entryWithName:@"bar/foo" error:&error];
299+
expect(entry).notTo(beNil());
300+
expect(error).to(beNil());
301+
});
302+
});
303+
279304
afterEach(^{
280305
[self tearDown];
281306
});

0 commit comments

Comments
 (0)