changeset 430:52e7aaa34ea3

Removed subrepos
author unexist
date Thu, 23 Aug 2012 22:09:57 +0200
parents a947a6e0535a
children e919ed554e73
files .hgext/.hgsub .hgext/crecord/crecord/__init__.py .hgext/crecord/crecord/__init__.pyc .hgext/crecord/crecord/chunk_selector.py .hgext/crecord/crecord/crecord_core.py .hgext/crecord/crecord/crecord_core.pyc .hgext/crecord/crecord/crpatch.py .hgext/histedit/Makefile .hgext/histedit/README .hgext/histedit/hg_histedit.py .hgext/histedit/setup.py .hgext/histedit/tests/histedit-helpers.sh .hgext/histedit/tests/run-tests.py .hgext/histedit/tests/test-histedit-commute .hgext/histedit/tests/test-histedit-commute.out .hgext/histedit/tests/test-histedit-drop .hgext/histedit/tests/test-histedit-drop.out .hgext/histedit/tests/test-histedit-edit .hgext/histedit/tests/test-histedit-edit.out .hgext/histedit/tests/test-histedit-fold .hgext/histedit/tests/test-histedit-fold-non-commute .hgext/histedit/tests/test-histedit-fold-non-commute.out .hgext/histedit/tests/test-histedit-fold.out .hgext/histedit/tests/test-histedit-no-change .hgext/histedit/tests/test-histedit-no-change.out .hgext/histedit/tests/test-histedit-non-commute .hgext/histedit/tests/test-histedit-non-commute-abort .hgext/histedit/tests/test-histedit-non-commute-abort.out .hgext/histedit/tests/test-histedit-non-commute.out .hgext/histedit/tests/test-histedit-outgoing .hgext/histedit/tests/test-histedit-outgoing.out
diffstat 31 files changed, 0 insertions(+), 4853 deletions(-) [+]
line wrap: on
line diff
--- a/.hgext/.hgsub	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-crecord = crecord
-histedit = histedit
--- a/.hgext/crecord/crecord/__init__.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-# crecord.py
-#
-# Copyright 2008 Mark Edgington <edgimar@gmail.com>
-#
-# This software may be used and distributed according to the terms of
-# the GNU General Public License, incorporated herein by reference.
-#
-# Much of this extension is based on Bryan O'Sullivan's record extension.
-
-'''text-gui based change selection during commit or qrefresh'''
-from mercurial.i18n import _
-from mercurial import commands, extensions, util
-
-from crecord_core import dorecord
-
-def crecord(ui, repo, *pats, **opts):
-    '''interactively select changes to commit
-
-    If a list of files is omitted, all changes reported by :hg:`status`
-    will be candidates for recording.
-
-    See :hg:`help dates` for a list of formats valid for -d/--date.
-
-    You will be shown a list of patch hunks from which you can select
-    those you would like to apply to the commit.
-
-    This command is not available when committing a merge.'''
-
-    dorecord(ui, repo, commands.commit, *pats, **opts)
-
-
-def qcrecord(ui, repo, patch, *pats, **opts):
-    '''interactively record a new patch
-
-    See :hg:`help qnew` & :hg:`help crecord` for more information and
-    usage.
-    '''
-
-    try:
-        mq = extensions.find('mq')
-    except KeyError:
-        raise util.Abort(_("'mq' extension not loaded"))
-
-    def committomq(ui, repo, *pats, **opts):
-        mq.new(ui, repo, patch, *pats, **opts)
-
-    opts = opts.copy()
-    opts['force'] = True    # always 'qnew -f'
-    dorecord(ui, repo, committomq, *pats, **opts)
-
-
-cmdtable = {
-    "crecord":
-        (crecord,
-
-         # add commit options
-         commands.table['^commit|ci'][1],
-
-         _('hg crecord [OPTION]... [FILE]...')),
-}
-
-
-def extsetup():
-    try:
-        keyword = extensions.find('keyword')
-        keyword.restricted += ' crecord qcrecord'
-        try:
-            keyword.recordextensions += ' crecord'
-            keyword.recordcommands += ' crecord qcrecord'
-        except AttributeError:
-            pass
-    except KeyError:
-        pass
-
-    try:
-        mq = extensions.find('mq')
-    except KeyError:
-        return
-
-    qnew = '^qnew'
-    if not qnew in mq.cmdtable:
-        # backwards compatible with pre 301633755dec
-        qnew = 'qnew'
-
-    qcmdtable = {
-    "qcrecord":
-        (qcrecord,
-
-         # add qnew options, except '--force'
-         [opt for opt in mq.cmdtable[qnew][1] if opt[1] != 'force'],
-
-         _('hg qcrecord [OPTION]... PATCH [FILE]...')),
-    }
-
-    cmdtable.update(qcmdtable)
Binary file .hgext/crecord/crecord/__init__.pyc has changed
--- a/.hgext/crecord/crecord/chunk_selector.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1064 +0,0 @@
-from mercurial.i18n import _
-from mercurial import util
-
-# accomodate older versions where encoding module doesn't yet exist
-from mercurial import demandimport
-demandimport.ignore.append('mercurial.encoding')
-try:
-    import mercurial.encoding as encoding
-    code = encoding.encoding
-except ImportError:
-    encoding = util
-    code = encoding._encoding
-
-import os
-import re
-import sys
-import fcntl
-import struct
-import termios
-import signal
-import textwrap
-
-from crpatch import Patch, header, hunk, HunkLine
-
-# os.name is one of: 'posix', 'nt', 'dos', 'os2', 'mac', or 'ce'
-if os.name == 'posix':
-    import curses
-else:
-    # I have no idea if wcurses works with crecord...
-    import wcurses as curses
-
-try:
-    curses
-except NameError:
-    raise util.Abort(
-        _('the python curses/wcurses module is not available/installed'))
-
-
-orig_stdout = sys.__stdout__ # used by gethw()
-
-def gethw():
-    """
-    Magically get the current height and width of the window (without initscr)
-
-    This is a rip-off of a rip-off - taken from the bpython code.  It is
-    useful / necessary because otherwise curses.initscr() must be called,
-    which can leave the terminal in a nasty state after exiting.
-
-    """
-    h, w = struct.unpack(
-        "hhhh", fcntl.ioctl(orig_stdout, termios.TIOCGWINSZ, "\000"*8))[0:2]
-    return h, w
-
-
-def chunkselector(opts, headerList, ui):
-    """
-    Curses interface to get selection of chunks, and mark the applied flags
-    of the chosen chunks.
-
-    """
-
-    chunkSelector = CursesChunkSelector(headerList, ui)
-    curses.wrapper(chunkSelector.main, opts)
-
-class CursesChunkSelector(object):
-    def __init__(self, headerList, ui):
-        # put the headers into a patch object
-        self.headerList = Patch(headerList)
-        
-        self.ui = ui
-
-        # list of all chunks
-        self.chunkList = []
-        for h in headerList:
-            self.chunkList.append(h)
-            self.chunkList.extend(h.hunks)
-
-        # dictionary mapping (fgColor,bgColor) pairs to the corresponding curses
-        # color-pair value.
-        self.colorPairs = {}
-        # maps custom nicknames of color-pairs to curses color-pair values
-        self.colorPairNames = {}
-
-        # the currently selected header, hunk, or hunk-line
-        self.currentSelectedItem = self.headerList[0]
-
-        # updated when printing out patch-display -- the 'lines' here are the
-        # line positions *in the pad*, not on the screen.
-        self.selectedItemStartLine = 0
-        self.selectedItemEndLine = None
-
-        # define indentation levels
-        self.headerIndentNumChars = 0
-        self.hunkIndentNumChars = 3
-        self.hunkLineIndentNumChars = 6
-
-        # the first line of the pad to print to the screen
-        self.firstLineOfPadToPrint = 0
-
-        # keeps track of the number of lines in the pad
-        self.numPadLines = None
-
-        self.numStatusLines = 2
-
-        # keep a running count of the number of lines printed to the pad
-        # (used for determining when the selected item begins/ends)
-        self.linesPrintedToPadSoFar = 0
-
-        # the first line of the pad which is visible on the screen
-        self.firstLineOfPadToPrint = 0
-
-        # stores optional text for a commit comment provided by the user
-        self.commentText = ""
-
-        # if the last 'toggle all' command caused all changes to be applied
-        self.wasLastToggleAllApplied = True
-
-    def upArrowEvent(self):
-        """
-        Try to select the previous item to the current item that has the
-        most-indented level.  For example, if a hunk is selected, try to select
-        the last HunkLine of the hunk prior to the selected hunk.  Or, if
-        the first HunkLine of a hunk is currently selected, then select the
-        hunk itself.
-
-        If the currently selected item is already at the top of the screen,
-        scroll the screen down to show the new-selected item.
-
-        """
-        currentItem = self.currentSelectedItem
-
-        nextItem = currentItem.prevItem(constrainLevel=False)
-
-        if nextItem is None:
-            # if no parent item (i.e. currentItem is the first header), then
-            # no change...
-            nextItem = currentItem
-
-        self.currentSelectedItem = nextItem
-
-    def upArrowShiftEvent(self):
-        """
-        Select (if possible) the previous item on the same level as the
-        currently selected item.  Otherwise, select (if possible) the
-        parent-item of the currently selected item.
-
-        If the currently selected item is already at the top of the screen,
-        scroll the screen down to show the new-selected item.
-
-        """
-        currentItem = self.currentSelectedItem
-        nextItem = currentItem.prevItem()
-        # if there's no previous item on this level, try choosing the parent
-        if nextItem is None:
-            nextItem = currentItem.parentItem()
-        if nextItem is None:
-            # if no parent item (i.e. currentItem is the first header), then
-            # no change...
-            nextItem = currentItem
-
-        self.currentSelectedItem = nextItem
-
-    def downArrowEvent(self):
-        """
-        Try to select the next item to the current item that has the
-        most-indented level.  For example, if a hunk is selected, select
-        the first HunkLine of the selected hunk.  Or, if the last HunkLine of
-        a hunk is currently selected, then select the next hunk, if one exists,
-        or if not, the next header if one exists.
-
-        If the currently selected item is already at the bottom of the screen,
-        scroll the screen up to show the new-selected item.
-
-        """
-        #self.startPrintLine += 1 #DEBUG
-        currentItem = self.currentSelectedItem
-
-        nextItem = currentItem.nextItem(constrainLevel=False)
-        # if there's no next item, keep the selection as-is
-        if nextItem is None:
-            nextItem = currentItem
-
-        self.currentSelectedItem = nextItem
-
-    def downArrowShiftEvent(self):
-        """
-        If the cursor is already at the bottom chunk, scroll the screen up and
-        move the cursor-position to the subsequent chunk.  Otherwise, only move
-        the cursor position down one chunk.
-
-        """
-        # TODO: update docstring
-
-        currentItem = self.currentSelectedItem
-        nextItem = currentItem.nextItem()
-        # if there's no previous item on this level, try choosing the parent's
-        # nextItem.
-        if nextItem is None:
-            try:
-                nextItem = currentItem.parentItem().nextItem()
-            except AttributeError:
-                # parentItem returned None, so nextItem() can't be called
-                nextItem = None
-        if nextItem is None:
-            # if no next item on parent-level, then no change...
-            nextItem = currentItem
-
-        self.currentSelectedItem = nextItem
-
-    def rightArrowEvent(self):
-        """
-        Select (if possible) the first of this item's child-items.
-
-        """
-        currentItem = self.currentSelectedItem
-        nextItem = currentItem.firstChild()
-
-        # turn off folding if we want to show a child-item
-        if currentItem.folded:
-            self.toggleFolded(currentItem)
-
-        if nextItem is None:
-            # if no next item on parent-level, then no change...
-            nextItem = currentItem
-
-        self.currentSelectedItem = nextItem
-
-    def leftArrowEvent(self):
-        """
-        If the current item can be folded (i.e. it is an unfolded header or
-        hunk), then fold it.  Otherwise try select (if possible) the parent
-        of this item.
-
-        """
-        currentItem = self.currentSelectedItem
-
-        # try to fold the item
-        if not isinstance(currentItem, HunkLine):
-            if not currentItem.folded:
-                self.toggleFolded(item=currentItem)
-                return
-
-        # if it can't be folded, try to select the parent item
-        nextItem = currentItem.parentItem()
-
-        if nextItem is None:
-            # if no item on parent-level, then no change...
-            nextItem = currentItem
-            if not nextItem.folded:
-                self.toggleFolded(item=nextItem)
-
-        self.currentSelectedItem = nextItem
-
-    def leftArrowShiftEvent(self):
-        """
-        Select the header of the current item (or fold current item if the
-        current item is already a header).
-
-        """
-        currentItem = self.currentSelectedItem
-
-        if isinstance(currentItem, header):
-            if not currentItem.folded:
-                self.toggleFolded(item=currentItem)
-                return
-
-        # select the parent item recursively until we're at a header
-        while True:
-            nextItem = currentItem.parentItem()
-            if nextItem is None:
-                break
-            else:
-                currentItem = nextItem
-
-        self.currentSelectedItem = currentItem
-
-    def updateScroll(self):
-        "Scroll the screen to fully show the currently-selected"
-        selStart = self.selectedItemStartLine
-        selEnd = self.selectedItemEndLine
-        #selNumLines = selEnd - selStart
-        padStart = self.firstLineOfPadToPrint
-        padEnd = padStart + self.yScreenSize - self.numStatusLines - 1
-        # 'buffered' pad start/end values which scroll with a certain
-        # top/bottom context margin
-        padStartBuffered = padStart + 3
-        padEndBuffered = padEnd - 3
-
-        if selEnd > padEndBuffered:
-            self.scrollLines(selEnd - padEndBuffered)
-        elif selStart < padStartBuffered:
-            # negative values scroll in pgup direction
-            self.scrollLines(selStart - padStartBuffered)
-
-
-    def scrollLines(self, numLines):
-        "Scroll the screen up (down) by numLines when numLines >0 (<0)."
-        self.firstLineOfPadToPrint += numLines
-        if self.firstLineOfPadToPrint < 0:
-            self.firstLineOfPadToPrint = 0
-        if self.firstLineOfPadToPrint > self.numPadLines-1:
-            self.firstLineOfPadToPrint = self.numPadLines-1
-
-    def toggleApply(self, item=None):
-        """
-        Toggle the applied flag of the specified item.  If no item is specified,
-        toggle the flag of the currently selected item.
-
-        """
-        if item is None:
-            item = self.currentSelectedItem
-
-        item.applied = not item.applied
-
-        if isinstance(item, header):
-            item.partial = False
-            if item.applied:
-                if not item.special():
-                    # apply all its hunks
-                    for hnk in item.hunks:
-                        hnk.applied = True
-                        # apply all their HunkLines
-                        for hunkLine in hnk.changedLines:
-                            hunkLine.applied = True
-                else:
-                    # all children are off (but the header is on)
-                    if len(item.allChildren()) > 0:
-                        item.partial = True
-            else:
-                # un-apply all its hunks
-                for hnk in item.hunks:
-                    hnk.applied = False
-                    hnk.partial = False
-                    # un-apply all their HunkLines
-                    for hunkLine in hnk.changedLines:
-                        hunkLine.applied = False
-        elif isinstance(item, hunk):
-            item.partial = False
-            # apply all it's HunkLines
-            for hunkLine in item.changedLines:
-                hunkLine.applied = item.applied
-
-            siblingAppliedStatus = [hnk.applied for hnk in item.header.hunks]
-            allSiblingsApplied = not (False in siblingAppliedStatus)
-            noSiblingsApplied = not (True in siblingAppliedStatus)
-
-            siblingsPartialStatus = [hnk.partial for hnk in item.header.hunks]
-            someSiblingsPartial = (True in siblingsPartialStatus)
-
-            #cases where applied or partial should be removed from header
-
-            # if no 'sibling' hunks are applied (including this hunk)
-            if noSiblingsApplied:
-                if not item.header.special():
-                    item.header.applied = False
-                    item.header.partial = False
-            else: # some/all parent siblings are applied
-                item.header.applied = True
-                item.header.partial = (someSiblingsPartial or
-                                        not allSiblingsApplied)
-
-        elif isinstance(item, HunkLine):
-            siblingAppliedStatus = [ln.applied for ln in item.hunk.changedLines]
-            allSiblingsApplied = not (False in siblingAppliedStatus)
-            noSiblingsApplied = not (True in siblingAppliedStatus)
-
-            # if no 'sibling' lines are applied
-            if noSiblingsApplied:
-                item.hunk.applied = False
-                item.hunk.partial = False
-            elif allSiblingsApplied:
-                item.hunk.applied = True
-                item.hunk.partial = False
-            else: # some siblings applied
-                item.hunk.applied = True
-                item.hunk.partial = True
-
-            parentSiblingsApplied = [hnk.applied for hnk
-                                     in item.hunk.header.hunks]
-            noParentSiblingsApplied = not (True in parentSiblingsApplied)
-            allParentSiblingsApplied = not (False in parentSiblingsApplied)
-
-            parentSiblingsPartial = [hnk.partial for hnk
-                                     in item.hunk.header.hunks]
-            someParentSiblingsPartial = (True in parentSiblingsPartial)
-
-            # if all parent hunks are not applied, un-apply header
-            if noParentSiblingsApplied:
-                if not item.hunk.header.special():
-                    item.hunk.header.applied = False
-                    item.hunk.header.partial = False
-            # set the applied and partial status of the header if needed
-            else: # some/all parent siblings are applied
-                item.hunk.header.applied = True
-                item.hunk.header.partial = (someParentSiblingsPartial or
-                                            not allParentSiblingsApplied)
-
-    def toggleAll(self):
-        "Toggle the applied flag of all items."
-        if self.wasLastToggleAllApplied: # then unapply them this time
-            for item in self.headerList:
-                if item.applied:
-                    self.toggleApply(item)
-        else:
-            for item in self.headerList:
-                if not item.applied:
-                    self.toggleApply(item)
-        self.wasLastToggleAllApplied = not self.wasLastToggleAllApplied
-
-    def toggleFolded(self, item=None, foldParent=False):
-        "Toggle folded flag of specified item (defaults to currently selected)"
-        if item is None:
-            item = self.currentSelectedItem
-        if foldParent or (isinstance(item, header) and item.neverUnfolded):
-            if not isinstance(item, header):
-                # we need to select the parent item in this case
-                self.currentSelectedItem = item = item.parentItem()
-            elif item.neverUnfolded:
-                item.neverUnfolded = False
-
-            # also fold any foldable children of the parent/current item
-            if isinstance(item, header): # the original OR 'new' item
-                for child in item.allChildren():
-                    child.folded = not item.folded
-
-        if isinstance(item, (header, hunk)):
-            item.folded = not item.folded
-
-
-    def alignString(self, inStr, window):
-        """
-        Add whitespace to the end of a string in order to make it fill
-        the screen in the x direction.  The current cursor position is
-        taken into account when making this calculation.  The string can span
-        multiple lines.
-
-        """
-        y,xStart = window.getyx()
-        width = self.xScreenSize
-        # turn tabs into spaces
-        inStr = inStr.expandtabs(4)
-        try:
-            strLen = len(unicode(encoding.fromlocal(inStr), code))
-        except:
-            # if text is not utf8, then assume an 8-bit single-byte encoding.
-            strLen = len(inStr)
-
-        numSpaces = (width - ((strLen + xStart) % width) - 1)
-        return inStr + " " * numSpaces + "\n"
-
-    def printString(self, window, text, fgColor=None, bgColor=None, pair=None,
-        pairName=None, attrList=None, toWin=True, align=True, showWhtSpc=False):
-        """
-        Print the string, text, with the specified colors and attributes, to
-        the specified curses window object.
-
-        The foreground and background colors are of the form
-        curses.COLOR_XXXX, where XXXX is one of: [BLACK, BLUE, CYAN, GREEN,
-        MAGENTA, RED, WHITE, YELLOW].  If pairName is provided, a color
-        pair will be looked up in the self.colorPairNames dictionary.
-
-        attrList is a list containing text attributes in the form of
-        curses.A_XXXX, where XXXX can be: [BOLD, DIM, NORMAL, STANDOUT,
-        UNDERLINE].
-
-        If align == True, whitespace is added to the printed string such that
-        the string stretches to the right border of the window.
-
-        If showWhtSpc == True, trailing whitespace of a string is highlighted.
-
-        """
-        # preprocess the text, converting tabs to spaces
-        text = text.expandtabs(4)
-        # Strip \n, and convert control characters to ^[char] representation
-        text = re.sub(r'[\x00-\x08\x0a-\x1f]',
-                lambda m:'^'+chr(ord(m.group())+64), text.strip('\n'))
-
-        if pair is not None:
-            colorPair = pair
-        elif pairName is not None:
-            colorPair = self.colorPairNames[pairName]
-        else:
-            if fgColor is None:
-                fgColor = -1
-            if bgColor is None:
-                bgColor = -1
-            if self.colorPairs.has_key((fgColor,bgColor)):
-                colorPair = self.colorPairs[(fgColor,bgColor)]
-            else:
-                colorPair = self.getColorPair(fgColor, bgColor)
-        # add attributes if possible
-        if attrList is None:
-            attrList = []
-        if colorPair < 256:
-            # then it is safe to apply all attributes
-            for textAttr in attrList:
-                colorPair |= textAttr
-        else:
-            # just apply a select few (safe?) attributes
-            for textAttr in (curses.A_UNDERLINE, curses.A_BOLD):
-                if textAttr in attrList:
-                    colorPair |= textAttr
-
-        y,xStart = self.chunkpad.getyx()
-        t = "" # variable for counting lines printed
-        # if requested, show trailing whitespace
-        if showWhtSpc:
-            origLen = len(text)
-            text = text.rstrip(' \n') # tabs have already been expanded
-            strippedLen = len(text)
-            numTrailingSpaces = origLen - strippedLen
-
-        if toWin:
-            window.addstr(text, colorPair)
-        t += text
-
-        if showWhtSpc:
-                wsColorPair = colorPair | curses.A_REVERSE
-                if toWin:
-                    for i in range(numTrailingSpaces):
-                        window.addch(curses.ACS_CKBOARD, wsColorPair)
-                t += " " * numTrailingSpaces
-
-        if align:
-            if toWin:
-                extraWhiteSpace = self.alignString("", window)
-                window.addstr(extraWhiteSpace, colorPair)
-            else:
-                # need to use t, since the x position hasn't incremented
-                extraWhiteSpace = self.alignString(t, window)
-            t += extraWhiteSpace
-
-        # is reset to 0 at the beginning of printItem()
-
-        linesPrinted = (xStart + len(t)) / self.xScreenSize
-        self.linesPrintedToPadSoFar += linesPrinted
-        return t
-
-    def updateScreen(self):
-        self.statuswin.erase()
-        self.chunkpad.erase()
-
-        printString = self.printString
-
-        # print out the status lines at the top
-        try:
-            printString(self.statuswin,
-                        "SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; "
-                        "(space/A) toggle hunk/all",
-                        pairName="legend")
-            printString(self.statuswin,
-                        " (f)old/unfold; (c)ommit applied; (q)uit; (?) help "
-                        "| [X]=hunk applied **=folded",
-                        pairName="legend")
-        except curses.error:
-            pass
-
-        # print out the patch in the remaining part of the window
-        try:
-            self.printItem()
-            self.updateScroll()
-            self.chunkpad.refresh(self.firstLineOfPadToPrint, 0,
-                                  self.numStatusLines, 0,
-                                  self.yScreenSize+1-self.numStatusLines,
-                                  self.xScreenSize)
-        except curses.error:
-            pass
-
-        # refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])
-        self.statuswin.refresh()
-
-    def getStatusPrefixString(self, item):
-        """
-        Create a string to prefix a line with which indicates whether 'item'
-        is applied and/or folded.
-
-        """
-        # create checkBox string
-        if item.applied:
-            if not isinstance(item, HunkLine) and item.partial:
-                checkBox = "[~]"
-            else:
-                checkBox = "[X]"
-        else:
-            checkBox = "[ ]"
-
-        try:
-            if item.folded:
-                checkBox += "**"
-                if isinstance(item, header):
-                    # one of "M", "A", or "D" (modified, added, deleted)
-                    fileStatus = item.changetype
-
-                    checkBox += fileStatus + " "
-            else:
-                checkBox += "  "
-                if isinstance(item, header):
-                    # add two more spaces for headers
-                    checkBox += "  "
-        except AttributeError: # not foldable
-            checkBox += "  "
-
-        return checkBox
-
-    def printHeader(self, header, selected=False, toWin=True,
-                    ignoreFolding=False):
-        """
-        Print the header to the pad.  If countLines is True, don't print
-        anything, but just count the number of lines which would be printed.
-
-        """
-        outStr = ""
-        text = header.prettyStr()
-        chunkIndex = self.chunkList.index(header)
-
-        if chunkIndex != 0 and not header.folded:
-            # add separating line before headers
-            outStr += self.printString(self.chunkpad, '_' * self.xScreenSize,
-                                       toWin=toWin, align=False)
-        # select color-pair based on if the header is selected
-        colorPair = self.getColorPair(name=selected and "selected" or "normal",
-                                      attrList=[curses.A_BOLD])
-
-        # print out each line of the chunk, expanding it to screen width
-
-        # number of characters to indent lines on this level by
-        indentNumChars = 0
-        checkBox = self.getStatusPrefixString(header)
-        if not header.folded or ignoreFolding:
-            textList = text.split("\n")
-            lineStr = checkBox + textList[0]
-        else:
-            lineStr = checkBox + header.filename()
-        outStr += self.printString(self.chunkpad, lineStr, pair=colorPair,
-                                   toWin=toWin)
-        if not header.folded or ignoreFolding:
-            if len(textList) > 1:
-                for line in textList[1:]:
-                    lineStr = " "*(indentNumChars + len(checkBox)) + line
-                    outStr += self.printString(self.chunkpad, lineStr,
-                                               pair=colorPair, toWin=toWin)
-
-        return outStr
-
-    def printHunkLinesBefore(self, hunk, selected=False, toWin=True,
-                             ignoreFolding=False):
-        "includes start/end line indicator"
-        outStr = ""
-        # where hunk is in list of siblings
-        hunkIndex = hunk.header.hunks.index(hunk)
-
-        if hunkIndex != 0:
-            # add separating line before headers
-            outStr += self.printString(self.chunkpad, ' '*self.xScreenSize,
-                                       toWin=toWin, align=False)
-
-        colorPair = self.getColorPair(name=selected and "selected" or "normal",
-                                      attrList=[curses.A_BOLD])
-
-        # print out from-to line with checkbox
-        checkBox = self.getStatusPrefixString(hunk)
-
-        linePrefix = " "*self.hunkIndentNumChars + checkBox
-        frToLine = "   " + hunk.getFromToLine().strip("\n")
-
-
-        outStr += self.printString(self.chunkpad, linePrefix, toWin=toWin,
-                                   align=False) # add uncolored checkbox/indent
-        outStr += self.printString(self.chunkpad, frToLine, pair=colorPair,
-                                   toWin=toWin)
-
-        if hunk.folded and not ignoreFolding:
-            # skip remainder of output
-            return outStr
-
-        # print out lines of the chunk preceeding changed-lines
-        for line in hunk.before:
-            lineStr = " "*(self.hunkLineIndentNumChars + len(checkBox)) + line
-            outStr += self.printString(self.chunkpad, lineStr, toWin=toWin)
-
-        return outStr
-
-    def printHunkLinesAfter(self, hunk, toWin=True, ignoreFolding=False):
-        outStr = ""
-        if hunk.folded and not ignoreFolding:
-            return outStr
-
-        indentNumChars = self.hunkLineIndentNumChars-1
-        # a bit superfluous, but to avoid hard-coding indent amount
-        checkBox = self.getStatusPrefixString(hunk)
-        for line in hunk.after:
-            lineStr = " "*(indentNumChars + len(checkBox)) + line
-            outStr += self.printString(self.chunkpad, lineStr, toWin=toWin)
-
-        return outStr
-
-    def printHunkChangedLine(self, hunkLine, selected=False, toWin=True):
-        outStr = ""
-        indentNumChars = self.hunkLineIndentNumChars
-        checkBox = self.getStatusPrefixString(hunkLine)
-
-        lineStr = hunkLine.prettyStr().strip("\n")
-
-        # select color-pair based on whether line is an addition/removal
-        if selected:
-            colorPair = self.getColorPair(name="selected")
-        elif lineStr.startswith("+"):
-            colorPair = self.getColorPair(name="addition")
-        elif lineStr.startswith("-"):
-            colorPair = self.getColorPair(name="deletion")
-        elif lineStr.startswith("\\"):
-            colorPair = self.getColorPair(name="normal")
-
-        linePrefix = " "*indentNumChars + checkBox
-        outStr += self.printString(self.chunkpad, linePrefix, toWin=toWin,
-                                   align=False) # add uncolored checkbox/indent
-        outStr += self.printString(self.chunkpad, lineStr, pair=colorPair,
-                                   toWin=toWin, showWhtSpc=True)
-        return outStr
-
-    def printItem(self, item=None, ignoreFolding=False, recurseChildren=True,
-                  toWin=True):
-        """
-        Use __printItem() to print the the specified item.applied.
-        If item is not specified, then print the entire patch.
-        (hiding folded elements, etc. -- see __printitem() docstring)
-        """
-        if item is None:
-            item = self.headerList
-        if recurseChildren:
-            self.linesPrintedToPadSoFar = 0
-            global outStr
-        retStr = self.__printItem(item, ignoreFolding, recurseChildren,
-                                  toWin=toWin)
-        if recurseChildren:
-            # remove the string when finished, so it doesn't accumulate
-            del outStr
-
-        return retStr
-
-    def __printItem(self, item, ignoreFolding, recurseChildren, toWin=True):
-        """
-        Recursive method for printing out patch/header/hunk/hunk-line data to
-        screen.  Also returns a string with all of the content of the displayed
-        patch (not including coloring, etc.).
-
-        If ignoreFolding is True, then folded items are printed out.
-
-        If recurseChildren is False, then only print the item without its
-        child items.
-
-        """
-        # keep outStr local, since we're not recursing
-        if recurseChildren:
-            global outStr
-            try:
-                outStr
-            except:
-                outStr = ""
-        else:
-            outStr = ""
-
-        selected = (item is self.currentSelectedItem)
-        if selected and recurseChildren:
-            # assumes line numbering starting from line 0
-            self.selectedItemStartLine = self.linesPrintedToPadSoFar
-            selectedItemLines = self.getNumLinesDisplayed(item,
-                                                          recurseChildren=False)
-            self.selectedItemEndLine = (self.selectedItemStartLine +
-                                        selectedItemLines - 1)
-
-        # Patch object is a list of headers
-        if isinstance(item, Patch):
-            if recurseChildren:
-                for hdr in item:
-                    self.__printItem(hdr, ignoreFolding, recurseChildren, toWin)
-        # TODO: eliminate all isinstance() calls
-        if isinstance(item, header):
-            outStr += self.printHeader(item, selected, toWin=toWin,
-                                       ignoreFolding=ignoreFolding)
-            if recurseChildren:
-                for hnk in item.hunks:
-                    self.__printItem(hnk, ignoreFolding, recurseChildren, toWin)
-        elif (isinstance(item, hunk) and
-              ((not item.header.folded) or ignoreFolding)):
-            # print the hunk data which comes before the changed-lines
-            outStr += self.printHunkLinesBefore(item, selected, toWin=toWin,
-                                                ignoreFolding=ignoreFolding)
-            if recurseChildren:
-                for l in item.changedLines:
-                    self.__printItem(l, ignoreFolding, recurseChildren, toWin)
-                outStr += self.printHunkLinesAfter(item, toWin=toWin,
-                                                   ignoreFolding=ignoreFolding)
-        elif (isinstance(item, HunkLine) and
-              ((not item.hunk.folded) or ignoreFolding)):
-            outStr += self.printHunkChangedLine(item, selected, toWin=toWin)
-
-        return outStr
-
-    def getNumLinesDisplayed(self, item=None, ignoreFolding=False,
-                             recurseChildren=True):
-        """
-        Return the number of lines which would be displayed if the item were
-        to be printed to the display.  The item will NOT be printed to the
-        display (pad).
-        If no item is given, assume the entire patch.
-        If ignoreFolding is True, folded items will be unfolded when counting
-        the number of lines.
-
-        """
-        # temporarily disable printing to windows by printString
-        patchDisplayString = self.printItem(item, ignoreFolding,
-                                            recurseChildren, toWin=False)
-        numLines = len(patchDisplayString)/self.xScreenSize
-        return numLines
-
-    def sigwinchHandler(self, n, frame):
-        "Handle window resizing"
-        try:
-            curses.endwin()
-            self.yScreenSize, self.xScreenSize = gethw()
-            self.statuswin.resize(self.numStatusLines,self.xScreenSize)
-            self.numPadLines = self.getNumLinesDisplayed(ignoreFolding=True) + 1
-            self.chunkpad = curses.newpad(self.numPadLines, self.xScreenSize)
-            # TODO: try to resize commit message window if possible
-        except curses.error:
-            pass
-
-    def getColorPair(self, fgColor=None, bgColor=None, name=None,
-                     attrList=None):
-        """
-        Get a curses color pair, adding it to self.colorPairs if it is not
-        already defined.  An optional string, name, can be passed as a shortcut
-        for referring to the color-pair.  By default, if no arguments are
-        specified, the white foreground / black background color-pair is
-        returned.
-
-        It is expected that this function will be used exclusively for
-        initializing color pairs, and NOT curses.init_pair().
-
-        attrList is used to 'flavor' the returned color-pair.  This information
-        is not stored in self.colorPairs.  It contains attribute values like
-        curses.A_BOLD.
-
-        """
-        if (name is not None) and self.colorPairNames.has_key(name):
-            # then get the associated color pair and return it
-            colorPair = self.colorPairNames[name]
-        else:
-            if fgColor is None:
-                fgColor = -1
-            if bgColor is None:
-                bgColor = -1
-            if self.colorPairs.has_key((fgColor,bgColor)):
-                colorPair = self.colorPairs[(fgColor,bgColor)]
-            else:
-                pairIndex = len(self.colorPairs) + 1
-                curses.init_pair(pairIndex, fgColor, bgColor)
-                colorPair = self.colorPairs[(fgColor, bgColor)] = (
-                    curses.color_pair(pairIndex))
-                if name is not None:
-                    self.colorPairNames[name] = curses.color_pair(pairIndex)
-
-        # add attributes if possible
-        if attrList is None:
-            attrList = []
-        if colorPair < 256:
-            # then it is safe to apply all attributes
-            for textAttr in attrList:
-                colorPair |= textAttr
-        else:
-            # just apply a select few (safe?) attributes
-            for textAttrib in (curses.A_UNDERLINE, curses.A_BOLD):
-                if textAttrib in attrList:
-                    colorPair |= textAttrib
-        return colorPair
-
-    def initColorPair(self, *args, **kwargs):
-        "Same as getColorPair."
-        self.getColorPair(*args, **kwargs)
-
-    def helpWindow(self):
-        "Print a help window to the screen.  Exit after any keypress."
-        helpText = """            [press any key to return to the patch-display]
-
-crecord allows you to interactively choose among the changes you have made,
-and commit only those changes you select.  After committing the selected
-changes, the unselected changes are still present in your working copy, so you
-can use crecord multiple times to split large changes into smaller changesets.
-The following are valid keystrokes:
-
-                [SPACE] : (un-)select item ([~]/[X] = partly/fully applied)
-                      A : (un-)select all items
-    Up/Down-arrow [k/j] : go to previous/next unfolded item
-        PgUp/PgDn [K/J] : go to previous/next item of same type
- Right/Left-arrow [l/h] : go to child item / parent item
- Shift-Left-arrow   [H] : go to parent header / fold selected header
-                      f : fold / unfold item, hiding/revealing its children
-                      F : fold / unfold parent item and all of its ancestors
-                      m : edit / resume editing the commit message
-                      c : commit selected changes
-                      r : review/edit and commit selected changes
-                      q : quit without committing (no changes will be made)
-                      ? : help (what you're currently reading)"""
-
-        helpwin = curses.newwin(self.yScreenSize, 0, 0, 0)
-        helpLines = helpText.split("\n")
-        helpLines = helpLines + [" "]*(
-            self.yScreenSize - self.numStatusLines - len(helpLines) - 1)
-        try:
-            for line in helpLines:
-                self.printString(helpwin, line, pairName="legend")
-        except curses.error:
-            pass
-        helpwin.refresh()
-        try:
-            helpwin.getkey()
-        except curses.error:
-            pass
-
-    def commitMessageWindow(self):
-        "Create a temporary commit message editing window on the screen."
-        if self.commentText == "":
-            self.commentText = textwrap.dedent("""
-            HG: Enter/resume commit message.  Lines beginning with 'HG:' are removed.
-            HG: You can save this message, and edit it again later before committing.
-            HG: After exiting the editor, you will return to the crecord patch view.
-            HG: --
-            HG: user: %s""" % self.ui.username())
-            
-        curses.raw()
-        curses.def_prog_mode()
-        curses.endwin()
-        self.commentText = self.ui.edit(self.commentText, self.ui.username())
-        curses.cbreak()
-        self.stdscr.refresh()
-        self.stdscr.keypad(1) # allow arrow-keys to continue to function
-        
-    def confirmCommit(self, review=False):
-        "Ask for 'Y' to be pressed to confirm commit. Return True if confirmed."
-        if review:
-            confirmText = (
-"""If you answer yes to the following, the your currently chosen patch chunks
-will be loaded into an editor.  You may modify the patch from the editor, and
-save the changes if you wish to change the patch.  Otherwise, you can just
-close the editor without saving to accept the current patch as-is.
-
-NOTE: don't add/remove lines unless you also modify the range information.
-      Failing to follow this rule will result in the commit aborting.
-
-Are you sure you want to review/edit and commit the selected changes [yN]? """)
-        else:
-            confirmText = (
-                "Are you sure you want to commit the selected changes [yN]? ")
-
-        confirmWin = curses.newwin(self.yScreenSize, 0, 0, 0)
-        try:
-            lines = confirmText.split("\n")
-            for line in lines:
-                self.printString(confirmWin, line, pairName="selected")
-        except curses.error:
-            pass
-        self.stdscr.refresh()
-        confirmWin.refresh()
-        try:
-            response = chr(self.stdscr.getch())
-        except ValueError:
-            response = "n"
-        if response.lower().startswith("y"):
-            return True
-        else:
-            return False
-
-    def main(self, stdscr, opts):
-        """
-        Method to be wrapped by curses.wrapper() for selecting chunks.
-
-        """
-        signal.signal(signal.SIGWINCH, self.sigwinchHandler)
-        self.stdscr = stdscr
-        self.yScreenSize, self.xScreenSize = self.stdscr.getmaxyx()
-
-        curses.start_color()
-        curses.use_default_colors()
-
-        # available colors: black, blue, cyan, green, magenta, white, yellow
-        # init_pair(color_id, foreground_color, background_color)
-        self.initColorPair(None, None, name="normal")
-        self.initColorPair(curses.COLOR_WHITE, curses.COLOR_MAGENTA,
-                           name="selected")
-        self.initColorPair(curses.COLOR_RED, None, name="deletion")
-        self.initColorPair(curses.COLOR_GREEN, None, name="addition")
-        self.initColorPair(curses.COLOR_WHITE, curses.COLOR_BLUE, name="legend")
-        # newwin([height, width,] begin_y, begin_x)
-        self.statuswin = curses.newwin(self.numStatusLines,0 ,0 , 0)
-        self.statuswin.keypad(1) # interpret arrow-key, etc. ESC sequences
-
-        # figure out how much space to allocate for the chunk-pad which is
-        # used for displaying the patch
-
-        # stupid hack to prevent getNumLinesDisplayed from failing
-        self.chunkpad = curses.newpad(1,self.xScreenSize)
-
-        # add 1 so to account for last line text reaching end of line
-        self.numPadLines = self.getNumLinesDisplayed(ignoreFolding=True) + 1
-        self.chunkpad = curses.newpad(self.numPadLines, self.xScreenSize)
-
-        # initialize selecteItemEndLine (initial start-line is 0)
-        self.selectedItemEndLine = self.getNumLinesDisplayed(
-            self.currentSelectedItem, recurseChildren=False)
-
-        # option which enables/disables patch-review (in editor) step
-        opts['crecord_reviewpatch'] = False
-
-        try:
-            self.commentText = opts['message']
-        except KeyError:
-            pass
-
-        while True:
-            self.updateScreen()
-            try:
-                keyPressed = self.statuswin.getkey()
-            except curses.error:
-                keyPressed = "FOOBAR"
-
-            if keyPressed in ["k", "KEY_UP"]:
-                self.upArrowEvent()
-            if keyPressed in ["K", "KEY_PPAGE"]:
-                self.upArrowShiftEvent()
-            elif keyPressed in ["j", "KEY_DOWN"]:
-                self.downArrowEvent()
-            elif keyPressed in ["J", "KEY_NPAGE"]:
-                self.downArrowShiftEvent()
-            elif keyPressed in ["l", "KEY_RIGHT"]:
-                self.rightArrowEvent()
-            elif keyPressed in ["h", "KEY_LEFT"]:
-                self.leftArrowEvent()
-            elif keyPressed in ["H", "KEY_SLEFT"]:
-                self.leftArrowShiftEvent()
-            elif keyPressed in ["q"]:
-                raise util.Abort(_('user quit'))
-            elif keyPressed in ["c"]:
-                if self.confirmCommit():
-                    break
-            elif keyPressed in ["r"]:
-                if self.confirmCommit(review=True):
-                    opts['crecord_reviewpatch'] = True
-                    break
-            elif keyPressed in [' ']:
-                self.toggleApply()
-            elif keyPressed in ['A']:
-                self.toggleAll()
-            elif keyPressed in ["f"]:
-                self.toggleFolded()
-            elif keyPressed in ["F"]:
-                self.toggleFolded(foldParent=True)
-            elif keyPressed in ["?"]:
-                self.helpWindow()
-            elif keyPressed in ["m"]:
-                self.commitMessageWindow()
-
-        if self.commentText != "":
-            opts['message'] = self.commentText
--- a/.hgext/crecord/crecord/crecord_core.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-# crecord.py
-#
-# Copyright 2008 Mark Edgington <edgimar@gmail.com>
-#
-# This software may be used and distributed according to the terms of
-# the GNU General Public License, incorporated herein by reference.
-#
-# Much of this extension is based on Bryan O'Sullivan's record extension.
-
-'''text-gui based change selection during commit or qrefresh'''
-from mercurial.i18n import _
-from mercurial import cmdutil, hg, mdiff, patch
-from mercurial import util
-import cStringIO
-import errno
-import os
-import tempfile
-
-import crpatch
-import chunk_selector
-
-def dorecord(ui, repo, commitfunc, *pats, **opts):
-    try:
-        if not ui.interactive():
-            raise util.Abort(_('running non-interactively, use commit instead'))
-    except TypeError: # backwards compatibility with hg 1.1
-        if not ui.interactive:
-            raise util.Abort(_('running non-interactively, use commit instead'))
-
-    def recordfunc(ui, repo, message, match, opts):
-        """This is generic record driver.
-
-        Its job is to interactively filter local changes, and accordingly
-        prepare working dir into a state, where the job can be delegated to
-        non-interactive commit command such as 'commit' or 'qrefresh'.
-
-        After the actual job is done by non-interactive command, working dir
-        state is restored to original.
-
-        In the end we'll record interesting changes, and everything else will be
-        left in place, so the user can continue his work.
-        """
-
-        merge = len(repo[None].parents()) > 1
-        if merge:
-            raise util.Abort(_('cannot partially commit a merge '
-                               '(use hg commit instead)'))
-
-        changes = repo.status(match=match)[:3]
-        diffopts = mdiff.diffopts(git=True, nodates=True)
-        chunks = patch.diff(repo, changes=changes, opts=diffopts)
-        fp = cStringIO.StringIO()
-        fp.write(''.join(chunks))
-        fp.seek(0)
-
-        # 1. filter patch, so we have intending-to apply subset of it
-        chunks = crpatch.filterpatch(opts,
-                                     crpatch.parsepatch(changes, fp),
-                                     chunk_selector.chunkselector, ui)
-        del fp
-
-        contenders = set()
-        for h in chunks:
-            try:
-                contenders.update(set(h.files()))
-            except AttributeError:
-                pass
-
-        changed = changes[0] + changes[1] + changes[2]
-        newfiles = [f for f in changed if f in contenders]
-
-        if not newfiles:
-            ui.status(_('no changes to record\n'))
-            return 0
-
-        modified = set(changes[0])
-
-        # 2. backup changed files, so we can restore them in the end
-        backups = {}
-        backupdir = repo.join('record-backups')
-        try:
-            os.mkdir(backupdir)
-        except OSError, err:
-            if err.errno != errno.EEXIST:
-                raise
-        try:
-            # backup continues
-            for f in newfiles:
-                if f not in modified:
-                    continue
-                fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
-                                               dir=backupdir)
-                os.close(fd)
-                ui.debug('backup %r as %r\n' % (f, tmpname))
-                util.copyfile(repo.wjoin(f), tmpname)
-                backups[f] = tmpname
-
-            fp = cStringIO.StringIO()
-            for c in chunks:
-                if c.filename() in backups:
-                    c.write(fp)
-            dopatch = fp.tell()
-            fp.seek(0)
-
-            # 2.5 optionally review / modify patch in text editor
-            if opts['crecord_reviewpatch']:
-                patchtext = fp.read()
-                reviewedpatch = ui.edit(patchtext, "")
-                fp.truncate(0)
-                fp.write(reviewedpatch)
-                fp.seek(0)
-
-            # 3a. apply filtered patch to clean repo  (clean)
-            if backups:
-                hg.revert(repo, repo.dirstate.parents()[0],
-                          lambda key: key in backups)
-
-            # 3b. (apply)
-            if dopatch:
-                try:
-                    ui.debug('applying patch\n')
-                    ui.debug(fp.getvalue())
-                    pfiles = {}
-                    try:
-                        from mercurial import scmutil
-                        patch.internalpatch(ui, repo, fp, strip=1, files=pfiles,
-                                            eolmode=None)
-                        scmutil.updatedir(ui, repo, pfiles)
-                    except ImportError: # pre 3438417a6657
-                        try:
-                            patch.internalpatch(ui, repo, fp, 1, eolmode=None)
-                        except (TypeError, AttributeError): # pre 17cea10c343e
-                            try:
-                                patch.internalpatch(ui, repo, fp, 1, repo.root,
-                                                    eolmode=None)
-                            except (TypeError, AttributeError): # pre 00a881581400
-                                try:
-                                    patch.internalpatch(fp, ui, 1, repo.root,
-                                                        files=pfiles, eolmode=None)
-                                except TypeError: # backwards compatible with hg 1.1
-                                    patch.internalpatch(fp, ui, 1,
-                                                        repo.root, files=pfiles)
-                        try:
-                            cmdutil.updatedir(ui, repo, pfiles)
-                        except AttributeError:
-                            try:
-                                patch.updatedir(ui, repo, pfiles)
-                            except AttributeError:
-                                # from 00a881581400 onwards
-                                pass
-                except patch.PatchError, err:
-                    s = str(err)
-                    if s:
-                        raise util.Abort(s)
-                    else:
-                        raise util.Abort(_('patch failed to apply'))
-            del fp
-
-            # 4. We prepared working directory according to filtered patch.
-            #    Now is the time to delegate the job to commit/qrefresh or the like!
-
-            # it is important to first chdir to repo root -- we'll call a
-            # highlevel command with list of pathnames relative to repo root
-            cwd = os.getcwd()
-            os.chdir(repo.root)
-            try:
-                commitfunc(ui, repo, *newfiles, **opts)
-            finally:
-                os.chdir(cwd)
-
-            return 0
-        finally:
-            # 5. finally restore backed-up files
-            try:
-                for realname, tmpname in backups.iteritems():
-                    ui.debug('restoring %r to %r\n' % (tmpname, realname))
-                    util.copyfile(tmpname, repo.wjoin(realname))
-                    os.unlink(tmpname)
-                os.rmdir(backupdir)
-            except OSError:
-                pass
-    return cmdutil.commit(ui, repo, recordfunc, pats, opts)
Binary file .hgext/crecord/crecord/crecord_core.pyc has changed
--- a/.hgext/crecord/crecord/crpatch.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,669 +0,0 @@
-# stuff related specifically to patch manipulation / parsing
-from mercurial.i18n import _
-from mercurial import patch
-
-import cStringIO
-import re
-
-lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
-
-def scanpatch(fp):
-    """like patch.iterhunks, but yield different events
-
-    - ('file',    [header_lines + fromfile + tofile])
-    - ('context', [context_lines])
-    - ('hunk',    [hunk_lines])
-    - ('range',   (-start,len, +start,len, diffp))
-    """
-    lr = patch.linereader(fp)
-
-    def scanwhile(first, p):
-        """scan lr while predicate holds"""
-        lines = [first]
-        while True:
-            line = lr.readline()
-            if not line:
-                break
-            if p(line):
-                lines.append(line)
-            else:
-                lr.push(line)
-                break
-        return lines
-
-    while True:
-        line = lr.readline()
-        if not line:
-            break
-        if line.startswith('diff --git a/'):
-            def notheader(line):
-                s = line.split(None, 1)
-                return not s or s[0] not in ('---', 'diff')
-            header = scanwhile(line, notheader)
-            fromfile = lr.readline()
-            if fromfile.startswith('---'):
-                tofile = lr.readline()
-                header += [fromfile, tofile]
-            else:
-                lr.push(fromfile)
-            yield 'file', header
-        elif line[0] == ' ':
-            yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
-        elif line[0] in '-+':
-            yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
-        else:
-            m = lines_re.match(line)
-            if m:
-                yield 'range', m.groups()
-            else:
-                raise patch.PatchError('unknown patch content: %r' % line)
-
-class PatchNode(object):
-    """Abstract Class for Patch Graph Nodes
-    (i.e. PatchRoot, header, hunk, HunkLine)
-    """
-
-    def firstChild(self):
-        raise NotImplementedError("method must be implemented by subclass")
-
-    def lastChild(self):
-        raise NotImplementedError("method must be implemented by subclass")
-
-    def allChildren(self):
-        "Return a list of all of the direct children of this node"
-        raise NotImplementedError("method must be implemented by subclass")
-    def nextSibling(self):
-        """
-        Return the closest next item of the same type where there are no items
-        of different types between the current item and this closest item.
-        If no such item exists, return None.
-
-        """
-        raise NotImplementedError("method must be implemented by subclass")
-
-    def prevSibling(self):
-        """
-        Return the closest previous item of the same type where there are no
-        items of different types between the current item and this closest item.
-        If no such item exists, return None.
-
-        """
-        raise NotImplementedError("method must be implemented by subclass")
-
-    def parentItem(self):
-        raise NotImplementedError("method must be implemented by subclass")
-
-
-    def nextItem(self, constrainLevel=True, skipFolded=True):
-        """
-        If constrainLevel == True, return the closest next item
-        of the same type where there are no items of different types between
-        the current item and this closest item.
-
-        If constrainLevel == False, then try to return the next item
-        closest to this item, regardless of item's type (header, hunk, or
-        HunkLine).
-
-        If skipFolded == True, and the current item is folded, then the child
-        items that are hidden due to folding will be skipped when determining
-        the next item.
-
-        If it is not possible to get the next item, return None.
-
-        """
-        try:
-            itemFolded = self.folded
-        except AttributeError:
-            itemFolded = False
-        if constrainLevel:
-            return self.nextSibling()
-        elif skipFolded and itemFolded:
-            nextItem = self.nextSibling()
-            if nextItem is None:
-                try:
-                    nextItem = self.parentItem().nextSibling()
-                except AttributeError:
-                    nextItem = None
-            return nextItem
-        else:
-            # try child
-            item = self.firstChild()
-            if item is not None:
-                return item
-
-            # else try next sibling
-            item = self.nextSibling()
-            if item is not None:
-                return item
-
-            try:
-                # else try parent's next sibling
-                item = self.parentItem().nextSibling()
-                if item is not None:
-                    return item
-
-                # else return grandparent's next sibling (or None)
-                return self.parentItem().parentItem().nextSibling()
-
-            except AttributeError: # parent and/or grandparent was None
-                return None
-
-    def prevItem(self, constrainLevel=True, skipFolded=True):
-        """
-        If constrainLevel == True, return the closest previous item
-        of the same type where there are no items of different types between
-        the current item and this closest item.
-
-        If constrainLevel == False, then try to return the previous item
-        closest to this item, regardless of item's type (header, hunk, or
-        HunkLine).
-
-        If skipFolded == True, and the current item is folded, then the items
-        that are hidden due to folding will be skipped when determining the
-        next item.
-
-        If it is not possible to get the previous item, return None.
-
-        """
-        if constrainLevel:
-            return self.prevSibling()
-        else:
-            # try previous sibling's last child's last child,
-            # else try previous sibling's last child, else try previous sibling
-            prevSibling = self.prevSibling()
-            if prevSibling is not None:
-                prevSiblingLastChild = prevSibling.lastChild()
-                if ((prevSiblingLastChild is not None) and
-                    not prevSibling.folded):
-                    prevSiblingLCLC = prevSiblingLastChild.lastChild()
-                    if ((prevSiblingLCLC is not None) and
-                        not prevSiblingLastChild.folded):
-                        return prevSiblingLCLC
-                    else:
-                        return prevSiblingLastChild
-                else:
-                    return prevSibling
-
-            # try parent (or None)
-            return self.parentItem()
-
-class Patch(PatchNode, list): # TODO: rename PatchRoot
-    """
-    List of header objects representing the patch.
-
-    """
-    def __init__(self, headerList):
-        self.extend(headerList)
-        # add parent patch object reference to each header
-        for header in self:
-            header.patch = self
-
-class header(PatchNode):
-    """patch header
-
-    XXX shoudn't we move this to mercurial/patch.py ?
-    """
-    diff_re = re.compile('diff --git a/(.*) b/(.*)$')
-    allhunks_re = re.compile('(?:index|new file|deleted file) ')
-    pretty_re = re.compile('(?:new file|deleted file) ')
-    special_re = re.compile('(?:index|new|deleted|copy|rename) ')
-
-    def __init__(self, header):
-        self.header = header
-        self.hunks = []
-        # flag to indicate whether to apply this chunk
-        self.applied = True
-        # flag which only affects the status display indicating if a node's
-        # children are partially applied (i.e. some applied, some not).
-        self.partial = False
-
-        # flag to indicate whether to display as folded/unfolded to user
-        self.folded = True
-
-        # list of all headers in patch
-        self.patch = None
-
-        # flag is False if this header was ever unfolded from initial state
-        self.neverUnfolded = True
-    def binary(self):
-        """
-        Return True if the file represented by the header is a binary file.
-        Otherwise return False.
-
-        """
-        for h in self.header:
-            if h.startswith('index '):
-                return True
-        return False
-
-    def pretty(self, fp):
-        for h in self.header:
-            if h.startswith('index '):
-                fp.write(_('this modifies a binary file (all or nothing)\n'))
-                break
-            if self.pretty_re.match(h):
-                fp.write(h)
-                if self.binary():
-                    fp.write(_('this is a binary file\n'))
-                break
-            if h.startswith('---'):
-                fp.write(_('%d hunks, %d lines changed\n') %
-                         (len(self.hunks),
-                          sum([h.added + h.removed for h in self.hunks])))
-                break
-            fp.write(h)
-
-    def prettyStr(self):
-        x = cStringIO.StringIO()
-        self.pretty(x)
-        return x.getvalue()
-
-    def write(self, fp):
-        fp.write(''.join(self.header))
-
-    def allhunks(self):
-        """
-        Return True if the file which the header represents was changed
-        completely (i.e.  there is no possibility of applying a hunk of changes
-        smaller than the size of the entire file.)  Otherwise return False
-
-        """
-        for h in self.header:
-            if self.allhunks_re.match(h):
-                return True
-        return False
-
-    def files(self):
-        fromfile, tofile = self.diff_re.match(self.header[0]).groups()
-        if fromfile == tofile:
-            return [fromfile]
-        return [fromfile, tofile]
-
-    def filename(self):
-        return self.files()[-1]
-
-    def __repr__(self):
-        return '<header %s>' % (' '.join(map(repr, self.files())))
-
-    def special(self):
-        for h in self.header:
-            if self.special_re.match(h):
-                return True
-
-    def nextSibling(self):
-        numHeadersInPatch = len(self.patch)
-        indexOfThisHeader = self.patch.index(self)
-
-        if indexOfThisHeader < numHeadersInPatch - 1:
-            nextHeader = self.patch[indexOfThisHeader + 1]
-            return nextHeader
-        else:
-            return None
-
-    def prevSibling(self):
-        indexOfThisHeader = self.patch.index(self)
-        if indexOfThisHeader > 0:
-            previousHeader = self.patch[indexOfThisHeader - 1]
-            return previousHeader
-        else:
-            return None
-
-    def parentItem(self):
-        """
-        There is no 'real' parent item of a header that can be selected,
-        so return None.
-        """
-        return None
-
-    def firstChild(self):
-        "Return the first child of this item, if one exists.  Otherwise None."
-        if len(self.hunks) > 0:
-            return self.hunks[0]
-        else:
-            return None
-
-    def lastChild(self):
-        "Return the last child of this item, if one exists.  Otherwise None."
-        if len(self.hunks) > 0:
-            return self.hunks[-1]
-        else:
-            return None
-
-    def allChildren(self):
-        "Return a list of all of the direct children of this node"
-        return self.hunks
-class HunkLine(PatchNode):
-    "Represents a changed line in a hunk"
-    def __init__(self, lineText, hunk):
-        self.lineText = lineText
-        self.applied = True
-        # the parent hunk to which this line belongs
-        self.hunk = hunk
-        # folding lines currently is not used/needed, but this flag is needed
-        # in the prevItem method.
-        self.folded = False
-
-    def prettyStr(self):
-        return self.lineText
-
-    def nextSibling(self):
-        numLinesInHunk = len(self.hunk.changedLines)
-        indexOfThisLine = self.hunk.changedLines.index(self)
-
-        if (indexOfThisLine < numLinesInHunk - 1):
-            nextLine = self.hunk.changedLines[indexOfThisLine + 1]
-            return nextLine
-        else:
-            return None
-
-    def prevSibling(self):
-        indexOfThisLine = self.hunk.changedLines.index(self)
-        if indexOfThisLine > 0:
-            previousLine = self.hunk.changedLines[indexOfThisLine - 1]
-            return previousLine
-        else:
-            return None
-
-    def parentItem(self):
-        "Return the parent to the current item"
-        return self.hunk
-
-    def firstChild(self):
-        "Return the first child of this item, if one exists.  Otherwise None."
-        # hunk-lines don't have children
-        return None
-
-    def lastChild(self):
-        "Return the last child of this item, if one exists.  Otherwise None."
-        # hunk-lines don't have children
-        return None
-
-class hunk(PatchNode):
-    """patch hunk
-
-    XXX shouldn't we merge this with patch.hunk ?
-    """
-    maxcontext = 3
-
-    def __init__(self, header, fromline, toline, proc, before, hunk, after):
-        def trimcontext(number, lines):
-            delta = len(lines) - self.maxcontext
-            if False and delta > 0:
-                return number + delta, lines[:self.maxcontext]
-            return number, lines
-
-        self.header = header
-        self.fromline, self.before = trimcontext(fromline, before)
-        self.toline, self.after = trimcontext(toline, after)
-        self.proc = proc
-        self.changedLines = [HunkLine(line, self) for line in hunk]
-        self.added, self.removed = self.countchanges()
-        # used at end for detecting how many removed lines were un-applied
-        self.originalremoved = self.removed
-
-        # flag to indicate whether to display as folded/unfolded to user
-        self.folded = True
-        # flag to indicate whether to apply this chunk
-        self.applied = True
-        # flag which only affects the status display indicating if a node's
-        # children are partially applied (i.e. some applied, some not).
-        self.partial = False
-
-    def nextSibling(self):
-        numHunksInHeader = len(self.header.hunks)
-        indexOfThisHunk = self.header.hunks.index(self)
-
-        if (indexOfThisHunk < numHunksInHeader - 1):
-            nextHunk = self.header.hunks[indexOfThisHunk + 1]
-            return nextHunk
-        else:
-            return None
-
-    def prevSibling(self):
-        indexOfThisHunk = self.header.hunks.index(self)
-        if indexOfThisHunk > 0:
-            previousHunk = self.header.hunks[indexOfThisHunk - 1]
-            return previousHunk
-        else:
-            return None
-
-    def parentItem(self):
-        "Return the parent to the current item"
-        return self.header
-
-    def firstChild(self):
-        "Return the first child of this item, if one exists.  Otherwise None."
-        if len(self.changedLines) > 0:
-            return self.changedLines[0]
-        else:
-            return None
-
-    def lastChild(self):
-        "Return the last child of this item, if one exists.  Otherwise None."
-        if len(self.changedLines) > 0:
-            return self.changedLines[-1]
-        else:
-            return None
-
-    def allChildren(self):
-        "Return a list of all of the direct children of this node"
-        return self.changedLines
-    def countchanges(self):
-        """changedLines -> (n+,n-)"""
-        add = len([l for l in self.changedLines if l.applied
-                   and l.prettyStr()[0] == '+'])
-        rem = len([l for l in self.changedLines if l.applied
-                   and l.prettyStr()[0] == '-'])
-        return add, rem
-
-    def getFromToLine(self):
-        # calculate the number of removed lines converted to context lines
-        removedConvertedToContext = self.originalremoved - self.removed
-        delta = len(self.before) + len(self.after) + removedConvertedToContext
-        if self.after and self.after[-1] == '\\ No newline at end of file\n':
-            delta -= 1
-        fromlen = delta + self.removed
-        tolen = delta + self.added
-        fromToLine = '@@ -%d,%d +%d,%d @@%s\n' % (
-            self.fromline, fromlen, self.toline, tolen,
-            self.proc and (' ' + self.proc))
-        return fromToLine
-
-    def write(self, fp):
-        # updated self.added/removed, which are used by getFromToLine()
-        self.added, self.removed = self.countchanges()
-        fp.write(self.getFromToLine())
-
-        hunkLineList = []
-        # add the following to the list: (1) all applied lines, and
-        # (2) all unapplied removal lines (convert these to context lines)
-        for changedLine in self.changedLines:
-            changedLineStr = changedLine.prettyStr()
-            if changedLine.applied:
-                hunkLineList.append(changedLineStr)
-            elif changedLineStr[0] == "-":
-                hunkLineList.append(" " + changedLineStr[1:])
-
-        fp.write(''.join(self.before + hunkLineList + self.after))
-
-    pretty = write
-
-    def filename(self):
-        return self.header.filename()
-
-    def prettyStr(self):
-        x = cStringIO.StringIO()
-        self.pretty(x)
-        return x.getvalue()
-
-    def __repr__(self):
-        return '<hunk %r@%d>' % (self.filename(), self.fromline)
-
-
-
-def parsepatch(changes, fp):
-    "Parse a patch, returning a list of header and hunk objects."
-    class parser(object):
-        """patch parsing state machine"""
-        def __init__(self):
-            self.fromline = 0
-            self.toline = 0
-            self.proc = ''
-            self.header = None
-            self.context = []
-            self.before = []
-            self.changedlines = []
-            self.stream = []
-            self.modified, self.added, self.removed = changes
-
-        def _range(self, (fromstart, fromend, tostart, toend, proc)):
-            "Store range line info to associated instance variables."
-            self.fromline = int(fromstart)
-            self.toline = int(tostart)
-            self.proc = proc
-
-        def add_new_hunk(self):
-            """
-            Create a new complete hunk object, adding it to the latest header
-            and to self.stream.
-
-            Add all of the previously collected information about
-            the hunk to the new hunk object.  This information includes
-            header, from/to-lines, function (self.proc), preceding context
-            lines, changed lines, as well as the current context lines (which
-            follow the changed lines).
-
-            The size of the from/to lines are updated to be correct for the
-            next hunk we parse.
-
-            """
-            h = hunk(self.header, self.fromline, self.toline, self.proc,
-                     self.before, self.changedlines, self.context)
-            self.header.hunks.append(h)
-            self.stream.append(h)
-            self.fromline += len(self.before) + h.removed
-            self.toline += len(self.before) + h.added
-            self.before = []
-            self.changedlines = []
-            self.context = []
-            self.proc = ''
-
-        def _context(self, context):
-            """
-            Set the value of self.context.
-
-            Also, if an unprocessed set of changelines was previously
-            encountered, this is the condition for creating a complete
-            hunk object.  In this case, we create and add a new hunk object to
-            the most recent header object, and to self.strem. 
-
-            """
-            self.context = context
-            # if there have been changed lines encountered that haven't yet
-            # been add to a hunk.
-            if self.changedlines:
-                self.add_new_hunk()
-
-        def _changedlines(self, changedlines):
-            """
-            Store the changed lines in self.changedlines.
-
-            Mark any context lines in the context-line buffer (self.context) as
-            lines preceding the changed-lines (i.e. stored in self.before), and
-            clear the context-line buffer.
-
-            """
-            self.changedlines = changedlines
-            self.before = self.context
-            self.context = []
-
-        def add_new_header(self, hdr):
-            """
-            Create a header object containing the header lines, and the
-            filename the header applies to.  Add the header to self.stream.
-
-            """
-            # if there are any lines in the unchanged-lines buffer, create a 
-            # new hunk using them, and add it to the last header.
-            if self.changedlines:
-                self.add_new_hunk()
-
-            # create a new header and add it to self.stream
-            self.header = header(hdr)
-            fileName = self.header.filename()
-            if fileName in self.modified:
-                self.header.changetype = "M"
-            elif fileName in self.added:
-                self.header.changetype = "A"
-            elif fileName in self.removed:
-                self.header.changetype = "R"
-            self.stream.append(self.header)
-
-        def finished(self):
-            # if there are any lines in the unchanged-lines buffer, create a 
-            # new hunk using them, and add it to the last header.
-            if self.changedlines:
-                self.add_new_hunk()
-
-            return self.stream
-
-        transitions = {
-            'file': {'context': _context,
-                     'file': add_new_header,
-                     'hunk': _changedlines,
-                     'range': _range},
-            'context': {'file': add_new_header,
-                        'hunk': _changedlines,
-                        'range': _range},
-            'hunk': {'context': _context,
-                     'file': add_new_header,
-                     'range': _range},
-            'range': {'context': _context,
-                      'hunk': _changedlines},
-            }
-
-    p = parser()
-
-    # run the state-machine
-    state = 'context'
-    for newstate, data in scanpatch(fp):
-        try:
-            p.transitions[state][newstate](p, data)
-        except KeyError:
-            raise patch.PatchError('unhandled transition: %s -> %s' %
-                                   (state, newstate))
-        state = newstate
-    return p.finished()
-
-def filterpatch(opts, chunks, chunk_selector, ui):
-    """Interactively filter patch chunks into applied-only chunks"""
-    chunks = list(chunks)
-    # convert chunks list into structure suitable for displaying/modifying
-    # with curses.  Create a list of headers only.
-    headers = [c for c in chunks if isinstance(c, header)]
-
-    # if there are no changed files
-    if len(headers) == 0:
-        return []
-
-    # let user choose headers/hunks/lines, and mark their applied flags accordingly
-    chunk_selector(opts, headers, ui)
-
-    appliedHunkList = []
-    for hdr in headers:
-        if (hdr.applied and
-            (hdr.special() or len([h for h in hdr.hunks if h.applied]) > 0)):
-            appliedHunkList.append(hdr)
-            fixoffset = 0
-            for hnk in hdr.hunks:
-                if hnk.applied:
-                    appliedHunkList.append(hnk)
-                    # adjust the 'to'-line offset of the hunk to be correct
-                    # after de-activating some of the other hunks for this file
-                    if fixoffset:
-                        #hnk = copy.copy(hnk) # necessary??
-                        hnk.toline += fixoffset
-                else:
-                    fixoffset += hnk.removed - hnk.added
-
-    return appliedHunkList
--- a/.hgext/histedit/Makefile	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-PYTHON=python
-
-help:
-	@echo 'Commonly used make targets:'
-	@echo '  tests              - run all tests in the automatic test suite'
-	@echo '  all-version-tests - run all tests against many hg versions'
-	@echo '  tests-%s           - run all tests in the specified hg version'
-
-all: help
-
-tests:
-	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS)
-
-test-%:
-	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS) $@
-
-tests-%:
-	@echo "Path to crew repo is $(CREW) - set this with CREW= if needed."
-	hg -R $(CREW) checkout $$(echo $@ | sed s/tests-//) && \
-	(cd $(CREW) ; $(MAKE) clean ) && \
-	cd tests && $(PYTHON) $(CREW)/tests/run-tests.py $(TESTFLAGS)
-
-all-version-tests: tests-1.3.1 tests-1.4.3 tests-1.5.4 \
-                   tests-1.6.4 tests-1.7.5 tests-1.8 tests-tip
-
-.PHONY: tests all-version-tests
--- a/.hgext/histedit/README	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-.. -*-restructuredtext-*-
-
-============
-histedit
-============
-Interactive history editing for Mercurial.
-
-**Warning**: ``histedit`` alters history! It probably won't destroy your data,
-but that chance exists. You should *never* edit already-published history. 
-Caveat Emptor. (You may want to use the --outgoing option to prevent editing
-pushed history, though the changes may already be in another repository.)
-
-**Warning 2**: If you ``drop`` a change, it's *gone* **forever** (unless you 
-passed ``--keep``). You've been warned!
-
-With this extension installed, Mercurial gains one new command: histedit. Usage
-is as follows, assuming the following history::
-
- @  3[tip]   7c2fd3b9020c   2009-04-27 18:04 -0500   durin42
- |    Add delta
- |
- o  2   030b686bedc4   2009-04-27 18:04 -0500   durin42
- |    Add gamma
- |
- o  1   c561b4e977df   2009-04-27 18:04 -0500   durin42
- |    Add beta
- |
- o  0   d8d2fcd0e319   2009-04-27 18:04 -0500   durin42
-      Add alpha
-
-If you were to run ``hg histedit c561b4e977df``, you would see the following
-file open in your editor::
-
- pick c561b4e977df Add beta
- pick 030b686bedc4 Add gamma
- pick 7c2fd3b9020c Add delta
- 
- # Edit history between 633536316234 and 7c2fd3b9020c
- #
- # Commands:
- #  p, pick = use commit
- #  e, edit = use commit, but stop for amending
- #  f, fold = use commit, but fold into previous commit
- #  d, drop = remove commit from history
- #
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-In this file, lines beginning with ``#`` are ignored. You must specify a rule
-for each revision in your history. For example, if you had meant to add gamma 
-before beta, and then wanted to add delta in the same revision as beta, you 
-would reorganize the file to look like this::
-
- pick 030b686bedc4 Add gamma
- pick c561b4e977df Add beta
- fold 7c2fd3b9020c Add delta
- 
- # Edit history between 633536316234 and 7c2fd3b9020c
- #
- # Commands:
- #  p, pick = use commit
- #  e, edit = use commit, but stop for amending
- #  f, fold = use commit, but fold into previous commit
- #  d, drop = remove commit from history
- #
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-At which point you close the editor and ``histedit`` starts working. When you
-specify a ``fold`` operation, ``histedit`` will open an editor when it folds
-those revisions together, offering you a chance to clean up the commit message::
-
- Add beta
- ***
- Add delta
-
-Edit the commit message to your liking, then close the editor. For this example,
-let's assume that the commit message was changed to ``Add beta and delta.`` After
-histedit has run and had a chance to remove any old or temporary revisions it
-needed, the history looks like this::
-
- @  2[tip]   989b4d060121   2009-04-27 18:04 -0500   durin42
- |    Add beta and delta.
- |
- o  1   081603921c3f   2009-04-27 18:04 -0500   durin42
- |    Add gamma
- |
- o  0   d8d2fcd0e319   2009-04-27 18:04 -0500   durin42
-      Add alpha
-
-Note that ``histedit`` does *not* remove any revisions (even its own temporary 
-ones) until after it has completed all the editing operations, so it will 
-probably perform several strip operations when it's done. For the above example,
-it had to run strip twice. Strip can be slow depending on a variety of factors,
-so you might need to be a little patient. You can choose to keep the original
-revisions by passing the ``--keep`` flag.
-
-The ``edit`` operation will drop you back to a command prompt, allowing you to
-edit files freely, or even use ``hg record`` to commit some changes as a separate
-commit. When you're done, any remaining uncommitted changes will be committed as 
-well. When done, run ``hg histedit --continue`` to finish this step. You'll be 
-prompted for a new commit message, but the default commit message will
-be the original message for the ``edit`` ed revision.
-
-If ``histedit`` encounters a conflict when moving a revision (while handling 
-``pick`` or ``fold``), it'll stop in a similar manner to ``edit`` with the 
-difference that it won't prompt you for a commit message when done. If you
-decide at this point that you don't like how much work it will be to rearrange
-history, or that you made a mistake, you can use ``hg histedit --abort`` to 
-abandon the new changes you have made and return to the state before you attempted
-to edit your history.
-
-============
---outgoing
-============
-Interactive history editing only pushed changes.
-
-If we clone the example repository above and add three more changes, such that
-we have the following history:
-
- @  6[tip]   038383181893   2009-04-27 18:04 -0500   stefan
- |    Add theta
- |
- o  5   140988835471   2009-04-27 18:04 -0500   stefan
- |    Add eta
- |
- o  4   122930637314   2009-04-27 18:04 -0500   stefan
- |    Add zeta
- |
- o  3   836302820282   2009-04-27 18:04 -0500   stefan
- |    Add epsilon
- |
- o  2   989b4d060121   2009-04-27 18:04 -0500   durin42
- |    Add beta and delta.
- |
- o  1   081603921c3f   2009-04-27 18:04 -0500   durin42
- |    Add gamma
- |
- o  0   d8d2fcd0e319   2009-04-27 18:04 -0500   durin42
-      Add alpha
-
-If you run "hg histedit --outgoing" on the clone then it is the same as running
-"hg histedit 836302820282". If you need plan to push to a repository that
-Mercurial does not detect to be related to the source repo, you can add a
---force option.
--- a/.hgext/histedit/hg_histedit.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-"""Interactive history editing.
-
-Inspired by git rebase --interactive.
-"""
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-import tempfile
-import os
-
-from mercurial import cmdutil
-from mercurial import error
-from mercurial import hg
-from mercurial import node
-from mercurial import repair
-from mercurial import patch
-from mercurial import util
-from mercurial import url
-from mercurial import discovery
-from mercurial.i18n import _
-
-# Remove this hack and use cmdutil.updatedir when we're 1.7-only
-def _revsingle(repo, parent):
-    return repo[parent]
-_revsingle = getattr(cmdutil, 'revsingle', _revsingle)
-
-# Remove this hack and use cmdutil.updatedir when we're 1.7-only
-if getattr(cmdutil, 'updatedir', None):
-    from mercurial.cmdutil import updatedir
-else:
-    from mercurial.patch import updatedir
-
-# almost entirely stolen from the git-rebase--interactive.sh source
-editcomment = """
-
-# Edit history between %s and %s
-#
-# Commands:
-#  p, pick = use commit
-#  e, edit = use commit, but stop for amending
-#  f, fold = use commit, but fold into previous commit
-#  d, drop = remove commit from history
-#
-"""
-
-def between(repo, old, new, keep):
-    revs = [old, ]
-    current = old
-    while current != new:
-        ctx = repo[current]
-        if not keep and len(ctx.children()) > 1:
-            raise util.Abort('cannot edit history that would orphan nodes')
-        if len(ctx.parents()) != 1 and ctx.parents()[1] != node.nullid:
-            raise util.Abort("can't edit history with merges")
-        if not ctx.children():
-            current = new
-        else:
-            current = ctx.children()[0].node()
-            revs.append(current)
-    if len(repo[current].children()) and not keep:
-        raise util.Abort('cannot edit history that would orphan nodes')
-    return revs
-
-
-def pick(ui, repo, ctx, ha, opts):
-    oldctx = repo[ha]
-    if oldctx.parents()[0] == ctx:
-        ui.debug('node %s unchanged\n' % ha)
-        return oldctx, [], [], []
-    hg.update(repo, ctx.node())
-    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
-    fp = os.fdopen(fd, 'w')
-    diffopts = patch.diffopts(ui, opts)
-    diffopts.git = True
-    diffopts.ignorews = False
-    diffopts.ignorewsamount = False
-    diffopts.ignoreblanklines = False
-    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
-    for chunk in gen:
-        fp.write(chunk)
-    fp.close()
-    try:
-        files = {}
-        try:
-            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
-            if not files:
-                ui.warn(_('%s: empty changeset')
-                             % node.hex(ha))
-                return ctx, [], [], []
-        finally:
-            files = updatedir(ui, repo, files)
-            os.unlink(patchfile)
-    except Exception, inst:
-        raise util.Abort(_('Fix up the change and run '
-                           'hg histedit --continue'))
-    n = repo.commit(text=oldctx.description(), user=oldctx.user(), date=oldctx.date(),
-                    extra=oldctx.extra())
-    return repo[n], [n, ], [oldctx.node(), ], []
-
-
-def edit(ui, repo, ctx, ha, opts):
-    oldctx = repo[ha]
-    hg.update(repo, ctx.node())
-    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
-    fp = os.fdopen(fd, 'w')
-    diffopts = patch.diffopts(ui, opts)
-    diffopts.git = True
-    diffopts.ignorews = False
-    diffopts.ignorewsamount = False
-    diffopts.ignoreblanklines = False
-    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
-    for chunk in gen:
-        fp.write(chunk)
-    fp.close()
-    try:
-        files = {}
-        try:
-            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
-        finally:
-            files = updatedir(ui, repo, files)
-            os.unlink(patchfile)
-    except Exception, inst:
-        pass
-    raise util.Abort('Make changes as needed, you may commit or record as '
-                     'needed now.\nWhen you are finished, run hg'
-                     ' histedit --continue to resume.')
-
-def fold(ui, repo, ctx, ha, opts):
-    oldctx = repo[ha]
-    hg.update(repo, ctx.node())
-    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
-    fp = os.fdopen(fd, 'w')
-    diffopts = patch.diffopts(ui, opts)
-    diffopts.git = True
-    diffopts.ignorews = False
-    diffopts.ignorewsamount = False
-    diffopts.ignoreblanklines = False
-    gen = patch.diff(repo, oldctx.parents()[0].node(), ha, opts=diffopts)
-    for chunk in gen:
-        fp.write(chunk)
-    fp.close()
-    try:
-        files = {}
-        try:
-            patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
-            if not files:
-                ui.warn(_('%s: empty changeset')
-                             % node.hex(ha))
-                return ctx, [], [], []
-        finally:
-            files = updatedir(ui, repo, files)
-            os.unlink(patchfile)
-    except Exception, inst:
-        raise util.Abort(_('Fix up the change and run '
-                           'hg histedit --continue'))
-    n = repo.commit(text='fold-temp-revision %s' % ha, user=oldctx.user(), date=oldctx.date(),
-                    extra=oldctx.extra())
-    return finishfold(ui, repo, ctx, oldctx, n, opts, [])
-
-def finishfold(ui, repo, ctx, oldctx, newnode, opts, internalchanges):
-    parent = ctx.parents()[0].node()
-    hg.update(repo, parent)
-    fd, patchfile = tempfile.mkstemp(prefix='hg-histedit-')
-    fp = os.fdopen(fd, 'w')
-    diffopts = patch.diffopts(ui, opts)
-    diffopts.git = True
-    diffopts.ignorews = False
-    diffopts.ignorewsamount = False
-    diffopts.ignoreblanklines = False
-    gen = patch.diff(repo, parent, newnode, opts=diffopts)
-    for chunk in gen:
-        fp.write(chunk)
-    fp.close()
-    files = {}
-    try:
-        patch.patch(patchfile, ui, cwd=repo.root, files=files, eolmode=None)
-    finally:
-        files = updatedir(ui, repo, files)
-        os.unlink(patchfile)
-    newmessage = '\n***\n'.join(
-        [ctx.description(), ] +
-        [repo[r].description() for r in internalchanges] +
-        [oldctx.description(), ])
-    # If the changesets are from the same author, keep it.
-    if ctx.user() == oldctx.user():
-        username = ctx.user()
-    else:
-        username = ui.username()
-    newmessage = ui.edit(newmessage, username)
-    n = repo.commit(text=newmessage, user=username, date=max(ctx.date(), oldctx.date()),
-                    extra=oldctx.extra())
-    return repo[n], [n, ], [oldctx.node(), ctx.node() ], [newnode, ] # xxx
-
-def drop(ui, repo, ctx, ha, opts):
-    return ctx, [], [repo[ha].node(), ], []
-
-
-actiontable = {'p': pick,
-               'pick': pick,
-               'e': edit,
-               'edit': edit,
-               'f': fold,
-               'fold': fold,
-               'd': drop,
-               'drop': drop,
-               }
-def histedit(ui, repo, *parent, **opts):
-    """hg histedit <parent>
-    """
-    # TODO only abort if we try and histedit mq patches, not just
-    # blanket if mq patches are applied somewhere
-    mq = getattr(repo, 'mq', None)
-    if mq and mq.applied:
-        raise util.Abort(_('source has mq patches applied'))
-
-    parent = list(parent) + opts.get('rev', [])
-    if opts.get('outgoing'):
-        if len(parent) > 1:
-            raise util.Abort('only one repo argument allowed with --outgoing')
-        elif parent:
-            parent = parent[0]
-
-        dest = ui.expandpath(parent or 'default-push', parent or 'default')
-        dest, revs = hg.parseurl(dest, None)[:2]
-        if isinstance(revs, tuple):
-            # python >= 1.6
-            revs, checkout = hg.addbranchrevs(repo, repo, revs, None)
-            other = hg.repository(hg.remoteui(repo, opts), dest)
-            findoutgoing = discovery.findoutgoing
-        else:
-            other = hg.repository(ui, dest)
-            def findoutgoing(repo, other, force=False):
-                return repo.findoutgoing(other, force=force)
-
-        if revs:
-            revs = [repo.lookup(rev) for rev in revs]
-
-        ui.status(_('comparing with %s\n') % url.hidepassword(dest))
-        parent = findoutgoing(repo, other, force=opts.get('force'))
-    else:
-        if opts.get('force'):
-            raise util.Abort('--force only allowed with --outgoing')
-
-    if opts.get('continue', False):
-        if len(parent) != 0:
-            raise util.Abort('no arguments allowed with --continue')
-        (parentctxnode, created, replaced,
-         tmpnodes, existing, rules, keep, tip, ) = readstate(repo)
-        currentparent, wantnull = repo.dirstate.parents()
-        parentctx = repo[parentctxnode]
-        # discover any nodes the user has added in the interim
-        newchildren = [c for c in parentctx.children()
-                       if c.node() not in existing]
-        action, currentnode = rules.pop(0)
-        while newchildren:
-            if action in ['f', 'fold', ]:
-                tmpnodes.extend([n.node() for n in newchildren])
-            else:
-                created.extend([n.node() for n in newchildren])
-            newchildren = filter(lambda x: x.node() not in existing,
-                                 reduce(lambda x, y: x + y,
-                                        map(lambda r: r.children(),
-                                            newchildren)))
-        m, a, r, d = repo.status()[:4]
-        oldctx = repo[currentnode]
-        message = oldctx.description()
-        if action in ('e', 'edit', ):
-            message = ui.edit(message, ui.username())
-        elif action in ('f', 'fold', ):
-            message = 'fold-temp-revision %s' % currentnode
-        new = None
-        if m or a or r or d:
-            new = repo.commit(text=message, user=oldctx.user(), date=oldctx.date(),
-                              extra=oldctx.extra())
-
-        if action in ('e', 'edit', 'p', 'pick', ):
-            if new != oldctx.node():
-                replaced.append(oldctx.node())
-            if new:
-                if new != oldctx.node():
-                    created.append(new)
-                parentctx = repo[new]
-        else: # fold
-            if new:
-                tmpnodes.append(new)
-            else:
-                new = newchildren[-1]
-            (parentctx, created_,
-             replaced_, tmpnodes_, ) = finishfold(ui, repo,
-                                                  parentctx, oldctx, new,
-                                                  opts, newchildren)
-            replaced.extend(replaced_)
-            created.extend(created_)
-            tmpnodes.extend(tmpnodes_)
-
-    elif opts.get('abort', False):
-        if len(parent) != 0:
-            raise util.Abort('no arguments allowed with --abort')
-        (parentctxnode, created, replaced, tmpnodes,
-         existing, rules, keep, tip, ) = readstate(repo)
-        ui.debug('restore wc to old tip %s\n' % node.hex(tip))
-        hg.clean(repo, tip)
-        ui.debug('should strip created nodes %s\n' %
-                 ', '.join([node.hex(n)[:12] for n in created]))
-        ui.debug('should strip temp nodes %s\n' %
-                 ', '.join([node.hex(n)[:12] for n in tmpnodes]))
-        for nodes in (created, tmpnodes, ):
-            for n in reversed(nodes):
-                try:
-                    repair.strip(ui, repo, n)
-                except error.LookupError:
-                    pass
-        os.unlink(os.path.join(repo.path, 'histedit-state'))
-        return
-    else:
-        cmdutil.bail_if_changed(repo)
-        if os.path.exists(os.path.join(repo.path, 'histedit-state')):
-            raise util.Abort('history edit already in progress, try '
-                             '--continue or --abort')
-
-        tip, empty = repo.dirstate.parents()
-
-
-        if len(parent) != 1:
-            raise util.Abort('requires exactly one parent revision')
-        parent = _revsingle(repo, parent[0]).node()
-
-        keep = opts.get('keep', False)
-        revs = between(repo, parent, tip, keep)
-
-        ctxs = [repo[r] for r in revs]
-        existing = [r.node() for r in ctxs]
-        rules = opts.get('commands', '')
-        if not rules:
-            rules = '\n'.join([('pick %s %s' % (
-                c.hex()[:12], c.description().splitlines()[0]))[:80]
-                               for c in ctxs])
-            rules += editcomment % (node.hex(parent)[:12], node.hex(tip)[:12], )
-            rules = ui.edit(rules, ui.username())
-        else:
-            f = open(rules)
-            rules = f.read()
-            f.close()
-        rules = [l for l in (r.strip() for r in rules.splitlines())
-                 if l and not l[0] == '#']
-        rules = verifyrules(rules, repo, ctxs)
-
-        parentctx = repo[parent].parents()[0]
-        keep = opts.get('keep', False)
-        replaced = []
-        tmpnodes = []
-        created = []
-
-
-    while rules:
-        writestate(repo, parentctx.node(), created, replaced, tmpnodes, existing,
-                   rules, keep, tip)
-        action, ha = rules.pop(0)
-        (parentctx, created_,
-         replaced_, tmpnodes_, ) = actiontable[action](ui, repo,
-                                                       parentctx, ha,
-                                                       opts)
-        created.extend(created_)
-        replaced.extend(replaced_)
-        tmpnodes.extend(tmpnodes_)
-
-    hg.update(repo, parentctx.node())
-
-    if not keep:
-        ui.debug('should strip replaced nodes %s\n' %
-                 ', '.join([node.hex(n)[:12] for n in replaced]))
-        for n in sorted(replaced, lambda x, y: cmp(repo[x].rev(), repo[y].rev())):
-            try:
-                repair.strip(ui, repo, n)
-            except error.LookupError:
-                pass
-
-    ui.debug('should strip temp nodes %s\n' %
-             ', '.join([node.hex(n)[:12] for n in tmpnodes]))
-    for n in reversed(tmpnodes):
-        try:
-            repair.strip(ui, repo, n)
-        except error.LookupError:
-            pass
-    os.unlink(os.path.join(repo.path, 'histedit-state'))
-
-
-def writestate(repo, parentctxnode, created, replaced,
-               tmpnodes, existing, rules, keep, oldtip):
-    fp = open(os.path.join(repo.path, 'histedit-state'), 'w')
-    pickle.dump((parentctxnode, created, replaced,
-                 tmpnodes, existing, rules, keep, oldtip,),
-                fp)
-    fp.close()
-
-def readstate(repo):
-    """Returns a tuple of (parentnode, created, replaced, tmp, existing, rules, keep, oldtip, ).
-    """
-    fp = open(os.path.join(repo.path, 'histedit-state'))
-    return pickle.load(fp)
-
-
-def verifyrules(rules, repo, ctxs):
-    """Verify that there exists exactly one edit rule per given changeset.
-
-    Will abort if there are to many or too few rules, a malformed rule,
-    or a rule on a changeset outside of the user-given range.
-    """
-    parsed = []
-    first = True
-    if len(rules) != len(ctxs):
-        raise util.Abort('must specify a rule for each changeset once')
-    for r in rules:
-        if ' ' not in r:
-            raise util.Abort('malformed line "%s"' % r)
-        action, rest = r.split(' ', 1)
-        if ' ' in rest.strip():
-            ha, rest = rest.split(' ', 1)
-        else:
-            ha = r.strip()
-        try:
-            if repo[ha] not in ctxs:
-                raise util.Abort('may not use changesets other than the ones listed')
-        except error.RepoError:
-            raise util.Abort('unknown changeset %s listed' % ha)
-        if action not in actiontable:
-            raise util.Abort('unknown action "%s"' % action)
-        parsed.append([action, ha])
-    return parsed
-
-
-cmdtable = {
-    "histedit":
-        (histedit,
-         [('', 'commands', '', 'Read history edits from the specified file.'),
-          ('c', 'continue', False, 'continue an edit already in progress', ),
-          ('k', 'keep', False, 'strip old nodes after edit is complete', ),
-          ('', 'abort', False, 'abort an edit in progress', ),
-          ('o', 'outgoing', False, 'changesets not found in destination'),
-          ('f', 'force', False, 'force outgoing even for unrelated repositories'),
-          ('r', 'rev', [], _('first revision to be edited')),
-          ],
-         __doc__,
-         ),
-}
--- a/.hgext/histedit/setup.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-try:
-    from setuptools import setup
-except:
-    from distutils.core import setup
-
-requires = []
-try:
-    import mercurial
-except ImportError:
-    requires.append('mercurial')
-
-setup(
-    name='hg-histedit',
-    version='1.0.0',
-    author='Augie Fackler',
-    maintainer='Augie Fackler',
-    maintainer_email='durin42@gmail.com',
-    url='http://bitbucket.org/durin42/histedit/',
-    description='Interactively edit history in Mercurial.',
-    long_description=open('README').read(),
-    keywords='hg mercurial',
-    license='GPLv2+',
-    py_modules=['hg_histedit'],
-    install_requires=requires,
-)
--- a/.hgext/histedit/tests/histedit-helpers.sh	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-fixbundle() {
-    grep -v 'saving bundle' | grep -v 'saved backup' | grep -v added | grep -v adding
-}
\ No newline at end of file
--- a/.hgext/histedit/tests/run-tests.py	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,708 +0,0 @@
-#!/usr/bin/env python
-#
-# run-tests.py - Run a set of tests on Mercurial
-#
-# Copyright 2006 Matt Mackall <mpm@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2, incorporated herein by reference.
-
-import difflib
-import errno
-import optparse
-import os
-try:
-    import subprocess
-    subprocess.Popen  # trigger ImportError early
-    closefds = os.name == 'posix'
-    def Popen4(cmd, bufsize=-1):
-        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
-                             close_fds=closefds,
-                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT)
-        p.fromchild = p.stdout
-        p.tochild = p.stdin
-        p.childerr = p.stderr
-        return p
-except ImportError:
-    subprocess = None
-    from popen2 import Popen4
-import shutil
-import signal
-import sys
-import tempfile
-import time
-
-# reserved exit code to skip test (used by hghave)
-SKIPPED_STATUS = 80
-SKIPPED_PREFIX = 'skipped: '
-FAILED_PREFIX  = 'hghave check failed: '
-PYTHON = sys.executable
-
-requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
-
-defaults = {
-    'jobs': ('HGTEST_JOBS', 1),
-    'timeout': ('HGTEST_TIMEOUT', 180),
-    'port': ('HGTEST_PORT', 20059),
-}
-
-def parseargs():
-    parser = optparse.OptionParser("%prog [options] [tests]")
-    parser.add_option("-C", "--annotate", action="store_true",
-        help="output files annotated with coverage")
-    parser.add_option("--child", type="int",
-        help="run as child process, summary to given fd")
-    parser.add_option("-c", "--cover", action="store_true",
-        help="print a test coverage report")
-    parser.add_option("-f", "--first", action="store_true",
-        help="exit on the first test failure")
-    parser.add_option("-i", "--interactive", action="store_true",
-        help="prompt to accept changed output")
-    parser.add_option("-j", "--jobs", type="int",
-        help="number of jobs to run in parallel"
-             " (default: $%s or %d)" % defaults['jobs'])
-    parser.add_option("--keep-tmpdir", action="store_true",
-        help="keep temporary directory after running tests"
-             " (best used with --tmpdir)")
-    parser.add_option("-R", "--restart", action="store_true",
-        help="restart at last error")
-    parser.add_option("-p", "--port", type="int",
-        help="port on which servers should listen"
-             " (default: $%s or %d)" % defaults['port'])
-    parser.add_option("-r", "--retest", action="store_true",
-        help="retest failed tests")
-    parser.add_option("-s", "--cover_stdlib", action="store_true",
-        help="print a test coverage report inc. standard libraries")
-    parser.add_option("-t", "--timeout", type="int",
-        help="kill errant tests after TIMEOUT seconds"
-             " (default: $%s or %d)" % defaults['timeout'])
-    parser.add_option("--tmpdir", type="string",
-        help="run tests in the given temporary directory")
-    parser.add_option("-v", "--verbose", action="store_true",
-        help="output verbose messages")
-    parser.add_option("-n", "--nodiff", action="store_true",
-        help="skip showing test changes")
-    parser.add_option("--with-hg", type="string",
-        help="test existing install at given location")
-    parser.add_option("--pure", action="store_true",
-        help="use pure Python code instead of C extensions")
-
-    for option, default in defaults.items():
-        defaults[option] = int(os.environ.get(*default))
-    parser.set_defaults(**defaults)
-    (options, args) = parser.parse_args()
-
-    global vlog
-    options.anycoverage = (options.cover or
-                           options.cover_stdlib or
-                           options.annotate)
-
-    if options.verbose:
-        def vlog(*msg):
-            for m in msg:
-                print m,
-            print
-    else:
-        vlog = lambda *msg: None
-
-    if options.jobs < 1:
-        print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
-        sys.exit(1)
-    if options.interactive and options.jobs > 1:
-        print '(--interactive overrides --jobs)'
-        options.jobs = 1
-
-    return (options, args)
-
-def rename(src, dst):
-    """Like os.rename(), trade atomicity and opened files friendliness
-    for existing destination support.
-    """
-    shutil.copy(src, dst)
-    os.remove(src)
-
-def splitnewlines(text):
-    '''like str.splitlines, but only split on newlines.
-    keep line endings.'''
-    i = 0
-    lines = []
-    while True:
-        n = text.find('\n', i)
-        if n == -1:
-            last = text[i:]
-            if last:
-                lines.append(last)
-            return lines
-        lines.append(text[i:n+1])
-        i = n + 1
-
-def parsehghaveoutput(lines):
-    '''Parse hghave log lines.
-    Return tuple of lists (missing, failed):
-      * the missing/unknown features
-      * the features for which existence check failed'''
-    missing = []
-    failed = []
-    for line in lines:
-        if line.startswith(SKIPPED_PREFIX):
-            line = line.splitlines()[0]
-            missing.append(line[len(SKIPPED_PREFIX):])
-        elif line.startswith(FAILED_PREFIX):
-            line = line.splitlines()[0]
-            failed.append(line[len(FAILED_PREFIX):])
-
-    return missing, failed
-
-def showdiff(expected, output):
-    for line in difflib.unified_diff(expected, output,
-            "Expected output", "Test output"):
-        sys.stdout.write(line)
-
-def findprogram(program):
-    """Search PATH for a executable program"""
-    for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
-        name = os.path.join(p, program)
-        if os.access(name, os.X_OK):
-            return name
-    return None
-
-def checktools():
-    # Before we go any further, check for pre-requisite tools
-    # stuff from coreutils (cat, rm, etc) are not tested
-    for p in requiredtools:
-        if os.name == 'nt':
-            p += '.exe'
-        found = findprogram(p)
-        if found:
-            vlog("# Found prerequisite", p, "at", found)
-        else:
-            print "WARNING: Did not find prerequisite tool: "+p
-
-def cleanup(options):
-    if not options.keep_tmpdir:
-        if options.verbose:
-            print "# Cleaning up HGTMP", HGTMP
-        shutil.rmtree(HGTMP, True)
-
-def usecorrectpython():
-    # some tests run python interpreter. they must use same
-    # interpreter we use or bad things will happen.
-    exedir, exename = os.path.split(sys.executable)
-    if exename == 'python':
-        path = findprogram('python')
-        if os.path.dirname(path) == exedir:
-            return
-    vlog('# Making python executable in test path use correct Python')
-    mypython = os.path.join(BINDIR, 'python')
-    try:
-        os.symlink(sys.executable, mypython)
-    except AttributeError:
-        # windows fallback
-        shutil.copyfile(sys.executable, mypython)
-        shutil.copymode(sys.executable, mypython)
-
-def installhg(options):
-    global PYTHON
-    vlog("# Performing temporary installation of HG")
-    installerrs = os.path.join("tests", "install.err")
-    pure = options.pure and "--pure" or ""
-
-    # Run installer in hg root
-    os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
-    cmd = ('%s setup.py %s clean --all'
-           ' install --force --prefix="%s" --install-lib="%s"'
-           ' --install-scripts="%s" >%s 2>&1'
-           % (sys.executable, pure, INST, PYTHONDIR, BINDIR, installerrs))
-    vlog("# Running", cmd)
-    if os.system(cmd) == 0:
-        if not options.verbose:
-            os.remove(installerrs)
-    else:
-        f = open(installerrs)
-        for line in f:
-            print line,
-        f.close()
-        sys.exit(1)
-    os.chdir(TESTDIR)
-
-    os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
-
-    pydir = os.pathsep.join([PYTHONDIR, TESTDIR])
-    pythonpath = os.environ.get("PYTHONPATH")
-    if pythonpath:
-        pythonpath = pydir + os.pathsep + pythonpath
-    else:
-        pythonpath = pydir
-    os.environ["PYTHONPATH"] = pythonpath
-
-    usecorrectpython()
-    global hgpkg
-    hgpkg = _hgpath()
-
-    vlog("# Installing dummy diffstat")
-    f = open(os.path.join(BINDIR, 'diffstat'), 'w')
-    f.write('#!' + sys.executable + '\n'
-            'import sys\n'
-            'files = 0\n'
-            'for line in sys.stdin:\n'
-            '    if line.startswith("diff "):\n'
-            '        files += 1\n'
-            'sys.stdout.write("files patched: %d\\n" % files)\n')
-    f.close()
-    os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
-
-    if options.anycoverage:
-        vlog("# Installing coverage wrapper")
-        os.environ['COVERAGE_FILE'] = COVERAGE_FILE
-        if os.path.exists(COVERAGE_FILE):
-            os.unlink(COVERAGE_FILE)
-        # Create a wrapper script to invoke hg via coverage.py
-        os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
-        f = open(os.path.join(BINDIR, 'hg'), 'w')
-        f.write('#!' + sys.executable + '\n')
-        f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
-                '"%s", "-x", "%s"] + sys.argv[1:])\n' %
-                (os.path.join(TESTDIR, 'coverage.py'),
-                 os.path.join(BINDIR, '_hg.py')))
-        f.close()
-        os.chmod(os.path.join(BINDIR, 'hg'), 0700)
-        PYTHON = '"%s" "%s" -x' % (sys.executable,
-                                   os.path.join(TESTDIR,'coverage.py'))
-
-def _hgpath():
-    cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
-    hgpath = os.popen(cmd % PYTHON)
-    path = hgpath.read().strip()
-    hgpath.close()
-    return path
-
-def outputcoverage(options):
-    vlog("# Producing coverage report")
-    omit = [BINDIR, TESTDIR, PYTHONDIR]
-    if not options.cover_stdlib:
-        # Exclude as system paths (ignoring empty strings seen on win)
-        omit += [x for x in sys.path if x != '']
-    omit = ','.join(omit)
-    os.chdir(PYTHONDIR)
-    cmd = '"%s" "%s" -i -r "--omit=%s"' % (
-        sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
-    vlog("# Running: "+cmd)
-    os.system(cmd)
-    if options.annotate:
-        adir = os.path.join(TESTDIR, 'annotated')
-        if not os.path.isdir(adir):
-            os.mkdir(adir)
-        cmd = '"%s" "%s" -i -a "--directory=%s" "--omit=%s"' % (
-            sys.executable, os.path.join(TESTDIR, 'coverage.py'),
-            adir, omit)
-        vlog("# Running: "+cmd)
-        os.system(cmd)
-
-class Timeout(Exception):
-    pass
-
-def alarmed(signum, frame):
-    raise Timeout
-
-def run(cmd, options):
-    """Run command in a sub-process, capturing the output (stdout and stderr).
-    Return the exist code, and output."""
-    # TODO: Use subprocess.Popen if we're running on Python 2.4
-    if os.name == 'nt' or sys.platform.startswith('java'):
-        tochild, fromchild = os.popen4(cmd)
-        tochild.close()
-        output = fromchild.read()
-        ret = fromchild.close()
-        if ret == None:
-            ret = 0
-    else:
-        proc = Popen4(cmd)
-        try:
-            output = ''
-            proc.tochild.close()
-            output = proc.fromchild.read()
-            ret = proc.wait()
-            if os.WIFEXITED(ret):
-                ret = os.WEXITSTATUS(ret)
-        except Timeout:
-            vlog('# Process %d timed out - killing it' % proc.pid)
-            os.kill(proc.pid, signal.SIGTERM)
-            ret = proc.wait()
-            if ret == 0:
-                ret = signal.SIGTERM << 8
-            output += ("\n### Abort: timeout after %d seconds.\n"
-                       % options.timeout)
-    return ret, splitnewlines(output)
-
-def runone(options, test, skips, fails):
-    '''tristate output:
-    None -> skipped
-    True -> passed
-    False -> failed'''
-
-    def skip(msg):
-        if not options.verbose:
-            skips.append((test, msg))
-        else:
-            print "\nSkipping %s: %s" % (test, msg)
-        return None
-
-    def fail(msg):
-        fails.append((test, msg))
-        if not options.nodiff:
-            print "\nERROR: %s %s" % (test, msg)
-        return None
-
-    vlog("# Test", test)
-
-    # create a fresh hgrc
-    hgrc = file(HGRCPATH, 'w+')
-    hgrc.write('[ui]\n')
-    hgrc.write('slash = True\n')
-    hgrc.write('[defaults]\n')
-    hgrc.write('backout = -d "0 0"\n')
-    hgrc.write('commit = -d "0 0"\n')
-    hgrc.write('debugrawcommit = -d "0 0"\n')
-    hgrc.write('tag = -d "0 0"\n')
-    hgrc.close()
-
-    err = os.path.join(TESTDIR, test+".err")
-    ref = os.path.join(TESTDIR, test+".out")
-    testpath = os.path.join(TESTDIR, test)
-
-    if os.path.exists(err):
-        os.remove(err)       # Remove any previous output files
-
-    # Make a tmp subdirectory to work in
-    tmpd = os.path.join(HGTMP, test)
-    os.mkdir(tmpd)
-    os.chdir(tmpd)
-
-    try:
-        tf = open(testpath)
-        firstline = tf.readline().rstrip()
-        tf.close()
-    except:
-        firstline = ''
-    lctest = test.lower()
-
-    if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
-        cmd = '%s "%s"' % (PYTHON, testpath)
-    elif lctest.endswith('.bat'):
-        # do not run batch scripts on non-windows
-        if os.name != 'nt':
-            return skip("batch script")
-        # To reliably get the error code from batch files on WinXP,
-        # the "cmd /c call" prefix is needed. Grrr
-        cmd = 'cmd /c call "%s"' % testpath
-    else:
-        # do not run shell scripts on windows
-        if os.name == 'nt':
-            return skip("shell script")
-        # do not try to run non-executable programs
-        if not os.path.exists(testpath):
-            return fail("does not exist")
-        elif not os.access(testpath, os.X_OK):
-            return skip("not executable")
-        cmd = '"%s"' % testpath
-
-    if options.timeout > 0:
-        signal.alarm(options.timeout)
-
-    vlog("# Running", cmd)
-    ret, out = run(cmd, options)
-    vlog("# Ret was:", ret)
-
-    if options.timeout > 0:
-        signal.alarm(0)
-
-    mark = '.'
-
-    skipped = (ret == SKIPPED_STATUS)
-    # If reference output file exists, check test output against it
-    if os.path.exists(ref):
-        f = open(ref, "r")
-        refout = splitnewlines(f.read())
-        f.close()
-    else:
-        refout = []
-    if skipped:
-        mark = 's'
-        missing, failed = parsehghaveoutput(out)
-        if not missing:
-            missing = ['irrelevant']
-        if failed:
-            fail("hghave failed checking for %s" % failed[-1])
-            skipped = False
-        else:
-            skip(missing[-1])
-    elif out != refout:
-        mark = '!'
-        if ret:
-            fail("output changed and returned error code %d" % ret)
-        else:
-            fail("output changed")
-        if not options.nodiff:
-            showdiff(refout, out)
-        ret = 1
-    elif ret:
-        mark = '!'
-        fail("returned error code %d" % ret)
-
-    if not options.verbose:
-        sys.stdout.write(mark)
-        sys.stdout.flush()
-
-    if ret != 0 and not skipped:
-        # Save errors to a file for diagnosis
-        f = open(err, "wb")
-        for line in out:
-            f.write(line)
-        f.close()
-
-    # Kill off any leftover daemon processes
-    try:
-        fp = file(DAEMON_PIDS)
-        for line in fp:
-            try:
-                pid = int(line)
-            except ValueError:
-                continue
-            try:
-                os.kill(pid, 0)
-                vlog('# Killing daemon process %d' % pid)
-                os.kill(pid, signal.SIGTERM)
-                time.sleep(0.25)
-                os.kill(pid, 0)
-                vlog('# Daemon process %d is stuck - really killing it' % pid)
-                os.kill(pid, signal.SIGKILL)
-            except OSError, err:
-                if err.errno != errno.ESRCH:
-                    raise
-        fp.close()
-        os.unlink(DAEMON_PIDS)
-    except IOError:
-        pass
-
-    os.chdir(TESTDIR)
-    if not options.keep_tmpdir:
-        shutil.rmtree(tmpd, True)
-    if skipped:
-        return None
-    return ret == 0
-
-def runchildren(options, expecthg, tests):
-    if not options.with_hg:
-        installhg(options)
-        if hgpkg != expecthg:
-            print '# Testing unexpected mercurial: %s' % hgpkg
-
-    optcopy = dict(options.__dict__)
-    optcopy['jobs'] = 1
-    optcopy['with_hg'] = INST
-    opts = []
-    for opt, value in optcopy.iteritems():
-        name = '--' + opt.replace('_', '-')
-        if value is True:
-            opts.append(name)
-        elif value is not None:
-            opts.append(name + '=' + str(value))
-
-    tests.reverse()
-    jobs = [[] for j in xrange(options.jobs)]
-    while tests:
-        for job in jobs:
-            if not tests: break
-            job.append(tests.pop())
-    fps = {}
-    for j, job in enumerate(jobs):
-        if not job:
-            continue
-        rfd, wfd = os.pipe()
-        childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
-        cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
-        vlog(' '.join(cmdline))
-        fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
-        os.close(wfd)
-    failures = 0
-    tested, skipped, failed = 0, 0, 0
-    skips = []
-    fails = []
-    while fps:
-        pid, status = os.wait()
-        fp = fps.pop(pid)
-        l = fp.read().splitlines()
-        test, skip, fail = map(int, l[:3])
-        split = -fail or len(l)
-        for s in l[3:split]:
-            skips.append(s.split(" ", 1))
-        for s in l[split:]:
-            fails.append(s.split(" ", 1))
-        tested += test
-        skipped += skip
-        failed += fail
-        vlog('pid %d exited, status %d' % (pid, status))
-        failures |= status
-    print
-    for s in skips:
-        print "Skipped %s: %s" % (s[0], s[1])
-    for s in fails:
-        print "Failed %s: %s" % (s[0], s[1])
-
-    if hgpkg != expecthg:
-        print '# Tested unexpected mercurial: %s' % hgpkg
-    print "# Ran %d tests, %d skipped, %d failed." % (
-        tested, skipped, failed)
-    sys.exit(failures != 0)
-
-def runtests(options, expecthg, tests):
-    global DAEMON_PIDS, HGRCPATH
-    DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
-    HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
-
-    try:
-        if not options.with_hg:
-            installhg(options)
-
-            if hgpkg != expecthg:
-                print '# Testing unexpected mercurial: %s' % hgpkg
-
-        if options.timeout > 0:
-            try:
-                signal.signal(signal.SIGALRM, alarmed)
-                vlog('# Running tests with %d-second timeout' %
-                     options.timeout)
-            except AttributeError:
-                print 'WARNING: cannot run tests with timeouts'
-                options.timeout = 0
-
-        tested = 0
-        failed = 0
-        skipped = 0
-
-        if options.restart:
-            orig = list(tests)
-            while tests:
-                if os.path.exists(tests[0] + ".err"):
-                    break
-                tests.pop(0)
-            if not tests:
-                print "running all tests"
-                tests = orig
-
-        skips = []
-        fails = []
-        for test in tests:
-            if options.retest and not os.path.exists(test + ".err"):
-                skipped += 1
-                continue
-            ret = runone(options, test, skips, fails)
-            if ret is None:
-                skipped += 1
-            elif not ret:
-                if options.interactive:
-                    print "Accept this change? [n] ",
-                    answer = sys.stdin.readline().strip()
-                    if answer.lower() in "y yes".split():
-                        rename(test + ".err", test + ".out")
-                        tested += 1
-                        fails.pop()
-                        continue
-                failed += 1
-                if options.first:
-                    break
-            tested += 1
-
-        if options.child:
-            fp = os.fdopen(options.child, 'w')
-            fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
-            for s in skips:
-                fp.write("%s %s\n" % s)
-            for s in fails:
-                fp.write("%s %s\n" % s)
-            fp.close()
-        else:
-            print
-            for s in skips:
-                print "Skipped %s: %s" % s
-            for s in fails:
-                print "Failed %s: %s" % s
-            if hgpkg != expecthg:
-                print '# Tested unexpected mercurial: %s' % hgpkg
-            print "# Ran %d tests, %d skipped, %d failed." % (
-                tested, skipped, failed)
-
-        if options.anycoverage:
-            outputcoverage(options)
-    except KeyboardInterrupt:
-        failed = True
-        print "\ninterrupted!"
-
-    if failed:
-        sys.exit(1)
-
-hgpkg = None
-def main():
-    (options, args) = parseargs()
-    if not options.child:
-        os.umask(022)
-
-        checktools()
-
-    # Reset some environment variables to well-known values so that
-    # the tests produce repeatable output.
-    os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
-    os.environ['TZ'] = 'GMT'
-    os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
-    os.environ['CDPATH'] = ''
-
-    global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
-    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
-    HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.',
-                                                   options.tmpdir))
-    DAEMON_PIDS = None
-    HGRCPATH = None
-
-    os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
-    os.environ["HGMERGE"] = "internal:merge"
-    os.environ["HGUSER"]   = "test"
-    os.environ["HGENCODING"] = "ascii"
-    os.environ["HGENCODINGMODE"] = "strict"
-    os.environ["HGPORT"] = str(options.port)
-    os.environ["HGPORT1"] = str(options.port + 1)
-    os.environ["HGPORT2"] = str(options.port + 2)
-
-    if options.with_hg:
-        INST = options.with_hg
-    else:
-        INST = os.path.join(HGTMP, "install")
-    BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
-    PYTHONDIR = os.path.join(INST, "lib", "python")
-    COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
-
-    expecthg = os.path.join(HGTMP, 'install', 'lib', 'python', 'mercurial')
-
-    if len(args) == 0:
-        args = os.listdir(".")
-        args.sort()
-
-    tests = []
-    for test in args:
-        if (test.startswith("test-") and '~' not in test and
-            ('.' not in test or test.endswith('.py') or
-             test.endswith('.bat'))):
-            tests.append(test)
-
-    vlog("# Using TESTDIR", TESTDIR)
-    vlog("# Using HGTMP", HGTMP)
-
-    try:
-        if len(tests) > 1 and options.jobs > 1:
-            runchildren(options, expecthg, tests)
-        else:
-            runtests(options, expecthg, tests)
-    finally:
-        cleanup(options)
-
-main()
--- a/.hgext/histedit/tests/test-histedit-commute	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick e860deea161a e
-pick 652413bf663e f
-pick 055a42cdd887 d
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % show the edit commands offered
-HGEDITOR=cat hg histedit 177f92b77385
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % log after edit
-hg log --graph
-
-echo % put things back
-
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick 853c68da763f d
-pick b069cc29fb22 e
-pick 26f6a030ae82 f
-EOF
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-hg log --graph
-
-
-echo % slightly different this time
-
-cat > $EDITED <<EOF
-pick 055a42cdd887 d
-pick 652413bf663e f
-pick e860deea161a e
-pick 177f92b77385 c
-EOF
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-hg log --graph
-
-
-echo % keep prevents stripping dead revs
-cat > $EDITED <<EOF
-pick bfe4a5a76b37 d
-pick c4f52e213402 f
-pick 99a62755c625 c
-pick 7c6fdd608667 e
-EOF
-HGEDITOR="cat $EDITED > " hg histedit bfe4a5a76b37 --keep 2>&1 | fixbundle
-hg log --graph
-
-echo '% try with --rev'
-cat > $EDITED <<EOF
-pick 7c6fdd608667 e
-pick 99a62755c625 c
-EOF
-hg histedit --commands "$EDITED" --rev -2 2>&1 | fixbundle
-hg log --graph
--- a/.hgext/histedit/tests/test-histedit-commute.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-% log before edit
-@  changeset:   5:652413bf663e
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% show the edit commands offered
-pick 177f92b77385 c
-pick 055a42cdd887 d
-pick e860deea161a e
-pick 652413bf663e f
-
-# Edit history between 177f92b77385 and 652413bf663e
-#
-# Commands:
-#  p, pick = use commit
-#  e, edit = use commit, but stop for amending
-#  f, fold = use commit, but fold into previous commit
-#  d, drop = remove commit from history
-#
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% edit the history
-0 files updated, 0 files merged, 3 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after edit
-@  changeset:   5:853c68da763f
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   4:26f6a030ae82
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   3:b069cc29fb22
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% put things back
-0 files updated, 0 files merged, 3 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   5:652413bf663e
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% slightly different this time
-0 files updated, 0 files merged, 4 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   5:99a62755c625
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   4:7c6fdd608667
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:c4f52e213402
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   2:bfe4a5a76b37
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% keep prevents stripping dead revs
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   7:99e266581538
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   6:5ad36efb0653
-|  parent:      3:c4f52e213402
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-| o  changeset:   5:99a62755c625
-| |  user:        test
-| |  date:        Thu Jan 01 00:00:00 1970 +0000
-| |  summary:     c
-| |
-| o  changeset:   4:7c6fdd608667
-|/   user:        test
-|    date:        Thu Jan 01 00:00:00 1970 +0000
-|    summary:     e
-|
-o  changeset:   3:c4f52e213402
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   2:bfe4a5a76b37
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% try with --rev
-abort: may not use changesets other than the ones listed
-@  changeset:   7:99e266581538
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   6:5ad36efb0653
-|  parent:      3:c4f52e213402
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-| o  changeset:   5:99a62755c625
-| |  user:        test
-| |  date:        Thu Jan 01 00:00:00 1970 +0000
-| |  summary:     c
-| |
-| o  changeset:   4:7c6fdd608667
-|/   user:        test
-|    date:        Thu Jan 01 00:00:00 1970 +0000
-|    summary:     e
-|
-o  changeset:   3:c4f52e213402
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   2:bfe4a5a76b37
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
--- a/.hgext/histedit/tests/test-histedit-drop	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-drop 177f92b77385 c
-pick e860deea161a e
-pick 652413bf663e f
-pick 055a42cdd887 d
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % log after edit
-hg log --graph
-
-echo % manifest after edit
-hg manifest
-
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-drop.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-% log before edit
-@  changeset:   5:652413bf663e
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 4 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after edit
-@  changeset:   4:708943196e52
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   3:75cbdffecadb
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   2:493dc0964412
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% manifest after edit
-a
-b
-d
-e
-f
-% EOF
--- a/.hgext/histedit/tests/test-histedit-edit	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick 055a42cdd887 d
-edit e860deea161a e
-pick 652413bf663e f
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % edit the revision
-echo a > e
-HGEDITOR='echo "foobaz" > ' hg histedit --continue 2>&1 | fixbundle
-
-hg log --graph
-
-echo '% contents of e:'
-hg cat e
-
-cat > $EDITED <<EOF
-edit c38516e9ed62 f
-EOF
-HGEDITOR="cat $EDITED > " hg histedit tip 2>&1 | fixbundle
-hg status
-HGEDITOR='true' hg histedit --continue
-hg status
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-edit.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-% log before edit
-@  changeset:   5:652413bf663e
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-abort: Make changes as needed, you may commit or record as needed now.
-When you are finished, run hg histedit --continue to resume.
-% edit the revision
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   5:c38516e9ed62
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:1da62d13177d
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     foobaz
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% contents of e:
-a
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-abort: Make changes as needed, you may commit or record as needed now.
-When you are finished, run hg histedit --continue to resume.
-A f
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% EOF
--- a/.hgext/histedit/tests/test-histedit-fold	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick e860deea161a e
-pick 652413bf663e f
-fold 177f92b77385 c
-pick 055a42cdd887 d
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % log after edit
-hg log --graph
-
-echo % post-fold manifest
-hg manifest
-
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-fold-non-commute	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick 055a42cdd887 d
-fold bfa474341cc9 does not commute with e
-pick e860deea161a e
-pick 652413bf663e f
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-    echo a >> e
-    hg ci -m 'does not commute with e'
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % fix up
-echo a > e
-hg add e
-HGEDITOR=cat hg histedit --continue 2>&1 | fixbundle
-
-echo
-echo % just continue this time
-hg histedit --continue 2>&1 | fixbundle
-
-echo % log after edit
-hg log --graph
-
-echo % contents of e
-hg cat e
-
-echo % manifest
-hg manifest
-
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-fold-non-commute.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-% log before edit
-@  changeset:   6:bfa474341cc9
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   5:652413bf663e
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-unable to find 'e' for patching
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-e: No such file or directory
-abort: Fix up the change and run hg histedit --continue
-% fix up
-d
-***
-does not commute with e0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-file e already exists
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-abort: Fix up the change and run hg histedit --continue
-
-% just continue this time
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after edit
-@  changeset:   4:f768fd60ca34
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   3:671efe372e33
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% contents of e
-a
-% manifest
-a
-b
-c
-d
-e
-f
-% EOF
--- a/.hgext/histedit/tests/test-histedit-fold.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-% log before edit
-@  changeset:   5:652413bf663e
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 4 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after edit
-@  changeset:   4:82b0c1ff1777
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   3:150aafb44a91
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     pick e860deea161a e
-|
-o  changeset:   2:493dc0964412
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% post-fold manifest
-a
-b
-c
-d
-e
-f
-% EOF
--- a/.hgext/histedit/tests/test-histedit-no-change	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#!/bin/sh
-
-# test for issue #6:
-# editing a changeset without any actual change would corrupt the repository
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-hg_histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py
-EOF
-
-initrepo ()
-{
-    dir="$1"
-    comment="$2"
-
-    if [ -n "${comment}" ]; then
-        echo % ${comment}
-        echo % ${comment} | sed 's:.:-:g'
-    fi
-
-    hg init ${dir}
-    cd ${dir}
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-}
-
-geneditor ()
-{
-    # generate an editor script for selecting changesets to be edited
-
-    choice=$1  # changesets that should be edited (using sed line ranges)
-
-    cat <<EOF | sed 's:^....::'
-    #!/bin/sh
-
-    # editing the rules, replacing 'pick' with 'edit' for the chosen lines
-    sed '${choice}s:^pick:edit:' \$1 > \${1}.tmp
-    mv \${1}.tmp \$1
-
-    # displaying the resulting rules, minus comments and empty lines
-    sed '/^#/d;/^$/d;s:^:| :' \$1 >&2
-EOF
-}
-
-startediting ()
-{
-    # begin an editing session
-
-    choice="$1"  # changesets that should be edited
-    number="$2"  # number of changesets considered (from tip)
-    comment="$3"
-
-    geneditor "${choice}" > edit.sh
-    chmod +x edit.sh
-
-    echo % start editing the history ${comment}
-    HGEDITOR=./edit.sh hg histedit -- -${number} 2>&1 | fixbundle
-}
-
-continueediting ()
-{
-    # continue an edit already in progress
-
-    editor="$1"  # message editor when finalizing editing
-    comment="$2"
-
-    echo % finalize changeset editing ${comment}
-    HGEDITOR=${editor} hg histedit --continue 2>&1 | fixbundle
-}
-
-graphlog ()
-{
-    comment="${1:-log}"
-
-    echo % "${comment}"
-    hg glog --template '{rev} {node} \"{desc|firstline}\"\n'
-}
-
-
-
-initrepo r1 "test editing with no change"
-graphlog "log before editing"
-startediting 2 3 "(not changing anything)" # edit the 2nd of 3 changesets
-continueediting true "(leaving commit message unaltered)"
-
-echo "% check state of working copy"
-hg id
-
-graphlog "log after history editing"
-
-
-cd ..
-initrepo r2 "test editing with no change, then abort"
-graphlog "log before editing"
-startediting 1,2 3 "(not changing anything)" # edit the 1st two of 3 changesets
-continueediting true "(leaving commit message unaltered)"
-graphlog "log after first edit"
-
-echo % abort editing session
-hg histedit --abort 2>&1 | fixbundle
-
-graphlog "log after abort"
-
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-no-change.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-% test editing with no change
------------------------------
-% log before editing
-@  5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
-|
-o  4 e860deea161a2f77de56603b340ebbb4536308ae "e"
-|
-o  3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
-|
-o  2 177f92b773850b59254aa5e923436f921b55483b "c"
-|
-o  1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
-|
-o  0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
-
-% start editing the history (not changing anything)
-| pick 055a42cdd887 d
-| edit e860deea161a e
-| pick 652413bf663e f
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-abort: Make changes as needed, you may commit or record as needed now.
-When you are finished, run hg histedit --continue to resume.
-% finalize changeset editing (leaving commit message unaltered)
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% check state of working copy
-652413bf663e tip
-% log after history editing
-@  5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
-|
-o  4 e860deea161a2f77de56603b340ebbb4536308ae "e"
-|
-o  3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
-|
-o  2 177f92b773850b59254aa5e923436f921b55483b "c"
-|
-o  1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
-|
-o  0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
-
-% test editing with no change, then abort
------------------------------------------
-% log before editing
-@  5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
-|
-o  4 e860deea161a2f77de56603b340ebbb4536308ae "e"
-|
-o  3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
-|
-o  2 177f92b773850b59254aa5e923436f921b55483b "c"
-|
-o  1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
-|
-o  0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
-
-% start editing the history (not changing anything)
-| edit 055a42cdd887 d
-| edit e860deea161a e
-| pick 652413bf663e f
-0 files updated, 0 files merged, 3 files removed, 0 files unresolved
-abort: Make changes as needed, you may commit or record as needed now.
-When you are finished, run hg histedit --continue to resume.
-% finalize changeset editing (leaving commit message unaltered)
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-abort: Make changes as needed, you may commit or record as needed now.
-When you are finished, run hg histedit --continue to resume.
-% log after first edit
-o  5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
-|
-o  4 e860deea161a2f77de56603b340ebbb4536308ae "e"
-|
-@  3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
-|
-o  2 177f92b773850b59254aa5e923436f921b55483b "c"
-|
-o  1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
-|
-o  0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
-
-% abort editing session
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after abort
-@  5 652413bf663ef2a641cab26574e46d5f5a64a55a "f"
-|
-o  4 e860deea161a2f77de56603b340ebbb4536308ae "e"
-|
-o  3 055a42cdd88768532f9cf79daa407fc8d138de9b "d"
-|
-o  2 177f92b773850b59254aa5e923436f921b55483b "c"
-|
-o  1 d2ae7f538514cd87c17547b0de4cea71fe1af9fb "b"
-|
-o  0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b "a"
-
-% EOF
--- a/.hgext/histedit/tests/test-histedit-non-commute	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick 055a42cdd887 d
-pick bfa474341cc9 does not commute with e
-pick e860deea161a e
-pick 652413bf663e f
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-    echo a >> e
-    hg ci -m 'does not commute with e'
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % abort the edit
-hg histedit --abort 2>&1 | fixbundle
-
-echo
-echo
-echo % second edit set
-
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo % fix up
-echo a > e
-hg add e
-hg histedit --continue 2>&1 | fixbundle
-
-echo
-echo % just continue this time
-hg histedit --continue 2>&1 | fixbundle
-
-echo % log after edit
-hg log --graph
-
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-non-commute-abort	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-. "$TESTDIR/histedit-helpers.sh"
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick 055a42cdd887 d
-pick bfa474341cc9 does not commute with e
-pick e860deea161a e
-pick 652413bf663e f
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-    echo a >> e
-    hg ci -m 'does not commute with e'
-}
-
-initrepo
-
-echo % log before edit
-hg log --graph
-
-echo % edit the history
-HGEDITOR="cat $EDITED > " hg histedit 177f92b77385 2>&1 | fixbundle
-
-echo '% fix up (pre abort)'
-echo a > e
-hg add e
-hg histedit --continue 2>&1 | fixbundle
-
-echo % abort the edit
-hg histedit --abort 2>&1 | fixbundle
-
-echo % log after abort
-hg log --graph
-echo % EOF
--- a/.hgext/histedit/tests/test-histedit-non-commute-abort.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-% log before edit
-@  changeset:   6:bfa474341cc9
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   5:652413bf663e
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-unable to find 'e' for patching
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-e: No such file or directory
-abort: Fix up the change and run hg histedit --continue
-% fix up (pre abort)
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-file e already exists
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-abort: Fix up the change and run hg histedit --continue
-% abort the edit
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after abort
-@  changeset:   6:bfa474341cc9
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   5:652413bf663e
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% EOF
--- a/.hgext/histedit/tests/test-histedit-non-commute.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-% log before edit
-@  changeset:   6:bfa474341cc9
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   5:652413bf663e
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-unable to find 'e' for patching
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-e: No such file or directory
-abort: Fix up the change and run hg histedit --continue
-% abort the edit
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-
-% second edit set
-@  changeset:   6:bfa474341cc9
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   5:652413bf663e
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:e860deea161a
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% edit the history
-0 files updated, 0 files merged, 2 files removed, 0 files unresolved
-unable to find 'e' for patching
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-e: No such file or directory
-abort: Fix up the change and run hg histedit --continue
-% fix up
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-file e already exists
-1 out of 1 hunks FAILED -- saving rejects to file e.rej
-abort: Fix up the change and run hg histedit --continue
-
-% just continue this time
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% log after edit
-@  changeset:   5:9ab84894b459
-|  tag:         tip
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     f
-|
-o  changeset:   4:1fff3ae8199d
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     does not commute with e
-|
-o  changeset:   3:055a42cdd887
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     d
-|
-o  changeset:   2:177f92b77385
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     c
-|
-o  changeset:   1:d2ae7f538514
-|  user:        test
-|  date:        Thu Jan 01 00:00:00 1970 +0000
-|  summary:     b
-|
-o  changeset:   0:cb9a9f314b8b
-   user:        test
-   date:        Thu Jan 01 00:00:00 1970 +0000
-   summary:     a
-
-% EOF
--- a/.hgext/histedit/tests/test-histedit-outgoing	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#!/bin/sh
-
-cat >> $HGRCPATH <<EOF
-[extensions]
-hgext.graphlog=
-EOF
-
-echo "histedit=$(echo $(dirname $(dirname $0)))/hg_histedit.py" >> $HGRCPATH
-
-EDITED=`pwd`/editedhistory
-cat > $EDITED <<EOF
-pick 177f92b77385 c
-pick e860deea161a e
-pick 652413bf663e f
-pick 055a42cdd887 d
-EOF
-initrepo ()
-{
-    hg init r
-    cd r
-    for x in a b c ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-
-    cd ..
-    hg clone r r2 | grep -v updating
-    cd r2
-    for x in d e f ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-
-    cd ..
-    hg init r3
-    cd r3
-    for x in g h i ; do
-        echo $x > $x
-        hg add $x
-        hg ci -m $x
-    done
-    cd ..
-}
-
-initrepo
-
-echo % show the edit commands offered by outgoing
-cd r2
-HGEDITOR=cat hg histedit --outgoing ../r
-cd ..
-
-echo % show the error from unrelated repos
-cd r3
-HGEDITOR=cat hg histedit --outgoing ../r
-cd ..
-
-echo % show the error from unrelated repos
-cd r3
-HGEDITOR=cat hg histedit --force --outgoing ../r
-cd ..
--- a/.hgext/histedit/tests/test-histedit-outgoing.out	Thu Aug 23 21:41:55 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-3 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% show the edit commands offered by outgoing
-pick 055a42cdd887 d
-pick e860deea161a e
-pick 652413bf663e f
-
-# Edit history between 055a42cdd887 and 652413bf663e
-#
-# Commands:
-#  p, pick = use commit
-#  e, edit = use commit, but stop for amending
-#  f, fold = use commit, but fold into previous commit
-#  d, drop = remove commit from history
-#
-comparing with ../r
-searching for changes
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-% show the error from unrelated repos
-comparing with ../r
-searching for changes
-abort: repository is unrelated
-% show the error from unrelated repos
-comparing with ../r
-searching for changes
-warning: repository is unrelated
-pick 2a4042b45417 g
-pick 68c46b4927ce h
-pick 51281e65ba79 i
-
-# Edit history between 2a4042b45417 and 51281e65ba79
-#
-# Commands:
-#  p, pick = use commit
-#  e, edit = use commit, but stop for amending
-#  f, fold = use commit, but fold into previous commit
-#  d, drop = remove commit from history
-#
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved