Skip to content

Commit

Permalink
Merge pull request #458 from sagmor/index_add_frombuffer
Browse files Browse the repository at this point in the history
Add/Fetch NSData from index
  • Loading branch information
joshaber committed Apr 13, 2015
2 parents 30219e2 + a64e915 commit a2de081
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 12 deletions.
2 changes: 1 addition & 1 deletion External/libgit2
Submodule libgit2 updated 148 files
8 changes: 8 additions & 0 deletions ObjectiveGit/GTIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@
/// Returns YES if successful, NO otherwise.
- (BOOL)addFile:(NSString *)file error:(NSError **)error;

/// Add an entry (with the provided data and name) to the index.
/// Will fail if the receiver's repository is nil.
///
/// data - The content of the entry to add. Cannot be nil.
/// name - The name of the entry to add. Cannot be nil.
/// error - The error if one occurred.
- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error;

/// Reads the contents of the given tree into the index.
///
/// tree - The tree to add to the index. This must not be nil.
Expand Down
23 changes: 22 additions & 1 deletion ObjectiveGit/GTIndex.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#import "GTRepository+Private.h"
#import "GTRepository.h"
#import "GTTree.h"
#import "GTBlob.h"
#import "NSArray+StringArray.h"
#import "NSError+Git.h"

Expand Down Expand Up @@ -76,6 +77,7 @@ - (void)dealloc {

+ (instancetype)inMemoryIndexWithRepository:(GTRepository *)repository error:(NSError **)error {
git_index *index = NULL;

int status = git_index_new(&index);
if (status != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to initialize in-memory index"];
Expand Down Expand Up @@ -141,7 +143,7 @@ - (GTIndexEntry *)entryAtIndex:(NSUInteger)index {
const git_index_entry *entry = git_index_get_byindex(self.git_index, (unsigned int)index);
if (entry == NULL) return nil;

return [[GTIndexEntry alloc] initWithGitIndexEntry:entry];
return [[GTIndexEntry alloc] initWithGitIndexEntry:entry index:self error:NULL];
}

- (GTIndexEntry *)entryWithName:(NSString *)name {
Expand Down Expand Up @@ -180,6 +182,25 @@ - (BOOL)addFile:(NSString *)file error:(NSError **)error {
return YES;
}

- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error {
NSParameterAssert(data != nil);
NSParameterAssert(name != nil);

git_index_entry entry;
memset(&entry, 0x0, sizeof(git_index_entry));
entry.path = [name cStringUsingEncoding:NSUTF8StringEncoding];
entry.mode = GIT_FILEMODE_BLOB;

int status = git_index_add_frombuffer(self.git_index, &entry, [data bytes], [data length]);

if (status != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to add data with name %@ into index.", name];
return NO;
}

return YES;
}

- (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error {
NSParameterAssert(tree != nil);

Expand Down
38 changes: 32 additions & 6 deletions ObjectiveGit/GTIndexEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

#import <Foundation/Foundation.h>
#include "git2/index.h"
#import "GTObject.h"

@class GTIndex;

typedef NS_ENUM(NSInteger, GTIndexEntryStatus) {
GTIndexEntryStatusUpdated = 0,
Expand All @@ -40,6 +43,22 @@ typedef NS_ENUM(NSInteger, GTIndexEntryStatus) {

@interface GTIndexEntry : NSObject

/// Initializes the receiver with the given libgit2 index entry.
///
/// entry - The libgit2 index entry. Cannot be NULL.
/// index - The index this entry belongs to.
/// error - will be filled if an error occurs
///
/// Returns the initialized object.
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry index:(GTIndex *)index error:(NSError **)error NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry;

/// The underlying `git_index_entry` object.
- (const git_index_entry *)git_index_entry __attribute__((objc_returns_inner_pointer));

/// The entry's index. This may be nil if nil is passed in to -initWithGitIndexEntry:
@property (nonatomic, strong, readonly) GTIndex *index;

/// The repository-relative path for the entry.
@property (nonatomic, readonly, copy) NSString *path;

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

/// Initializes the receiver with the given libgit2 index entry.
/// The OID of the entry.
@property (nonatomic, strong, readonly) GTOID *OID;

/// Convert the entry into an GTObject
///
/// entry - The libgit2 index entry. Cannot be NULL.
/// error - will be filled if an error occurs
///
/// Returns the initialized object.
- (id)initWithGitIndexEntry:(const git_index_entry *)entry NS_DESIGNATED_INITIALIZER;
/// Returns this entry as a GTObject or nil if an error occurred.
- (GTObject *)GTObject:(NSError **)error;

/// The underlying `git_index_entry` object.
- (const git_index_entry *)git_index_entry __attribute__((objc_returns_inner_pointer));
@end

@interface GTObject (GTIndexEntry)

+ (instancetype)objectWithIndexEntry:(GTIndexEntry *)treeEntry error:(NSError **)error;
- (instancetype)initWithIndexEntry:(GTIndexEntry *)treeEntry error:(NSError **)error;

@end
55 changes: 51 additions & 4 deletions ObjectiveGit/GTIndexEntry.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
#import "GTIndexEntry.h"
#import "NSError+Git.h"
#import "NSString+Git.h"
#import "GTOID.h"
#import "GTRepository.h"
#import "GTIndex.h"

#import "git2.h"

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

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

#pragma mark Lifecycle

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

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

_git_index_entry = entry;

_index = index;

return self;
}

- (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry {
return [self initWithGitIndexEntry:entry index:nil error:NULL];
}

#pragma mark Properties

- (NSString *)path {
Expand All @@ -82,8 +92,45 @@ - (GTIndexEntryStatus)status {
} else if ((self.flags & GIT_IDXENTRY_REMOVE) != 0) {
return GTIndexEntryStatusRemoved;
}

return GTIndexEntryStatusUpToDate;
}

- (GTOID *)OID {
return [GTOID oidWithGitOid:&self.git_index_entry->id];
}

#pragma mark API

- (GTRepository *)repository {
return self.index.repository;
}

- (GTObject *)GTObject:(NSError **)error {
return [GTObject objectWithIndexEntry:self error:error];
}

@end

@implementation GTObject (GTIndexEntry)

+ (instancetype)objectWithIndexEntry:(GTIndexEntry *)indexEntry error:(NSError **)error {
return [[self alloc] initWithIndexEntry:indexEntry error:error];
}

- (instancetype)initWithIndexEntry:(GTIndexEntry *)indexEntry error:(NSError **)error {
git_object *obj;
int gitError = git_object_lookup(&obj, indexEntry.repository.git_repository, indexEntry.OID.git_oid, (git_otype)GTObjectTypeAny);

if (gitError < GIT_OK) {
if (error != NULL) {
*error = [NSError git_errorFor:gitError description:@"Failed to get object for index entry."];
}

return nil;
}

return [self initWithObj:obj inRepository:indexEntry.repository];
}

@end
25 changes: 25 additions & 0 deletions ObjectiveGitTests/GTIndexSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,31 @@
});
});

describe(@"adding data", ^{
__block GTRepository *repo;
__block GTIndex *index;
__block NSError *error;

beforeEach(^{
error = nil;
repo = self.testUnicodeFixtureRepository;
// Not sure why but it doesn't work with an in memory index
// index = [GTIndex inMemoryIndexWithRepository:repo error:&error];
index = [repo indexWithError:&error];
expect(error).to(beNil());
});

it(@"should store data at given path", ^{
NSData *data = [NSData dataWithBytes:"foo" length:4];
[index addData:data withName:@"bar/foo" error:&error];
expect(error).to(beNil());

GTIndexEntry *entry = [index entryWithName:@"bar/foo" error:&error];
expect(entry).notTo(beNil());
expect(error).to(beNil());
});
});

afterEach(^{
[self tearDown];
});
Expand Down

0 comments on commit a2de081

Please sign in to comment.