From 6c52f86746581aacc4d0115989232a56903336ce Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Thu, 9 Apr 2015 20:04:44 -0300 Subject: [PATCH 1/7] Update libgit to get git_index_add_frombuffer --- External/libgit2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/External/libgit2 b/External/libgit2 index bdf0e7345..a01d3a0b5 160000 --- a/External/libgit2 +++ b/External/libgit2 @@ -1 +1 @@ -Subproject commit bdf0e734506b5b18234d48a0e7c6995aeda30b9d +Subproject commit a01d3a0b503559fe09519b787f353b25e52a0420 From 16a57f04fb7409a10cd509c001ef4eb0bded9729 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Thu, 9 Apr 2015 20:04:58 -0300 Subject: [PATCH 2/7] Wrap git_index_add_frombuffer --- ObjectiveGit/GTIndex.h | 6 ++++++ ObjectiveGit/GTIndex.m | 31 +++++++++++++++++++++++++++++++ ObjectiveGitTests/GTIndexSpec.m | 26 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/ObjectiveGit/GTIndex.h b/ObjectiveGit/GTIndex.h index b649e3455..d27ab5501 100644 --- a/ObjectiveGit/GTIndex.h +++ b/ObjectiveGit/GTIndex.h @@ -114,6 +114,9 @@ /// Returns a new GTIndexEntry, or nil if an error occurred. - (GTIndexEntry *)entryWithName:(NSString *)name error:(NSError **)error; +///TODO: Document +- (NSData *)dataWithName:(NSString *)name error:(NSError **)error; + /// Add an entry to the index. /// /// Note that this *cannot* add submodules. See -[GTSubmodule addToIndex:]. @@ -143,6 +146,9 @@ /// Returns whether reading the tree was successful. - (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error; +///TODO: Document +- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error; + /// Remove an entry (by relative path) from the index. /// Will fail if the receiver's repository is nil. /// diff --git a/ObjectiveGit/GTIndex.m b/ObjectiveGit/GTIndex.m index 940980f14..936b6a254 100644 --- a/ObjectiveGit/GTIndex.m +++ b/ObjectiveGit/GTIndex.m @@ -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" @@ -158,6 +159,18 @@ - (GTIndexEntry *)entryWithName:(NSString *)name error:(NSError **)error { return [self entryAtIndex:pos]; } +- (NSData *)dataWithName:(NSString *)name error:(NSError **)error { + GTIndexEntry *entry = [self entryWithName:name error:error]; + if (*error) return nil; + + const git_oid *oid = &entry.git_index_entry->id; + GTBlob *blob = [self.repository lookUpObjectByGitOid:oid + objectType:GTObjectTypeBlob + error:error]; + + return [blob data]; +} + - (BOOL)addEntry:(GTIndexEntry *)entry error:(NSError **)error { int status = git_index_add(self.git_index, entry.git_index_entry); if (status != GIT_OK) { @@ -191,6 +204,24 @@ - (BOOL)addContentsOfTree:(GTTree *)tree 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)removeFile:(NSString *)file error:(NSError **)error { NSString *unicodeString = [self composedUnicodeStringWithString:file]; diff --git a/ObjectiveGitTests/GTIndexSpec.m b/ObjectiveGitTests/GTIndexSpec.m index 9a93d88d2..1c52d6adb 100644 --- a/ObjectiveGitTests/GTIndexSpec.m +++ b/ObjectiveGitTests/GTIndexSpec.m @@ -276,6 +276,32 @@ }); }); +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()); + + NSData *returnData = [index dataWithName:@"bar/foo" error:&error]; + expect(error).to(beNil()); +// expect([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]).to(equal(@"foo")); + expect(returnData).to(equal(data)); + }); +}); + afterEach(^{ [self tearDown]; }); From 9594659a01b2664187158e67ef2982ff07307518 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Thu, 9 Apr 2015 20:52:49 -0300 Subject: [PATCH 3/7] Add documentation on addData --- ObjectiveGit/GTIndex.h | 12 +++++++++--- ObjectiveGit/GTIndex.m | 24 +++++++++++++----------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ObjectiveGit/GTIndex.h b/ObjectiveGit/GTIndex.h index d27ab5501..abb42ede7 100644 --- a/ObjectiveGit/GTIndex.h +++ b/ObjectiveGit/GTIndex.h @@ -115,6 +115,7 @@ - (GTIndexEntry *)entryWithName:(NSString *)name error:(NSError **)error; ///TODO: Document +/// Get the - (NSData *)dataWithName:(NSString *)name error:(NSError **)error; /// Add an entry to the index. @@ -138,6 +139,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 +/// name - The name of the entry to add +/// 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. @@ -146,9 +155,6 @@ /// Returns whether reading the tree was successful. - (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error; -///TODO: Document -- (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error; - /// Remove an entry (by relative path) from the index. /// Will fail if the receiver's repository is nil. /// diff --git a/ObjectiveGit/GTIndex.m b/ObjectiveGit/GTIndex.m index 936b6a254..1dbf0ad2b 100644 --- a/ObjectiveGit/GTIndex.m +++ b/ObjectiveGit/GTIndex.m @@ -77,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"]; @@ -193,17 +194,6 @@ - (BOOL)addFile:(NSString *)file error:(NSError **)error { return YES; } -- (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error { - NSParameterAssert(tree != nil); - - int status = git_index_read_tree(self.git_index, tree.git_tree); - if (status != GIT_OK) { - if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to read tree %@ into index.", tree]; - return NO; - } - - return YES; -} - (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error { NSParameterAssert(data != nil); NSParameterAssert(name != nil); @@ -223,6 +213,18 @@ - (BOOL)addData:(NSData *)data withName:(NSString *)name error:(NSError **)error return YES; } +- (BOOL)addContentsOfTree:(GTTree *)tree error:(NSError **)error { + NSParameterAssert(tree != nil); + + int status = git_index_read_tree(self.git_index, tree.git_tree); + if (status != GIT_OK) { + if (error != NULL) *error = [NSError git_errorFor:status description:@"Failed to read tree %@ into index.", tree]; + return NO; + } + + return YES; +} + - (BOOL)removeFile:(NSString *)file error:(NSError **)error { NSString *unicodeString = [self composedUnicodeStringWithString:file]; From 0b91bc4baa0b2186d2813615eefbbe3d86f00ad0 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Thu, 9 Apr 2015 20:53:49 -0300 Subject: [PATCH 4/7] remove data getter --- ObjectiveGit/GTIndex.h | 4 ---- ObjectiveGit/GTIndex.m | 12 ------------ 2 files changed, 16 deletions(-) diff --git a/ObjectiveGit/GTIndex.h b/ObjectiveGit/GTIndex.h index abb42ede7..d0b785738 100644 --- a/ObjectiveGit/GTIndex.h +++ b/ObjectiveGit/GTIndex.h @@ -114,10 +114,6 @@ /// Returns a new GTIndexEntry, or nil if an error occurred. - (GTIndexEntry *)entryWithName:(NSString *)name error:(NSError **)error; -///TODO: Document -/// Get the -- (NSData *)dataWithName:(NSString *)name error:(NSError **)error; - /// Add an entry to the index. /// /// Note that this *cannot* add submodules. See -[GTSubmodule addToIndex:]. diff --git a/ObjectiveGit/GTIndex.m b/ObjectiveGit/GTIndex.m index 1dbf0ad2b..a99d0e1e9 100644 --- a/ObjectiveGit/GTIndex.m +++ b/ObjectiveGit/GTIndex.m @@ -160,18 +160,6 @@ - (GTIndexEntry *)entryWithName:(NSString *)name error:(NSError **)error { return [self entryAtIndex:pos]; } -- (NSData *)dataWithName:(NSString *)name error:(NSError **)error { - GTIndexEntry *entry = [self entryWithName:name error:error]; - if (*error) return nil; - - const git_oid *oid = &entry.git_index_entry->id; - GTBlob *blob = [self.repository lookUpObjectByGitOid:oid - objectType:GTObjectTypeBlob - error:error]; - - return [blob data]; -} - - (BOOL)addEntry:(GTIndexEntry *)entry error:(NSError **)error { int status = git_index_add(self.git_index, entry.git_index_entry); if (status != GIT_OK) { From 816a6cda721213758f3d44fc3131a38fb96f8f92 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Thu, 9 Apr 2015 22:28:02 -0300 Subject: [PATCH 5/7] Add some methods to GTIndexEntry --- ObjectiveGit/GTIndexEntry.h | 38 ++++++++++++++++++++---- ObjectiveGit/GTIndexEntry.m | 52 ++++++++++++++++++++++++++++++++- ObjectiveGitTests/GTIndexSpec.m | 5 ++-- 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/ObjectiveGit/GTIndexEntry.h b/ObjectiveGit/GTIndexEntry.h index bba4a7436..8f2bc45ab 100644 --- a/ObjectiveGit/GTIndexEntry.h +++ b/ObjectiveGit/GTIndexEntry.h @@ -29,6 +29,9 @@ #import #include "git2/index.h" +#import "GTObject.h" + +@class GTIndex; typedef NS_ENUM(NSInteger, GTIndexEntryStatus) { GTIndexEntryStatusUpdated = 0, @@ -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; @@ -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 diff --git a/ObjectiveGit/GTIndexEntry.m b/ObjectiveGit/GTIndexEntry.m index 0360755da..3d9f81a68 100644 --- a/ObjectiveGit/GTIndexEntry.m +++ b/ObjectiveGit/GTIndexEntry.m @@ -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; @@ -45,17 +50,22 @@ - (NSString *)description { #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 { @@ -86,4 +96,44 @@ - (GTIndexEntryStatus)status { 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 + diff --git a/ObjectiveGitTests/GTIndexSpec.m b/ObjectiveGitTests/GTIndexSpec.m index 1c52d6adb..c065e359a 100644 --- a/ObjectiveGitTests/GTIndexSpec.m +++ b/ObjectiveGitTests/GTIndexSpec.m @@ -295,10 +295,9 @@ [index addData:data withName:@"bar/foo" error:&error]; expect(error).to(beNil()); - NSData *returnData = [index dataWithName:@"bar/foo" error:&error]; + GTIndexEntry *entry = [index entryWithName:@"bar/foo" error:&error]; + expect(entry).notTo(beNil()); expect(error).to(beNil()); -// expect([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]).to(equal(@"foo")); - expect(returnData).to(equal(data)); }); }); From ec9dbdad78401c12b245d89e1d61f101a4d69d1e Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Fri, 10 Apr 2015 00:45:21 -0300 Subject: [PATCH 6/7] Fix Index entry initialization --- ObjectiveGit/GTIndex.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ObjectiveGit/GTIndex.m b/ObjectiveGit/GTIndex.m index a99d0e1e9..dc3f23dcd 100644 --- a/ObjectiveGit/GTIndex.m +++ b/ObjectiveGit/GTIndex.m @@ -143,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 { From a64e9154b491060aa93279fe311634f8af88143a Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Fri, 10 Apr 2015 18:49:58 -0300 Subject: [PATCH 7/7] Fix formatting and documentation --- ObjectiveGit/GTIndex.h | 4 ++-- ObjectiveGit/GTIndexEntry.m | 13 +++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/ObjectiveGit/GTIndex.h b/ObjectiveGit/GTIndex.h index d0b785738..4119c8917 100644 --- a/ObjectiveGit/GTIndex.h +++ b/ObjectiveGit/GTIndex.h @@ -138,8 +138,8 @@ /// 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 -/// name - The name of the entry to add +/// 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; diff --git a/ObjectiveGit/GTIndexEntry.m b/ObjectiveGit/GTIndexEntry.m index 3d9f81a68..8a6971c70 100644 --- a/ObjectiveGit/GTIndexEntry.m +++ b/ObjectiveGit/GTIndexEntry.m @@ -45,7 +45,7 @@ @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 @@ -58,7 +58,7 @@ - (instancetype)initWithGitIndexEntry:(const git_index_entry *)entry index:(GTIn _git_index_entry = entry; _index = index; - + return self; } @@ -92,7 +92,7 @@ - (GTIndexEntryStatus)status { } else if ((self.flags & GIT_IDXENTRY_REMOVE) != 0) { return GTIndexEntryStatusRemoved; } - + return GTIndexEntryStatusUpToDate; } @@ -119,21 +119,18 @@ + (instancetype)objectWithIndexEntry:(GTIndexEntry *)indexEntry error:(NSError * } - (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."]; + *error = [NSError git_errorFor:gitError description:@"Failed to get object for index entry."]; } return nil; } - - return [self initWithObj:obj inRepository:indexEntry.repository]; + return [self initWithObj:obj inRepository:indexEntry.repository]; } @end -