view hgeditor @ 29322:66dbdd3cc2b9 stable

bdiff: extend matches across popular lines For very large diffs that have large numbers of identical lines (JSON dumps) that also have large blocks of identical text, bdiff could become confused about which block matches which because it can only match very limited regions. The result is very large diffs for small sets of edits. The earlier recursion rebalancing fix made this behavior more frequent because it's now more prone to match block 1 to block 2. One frequent user of large JSON files reported being unable to pass the resulting diffs through their code review system. Prior to this change, bdiff would calculate the length of a match at (i, j) as 1 + length found at (i-1, j-1). With large number of popular (ignored) lines, this often meant matches couldn't be extended backwards at all and thus all matching regions were very small. Disabling the popularity threshold is not an option because it brings back quadratic behavior. Instead, we extend a match backwards until we either found a previously discovered match or we find a mismatching line. This thus successfully bridges over any popular lines inside and before a matching region. The larger regions then significant reduce the probability of confusion.
author Matt Mackall <mpm@selenic.com>
date Thu, 02 Jun 2016 17:09:06 -0500
parents 1aee2ab0f902
children
line wrap: on
line source

#!/bin/sh
#
# This is an example of using HGEDITOR to create of diff to review the
# changes while committing.

# If you want to pass your favourite editor some other parameters
# only for Mercurial, modify this:
case "${EDITOR}" in
    "")
        EDITOR="vi"
        ;;
    emacs)
        EDITOR="$EDITOR -nw"
        ;;
    gvim|vim)
        EDITOR="$EDITOR -f -o"
        ;;
esac


HGTMP=""
cleanup_exit() {
    rm -rf "$HGTMP"
}

# Remove temporary files even if we get interrupted
trap "cleanup_exit" 0 # normal exit
trap "exit 255" HUP INT QUIT ABRT TERM

HGTMP=$(mktemp -d ${TMPDIR-/tmp}/hgeditor.XXXXXX)
[ x$HGTMP != x -a -d $HGTMP ] || {
  echo "Could not create temporary directory! Exiting." 1>&2
  exit 1
}

(
    grep '^HG: changed' "$1" | cut -b 13- | while read changed; do
        "$HG" diff "$changed" >> "$HGTMP/diff"
    done
)

cat "$1" > "$HGTMP/msg"

MD5=$(which md5sum 2>/dev/null) || \
    MD5=$(which md5 2>/dev/null)
[ -x "${MD5}" ] && CHECKSUM=`${MD5} "$HGTMP/msg"`
if [ -s "$HGTMP/diff" ]; then
    $EDITOR "$HGTMP/msg" "$HGTMP/diff" || exit $?
else
    $EDITOR "$HGTMP/msg" || exit $?
fi
[ -x "${MD5}" ] && (echo "$CHECKSUM" | ${MD5} -c >/dev/null 2>&1 && exit 13)

mv "$HGTMP/msg" "$1"

exit $?