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

automerge implementation ideas for Windows

From
Seth House <seth@eseth.com>
Date
Jan 20, 2021, 23:24 UTC
Message-ID
<20210120232447.GA35105@ellen>
In-Reply-To
<20210116042454.GA4913@ellen>
On Fri, Jan 15, 2021 at 09:24:59PM -0700, Seth House wrote:
> The autocrlf test is breaking because the sed that ships with some mingw
> versions (and also some minsys and cygwin versions) will *automatically*
> remove carriage returns:

So the mingw builds of both sed and awk change carriage returns. So far I haven't found documentation on it so I'm not aware of a portable way to disable the behavior. Instead I've been playing with alternate approaches. The two patches below work and pass the autocrlf test on Windows, however they are first-draft implementations. Feedback welcome.

One other point of discussion: I would like to change the name of this feature. "Automerge" is a bit of an overloaded term and, IMO, doesn't describe this feature very well. Several of the GUI diff programs have a feature that they call "automerge" or "auto merge", and there's a flag for Meld already in Git called "mergetool.meld.useAutoMerge" which could cause confusion.

Instead, I'd like to propose "mergetool.hideResolved" or the more verbose "mergetool.hideResolvedConflicts" as the name. We're not really merging anything (Git aleady did that before the mergetool is invoked), but rather we're just not showing any conflicts that Git was already able to resolve.

---------->8--------->8--------->8--------->8-------
#1: Use POSIX read and a while loop to emulate an awk-like approach:
diff --git a/git-mergetool.sh b/git-mergetool.sh
index 246d6b76fc..94728dd518 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -240,19 +240,46 @@ checkout_staged_file () {
 }
 
 auto_merge () {
+	C0="<<<<<<< "
+	C1="||||||| "
+	C2="======="
+	C3=">>>>>>> "
+	inl=0
+	inb=0
+	inr=0
+
 	git merge-file --diff3 --marker-size=7 -q -p "$LOCAL" "$BASE" "$REMOTE" >"$DIFF3"
+
 	if test -s "$DIFF3"
 	then
-		C0="^<<<<<<< "
-		C1="^||||||| "
-		C2="^=======$(printf '\015')\{0,1\}$"
-		C3="^>>>>>>> "
-
-		sed -e "/$C0/,/$C1/d" -e "/$C2/,/$C3/d" "$DIFF3" >"$BASE"
-		sed -e "/$C1/,/$C3/d" -e "/$C0/d" "$DIFF3" >"$LOCAL"
-		sed -e "/$C0/,/$C2/d" -e "/$C3/d" "$DIFF3" >"$REMOTE"
+		touch "$LCONFL" "$BCONFL" "$RCONFL"
+
+		while read -r line
+		do
+			case $line in
+				$C0*) inl=1; continue ;;
+				$C1*) inl=0; inb=1; continue ;;
+				$C2*) inb=0; inr=1; continue ;;
+				$C3*) inr=0; continue ;;
+			esac
+
+			case 1 in
+				$inl) printf '%s\n' "$line" >>"$LCONFL" ;;
+				$inb) printf '%s\n' "$line" >>"$BCONFL" ;;
+				$inr) printf '%s\n' "$line" >>"$RCONFL" ;;
+				*)
+					printf '%s\n' "$line" >>"$LCONFL"
+					printf '%s\n' "$line" >>"$BCONFL"
+					printf '%s\n' "$line" >>"$RCONFL"
+				;;
+			esac
+		done < "$DIFF3"
+
+		mv -- "$LCONFL" "$LOCAL"
+		mv -- "$BCONFL" "$BASE"
+		mv -- "$RCONFL" "$REMOTE"
+		rm -- "$DIFF3"
 	fi
-	rm -- "$DIFF3"
 }
 
 merge_file () {
@@ -295,8 +322,11 @@ merge_file () {
 	DIFF3="$MERGETOOL_TMPDIR/${BASE}_DIFF3_$$$ext"
 	BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
 	LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
+	LCONFL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_LCONFL_$$$ext"
 	REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
+	RCONFL="$MERGETOOL_TMPDIR/${BASE}_REMOTE_RCONFL_$$$ext"
 	BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
+	BCONFL="$MERGETOOL_TMPDIR/${BASE}_BASE_BCONFL_$$$ext"
 
 	base_mode= local_mode= remote_mode=

---------->8--------->8--------->8--------->8-------

#2: Call merge-file twice:

A much simpler implementation but probably less performant. Is it enough
to matter?

diff --git a/git-mergetool.sh b/git-mergetool.sh
index 246d6b76fc..1cb45a7437 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -240,19 +240,10 @@ checkout_staged_file () {
 }
 
 auto_merge () {
-	git merge-file --diff3 --marker-size=7 -q -p "$LOCAL" "$BASE" "$REMOTE" >"$DIFF3"
-	if test -s "$DIFF3"
-	then
-		C0="^<<<<<<< "
-		C1="^||||||| "
-		C2="^=======$(printf '\015')\{0,1\}$"
-		C3="^>>>>>>> "
-
-		sed -e "/$C0/,/$C1/d" -e "/$C2/,/$C3/d" "$DIFF3" >"$BASE"
-		sed -e "/$C1/,/$C3/d" -e "/$C0/d" "$DIFF3" >"$LOCAL"
-		sed -e "/$C0/,/$C2/d" -e "/$C3/d" "$DIFF3" >"$REMOTE"
-	fi
-	rm -- "$DIFF3"
+	git merge-file --ours -q -p "$LOCAL" "$BASE" "$REMOTE" >"$LCONFL"
+	git merge-file --theirs -q -p "$LOCAL" "$BASE" "$REMOTE" >"$RCONFL"
+	mv -- "$LCONFL" "$LOCAL"
+	mv -- "$RCONFL" "$REMOTE"
 }
 
 merge_file () {
@@ -295,7 +286,9 @@ merge_file () {
 	DIFF3="$MERGETOOL_TMPDIR/${BASE}_DIFF3_$$$ext"
 	BACKUP="$MERGETOOL_TMPDIR/${BASE}_BACKUP_$$$ext"
 	LOCAL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_$$$ext"
+	LCONFL="$MERGETOOL_TMPDIR/${BASE}_LOCAL_LCONFL_$$$ext"
 	REMOTE="$MERGETOOL_TMPDIR/${BASE}_REMOTE_$$$ext"
+	RCONFL="$MERGETOOL_TMPDIR/${BASE}_REMOTE_RCONFL_$$$ext"
 	BASE="$MERGETOOL_TMPDIR/${BASE}_BASE_$$$ext"
 
 	base_mode= local_mode= remote_mode=
Previous: Seth HouseNext: Junio C Hamano
Message 10 of 24 in “fixup! mergetool: add automerge configuration”
  1. fixup! mergetool: add automerge configurationDavid Aguilar, Jan 9, 2021
  2. brian m. carlsonJan 9, 2021
  3. fixup! mergetool: add automerge configurationDavid Aguilar, Jan 9, 2021
  4. Seth HouseJan 9, 2021
  5. Junio C HamanoJan 10, 2021
  6. Re* [PATCH v2] fixup! mergetool: add automerge configurationJunio C Hamano, Jan 10, 2021
  7. Seth HouseJan 10, 2021
  8. Junio C HamanoJan 10, 2021
  9. Seth HouseJan 16, 2021
  10. automerge implementation ideas for WindowsSeth House, Jan 20, 2021
  11. Junio C HamanoJan 21, 2021
  12. Seth HouseJan 22, 2021
  13. Junio C HamanoJan 22, 2021
  14. brian m. carlsonJan 22, 2021
  15. Johannes SchindelinJan 22, 2021
  16. brian m. carlsonJan 22, 2021
  17. Johannes SchindelinJan 26, 2021
  18. Seth HouseJan 26, 2021
  19. Junio C HamanoJan 26, 2021
  20. Seth HouseJan 27, 2021
  21. Junio C HamanoJan 29, 2021
  22. Junio C HamanoJan 9, 2021
  23. Junio C HamanoJan 10, 2021
  24. Junio C HamanoJan 9, 2021

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.