5 #include "notes-merge.h"
7 void init_notes_merge_options(struct notes_merge_options
*o
)
9 memset(o
, 0, sizeof(struct notes_merge_options
));
10 o
->verbosity
= NOTES_MERGE_VERBOSITY_DEFAULT
;
13 #define OUTPUT(o, v, ...) \
15 if ((o)->verbosity >= (v)) { \
16 printf(__VA_ARGS__); \
21 void create_notes_commit(struct notes_tree
*t
, struct commit_list
*parents
,
22 const char *msg
, unsigned char *result_sha1
)
24 unsigned char tree_sha1
[20];
26 assert(t
->initialized
);
28 if (write_notes_tree(t
, tree_sha1
))
29 die("Failed to write notes tree to database");
32 /* Deduce parent commit from t->ref */
33 unsigned char parent_sha1
[20];
34 if (!read_ref(t
->ref
, parent_sha1
)) {
35 struct commit
*parent
= lookup_commit(parent_sha1
);
36 if (!parent
|| parse_commit(parent
))
37 die("Failed to find/parse commit %s", t
->ref
);
38 commit_list_insert(parent
, &parents
);
40 /* else: t->ref points to nothing, assume root/orphan commit */
43 if (commit_tree(msg
, tree_sha1
, parents
, result_sha1
, NULL
))
44 die("Failed to commit notes tree to database");
47 int notes_merge(struct notes_merge_options
*o
,
48 unsigned char *result_sha1
)
50 unsigned char local_sha1
[20], remote_sha1
[20];
51 struct commit
*local
, *remote
;
52 struct commit_list
*bases
= NULL
;
53 const unsigned char *base_sha1
;
56 assert(o
->local_ref
&& o
->remote_ref
);
59 trace_printf("notes_merge(o->local_ref = %s, o->remote_ref = %s)\n",
60 o
->local_ref
, o
->remote_ref
);
62 /* Dereference o->local_ref into local_sha1 */
63 if (!resolve_ref(o
->local_ref
, local_sha1
, 0, NULL
))
64 die("Failed to resolve local notes ref '%s'", o
->local_ref
);
65 else if (!check_ref_format(o
->local_ref
) && is_null_sha1(local_sha1
))
66 local
= NULL
; /* local_sha1 == null_sha1 indicates unborn ref */
67 else if (!(local
= lookup_commit_reference(local_sha1
)))
68 die("Could not parse local commit %s (%s)",
69 sha1_to_hex(local_sha1
), o
->local_ref
);
70 trace_printf("\tlocal commit: %.7s\n", sha1_to_hex(local_sha1
));
72 /* Dereference o->remote_ref into remote_sha1 */
73 if (get_sha1(o
->remote_ref
, remote_sha1
)) {
75 * Failed to get remote_sha1. If o->remote_ref looks like an
76 * unborn ref, perform the merge using an empty notes tree.
78 if (!check_ref_format(o
->remote_ref
)) {
82 die("Failed to resolve remote notes ref '%s'",
85 } else if (!(remote
= lookup_commit_reference(remote_sha1
))) {
86 die("Could not parse remote commit %s (%s)",
87 sha1_to_hex(remote_sha1
), o
->remote_ref
);
89 trace_printf("\tremote commit: %.7s\n", sha1_to_hex(remote_sha1
));
91 if (!local
&& !remote
)
92 die("Cannot merge empty notes ref (%s) into empty notes ref "
93 "(%s)", o
->remote_ref
, o
->local_ref
);
95 /* result == remote commit */
96 hashcpy(result_sha1
, remote_sha1
);
100 /* result == local commit */
101 hashcpy(result_sha1
, local_sha1
);
104 assert(local
&& remote
);
106 /* Find merge bases */
107 bases
= get_merge_bases(local
, remote
, 1);
109 base_sha1
= null_sha1
;
110 OUTPUT(o
, 4, "No merge base found; doing history-less merge");
111 } else if (!bases
->next
) {
112 base_sha1
= bases
->item
->object
.sha1
;
113 OUTPUT(o
, 4, "One merge base found (%.7s)",
114 sha1_to_hex(base_sha1
));
116 /* TODO: How to handle multiple merge-bases? */
117 base_sha1
= bases
->item
->object
.sha1
;
118 OUTPUT(o
, 3, "Multiple merge bases found. Using the first "
119 "(%.7s)", sha1_to_hex(base_sha1
));
122 OUTPUT(o
, 4, "Merging remote commit %.7s into local commit %.7s with "
123 "merge-base %.7s", sha1_to_hex(remote
->object
.sha1
),
124 sha1_to_hex(local
->object
.sha1
), sha1_to_hex(base_sha1
));
126 if (!hashcmp(remote
->object
.sha1
, base_sha1
)) {
127 /* Already merged; result == local commit */
128 OUTPUT(o
, 2, "Already up-to-date!");
129 hashcpy(result_sha1
, local
->object
.sha1
);
132 if (!hashcmp(local
->object
.sha1
, base_sha1
)) {
133 /* Fast-forward; result == remote commit */
134 OUTPUT(o
, 2, "Fast-forward");
135 hashcpy(result_sha1
, remote
->object
.sha1
);
140 result
= error("notes_merge() cannot yet handle real merges.");
143 free_commit_list(bases
);
144 trace_printf("notes_merge(): result = %i, result_sha1 = %.7s\n",
145 result
, sha1_to_hex(result_sha1
));