merge-ort: provide a merge_get_conflicted_files() helper function

After a merge, this function allows the user to extract the same information that would be printed by `ls-files -u`, which means files with their mode, oid, and stage. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Jun 18, 2022 at 00:20 UTC fae26ce79cad6d290e296e40f2d46eb783e91110
2 files changed +52
merge-ort.c
+31
@@ -4296,6 +4296,37 @@ void merge_display_update_messages(struct merge_options *opt,
4296 trace2_region_leave("merge", "display messages", opt->repo);
4297 }
4298
4299 +void merge_get_conflicted_files(struct merge_result *result,
4300 + struct string_list *conflicted_files)
4301 +{
4302 + struct hashmap_iter iter;
4303 + struct strmap_entry *e;
4304 + struct merge_options_internal *opti = result->priv;
4305 +
4306 + strmap_for_each_entry(&opti->conflicted, &iter, e) {
4307 + const char *path = e->key;
4308 + struct conflict_info *ci = e->value;
4309 + int i;
4310 +
4311 + VERIFY_CI(ci);
4312 +
4313 + for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
4314 + struct stage_info *si;
4315 +
4316 + if (!(ci->filemask & (1ul << i)))
4317 + continue;
4318 +
4319 + si = xmalloc(sizeof(*si));
4320 + si->stage = i+1;
4321 + si->mode = ci->stages[i].mode;
4322 + oidcpy(&si->oid, &ci->stages[i].oid);
4323 + string_list_append(conflicted_files, path)->util = si;
4324 + }
4325 + }
4326 + /* string_list_sort() uses a stable sort, so we're good */
4327 + string_list_sort(conflicted_files);
4328 +}
4329 +
4330 void merge_switch_to_result(struct merge_options *opt,
4331 struct tree *head,
4332 struct merge_result *result,
merge-ort.h
+21
@@ -2,6 +2,7 @@
2 #define MERGE_ORT_H
3
4 #include "merge-recursive.h"
5 +#include "hash.h"
6
7 struct commit;
8 struct tree;
@@ -88,6 +89,26 @@ void merge_switch_to_result(struct merge_options *opt,
89 void merge_display_update_messages(struct merge_options *opt,
90 struct merge_result *result);
91
92 +struct stage_info {
93 + struct object_id oid;
94 + int mode;
95 + int stage;
96 +};
97 +
98 +/*
99 + * Provide a list of path -> {struct stage_info*} mappings for
100 + * all conflicted files. Note that each path could appear up to three
101 + * times in the list, corresponding to 3 different stage entries. In short,
102 + * this basically provides the info that would be printed by `ls-files -u`.
103 + *
104 + * result should have been populated by a call to
105 + * one of the merge_incore_[non]recursive() functions.
106 + *
107 + * conflicted_files should be empty before calling this function.
108 + */
109 +void merge_get_conflicted_files(struct merge_result *result,
110 + struct string_list *conflicted_files);
111 +
112 /* Do needed cleanup when not calling merge_switch_to_result() */
113 void merge_finalize(struct merge_options *opt,
114 struct merge_result *result);