Skip to content

Commit ca46c73

Browse files
committed
Merge pull request #556 from libgit2/repository-state
Add APIs to calculate and cleanup repository states
2 parents 8b46e45 + 9b092ac commit ca46c73

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

ObjectiveGit/GTRepository.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,20 @@ extern NSString * const GTRepositoryInitOptionsInitialHEAD;
150150
/// initialization.
151151
extern NSString * const GTRepositoryInitOptionsOriginURLString;
152152

153+
/// The possible states for the repository to be in, based on the current ongoing operation.
154+
typedef NS_ENUM(NSInteger, GTRepositoryStateType) {
155+
GTRepositoryStateNone = GIT_REPOSITORY_STATE_NONE,
156+
GTRepositoryStateMerge = GIT_REPOSITORY_STATE_MERGE,
157+
GTRepositoryStateRevert = GIT_REPOSITORY_STATE_REVERT,
158+
GTRepositoryStateCherryPick = GIT_REPOSITORY_STATE_CHERRYPICK,
159+
GTRepositoryStateBisect = GIT_REPOSITORY_STATE_BISECT,
160+
GTRepositoryStateRebase = GIT_REPOSITORY_STATE_REBASE,
161+
GTRepositoryStateRebaseInteractive = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE,
162+
GTRepositoryStateRebaseMerge = GIT_REPOSITORY_STATE_REBASE_MERGE,
163+
GTRepositoryStateApplyMailbox = GIT_REPOSITORY_STATE_APPLY_MAILBOX,
164+
GTRepositoryStateApplyMailboxOrRebase = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE,
165+
};
166+
153167
@interface GTRepository : NSObject
154168

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

590+
/// Determines the status of a git repository--i.e., whether an operation
591+
/// (merge, cherry-pick, etc) is in progress.
592+
///
593+
/// state - A pointer to set the retrieved state. Must not be NULL.
594+
/// error - The error if one occurred.
595+
///
596+
/// Returns YES if operation was successful, NO otherwise
597+
- (BOOL)calculateState:(GTRepositoryStateType *)state withError:(NSError **)error;
598+
599+
/// Remove all the metadata associated with an ongoing command like merge,
600+
/// revert, cherry-pick, etc. For example: MERGE_HEAD, MERGE_MSG, etc.
601+
///
602+
/// error - The error if one occurred.
603+
///
604+
/// Returns YES if operation was successful, NO otherwise
605+
- (BOOL)cleanupStateWithError:(NSError **)error;
606+
576607
@end
577608

578609
NS_ASSUME_NONNULL_END

ObjectiveGit/GTRepository.m

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,4 +898,25 @@ - (nullable GTEnumerator *)enumeratorForUniqueCommitsFromOID:(GTOID *)fromOID re
898898
return enumerator;
899899
}
900900

901+
- (BOOL)calculateState:(GTRepositoryStateType *)state withError:(NSError **)error {
902+
NSParameterAssert(state != NULL);
903+
904+
int result = git_repository_state(self.git_repository);
905+
if (result < 0) {
906+
if (error != NULL) *error = [NSError git_errorFor:result description:@"Failed to calculate repository state"];
907+
return NO;
908+
}
909+
910+
*state = result;
911+
return YES;
912+
}
913+
914+
- (BOOL)cleanupStateWithError:(NSError * _Nullable __autoreleasing *)error {
915+
int errorCode = git_repository_state_cleanup(self.git_repository);
916+
if (errorCode != GIT_OK) {
917+
if (error != NULL) *error = [NSError git_errorFor:errorCode description:@"Failed to clean up repository state"];
918+
}
919+
return YES;
920+
}
921+
901922
@end

ObjectiveGitTests/GTRepositorySpec.m

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,44 @@
700700
});
701701
});
702702

703+
describe(@"-calculateState:withError:", ^{
704+
it(@"should find if the repository is mid-merge", ^{
705+
GTRepository *repository = [self conflictedFixtureRepository];
706+
GTRepositoryStateType state;
707+
BOOL result;
708+
result = [repository calculateState:&state withError:NULL];
709+
expect(@(result)).to(beTruthy());
710+
expect(@(state)).to(equal(@(GTRepositoryStateMerge)));
711+
});
712+
713+
it(@"should return none otherwise", ^{
714+
GTRepository *repository = [self testAppFixtureRepository];
715+
GTRepositoryStateType state;
716+
BOOL result;
717+
result = [repository calculateState:&state withError:NULL];
718+
expect(@(result)).to(beTruthy());
719+
expect(@(state)).to(equal(@(GTRepositoryStateNone)));
720+
});
721+
});
722+
723+
describe(@"-cleanupStateWithError:", ^{
724+
it(@"should return a repository to a pre-merge state", ^{
725+
GTRepository *repository = [self conflictedFixtureRepository];
726+
727+
GTRepositoryStateType state;
728+
BOOL result;
729+
result = [repository calculateState:&state withError:NULL];
730+
expect(@(result)).to(beTruthy());
731+
expect(@(state)).to(equal(@(GTRepositoryStateMerge)));
732+
733+
expect(@([repository cleanupStateWithError:NULL])).to(beTruthy());
734+
735+
result = [repository calculateState:&state withError:NULL];
736+
expect(@(result)).to(beTruthy());
737+
expect(@(state)).to(equal(@(GTRepositoryStateNone)));
738+
});
739+
});
740+
703741
afterEach(^{
704742
[self tearDown];
705743
});

0 commit comments

Comments
 (0)