Skip to content

Commit 78783db

Browse files
committed
Add a method to complete merges from the current repository state
1 parent f09bddd commit 78783db

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

Diff for: ObjectiveGit/GTRepository+Merging.h

+10
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ typedef NS_OPTIONS(NSInteger, GTMergePreference) {
6363
/// will point to an error describing what happened).
6464
- (BOOL)mergeBranchIntoCurrentBranch:(GTBranch *)fromBranch withError:(NSError **)error;
6565

66+
/// Complete a pending merge
67+
///
68+
/// This method can be used to complete a merge that has been stopped because
69+
/// of conflicts.
70+
///
71+
/// error - The error if one occurred. Can be NULL
72+
///
73+
/// Returns YES if the merge could be committed, NO otherwise.
74+
- (BOOL)finalizeMerge:(NSError **)error;
75+
6676
/// Gets the file content with conflict markers for the given file
6777
///
6878
/// The parameters taked are the ones received from `enumerateConflictedFiles`.

Diff for: ObjectiveGit/GTRepository+Merging.m

+63
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,69 @@ - (BOOL)mergeAnnotatedCommits:(NSArray <GTAnnotatedCommit *> *)annotatedCommits
129129
return YES;
130130
}
131131

132+
- (BOOL)finalizeMerge:(NSError **)error {
133+
GTRepositoryStateType state;
134+
BOOL success = [self calculateState:&state withError:error];
135+
if (!success) {
136+
return NO;
137+
}
138+
139+
if (state != GTRepositoryStateMerge) {
140+
if (error) *error = [NSError git_errorFor:GIT_EINVALID description:@"Repository is not in a merge state"];
141+
return NO;
142+
}
143+
144+
GTIndex *index = [self indexWithError:error];
145+
if (index == nil) {
146+
return NO;
147+
}
148+
149+
if (index.hasConflicts) {
150+
if (error) *error = [NSError git_errorFor:GIT_ECONFLICT description:@"Index has unmerged changes"];
151+
return NO;
152+
}
153+
154+
GTTree *mergedTree = [index writeTree:error];
155+
if (mergedTree == nil) {
156+
return NO;
157+
}
158+
159+
GTBranch *localBranch = [self currentBranchWithError:error];
160+
if (localBranch == nil) {
161+
return NO;
162+
}
163+
164+
GTCommit *localCommit = [localBranch targetCommitWithError:error];
165+
if (!localCommit) {
166+
return NO;
167+
}
168+
169+
// Build the commits' parents
170+
NSMutableArray *parents = [NSMutableArray array];
171+
[parents addObject:localCommit];
172+
173+
NSArray *mergeHeads = [self mergeHeadEntriesWithError:error];
174+
if (mergeHeads.count == 0) {
175+
return NO;
176+
}
177+
for (GTOID *oid in mergeHeads) {
178+
NSError *lookupError = nil;
179+
GTCommit *commit = [self lookUpObjectByOID:oid objectType:GTObjectTypeCommit error:&lookupError];
180+
if (commit == nil) {
181+
if (error) {
182+
*error = [NSError git_errorFor:GIT_ERROR
183+
description:@"Failed to lookup one of the merge heads"
184+
userInfo:@{ NSUnderlyingErrorKey: lookupError }
185+
failureReason:nil];
186+
}
187+
return NO;
188+
}
189+
[parents addObject:commit];
190+
}
191+
192+
return [self finalizeMergeOfBranch:localBranch mergedTree:mergedTree parents:parents error:error];
193+
}
194+
132195
- (BOOL)finalizeMergeOfBranch:(GTBranch *)localBranch mergedTree:(GTTree *)mergedTree parents:(NSArray <GTCommit *> *)parents error:(NSError **)error {
133196

134197
// Load the message to use

0 commit comments

Comments
 (0)