Coverage Report

Created: 2025-12-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/merge-ort-wrappers.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "gettext.h"
3
#include "hash.h"
4
#include "hex.h"
5
#include "lockfile.h"
6
#include "merge-ort.h"
7
#include "merge-ort-wrappers.h"
8
#include "read-cache-ll.h"
9
#include "repository.h"
10
#include "tag.h"
11
#include "tree.h"
12
13
#include "commit.h"
14
15
static int unclean(struct merge_options *opt, struct tree *head)
16
0
{
17
  /* Sanity check on repo state; index must match head */
18
0
  struct strbuf sb = STRBUF_INIT;
19
20
0
  if (head && repo_index_has_changes(opt->repo, head, &sb)) {
21
0
    error(_("Your local changes to the following files would be overwritten by merge:\n  %s"),
22
0
          sb.buf);
23
0
    strbuf_release(&sb);
24
0
    return -1;
25
0
  }
26
27
0
  return 0;
28
0
}
29
30
int merge_ort_nonrecursive(struct merge_options *opt,
31
         struct tree *head,
32
         struct tree *merge,
33
         struct tree *merge_base)
34
0
{
35
0
  struct merge_result result;
36
0
  int show_msgs;
37
38
0
  if (unclean(opt, head))
39
0
    return -1;
40
41
0
  if (oideq(&merge_base->object.oid, &merge->object.oid)) {
42
0
    printf_ln(_("Already up to date."));
43
0
    return 1;
44
0
  }
45
46
0
  show_msgs = !!opt->verbosity;
47
0
  memset(&result, 0, sizeof(result));
48
0
  merge_incore_nonrecursive(opt, merge_base, head, merge, &result);
49
0
  merge_switch_to_result(opt, head, &result, 1, show_msgs);
50
51
0
  return result.clean;
52
0
}
53
54
int merge_ort_recursive(struct merge_options *opt,
55
      struct commit *side1,
56
      struct commit *side2,
57
      const struct commit_list *merge_bases,
58
      struct commit **result)
59
0
{
60
0
  struct tree *head = repo_get_commit_tree(opt->repo, side1);
61
0
  struct merge_result tmp;
62
0
  int show_msgs;
63
64
0
  if (unclean(opt, head))
65
0
    return -1;
66
67
0
  show_msgs = !!opt->verbosity;
68
0
  memset(&tmp, 0, sizeof(tmp));
69
0
  merge_incore_recursive(opt, merge_bases, side1, side2, &tmp);
70
0
  merge_switch_to_result(opt, head, &tmp, 1, show_msgs);
71
0
  *result = NULL;
72
73
0
  return tmp.clean;
74
0
}
75
76
static struct commit *get_ref(struct repository *repo,
77
            const struct object_id *oid,
78
            const char *name)
79
0
{
80
0
  struct object *object;
81
82
0
  object = deref_tag(repo, parse_object(repo, oid),
83
0
         name, strlen(name));
84
0
  if (!object)
85
0
    return NULL;
86
0
  if (object->type == OBJ_TREE)
87
0
    return make_virtual_commit(repo, (struct tree*)object, name);
88
0
  if (object->type != OBJ_COMMIT)
89
0
    return NULL;
90
0
  if (repo_parse_commit(repo, (struct commit *)object))
91
0
    return NULL;
92
0
  return (struct commit *)object;
93
0
}
94
95
int merge_ort_generic(struct merge_options *opt,
96
          const struct object_id *head,
97
          const struct object_id *merge,
98
          int num_merge_bases,
99
          const struct object_id *merge_bases,
100
          struct commit **result)
101
0
{
102
0
  int clean;
103
0
  struct lock_file lock = LOCK_INIT;
104
0
  struct commit *head_commit = get_ref(opt->repo, head, opt->branch1);
105
0
  struct commit *next_commit = get_ref(opt->repo, merge, opt->branch2);
106
0
  struct commit_list *ca = NULL;
107
108
0
  if (merge_bases) {
109
0
    int i;
110
0
    for (i = 0; i < num_merge_bases; ++i) {
111
0
      struct commit *base;
112
0
      if (!(base = get_ref(opt->repo, &merge_bases[i],
113
0
               oid_to_hex(&merge_bases[i]))))
114
0
        return error(_("Could not parse object '%s'"),
115
0
               oid_to_hex(&merge_bases[i]));
116
0
      commit_list_insert(base, &ca);
117
0
    }
118
0
  }
119
120
0
  repo_hold_locked_index(opt->repo, &lock, LOCK_DIE_ON_ERROR);
121
0
  clean = merge_ort_recursive(opt, head_commit, next_commit, ca,
122
0
            result);
123
0
  free_commit_list(ca);
124
0
  if (clean < 0) {
125
0
    rollback_lock_file(&lock);
126
0
    return clean;
127
0
  }
128
129
0
  if (write_locked_index(opt->repo->index, &lock,
130
0
             COMMIT_LOCK | SKIP_IF_UNCHANGED))
131
0
    return error(_("Unable to write index."));
132
133
0
  return clean ? 0 : 1;
134
0
}