Skip to content

Commit 26a85b2

Browse files
committed
Wrap git_merge_file
1 parent e3a95be commit 26a85b2

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

ObjectiveGit/GTRepository+Merging.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "GTRepository.h"
10+
#import "GTIndexEntry.h"
1011
#import "git2/merge.h"
1112

1213
NS_ASSUME_NONNULL_BEGIN
@@ -52,6 +53,18 @@ typedef NS_OPTIONS(NSInteger, GTMergeAnalysis) {
5253
/// will point to an error describing what happened).
5354
- (BOOL)mergeBranchIntoCurrentBranch:(GTBranch *)fromBranch withError:(NSError **)error;
5455

56+
/// Gets the file content with conflict markers for the given file
57+
///
58+
/// The parameters taked are the ones received from `enumerateConflictedFiles`.
59+
///
60+
/// ancestor - The ancestor entry
61+
/// ours - The index entry of our side
62+
/// theirs - The index entry of their side
63+
/// error - The error if one occurred. Can be NULL.
64+
///
65+
/// Returns The file content annotated with conflict markers or null on error
66+
- (NSString* _Nullable)stringForConflictWithAncestor:(GTIndexEntry *)ancestor ourSide:(GTIndexEntry *)ourSide theirSide:(GTIndexEntry *)theirSide withError:(NSError **)error;
67+
5568
/// Analyze which merge to perform.
5669
///
5770
/// analysis - The resulting analysis.

ObjectiveGit/GTRepository+Merging.m

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#import "GTTree.h"
1818
#import "GTIndex.h"
1919
#import "GTIndexEntry.h"
20+
#import "GTOdbObject.h"
21+
#import "GTObjectDatabase.h"
2022

2123
typedef void (^GTRemoteFetchTransferProgressBlock)(const git_transfer_progress *stats, BOOL *stop);
2224

@@ -170,6 +172,86 @@ - (BOOL)mergeBranchIntoCurrentBranch:(GTBranch *)branch withError:(NSError **)er
170172
return NO;
171173
}
172174

175+
- (NSString* _Nullable)stringForConflictWithAncestor:(GTIndexEntry *)ancestor ourSide:(GTIndexEntry *)ourSide theirSide:(GTIndexEntry *)theirSide withError:(NSError **)error {
176+
177+
GTObjectDatabase *database = [self objectDatabaseWithError:error];
178+
if (database == nil) {
179+
return nil;
180+
}
181+
182+
// initialize the ancestor's merge file input
183+
git_merge_file_input ancestorInput;
184+
int gitError = git_merge_file_init_input(&ancestorInput, GIT_MERGE_FILE_INPUT_VERSION);
185+
if (gitError != GIT_OK) {
186+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to create merge file input for ancestor"];
187+
return nil;
188+
}
189+
190+
git_oid ancestorId = ancestor.git_index_entry->id;
191+
GTOID *ancestorOID = [[GTOID alloc] initWithGitOid:&ancestorId];
192+
NSData *ancestorData = [[database objectWithOID:ancestorOID error: error] data];
193+
if (ancestorData == nil) {
194+
return nil;
195+
}
196+
NSString *ancestorString = [[NSString alloc] initWithData: ancestorData encoding:NSUTF8StringEncoding];
197+
ancestorInput.ptr = [ancestorString cStringUsingEncoding:NSUTF8StringEncoding];
198+
ancestorInput.size = ancestorString.length;
199+
200+
201+
// initialize our merge file input
202+
git_merge_file_input ourInput;
203+
gitError = git_merge_file_init_input(&ourInput, GIT_MERGE_FILE_INPUT_VERSION);
204+
if (gitError != GIT_OK) {
205+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to create merge file input for our side"];
206+
return nil;
207+
}
208+
209+
git_oid ourId = ourSide.git_index_entry->id;
210+
GTOID *ourOID = [[GTOID alloc] initWithGitOid:&ourId];
211+
NSData *ourData = [[database objectWithOID:ourOID error: error] data];
212+
if (ourData == nil) {
213+
return nil;
214+
}
215+
NSString *ourString = [[NSString alloc] initWithData: ourData encoding:NSUTF8StringEncoding];
216+
ourInput.ptr = [ourString cStringUsingEncoding:NSUTF8StringEncoding];
217+
ourInput.size = ourString.length;
218+
219+
220+
// initialize their merge file input
221+
git_merge_file_input theirInput;
222+
gitError = git_merge_file_init_input(&theirInput, GIT_MERGE_FILE_INPUT_VERSION);
223+
if (gitError != GIT_OK) {
224+
if (error != NULL) *error = [NSError git_errorFor:gitError description:@"Failed to create merge file input other side"];
225+
return nil;
226+
}
227+
228+
git_oid theirId = theirSide.git_index_entry->id;
229+
GTOID *theirOID = [[GTOID alloc] initWithGitOid:&theirId];
230+
NSData *theirData = [[database objectWithOID:theirOID error: error] data];
231+
if (theirData == nil) {
232+
return nil;
233+
}
234+
NSString *theirString = [[NSString alloc] initWithData: theirData encoding:NSUTF8StringEncoding];
235+
theirInput.ptr = [theirString cStringUsingEncoding:NSUTF8StringEncoding];
236+
theirInput.size = theirString.length;
237+
238+
239+
git_merge_file_result result;
240+
git_merge_file(&result, &ancestorInput, &ourInput, &theirInput, nil);
241+
242+
char * cString = malloc(result.len * sizeof(char*) + 1);
243+
strncpy(cString, result.ptr, result.len);
244+
cString[result.len] = '\0';
245+
246+
NSString *mergedContent = [[NSString alloc] initWithCString:cString encoding:NSUTF8StringEncoding];
247+
248+
free(cString);
249+
250+
git_merge_file_result_free(&result);
251+
252+
return mergedContent;
253+
}
254+
173255
- (BOOL)annotatedCommit:(git_annotated_commit **)annotatedCommit fromCommit:(GTCommit *)fromCommit error:(NSError **)error {
174256
int gitError = git_annotated_commit_lookup(annotatedCommit, self.git_repository, fromCommit.OID.git_oid);
175257
if (gitError != GIT_OK) {

0 commit comments

Comments
 (0)