view hgeditor @ 32334:6e0d1043e8fc

fsmonitor: acquire localrepo.wlock prior to emitting hg.update state we see some weird things in the watchman logs where the mercurial process is seemingly confused about which hg.update state it is publishing through watchman. On closer examination, we're seeing conflicting pids for the clients involved and this implies a race. To resolve this, we extend the wlock around the state-enter/state-leave events that are emitted to watchman. Test Plan: Some manual testing: In one window, run this, and then checkout a different rev: ``` $ watchman -p -j <<<'["subscribe", "/data/users/wez/fbsource", "wez", {"expression": ["name", ".hg/updatestate"]}]' { "version": "4.9.0", "subscribe": "wez", "clock": "c:1495034090:814028:1:312576" } { "state-enter": "hg.update", "version": "4.9.0", "clock": "c:1495034090:814028:1:312596", "unilateral": true, "subscription": "wez", "metadata": { "status": "ok", "distance": 125, "rev": "a1275d79ffa6c58b53116c8ec401c275ca6c1e2a", "partial": false }, "root": "/data/users/wez/fbsource" } { "root": "/data/users/wez/fbsource", "metadata": { "status": "ok", "distance": 125, "rev": "a1275d79ffa6c58b53116c8ec401c275ca6c1e2a", "partial": false }, "subscription": "wez", "unilateral": true, "version": "4.9.0", "clock": "c:1495034090:814028:1:312627", "state-leave": "hg.update" } ``` Tailed the watchman log file and looked for invalid state assertion errors, then ran my `rebase-all` script to update/rebase all of my heads. Didn't trigger the error condition (but couldn't reliably trigger it previously anyway), and the output captured above shows that the states are being emitted correctly.
author Wez Furlong <wez@fb.com>
date Thu, 18 May 2017 12:48:07 -0700
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 $?