Coverage Report

Created: 2024-09-16 06:10

/src/git/merge-blobs.c
Line
Count
Source (jump to first uncovered line)
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 "object-store-ll.h"
8
9
static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
10
0
{
11
0
  void *buf;
12
0
  unsigned long size;
13
0
  enum object_type type;
14
15
0
  buf = repo_read_object_file(the_repository, &obj->object.oid, &type,
16
0
            &size);
17
0
  if (!buf)
18
0
    return -1;
19
0
  if (type != OBJ_BLOB) {
20
0
    free(buf);
21
0
    return -1;
22
0
  }
23
0
  f->ptr = buf;
24
0
  f->size = size;
25
0
  return 0;
26
0
}
27
28
static void free_mmfile(mmfile_t *f)
29
0
{
30
0
  free(f->ptr);
31
0
}
32
33
static 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
0
{
40
0
  enum ll_merge_result merge_status;
41
0
  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
0
  merge_status = ll_merge(&res, path, base, NULL,
50
0
        our, ".our", their, ".their",
51
0
        istate, NULL);
52
0
  if (merge_status < 0)
53
0
    return NULL;
54
0
  if (merge_status == LL_MERGE_BINARY_CONFLICT)
55
0
    warning("Cannot merge binary files: %s (%s vs. %s)",
56
0
      path, ".our", ".their");
57
58
0
  *size = res.size;
59
0
  return res.ptr;
60
0
}
61
62
void *merge_blobs(struct index_state *istate, const char *path,
63
      struct blob *base, struct blob *our,
64
      struct blob *their, unsigned long *size)
65
0
{
66
0
  void *res = NULL;
67
0
  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
0
  if (!our || !their) {
77
0
    enum object_type type;
78
0
    if (base)
79
0
      return NULL;
80
0
    if (!our)
81
0
      our = their;
82
0
    return repo_read_object_file(the_repository, &our->object.oid,
83
0
               &type, size);
84
0
  }
85
86
0
  if (fill_mmfile_blob(&f1, our) < 0)
87
0
    goto out_no_mmfile;
88
0
  if (fill_mmfile_blob(&f2, their) < 0)
89
0
    goto out_free_f1;
90
91
0
  if (base) {
92
0
    if (fill_mmfile_blob(&common, base) < 0)
93
0
      goto out_free_f2_f1;
94
0
  } else {
95
0
    common.ptr = xstrdup("");
96
0
    common.size = 0;
97
0
  }
98
0
  res = three_way_filemerge(istate, path, &common, &f1, &f2, size);
99
0
  free_mmfile(&common);
100
0
out_free_f2_f1:
101
0
  free_mmfile(&f2);
102
0
out_free_f1:
103
0
  free_mmfile(&f1);
104
0
out_no_mmfile:
105
0
  return res;
106
0
}