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
31 changes: 31 additions & 0 deletions ObjectiveGit/GTRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,20 @@ extern NSString * const GTRepositoryInitOptionsInitialHEAD;
/// initialization.
extern NSString * const GTRepositoryInitOptionsOriginURLString;

/// The possible states for the repository to be in, based on the current ongoing operation.
typedef NS_ENUM(NSInteger, GTRepositoryStateType) {
GTRepositoryStateNone = GIT_REPOSITORY_STATE_NONE,
GTRepositoryStateMerge = GIT_REPOSITORY_STATE_MERGE,
GTRepositoryStateRevert = GIT_REPOSITORY_STATE_REVERT,
GTRepositoryStateCherryPick = GIT_REPOSITORY_STATE_CHERRYPICK,
GTRepositoryStateBisect = GIT_REPOSITORY_STATE_BISECT,
GTRepositoryStateRebase = GIT_REPOSITORY_STATE_REBASE,
GTRepositoryStateRebaseInteractive = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
GTRepositoryStateRebaseMerge = GIT_REPOSITORY_STATE_REBASE_MERGE,
GTRepositoryStateApplyMailbox = GIT_REPOSITORY_STATE_APPLY_MAILBOX,
GTRepositoryStateApplyMailboxOrRebase = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE,
};

@interface GTRepository : NSObject

/// The file URL for the repository's working directory.
Expand Down Expand Up @@ -573,6 +587,23 @@ extern NSString * const GTRepositoryInitOptionsOriginURLString;
/// Returns the enumerator or nil if an error occurred.
- (nullable GTEnumerator *)enumeratorForUniqueCommitsFromOID:(GTOID *)fromOID relativeToOID:(GTOID *)relativeOID error:(NSError **)error;

/// Determines the status of a git repository--i.e., whether an operation
/// (merge, cherry-pick, etc) is in progress.
///
/// state - A pointer to set the retrieved state. Must not be NULL.
/// error - The error if one occurred.
///
/// Returns YES if operation was successful, NO otherwise
- (BOOL)calculateState:(GTRepositoryStateType *)state withError:(NSError **)error;

/// Remove all the metadata associated with an ongoing command like merge,
/// revert, cherry-pick, etc. For example: MERGE_HEAD, MERGE_MSG, etc.
///
/// error - The error if one occurred.
///
/// Returns YES if operation was successful, NO otherwise
- (BOOL)cleanupStateWithError:(NSError **)error;

@end

NS_ASSUME_NONNULL_END
21 changes: 21 additions & 0 deletions ObjectiveGit/GTRepository.m
Original file line number Diff line number Diff line change
Expand Up @@ -898,4 +898,25 @@ - (nullable GTEnumerator *)enumeratorForUniqueCommitsFromOID:(GTOID *)fromOID re
return enumerator;
}

- (BOOL)calculateState:(GTRepositoryStateType *)state withError:(NSError **)error {
NSParameterAssert(state != NULL);

int result = git_repository_state(self.git_repository);
if (result < 0) {
if (error != NULL) *error = [NSError git_errorFor:result description:@"Failed to calculate repository state"];
return NO;
}

*state = result;
return YES;
}

- (BOOL)cleanupStateWithError:(NSError * _Nullable __autoreleasing *)error {
int errorCode = git_repository_state_cleanup(self.git_repository);
if (errorCode != GIT_OK) {
if (error != NULL) *error = [NSError git_errorFor:errorCode description:@"Failed to clean up repository state"];
}
return YES;
}

@end
38 changes: 38 additions & 0 deletions ObjectiveGitTests/GTRepositorySpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,44 @@
});
});

describe(@"-calculateState:withError:", ^{
it(@"should find if the repository is mid-merge", ^{
GTRepository *repository = [self conflictedFixtureRepository];
GTRepositoryStateType state;
BOOL result;
result = [repository calculateState:&state withError:NULL];
expect(@(result)).to(beTruthy());
expect(@(state)).to(equal(@(GTRepositoryStateMerge)));
});

it(@"should return none otherwise", ^{
GTRepository *repository = [self testAppFixtureRepository];
GTRepositoryStateType state;
BOOL result;
result = [repository calculateState:&state withError:NULL];
expect(@(result)).to(beTruthy());
expect(@(state)).to(equal(@(GTRepositoryStateNone)));
});
});

describe(@"-cleanupStateWithError:", ^{
it(@"should return a repository to a pre-merge state", ^{
GTRepository *repository = [self conflictedFixtureRepository];

GTRepositoryStateType state;
BOOL result;
result = [repository calculateState:&state withError:NULL];
expect(@(result)).to(beTruthy());
expect(@(state)).to(equal(@(GTRepositoryStateMerge)));

expect(@([repository cleanupStateWithError:NULL])).to(beTruthy());

result = [repository calculateState:&state withError:NULL];
expect(@(result)).to(beTruthy());
expect(@(state)).to(equal(@(GTRepositoryStateNone)));
});
});

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