Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2022-02-02 05:37:35 +0300
committerJunio C Hamano <gitster@pobox.com>2022-02-02 21:02:28 +0300
commit20323d104ec389505e83b9376c8ecab94e852fb8 (patch)
tree2a2190c34b5ab8a20a19465e4654c95ebc0a3cd0
parent95433eeed9eac439eb21eb30105354b15e71302e (diff)
show, log: include conflict/warning messages in --remerge-diff headers
Conflicts such as modify/delete, rename/rename, or file/directory are not representable via content conflict markers, and the normal output messages notifying users about these were dropped with --remerge-diff. While we don't want these messages randomly shown before the commit and diff headers, we do want them to still be shown; include them as part of the diff headers instead. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--log-tree.c51
-rw-r--r--merge-ort.c1
-rw-r--r--merge-ort.h10
-rwxr-xr-xt/t4069-remerge-diff.sh144
4 files changed, 206 insertions, 0 deletions
diff --git a/log-tree.c b/log-tree.c
index fe2084625e..25165e2a91 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -19,6 +19,7 @@
#include "line-log.h"
#include "help.h"
#include "range-diff.h"
+#include "strmap.h"
static struct decoration name_decoration = { "object names" };
static int decoration_loaded;
@@ -907,6 +908,52 @@ static int do_diff_combined(struct rev_info *opt, struct commit *commit)
return !opt->loginfo;
}
+static void setup_additional_headers(struct diff_options *o,
+ struct strmap *all_headers)
+{
+ struct hashmap_iter iter;
+ struct strmap_entry *entry;
+
+ /*
+ * Make o->additional_path_headers contain the subset of all_headers
+ * that match o->pathspec. If there aren't any that match o->pathspec,
+ * then make o->additional_path_headers be NULL.
+ */
+
+ if (!o->pathspec.nr) {
+ o->additional_path_headers = all_headers;
+ return;
+ }
+
+ o->additional_path_headers = xmalloc(sizeof(struct strmap));
+ strmap_init_with_options(o->additional_path_headers, NULL, 0);
+ strmap_for_each_entry(all_headers, &iter, entry) {
+ if (match_pathspec(the_repository->index, &o->pathspec,
+ entry->key, strlen(entry->key),
+ 0 /* prefix */, NULL /* seen */,
+ 0 /* is_dir */))
+ strmap_put(o->additional_path_headers,
+ entry->key, entry->value);
+ }
+ if (!strmap_get_size(o->additional_path_headers)) {
+ strmap_clear(o->additional_path_headers, 0);
+ FREE_AND_NULL(o->additional_path_headers);
+ }
+}
+
+static void cleanup_additional_headers(struct diff_options *o)
+{
+ if (!o->pathspec.nr) {
+ o->additional_path_headers = NULL;
+ return;
+ }
+ if (!o->additional_path_headers)
+ return;
+
+ strmap_clear(o->additional_path_headers, 0);
+ FREE_AND_NULL(o->additional_path_headers);
+}
+
static int do_remerge_diff(struct rev_info *opt,
struct commit_list *parents,
struct object_id *oid,
@@ -924,6 +971,8 @@ static int do_remerge_diff(struct rev_info *opt,
/* Setup merge options */
init_merge_options(&o, the_repository);
o.show_rename_progress = 0;
+ o.record_conflict_msgs_as_headers = 1;
+ o.msg_header_prefix = "remerge";
ctx.abbrev = DEFAULT_ABBREV;
format_commit_message(parent1, "%h (%s)", &parent1_desc, &ctx);
@@ -940,10 +989,12 @@ static int do_remerge_diff(struct rev_info *opt,
merge_incore_recursive(&o, bases, parent1, parent2, &res);
/* Show the diff */
+ setup_additional_headers(&opt->diffopt, res.path_messages);
diff_tree_oid(&res.tree->object.oid, oid, "", &opt->diffopt);
log_tree_diff_flush(opt);
/* Cleanup */
+ cleanup_additional_headers(&opt->diffopt);
strbuf_release(&parent1_desc);
strbuf_release(&parent2_desc);
merge_finalize(&o, &res);
diff --git a/merge-ort.c b/merge-ort.c
index 481305d2bc..43f980d258 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -4585,6 +4585,7 @@ redo:
trace2_region_leave("merge", "process_entries", opt->repo);
/* Set return values */
+ result->path_messages = &opt->priv->output;
result->tree = parse_tree_indirect(&working_tree_oid);
/* existence of conflicted entries implies unclean */
result->clean &= strmap_empty(&opt->priv->conflicted);
diff --git a/merge-ort.h b/merge-ort.h
index c011864ffe..fe599b8786 100644
--- a/merge-ort.h
+++ b/merge-ort.h
@@ -5,6 +5,7 @@
struct commit;
struct tree;
+struct strmap;
struct merge_result {
/*
@@ -24,6 +25,15 @@ struct merge_result {
struct tree *tree;
/*
+ * Special messages and conflict notices for various paths
+ *
+ * This is a map of pathnames to strbufs. It contains various
+ * warning/conflict/notice messages (possibly multiple per path)
+ * that callers may want to use.
+ */
+ struct strmap *path_messages;
+
+ /*
* Additional metadata used by merge_switch_to_result() or future calls
* to merge_incore_*(). Includes data needed to update the index (if
* !clean) and to print "CONFLICT" messages. Not for external use.
diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh
index d7ab0f5006..fd6bce6478 100755
--- a/t/t4069-remerge-diff.sh
+++ b/t/t4069-remerge-diff.sh
@@ -60,6 +60,7 @@ test_expect_success 'remerge-diff with both a resolved conflict and an unrelated
git log -1 --oneline ab_resolution >tmp &&
cat <<-EOF >>tmp &&
diff --git a/numbers b/numbers
+ remerge CONFLICT (content): Merge conflict in numbers
index a1fb731..6875544 100644
--- a/numbers
+++ b/numbers
@@ -88,4 +89,147 @@ test_expect_success 'remerge-diff with both a resolved conflict and an unrelated
test_cmp expect actual
'
+test_expect_success 'setup non-content conflicts' '
+ git switch --orphan base &&
+
+ test_write_lines 1 2 3 4 5 6 7 8 9 >numbers &&
+ test_write_lines a b c d e f g h i >letters &&
+ test_write_lines in the way >content &&
+ git add numbers letters content &&
+ git commit -m base &&
+
+ git branch side1 &&
+ git branch side2 &&
+
+ git checkout side1 &&
+ test_write_lines 1 2 three 4 5 6 7 8 9 >numbers &&
+ git mv letters letters_side1 &&
+ git mv content file_or_directory &&
+ git add numbers &&
+ git commit -m side1 &&
+
+ git checkout side2 &&
+ git rm numbers &&
+ git mv letters letters_side2 &&
+ mkdir file_or_directory &&
+ echo hello >file_or_directory/world &&
+ git add file_or_directory/world &&
+ git commit -m side2 &&
+
+ git checkout -b resolution side1 &&
+ test_must_fail git merge side2 &&
+ test_write_lines 1 2 three 4 5 6 7 8 9 >numbers &&
+ git add numbers &&
+ git add letters_side1 &&
+ git rm letters &&
+ git rm letters_side2 &&
+ git add file_or_directory~HEAD &&
+ git mv file_or_directory~HEAD wanted_content &&
+ git commit -m resolved
+'
+
+test_expect_success 'remerge-diff with non-content conflicts' '
+ git log -1 --oneline resolution >tmp &&
+ cat <<-EOF >>tmp &&
+ diff --git a/file_or_directory~HASH (side1) b/wanted_content
+ similarity index 100%
+ rename from file_or_directory~HASH (side1)
+ rename to wanted_content
+ remerge CONFLICT (file/directory): directory in the way of file_or_directory from HASH (side1); moving it to file_or_directory~HASH (side1) instead.
+ diff --git a/letters b/letters
+ remerge CONFLICT (rename/rename): letters renamed to letters_side1 in HASH (side1) and to letters_side2 in HASH (side2).
+ diff --git a/letters_side2 b/letters_side2
+ deleted file mode 100644
+ index b236ae5..0000000
+ --- a/letters_side2
+ +++ /dev/null
+ @@ -1,9 +0,0 @@
+ -a
+ -b
+ -c
+ -d
+ -e
+ -f
+ -g
+ -h
+ -i
+ diff --git a/numbers b/numbers
+ remerge CONFLICT (modify/delete): numbers deleted in HASH (side2) and modified in HASH (side1). Version HASH (side1) of numbers left in tree.
+ EOF
+ # We still have some sha1 hashes above; rip them out so test works
+ # with sha256
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >expect &&
+
+ git show --oneline --remerge-diff resolution >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'remerge-diff w/ diff-filter=U: all conflict headers, no diff content' '
+ git log -1 --oneline resolution >tmp &&
+ cat <<-EOF >>tmp &&
+ diff --git a/file_or_directory~HASH (side1) b/file_or_directory~HASH (side1)
+ remerge CONFLICT (file/directory): directory in the way of file_or_directory from HASH (side1); moving it to file_or_directory~HASH (side1) instead.
+ diff --git a/letters b/letters
+ remerge CONFLICT (rename/rename): letters renamed to letters_side1 in HASH (side1) and to letters_side2 in HASH (side2).
+ diff --git a/numbers b/numbers
+ remerge CONFLICT (modify/delete): numbers deleted in HASH (side2) and modified in HASH (side1). Version HASH (side1) of numbers left in tree.
+ EOF
+ # We still have some sha1 hashes above; rip them out so test works
+ # with sha256
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >expect &&
+
+ git show --oneline --remerge-diff --diff-filter=U resolution >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'remerge-diff w/ diff-filter=R: relevant file + conflict header' '
+ git log -1 --oneline resolution >tmp &&
+ cat <<-EOF >>tmp &&
+ diff --git a/file_or_directory~HASH (side1) b/wanted_content
+ similarity index 100%
+ rename from file_or_directory~HASH (side1)
+ rename to wanted_content
+ remerge CONFLICT (file/directory): directory in the way of file_or_directory from HASH (side1); moving it to file_or_directory~HASH (side1) instead.
+ EOF
+ # We still have some sha1 hashes above; rip them out so test works
+ # with sha256
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >expect &&
+
+ git show --oneline --remerge-diff --diff-filter=R resolution >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'remerge-diff w/ pathspec: limits to relevant file including conflict header' '
+ git log -1 --oneline resolution >tmp &&
+ cat <<-EOF >>tmp &&
+ diff --git a/letters b/letters
+ remerge CONFLICT (rename/rename): letters renamed to letters_side1 in HASH (side1) and to letters_side2 in HASH (side2).
+ diff --git a/letters_side2 b/letters_side2
+ deleted file mode 100644
+ index b236ae5..0000000
+ --- a/letters_side2
+ +++ /dev/null
+ @@ -1,9 +0,0 @@
+ -a
+ -b
+ -c
+ -d
+ -e
+ -f
+ -g
+ -h
+ -i
+ EOF
+ # We still have some sha1 hashes above; rip them out so test works
+ # with sha256
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >expect &&
+
+ git show --oneline --remerge-diff --full-history resolution -- "letters*" >tmp &&
+ sed -e "s/[0-9a-f]\{7,\}/HASH/g" tmp >actual &&
+ test_cmp expect actual
+'
+
test_done