git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] xdl_merge(): make XDL_MERGE_ZEALOUS output simpler

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Feb 17, 2008, 19:07 UTC
Message-ID
<alpine.LSU.1.00.0802171906590.30505@racer.site>
In-Reply-To
<alpine.LSU.1.00.0802171816150.30505@racer.site>

When a merge conflicts, there are often less than three common lines between two conflicting regions.

Since a conflict takes up as many lines as are conflicting, plus three lines for the commit markers, the output will be shorter (and thus, simpler) in this case, if the common lines will be merged into the conflicting regions.

This patch merges up to three common lines into the conflicts.
For example, what looked like this before this patch:
	<<<<<<<
	if (a == 1)
	=======
	if (a != 0)
	>>>>>>>
	{
		int i;
	<<<<<<<
		a = 0;
	=======
		a = !a;
	>>>>>>>
will now look like this:
	<<<<<<<
	if (a == 1)
	{
		int i;
		a = 0;
	=======
	if (a != 0)
	{
		int i;
		a = !a;
	>>>>>>>

Suggested Linus (based on ideas by "Voltage Spike" -- if that name is real, it is mighty cool).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 t/t6023-merge-file.sh |   10 ++++++++++
 xdiff/xmerge.c        |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 1 deletions(-)
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index 8641996..869e8d5 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -139,4 +139,14 @@ test_expect_success 'binary files cannot be merged' '
 	grep "Cannot merge binary files" merge.err
 '
 
+sed -e "s/deerit.$/deerit;/" -e "s/me;$/me./" < new5.txt > new6.txt
+sed -e "s/deerit.$/deerit,/" -e "s/me;$/me,/" < new5.txt > new7.txt
+
+test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' '
+
+	! git merge-file -p new6.txt new5.txt new7.txt > output &&
+	test 1 = $(grep ======= < output | wc -l)
+
+'
+
 test_done
diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c
index b83b334..9cd448c 100644
--- a/xdiff/xmerge.c
+++ b/xdiff/xmerge.c
@@ -249,6 +249,49 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
 }
 
 /*
+ * This function merges m and m->next, marking everything between those hunks
+ * as conflicting, too.
+ */
+static void xdl_merge_two_conflicts(xdmerge_t *m)
+{
+	xdmerge_t *next_m = m->next;
+	m->chg1 = next_m->i1 + next_m->chg1 - m->i1;
+	m->chg2 = next_m->i2 + next_m->chg2 - m->i2;
+	m->next = next_m->next;
+	free(next_m);
+}
+
+/*
+ * If there are less than 3 non-conflicting lines between conflicts,
+ * it appears simpler -- because it takes up less (or as many) lines --
+ * if the lines are moved into the conflicts.
+ */
+static int xdl_simplify_non_conflicts(xdfenv_t *xe1, xdmerge_t *m)
+{
+	int result = 0;
+
+	if (!m)
+		return result;
+	for (;;) {
+		xdmerge_t *next_m = m->next;
+		int begin, end;
+
+		if (!next_m)
+			return result;
+
+		begin = m->i1 + m->chg1;
+		end = next_m->i1;
+
+		if (m->mode != 0 || next_m->mode != 0 || end - begin > 3)
+			m = next_m;
+		else {
+			result++;
+			xdl_merge_two_conflicts(m);
+		}
+	}
+}
+
+/*
  * level == 0: mark all overlapping changes as conflict
  * level == 1: mark overlapping changes as conflict only if not identical
  * level == 2: analyze non-identical changes for minimal conflict set
@@ -355,7 +398,9 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1, const char *name1,
 	if (!changes)
 		changes = c;
 	/* refine conflicts */
-	if (level > 1 && xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0) {
+	if (level > 1 &&
+			(xdl_refine_conflicts(xe1, xe2, changes, xpp) < 0 ||
+			 xdl_simplify_non_conflicts(xe1, changes) < 0)) {
 		xdl_cleanup_merge(changes);
 		return -1;
 	}
-- 
1.5.4.1.1396.g177d-dirty
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 13 of 23 in “Merge-Recursive Improvements”
  1. Voltage SpikeFeb 12, 2008
  2. Stefan MonnierFeb 12, 2008
  3. Junio C HamanoFeb 12, 2008
  4. Linus TorvaldsFeb 12, 2008
  5. Johannes SchindelinFeb 13, 2008
  6. xdl_merge(): introduce XDL_MERGE_ZEALOUS_ALNUMJohannes Schindelin, Feb 13, 2008
  7. Junio C HamanoFeb 13, 2008
  8. Johannes SchindelinFeb 13, 2008
  9. Junio C HamanoFeb 15, 2008
  10. Linus TorvaldsFeb 15, 2008
  11. Johannes SchindelinFeb 15, 2008
  12. Johannes SchindelinFeb 17, 2008
  13. 1/2 xdl_merge(): make XDL_MERGE_ZEALOUS output simplerJohannes Schindelin, Feb 17, 2008
  14. 2/2 xdl_merge(): introduce XDL_MERGE_ZEALOUS_ALNUMJohannes Schindelin, Feb 17, 2008
  15. Junio C HamanoFeb 18, 2008
  16. Johannes SchindelinFeb 18, 2008
  17. Linus TorvaldsFeb 13, 2008
  18. Johannes SchindelinFeb 13, 2008
  19. Johannes SixtFeb 13, 2008
  20. Steffen ProhaskaFeb 13, 2008
  21. Voltage SpikeFeb 13, 2008
  22. Johannes SixtFeb 13, 2008
  23. Junio C HamanoFeb 15, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.