Skip to content

Commit 9560b9f

Browse files
committed
Merge pull request #510 from dleehr/fix-checkout-notify
Fix checkout methods that use notifyBlock/GTCheckoutStrategySafe
2 parents f86fc7e + 5fa70c9 commit 9560b9f

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

ObjectiveGit/GTRepository.m

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ - (BOOL)moveHEADToCommit:(GTCommit *)commit error:(NSError **)error {
809809
return gitError == GIT_OK;
810810
}
811811

812-
- (BOOL)performCheckoutWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
812+
- (BOOL)performCheckout:(GTObject *)target withStrategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
813813

814814
git_checkout_options checkoutOptions = GIT_CHECKOUT_OPTIONS_INIT;
815815

@@ -821,7 +821,7 @@ - (BOOL)performCheckoutWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags
821821
checkoutOptions.notify_flags = notifyFlags;
822822
checkoutOptions.notify_payload = (__bridge void *)notifyBlock;
823823

824-
int gitError = git_checkout_head(self.git_repository, &checkoutOptions);
824+
int gitError = git_checkout_tree(self.git_repository, target.git_object, &checkoutOptions);
825825
if (gitError < GIT_OK) {
826826
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to checkout tree."];
827827
}
@@ -830,17 +830,18 @@ - (BOOL)performCheckoutWithStrategy:(GTCheckoutStrategyType)strategy notifyFlags
830830
}
831831

832832
- (BOOL)checkoutCommit:(GTCommit *)targetCommit strategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
833-
BOOL success = [self moveHEADToCommit:targetCommit error:error];
833+
BOOL success = [self performCheckout:targetCommit withStrategy:strategy notifyFlags:notifyFlags error:error progressBlock:progressBlock notifyBlock:notifyBlock];
834834
if (success == NO) return NO;
835-
836-
return [self performCheckoutWithStrategy:strategy notifyFlags:notifyFlags error:error progressBlock:progressBlock notifyBlock:notifyBlock];
835+
return [self moveHEADToCommit:targetCommit error:error];
837836
}
838837

839838
- (BOOL)checkoutReference:(GTReference *)targetReference strategy:(GTCheckoutStrategyType)strategy notifyFlags:(GTCheckoutNotifyFlags)notifyFlags error:(NSError **)error progressBlock:(GTCheckoutProgressBlock)progressBlock notifyBlock:(GTCheckoutNotifyBlock)notifyBlock {
840-
BOOL success = [self moveHEADToReference:targetReference error:error];
839+
GTOID *targetOID = [targetReference targetOID];
840+
GTObject *target = [self lookUpObjectByOID:targetOID error:error];
841+
if (target == nil) return NO;
842+
BOOL success = [self performCheckout:target withStrategy:strategy notifyFlags:notifyFlags error:error progressBlock:progressBlock notifyBlock:notifyBlock];
841843
if (success == NO) return NO;
842-
843-
return [self performCheckoutWithStrategy:strategy notifyFlags:notifyFlags error:error progressBlock:progressBlock notifyBlock:notifyBlock];
844+
return [self moveHEADToReference:targetReference error:error];
844845
}
845846

846847
- (BOOL)checkoutCommit:(GTCommit *)target strategy:(GTCheckoutStrategyType)strategy error:(NSError **)error progressBlock:(GTCheckoutProgressBlock)progressBlock {

ObjectiveGitTests/GTRepositorySpec.m

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
QuickSpecBegin(GTRepositorySpec)
1616

17+
static NSString * const readmeFile = @"README.md";
18+
static NSString * const readme1File = @"README1.txt";
19+
20+
1721
__block GTRepository *repository;
1822

1923
beforeEach(^{
@@ -376,6 +380,58 @@
376380
});
377381
});
378382

383+
describe(@"-checkout:strategy:notifyFlags:error:notifyBlock:progressBlock:", ^{
384+
it(@"should fail ref checkout with conflict and notify", ^{
385+
NSError *error = nil;
386+
GTReference *ref = [repository lookUpReferenceWithName:@"refs/heads/other-branch" error:&error];
387+
expect(ref).notTo(beNil());
388+
expect(error.localizedDescription).to(beNil());
389+
BOOL writeResult = [@"Conflicting data in README.md\n" writeToURL:[repository.fileURL URLByAppendingPathComponent:readmeFile] atomically:YES encoding:NSUTF8StringEncoding error:&error];
390+
expect(@(writeResult)).to(beTruthy());
391+
__block NSUInteger notifyCount = 0;
392+
__block BOOL readmeFileConflicted = NO;
393+
int (^notifyBlock)(GTCheckoutNotifyFlags, NSString *, GTDiffFile *, GTDiffFile *, GTDiffFile *);
394+
notifyBlock = ^(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir) {
395+
notifyCount++;
396+
if([path isEqualToString:readmeFile] && (why & GTCheckoutNotifyConflict)) {
397+
readmeFileConflicted = YES;
398+
}
399+
return 0;
400+
};
401+
402+
BOOL result = [repository checkoutReference:ref strategy:GTCheckoutStrategySafe notifyFlags:GTCheckoutNotifyConflict error:&error progressBlock:nil notifyBlock:notifyBlock];
403+
expect(@(notifyCount)).to(equal(@(1)));
404+
expect(@(readmeFileConflicted)).to(beTruthy());
405+
expect(@(result)).to(beFalsy());
406+
expect(@(error.code)).to(equal(@(GIT_ECONFLICT)));
407+
});
408+
409+
it(@"should fail commit checkout with conflict and notify", ^{
410+
NSError *error = nil;
411+
GTCommit *commit = [repository lookUpObjectBySHA:@"1d69f3c0aeaf0d62e25591987b93b8ffc53abd77" objectType:GTObjectTypeCommit error:&error];
412+
expect(commit).notTo(beNil());
413+
expect(error.localizedDescription).to(beNil());
414+
BOOL writeResult = [@"Conflicting data in README1.txt\n" writeToURL:[repository.fileURL URLByAppendingPathComponent:readme1File] atomically:YES encoding:NSUTF8StringEncoding error:&error];
415+
expect(@(writeResult)).to(beTruthy());
416+
__block NSUInteger notifyCount = 0;
417+
__block BOOL readme1FileConflicted = NO;
418+
int (^notifyBlock)(GTCheckoutNotifyFlags, NSString *, GTDiffFile *, GTDiffFile *, GTDiffFile *);
419+
notifyBlock = ^(GTCheckoutNotifyFlags why, NSString *path, GTDiffFile *baseline, GTDiffFile *target, GTDiffFile *workdir) {
420+
notifyCount++;
421+
if([path isEqualToString:readme1File] && (why & GTCheckoutNotifyConflict)) {
422+
readme1FileConflicted = YES;
423+
}
424+
return 0;
425+
};
426+
427+
BOOL result = [repository checkoutCommit:commit strategy:GTCheckoutStrategySafe notifyFlags:GTCheckoutNotifyConflict error:&error progressBlock:nil notifyBlock:notifyBlock];
428+
expect(@(notifyCount)).to(equal(@(1)));
429+
expect(@(readme1FileConflicted)).to(beTruthy());
430+
expect(@(result)).to(beFalsy());
431+
expect(@(error.code)).to(equal(@(GIT_ECONFLICT)));
432+
});
433+
});
434+
379435
describe(@"-remoteNamesWithError:", ^{
380436
it(@"allows access to remote names", ^{
381437
NSError *error = nil;

0 commit comments

Comments
 (0)