Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add stash commands #198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
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
34 changes: 34 additions & 0 deletions Classes/GTRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ typedef enum {
GTRepositoryResetTypeHard = GIT_RESET_HARD
} GTRepositoryResetType;

// Flags for -stashChangesWithMessage:flags:error:.
// Those can be ORed together. See git_stash_flags for additional information.
typedef enum {
GTRepositoryStashFlagDefault = GIT_STASH_DEFAULT,
GTRepositoryStashFlagKeepIndex = GIT_STASH_KEEP_INDEX,
GTRepositoryStashFlagIncludeUntracked = GIT_STASH_INCLUDE_UNTRACKED,
GTRepositoryStashFlagIncludeIgnored = GIT_STASH_INCLUDE_IGNORED
} GTRepositoryStashFlag;

typedef void (^GTRepositoryStatusBlock)(NSURL *fileURL, GTRepositoryFileStatus status, BOOL *stop);

@interface GTRepository : NSObject
Expand Down Expand Up @@ -202,6 +211,31 @@ typedef void (^GTRepositoryStatusBlock)(NSURL *fileURL, GTRepositoryFileStatus s
// Returns the signature.
- (GTSignature *)userSignatureForNow;

// Stash the repository's changes.
//
// message - Optional message to be attributed to the item in the stash.
// stashFlag - The flags of stash to be used.
// error - If not NULL, it will be set on return to any error that occurred
//
// Returns commit of the stashed changes if successful, nil otherwise
- (GTCommit *)stashChangesWithMessage:(NSString *)message flags:(GTRepositoryStashFlag)flags error:(NSError **)error;

// Enumerate over all the stashes in the repository
//
// block - A block to execute for each stash found, giving the stash's index and
// message along with its OID. Setting `stop` to YES will cause enumeration
// to stop after the block returns.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like some tabs got mixed in here. Otherwise, great documentation!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we should document whether it's safe to modify the stashes during enumeration. Can I safely call -dropStashAtIndex:error: from this block?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely no idea... It's not precised in the documentation to git_stash_delete/git_stash_foreach and I can't easily tell just by looking at the code since I'm a complete libgit2 noob. I'll do some tests (as I said, that's fairly preliminary stuff).

//
- (void)enumerateStashesUsingBlock:(void (^)(size_t index, NSString *message, GTOID *oid, BOOL *stop))block;

// Drop a stash from the repository's list of stashes
//
// index - The index of the stash to drop
// error - If not NULL, set to any error that occurs
//
// Returns YES if the stash was successfully dropped, NO otherwise
- (BOOL)dropStashAtIndex:(size_t)index error:(NSError **)error;

// Reloads all cached information about the receiver's submodules.
//
// Existing GTSubmodule objects from this repository will be mutated as part of
Expand Down
49 changes: 48 additions & 1 deletion Classes/GTRepository.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@
#import "NSError+Git.h"
#import "NSString+Git.h"

// The type of block passed to -enumerateSubmodulesRecursively:usingBlock:.
// Blocks typedef for -enumerateSubmodulesRecursively:usingBlock: and
// -enumerateStashesWithBlock:flags:error:.
typedef void (^GTRepositorySubmoduleEnumerationBlock)(GTSubmodule *submodule, BOOL *stop);
typedef void (^GTRepositoryStashEnumerationBlock)(size_t index, NSString *message, GTOID *oid, BOOL *stop);

// Used as a payload for submodule enumeration.
//
Expand Down Expand Up @@ -614,4 +616,49 @@ - (GTSignature *)userSignatureForNow {
return [[GTSignature alloc] initWithName:name email:email time:[NSDate date]];
}

#pragma mark Stash

- (GTCommit*)stashChangesWithMessage:(NSString *)message flags:(GTRepositoryStashFlag)flags error:(NSError **)error
{
git_oid oid;
git_signature *sign = (git_signature *)[self userSignatureForNow].git_signature;

int gitError = git_stash_save(&oid, self.git_repository, sign, [message UTF8String], flags);
if (gitError != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:gitError withAdditionalDescription:@"Failed to stash."];
return nil;
}

GTCommit* commit = (GTCommit*)[self lookupObjectByOid:&oid error:error];

return commit;
}

static int stashEnumerationCallback(size_t index, const char* message, const git_oid *stash_id, void *payload) {
GTRepositoryStashEnumerationBlock block = (__bridge GTRepositoryStashEnumerationBlock)payload;

NSString *messageString = @(message);
GTOID *stash_oid = [[GTOID alloc] initWithGitOid:stash_id];
BOOL stop = NO;

block(index, messageString, stash_oid, &stop);

return stop;
}

- (void)enumerateStashesUsingBlock:(GTRepositoryStashEnumerationBlock)block {
NSParameterAssert(block != nil);

git_stash_foreach(self.git_repository, &stashEnumerationCallback, &block);
}

- (BOOL)dropStashAtIndex:(size_t)index error:(NSError **)error {
int gitError = git_stash_drop(self.git_repository, index);
if (gitError != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:gitError withAdditionalDescription:@"Failed to drop stash."];
return NO;
}
return YES;
}

@end
10 changes: 10 additions & 0 deletions ObjectiveGitTests/GTRepositorySpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,14 @@
});
});

describe(@"-stashChangesWithMessage:flags:error:", ^{
it(@"should fail if there's nothing to stash (with default options)", ^{
NSError *error = nil;
GTCommit *stash = [repository stashChangesWithMessage:nil flags:GTRepositoryStashFlagDefault error:&error];
expect(stash).to.beNil();
expect(error).notTo.beNil();
expect(error.code).to.equal(GIT_ENOTFOUND);
});
});

SpecEnd