Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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