Patchwork contrib: add editmerge script for editor conflict prompts

login
register
mail settings
Submitter Durham Goode
Date Nov. 15, 2013, 9:23 p.m.
Message ID <23b877e29c1cdcec4668.1384550608@dev350.prn1.facebook.com>
Download mbox | patch
Permalink /patch/2951/
State Accepted
Commit 34d720b3b33ee27104c1ae6cb4d544d185e32327
Headers show

Comments

Durham Goode - Nov. 15, 2013, 9:23 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1384550449 28800
#      Fri Nov 15 13:20:49 2013 -0800
# Node ID 23b877e29c1cdcec46687e8912f2e8aae69d2003
# Parent  aa80446aacc3b1574211649cd8f190250b6b04b3
contrib: add editmerge script for editor conflict prompts

Adds a script that opens the editor to the conflict as part of the merge
process. This way you can fix the merge during the rebase instead of having to
pause the rebase, resolve --mark, rebase --continue.

Only works on unix.
Matt Mackall - Nov. 16, 2013, 5:02 p.m.
On Fri, 2013-11-15 at 13:23 -0800, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1384550449 28800
> #      Fri Nov 15 13:20:49 2013 -0800
> # Node ID 23b877e29c1cdcec46687e8912f2e8aae69d2003
> # Parent  aa80446aacc3b1574211649cd8f190250b6b04b3
> contrib: add editmerge script for editor conflict prompts

Queued for default, thanks.
Aaron Kushner - Nov. 21, 2013, 6:33 p.m.
On 11/15/13 1:23 PM, "Durham Goode" <durham@fb.com> wrote:


>+getlines() {
>+  grep -n "<<<<<<" $FILE | cut -f1 -d:
>+}

Consider 

  awk '/<<<<<</ {print NR}'

>the bottom though, since it's slow to run (0.15 seconds)
>+ED=$HGEDITOR
>+if [ "$ED" = "" ] ; then
>+  ED=$VISUAL
>+fi
>+if [ "$ED" = "" ] ; then
>+  ED=$EDITOR
>+fi
>+if [ "$ED" = "" ] ; then
>+  ED=$(hg showconfig ui.editor)
>+fi
>+if [ "$ED" = "" ] ; then
>+  echo "merge failed - unable to find editor"
>+  exit 1
>+fi


The shorter and more idiomatic bash way of the above is:

ED=${HGEDITOR:-$VISUAL}
ED=${ED:-$EDITOR}
ED=${ED:-$(hg showconfig ui.editor)}
ED=${ED:?"merge failed - unable to find editor"}



>+
>+if [ "$ED" = "emacs" ] || [ "$ED" = "nano" ] || [ "$ED" = "vim" ] ; then

Use double [[]] and the above becomes (don't need to quote the left side
(or right, really)):

If [[ $ED = "emacs || $ED = "nano" || $ED = "vim" ]]; then

Patch

diff --git a/contrib/editmerge b/contrib/editmerge
new file mode 100755
--- /dev/null
+++ b/contrib/editmerge
@@ -0,0 +1,58 @@ 
+#!/bin/bash
+# A simple script for opening merge conflicts in the editor.
+# Use the following Mercurial settings to enable it.
+#
+# [ui]
+# merge = editmerge
+#
+# [merge-tools]
+# editmerge.args=$output
+# editmerge.check=changed
+# editmerge.premerge=keep
+
+FILE=$1
+
+getlines() {
+  grep -n "<<<<<<" $FILE | cut -f1 -d:
+}
+
+# editor preference loosely based on http://mercurial.selenic.com/wiki/editor
+# hg showconfig is at the bottom though, since it's slow to run (0.15 seconds)
+ED=$HGEDITOR
+if [ "$ED" = "" ] ; then
+  ED=$VISUAL
+fi
+if [ "$ED" = "" ] ; then
+  ED=$EDITOR
+fi
+if [ "$ED" = "" ] ; then
+  ED=$(hg showconfig ui.editor)
+fi
+if [ "$ED" = "" ] ; then
+  echo "merge failed - unable to find editor"
+  exit 1
+fi
+
+if [ "$ED" = "emacs" ] || [ "$ED" = "nano" ] || [ "$ED" = "vim" ] ; then
+  FIRSTLINE=$(getlines | head -n 1)
+  PREVIOUSLINE=""
+
+  # open the editor to the first conflict until there are no more
+  # or the user stops editing the file
+  while [ ! "$FIRSTLINE" = "" ] && [ ! "$FIRSTLINE" = "$PREVIOUSLINE" ] ; do
+    $ED +$FIRSTLINE $FILE
+    PREVIOUSLINE=$FIRSTLINE
+    FIRSTLINE=$(getlines | head -n 1)
+  done
+else
+  $ED $FILE
+fi
+
+# get the line numbers of the remaining conflicts
+CONFLICTS=$(getlines | sed ':a;N;$!ba;s/\n/, /g')
+if [ ! "$CONFLICTS" = "" ] ; then
+  echo "merge failed - resolve the conflicts (line $CONFLICTS) then use 'hg resolve --mark'"
+  exit 1
+fi
+
+exit 0