4 #include "notes-merge.h"
6 void init_notes_merge_options(struct notes_merge_options
*o
)
8 memset(o
, 0, sizeof(struct notes_merge_options
));
9 o
->verbosity
= NOTES_MERGE_VERBOSITY_DEFAULT
;
12 #define OUTPUT(o, v, ...) \
14 if ((o)->verbosity >= (v)) { \
15 printf(__VA_ARGS__); \
20 int notes_merge(struct notes_merge_options
*o
,
21 unsigned char *result_sha1
)
23 unsigned char local_sha1
[20], remote_sha1
[20];
24 struct commit
*local
, *remote
;
25 struct commit_list
*bases
= NULL
;
26 const unsigned char *base_sha1
;
29 assert(o
->local_ref
&& o
->remote_ref
);
32 trace_printf("notes_merge(o->local_ref = %s, o->remote_ref = %s)\n",
33 o
->local_ref
, o
->remote_ref
);
35 /* Dereference o->local_ref into local_sha1 */
36 if (!resolve_ref(o
->local_ref
, local_sha1
, 0, NULL
))
37 die("Failed to resolve local notes ref '%s'", o
->local_ref
);
38 else if (!check_ref_format(o
->local_ref
) && is_null_sha1(local_sha1
))
39 local
= NULL
; /* local_sha1 == null_sha1 indicates unborn ref */
40 else if (!(local
= lookup_commit_reference(local_sha1
)))
41 die("Could not parse local commit %s (%s)",
42 sha1_to_hex(local_sha1
), o
->local_ref
);
43 trace_printf("\tlocal commit: %.7s\n", sha1_to_hex(local_sha1
));
45 /* Dereference o->remote_ref into remote_sha1 */
46 if (get_sha1(o
->remote_ref
, remote_sha1
)) {
48 * Failed to get remote_sha1. If o->remote_ref looks like an
49 * unborn ref, perform the merge using an empty notes tree.
51 if (!check_ref_format(o
->remote_ref
)) {
55 die("Failed to resolve remote notes ref '%s'",
58 } else if (!(remote
= lookup_commit_reference(remote_sha1
))) {
59 die("Could not parse remote commit %s (%s)",
60 sha1_to_hex(remote_sha1
), o
->remote_ref
);
62 trace_printf("\tremote commit: %.7s\n", sha1_to_hex(remote_sha1
));
64 if (!local
&& !remote
)
65 die("Cannot merge empty notes ref (%s) into empty notes ref "
66 "(%s)", o
->remote_ref
, o
->local_ref
);
68 /* result == remote commit */
69 hashcpy(result_sha1
, remote_sha1
);
73 /* result == local commit */
74 hashcpy(result_sha1
, local_sha1
);
77 assert(local
&& remote
);
79 /* Find merge bases */
80 bases
= get_merge_bases(local
, remote
, 1);
82 base_sha1
= null_sha1
;
83 OUTPUT(o
, 4, "No merge base found; doing history-less merge");
84 } else if (!bases
->next
) {
85 base_sha1
= bases
->item
->object
.sha1
;
86 OUTPUT(o
, 4, "One merge base found (%.7s)",
87 sha1_to_hex(base_sha1
));
89 /* TODO: How to handle multiple merge-bases? */
90 base_sha1
= bases
->item
->object
.sha1
;
91 OUTPUT(o
, 3, "Multiple merge bases found. Using the first "
92 "(%.7s)", sha1_to_hex(base_sha1
));
95 OUTPUT(o
, 4, "Merging remote commit %.7s into local commit %.7s with "
96 "merge-base %.7s", sha1_to_hex(remote
->object
.sha1
),
97 sha1_to_hex(local
->object
.sha1
), sha1_to_hex(base_sha1
));
99 if (!hashcmp(remote
->object
.sha1
, base_sha1
)) {
100 /* Already merged; result == local commit */
101 OUTPUT(o
, 2, "Already up-to-date!");
102 hashcpy(result_sha1
, local
->object
.sha1
);
105 if (!hashcmp(local
->object
.sha1
, base_sha1
)) {
106 /* Fast-forward; result == remote commit */
107 OUTPUT(o
, 2, "Fast-forward");
108 hashcpy(result_sha1
, remote
->object
.sha1
);
113 result
= error("notes_merge() cannot yet handle real merges.");
116 free_commit_list(bases
);
117 trace_printf("notes_merge(): result = %i, result_sha1 = %.7s\n",
118 result
, sha1_to_hex(result_sha1
));