Git fork
at reftables-rust 106 lines 2.3 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "merge-ll.h" 5#include "blob.h" 6#include "merge-blobs.h" 7#include "odb.h" 8 9static int fill_mmfile_blob(mmfile_t *f, struct blob *obj) 10{ 11 void *buf; 12 unsigned long size; 13 enum object_type type; 14 15 buf = odb_read_object(the_repository->objects, &obj->object.oid, 16 &type, &size); 17 if (!buf) 18 return -1; 19 if (type != OBJ_BLOB) { 20 free(buf); 21 return -1; 22 } 23 f->ptr = buf; 24 f->size = size; 25 return 0; 26} 27 28static void free_mmfile(mmfile_t *f) 29{ 30 free(f->ptr); 31} 32 33static void *three_way_filemerge(struct index_state *istate, 34 const char *path, 35 mmfile_t *base, 36 mmfile_t *our, 37 mmfile_t *their, 38 unsigned long *size) 39{ 40 enum ll_merge_result merge_status; 41 mmbuffer_t res; 42 43 /* 44 * This function is only used by cmd_merge_tree, which 45 * does not respect the merge.conflictstyle option. 46 * There is no need to worry about a label for the 47 * common ancestor. 48 */ 49 merge_status = ll_merge(&res, path, base, NULL, 50 our, ".our", their, ".their", 51 istate, NULL); 52 if (merge_status < 0) 53 return NULL; 54 if (merge_status == LL_MERGE_BINARY_CONFLICT) 55 warning("Cannot merge binary files: %s (%s vs. %s)", 56 path, ".our", ".their"); 57 58 *size = res.size; 59 return res.ptr; 60} 61 62void *merge_blobs(struct index_state *istate, const char *path, 63 struct blob *base, struct blob *our, 64 struct blob *their, unsigned long *size) 65{ 66 void *res = NULL; 67 mmfile_t f1, f2, common; 68 69 /* 70 * Removed in either branch? 71 * 72 * NOTE! This depends on the caller having done the 73 * proper warning about removing a file that got 74 * modified in the other branch! 75 */ 76 if (!our || !their) { 77 enum object_type type; 78 if (base) 79 return NULL; 80 if (!our) 81 our = their; 82 return odb_read_object(the_repository->objects, &our->object.oid, 83 &type, size); 84 } 85 86 if (fill_mmfile_blob(&f1, our) < 0) 87 goto out_no_mmfile; 88 if (fill_mmfile_blob(&f2, their) < 0) 89 goto out_free_f1; 90 91 if (base) { 92 if (fill_mmfile_blob(&common, base) < 0) 93 goto out_free_f2_f1; 94 } else { 95 common.ptr = xstrdup(""); 96 common.size = 0; 97 } 98 res = three_way_filemerge(istate, path, &common, &f1, &f2, size); 99 free_mmfile(&common); 100out_free_f2_f1: 101 free_mmfile(&f2); 102out_free_f1: 103 free_mmfile(&f1); 104out_no_mmfile: 105 return res; 106}