#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2005, Giovanni Bajo
# Copyright (c) 2004-2005, Awarix, Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
# Author: Archie Cobbs <archie at awarix dot com>
# Rewritten in Python by: Giovanni Bajo <rasky at develer dot com>
#
# Acknowledgments:
#   John Belmonte <john at neggie dot net> - metadata and usability
#     improvements
#   Blair Zajac <blair at orcaware dot com> - random improvements
#   Raman Gupta <rocketraman at fastmail dot fm> - bidirectional and transitive
#     merging support
#
# $HeadURL$
# $LastChangedDate$
# $LastChangedBy$
# $LastChangedRevision$
#
# Requisites:
# svnmerge.py has been tested with all SVN major versions since 1.1 (both
# client and server). It is unknown if it works with previous versions.
#
# Differences from svnmerge.sh:
# - More portable: tested as working in FreeBSD and OS/2.
# - Add double-verbose mode, which shows every svn command executed (-v -v).
# - "svnmerge avail" now only shows commits in source, not also commits in
#   other parts of the repository.
# - Add "svnmerge block" to flag some revisions as blocked, so that
#   they will not show up anymore in the available list.  Added also
#   the complementary "svnmerge unblock".
# - "svnmerge avail" has grown two new options:
#   -B to display a list of the blocked revisions
#   -A to display both the blocked and the available revisions.
# - Improved generated commit message to make it machine parsable even when
#   merging commits which are themselves merges.
# - Add --force option to skip working copy check
# - Add --record-only option to "svnmerge merge" to avoid performing
#   an actual merge, yet record that a merge happened.
#
# TODO:
#  - Add "svnmerge avail -R": show logs in reverse order
#
# Information for Hackers:
#
# Identifiers for branches:
#  A branch is identified in three ways within this source:
#  - as a working copy (variable name usually includes 'dir')
#  - as a fully qualified URL
#  - as a path identifier (an opaque string indicating a particular path
#    in a particular repository; variable name includes 'pathid')
#  A "target" is generally user-specified, and may be a working copy or
#  a URL.

import sys, os, getopt, re, types, tempfile, time, popen2
from bisect import bisect
from xml.dom import pulldom

NAME = "svnmerge"
if not hasattr(sys, "version_info") or sys.version_info < (2, 0):
    error("requires Python 2.0 or newer")

# Set up the separator used to separate individual log messages from
# each revision merged into the target location.  Also, create a
# regular expression that will find this same separator in already
# committed log messages, so that the separator used for this run of
# svnmerge.py will have one more LOG_SEPARATOR appended to the longest
# separator found in all the commits.
LOG_SEPARATOR = 8 * '.'
LOG_SEPARATOR_RE = re.compile('^((%s)+)' % re.escape(LOG_SEPARATOR),
                              re.MULTILINE)

# Each line of the embedded log messages will be prefixed by LOG_LINE_PREFIX.
LOG_LINE_PREFIX = 2 * ' '

# We expect non-localized output from SVN
os.environ["LC_ALL"] = "C"

###############################################################################
# Support for older Python versions
###############################################################################

# True/False constants are Python 2.2+
try:
    True, False
except NameError:
    True, False = 1, 0

def lstrip(s, ch):
    """Replacement for str.lstrip (support for arbitrary chars to strip was
    added in Python 2.2.2)."""
    i = 0
    try:
        while s[i] == ch:
            i = i+1
        return s[i:]
    except IndexError:
        return ""

def rstrip(s, ch):
    """Replacement for str.rstrip (support for arbitrary chars to strip was
    added in Python 2.2.2)."""
    try:
        if s[-1] != ch:
            return s
        i = -2
        while s[i] == ch:
            i = i-1
        return s[:i+1]
    except IndexError:
        return ""

def strip(s, ch):
    """Replacement for str.strip (support for arbitrary chars to strip was
    added in Python 2.2.2)."""
    return lstrip(rstrip(s, ch), ch)

def rsplit(s, sep, maxsplits=0):
    """Like str.rsplit, which is Python 2.4+ only."""
    L = s.split(sep)
    if not 0 < maxsplits <= len(L):
        return L
    return [sep.join(L[0:-maxsplits])] + L[-maxsplits:]

###############################################################################

def kwextract(s):
    """Extract info from a svn keyword string."""
    try:
        return strip(s, "$").strip().split(": ")[1]
    except IndexError:
        return "<unknown>"

__revision__ = kwextract('$Rev$')
__date__ = kwextract('$Date$')

# Additional options, not (yet?) mapped to command line flags
default_opts = {
    "svn": "svn",
    "prop": NAME + "-integrated",
    "block-prop": NAME + "-blocked",
    "commit-verbose": True,
}
logs = {}

def console_width():
    """Get the width of the console screen (if any)."""
    try:
        return int(os.environ["COLUMNS"])
    except (KeyError, ValueError):
        pass

    try:
        # Call the Windows API (requires ctypes library)
        from ctypes import windll, create_string_buffer
        h = windll.kernel32.GetStdHandle(-11)
        csbi = create_string_buffer(22)
        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
        if res:
            import struct
            (bufx, bufy,
             curx, cury, wattr,
             left, top, right, bottom,
             maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
            return right - left + 1
    except ImportError:
        pass

    # Parse the output of stty -a
    out = os.popen("stty -a").read()
    m = re.search(r"columns (\d+);", out)
    if m:
        return int(m.group(1))

    # sensible default
    return 80

def error(s):
    """Subroutine to output an error and bail."""
    print >> sys.stderr, "%s: %s" % (NAME, s)
    sys.exit(1)

def report(s):
    """Subroutine to output progress message, unless in quiet mode."""
    if opts["verbose"]:
        print "%s: %s" % (NAME, s)

def prefix_lines(prefix, lines):
    """Given a string representing one or more lines of text, insert the
    specified prefix at the beginning of each line, and return the result.
    The input must be terminated by a newline."""
    assert lines[-1] == "\n"
    return prefix + lines[:-1].replace("\n", "\n"+prefix) + "\n"

class LaunchError(Exception):
    """Signal a failure in execution of an external command. Parameters are the
    exit code of the process, the original command line, and the output of the
    command."""

try:
    """Launch a sub-process. Return its output (both stdout and stderr),
    optionally split by lines (if split_lines is True). Raise a LaunchError
    exception if the exit code of the process is non-zero (failure).

    This function has two implementations, one based on subprocess (preferred),
    and one based on popen (for compatibility).
    """
    import subprocess
    import shlex

    def launch(cmd, split_lines=True):
        # Requiring python 2.4 or higher, on some platforms we get
        # much faster performance from the subprocess module (where python
        # doesn't try to close an exhorbitant number of file descriptors)
        stdout = ""
        stderr = ""
        try:
            if os.name == 'nt':
                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, \
                                     close_fds=False, stderr=subprocess.PIPE)
            else:
                # Use shlex to break up the parameters intelligently,
                # respecting quotes. shlex can't handle unicode.
                args = shlex.split(cmd.encode('ascii'))
                p = subprocess.Popen(args, stdout=subprocess.PIPE, \
                                     close_fds=False, stderr=subprocess.PIPE)
            stdoutAndErr = p.communicate()
            stdout = stdoutAndErr[0]
            stderr = stdoutAndErr[1]
        except OSError, inst:
            # Using 1 as failure code; should get actual number somehow? For
            # examples see svnmerge_test.py's TestCase_launch.test_failure and
            # TestCase_launch.test_failurecode.
            raise LaunchError(1, cmd, stdout + " " + stderr + ": " + str(inst))

        if p.returncode == 0:
            if split_lines:
                # Setting keepends=True for compatibility with previous logic
                # (where file.readlines() preserves newlines)
                return stdout.splitlines(True)
            else:
                return stdout
        else:
            raise LaunchError(p.returncode, cmd, stdout + stderr)
except ImportError:
    # support versions of python before 2.4 (slower on some systems)
    def launch(cmd, split_lines=True):
        if os.name not in ['nt', 'os2']:
            p = popen2.Popen4(cmd)
            p.tochild.close()
            if split_lines:
                out = p.fromchild.readlines()
            else:
                out = p.fromchild.read()
            ret = p.wait()
            if ret == 0:
                ret = None
            else:
                ret >>= 8
        else:
            i,k = os.popen4(cmd)
            i.close()
            if split_lines:
                out = k.readlines()
            else:
                out = k.read()
            ret = k.close()

        if ret is None:
            return out
        raise LaunchError(ret, cmd, out)

def launchsvn(s, show=False, pretend=False, **kwargs):
    """Launch SVN and grab its output."""
    username = opts.get("username", None)
    password = opts.get("password", None)
    if username:
        username = " --username=" + username
    else:
        username = ""
    if password:
        password = " --password=" + password
    else:
        password = ""
    cmd = opts["svn"] + " --non-interactive" + username + password + " " + s
    if show or opts["verbose"] >= 2:
        print cmd
    if pretend:
        return None
    return launch(cmd, **kwargs)

def svn_command(s):
    """Do (or pretend to do) an SVN command."""
    out = launchsvn(s, show=opts["show-changes"] or opts["dry-run"],
                    pretend=opts["dry-run"],
                    split_lines=False)
    if not opts["dry-run"]:
        print out

def check_dir_clean(dir):
    """Check the current status of dir for local mods."""
    if opts["force"]:
        report('skipping status check because of --force')
        return
    report('checking status of "%s"' % dir)

    # Checking with -q does not show unversioned files or external
    # directories.  Though it displays a debug message for external
    # directories, after a blank line.  So, practically, the first line
    # matters: if it's non-empty there is a modification.
    out = launchsvn("status -q %s" % dir)
    if out and out[0].strip():
        error('"%s" has local modifications; it must be clean' % dir)

class RevisionLog:
    """
    A log of the revisions which affected a given URL between two
    revisions.
    """

    def __init__(self, url, begin, end, find_propchanges=False):
        """
        Create a new RevisionLog object, which stores, in self.revs, a list
        of the revisions which affected the specified URL between begin and
        end. If find_propchanges is True, self.propchange_revs will contain a
        list of the revisions which changed properties directly on the
        specified URL. URL must be the URL for a directory in the repository.
        """
        self.url = url

        # Setup the log options (--quiet, so we don't show log messages)
        log_opts = '--xml --quiet -r%s:%s "%s"' % (begin, end, url)
        if find_propchanges:
            # The --verbose flag lets us grab merge tracking information
            # by looking at propchanges
            log_opts = "--verbose " + log_opts

        # Read the log to look for revision numbers and merge-tracking info
        self.revs = []
        self.propchange_revs = []
        repos_pathid = target_to_pathid(url)
        for chg in SvnLogParser(launchsvn("log %s" % log_opts,
                                          split_lines=False)):
            self.revs.append(chg.revision())
            for p in chg.paths():
                if p.action() == 'M' and p.pathid() == repos_pathid:
                    self.propchange_revs.append(chg.revision())

        # Save the range of the log
        self.begin = int(begin)
        if end == "HEAD":
            # If end is not provided, we do not know which is the latest
            # revision in the repository. So we set 'end' to the latest
            # known revision.
            self.end = self.revs[-1]
        else:
            self.end = int(end)

        self._merges = None
        self._blocks = None

    def merge_metadata(self):
        """
        Return a VersionedProperty object, with a cached view of the merge
        metadata in the range of this log.
        """

        # Load merge metadata if necessary
        if not self._merges:
            self._merges = VersionedProperty(self.url, opts["prop"])
            self._merges.load(self)

        return self._merges

    def block_metadata(self):
        if not self._blocks:
            self._blocks = VersionedProperty(self.url, opts["block-prop"])
            self._blocks.load(self)

        return self._blocks


class VersionedProperty:
    """
    A read-only, cached view of a versioned property.

    self.revs contains a list of the revisions in which the property changes.
    self.values stores the new values at each corresponding revision. If the
    value of the property is unknown, it is set to None.

    Initially, we set self.revs to [0] and self.values to [None]. This
    indicates that, as of revision zero, we know nothing about the value of
    the property.

    Later, if you run self.load(log), we cache the value of this property over
    the entire range of the log by noting each revision in which the property
    was changed. At the end of the range of the log, we invalidate our cache
    by adding the value "None" to our cache for any revisions which fall out
    of the range of our log.

    Once self.revs and self.values are filled, we can find the value of the
    property at any arbitrary revision using a binary search on self.revs.
    Once we find the last revision during which the property was changed,
    we can lookup the associated value in self.values. (If the associated
    value is None, the associated value was not cached and we have to do
    a full propget.)

    An example: We know that the 'svnmerge' property was added in r10, and
    changed in r21. We gathered log info up until r40.

    revs = [0, 10, 21, 40]
    values = [None, "val1", "val2", None]

    What these values say:
    - From r0 to r9, we know nothing about the property.
    - In r10, the property was set to "val1". This property stayed the same
      until r21, when it was changed to "val2".
    - We don't know what happened after r40.
    """

    def __init__(self, url, name):
        """View the history of a versioned property at URL with name"""
        self.url = url
        self.name = name

        # We know nothing about the value of the property. Setup revs
        # and values to indicate as such.
        self.revs = [0]
        self.values = [None]

        # We don't have any revisions cached
        self._initial_value = None
        self._changed_revs = []
        self._changed_values = []

    def load(self, log):
        """
        Load the history of property changes from the specified
        RevisionLog object.
        """

        # Get the property value before the range of the log
        if log.begin > 1:
            self.revs.append(log.begin-1)
            try:
                self._initial_value = self.raw_get(log.begin-1)
            except LaunchError:
                # The specified URL might not exist before the
                # range of the log. If so, we can safely assume
                # that the property was empty at that time.
                self._initial_value = { }
            self.values.append(self._initial_value)
        else:
            self._initial_value = { }
            self.values[0] = self._initial_value

        # Cache the property values in the log range
        old_value = self._initial_value
        for rev in log.propchange_revs:
            new_value = self.raw_get(rev)
            if new_value != old_value:
                self._changed_revs.append(rev)
                self._changed_values.append(new_value)
                self.revs.append(rev)
                self.values.append(new_value)
                old_value = new_value

        # Indicate that we know nothing about the value of the property
        # after the range of the log.
        if log.revs:
            self.revs.append(log.end+1)
            self.values.append(None)

    def raw_get(self, rev=None):
        """
        Get the property at revision REV. If rev is not specified, get
        the property at revision HEAD.
        """
        return get_revlist_prop(self.url, self.name, rev)

    def get(self, rev=None):
        """
        Get the property at revision REV. If rev is not specified, get
        the property at revision HEAD.
        """

        if rev is not None:

            # Find the index using a binary search
            i = bisect(self.revs, rev) - 1

            # Return the value of the property, if it was cached
            if self.values[i] is not None:
                return self.values[i]

        # Get the current value of the property
        return self.raw_get(rev)

    def changed_revs(self, key=None):
        """
        Get a list of the revisions in which the specified dictionary
        key was changed in this property. If key is not specified,
        return a list of revisions in which any key was changed.
        """
        if key is None:
            return self._changed_revs
        else:
            changed_revs = []
            old_val = self._initial_value
            for rev, val in zip(self._changed_revs, self._changed_values):
                if val.get(key) != old_val.get(key):
                    changed_revs.append(rev)
                    old_val = val
            return changed_revs

    def initialized_revs(self):
        """
        Get a list of the revisions in which keys were added or
        removed in this property.
        """
        initialized_revs = []
        old_len = len(self._initial_value)
        for rev, val in zip(self._changed_revs, self._changed_values):
            if len(val) != old_len:
                initialized_revs.append(rev)
                old_len = len(val)
        return initialized_revs

class RevisionSet:
    """
    A set of revisions, held in dictionary form for easy manipulation. If we
    were to rewrite this script for Python 2.3+, we would subclass this from
    set (or UserSet).  As this class does not include branch
    information, it's assumed that one instance will be used per
    branch.
    """
    def __init__(self, parm):
        """Constructs a RevisionSet from a string in property form, or from
        a dictionary whose keys are the revisions. Raises ValueError if the
        input string is invalid."""

        self._revs = {}

        revision_range_split_re = re.compile('[-:]')

        if isinstance(parm, types.DictType):
            self._revs = parm.copy()
        elif isinstance(parm, types.ListType):
            for R in parm:
                self._revs[int(R)] = 1
        else:
            parm = parm.strip()
            if parm:
                for R in parm.split(","):
                    rev_or_revs = re.split(revision_range_split_re, R)
                    if len(rev_or_revs) == 1:
                        self._revs[int(rev_or_revs[0])] = 1
                    elif len(rev_or_revs) == 2:
                        for rev in range(int(rev_or_revs[0]),
                                         int(rev_or_revs[1])+1):
                            self._revs[rev] = 1
                    else:
                        raise ValueError, 'Ill formatted revision range: ' + R

    def sorted(self):
        revnums = self._revs.keys()
        revnums.sort()
        return revnums

    def normalized(self):
        """Returns a normalized version of the revision set, which is an
        ordered list of couples (start,end), with the minimum number of
        intervals."""
        revnums = self.sorted()
        revnums.reverse()
        ret = []
        while revnums:
            s = e = revnums.pop()
            while revnums and revnums[-1] in (e, e+1):
                e = revnums.pop()
            ret.append((s, e))
        return ret

    def __str__(self):
        """Convert the revision set to a string, using its normalized form."""
        L = []
        for s,e in self.normalized():
            if s == e:
                L.append(str(s))
            else:
                L.append(str(s) + "-" + str(e))
        return ",".join(L)

    def __contains__(self, rev):
        return self._revs.has_key(rev)

    def __sub__(self, rs):
        """Compute subtraction as in sets."""
        revs = {}
        for r in self._revs.keys():
            if r not in rs:
                revs[r] = 1
        return RevisionSet(revs)

    def __and__(self, rs):
        """Compute intersections as in sets."""
        revs = {}
        for r in self._revs.keys():
            if r in rs:
                revs[r] = 1
        return RevisionSet(revs)

    def __nonzero__(self):
        return len(self._revs) != 0

    def __len__(self):
        """Return the number of revisions in the set."""
        return len(self._revs)

    def __iter__(self):
        return iter(self.sorted())

    def __or__(self, rs):
        """Compute set union."""
        revs = self._revs.copy()
        revs.update(rs._revs)
        return RevisionSet(revs)

def merge_props_to_revision_set(merge_props, pathid):
    """A converter which returns a RevisionSet instance containing the
    revisions from PATH as known to BRANCH_PROPS.  BRANCH_PROPS is a
    dictionary of pathid -> revision set branch integration information
    (as returned by get_merge_props())."""
    if not merge_props.has_key(pathid):
        error('no integration info available for path "%s"' % pathid)
    return RevisionSet(merge_props[pathid])

def dict_from_revlist_prop(propvalue):
    """Given a property value as a string containing per-source revision
    lists, return a dictionary whose key is a source path identifier
    and whose value is the revisions for that source."""
    prop = {}

    # Multiple sources are separated by any whitespace.
    for L in propvalue.split():
        # We use rsplit to play safe and allow colons in pathids.
        source, revs = rsplit(L.strip(), ":", 1)
        prop[source] = revs
    return prop

def get_revlist_prop(url_or_dir, propname, rev=None):
    """Given a repository URL or working copy path and a property
    name, extract the values of the property which store per-source
    revision lists and return a dictionary whose key is a source path
    identifier, and whose value is the revisions for that source."""

    # Note that propget does not return an error if the property does
    # not exist, it simply does not output anything. So we do not need
    # to check for LaunchError here.
    args = '--strict "%s" "%s"' % (propname, url_or_dir)
    if rev:
        args = '-r %s %s' % (rev, args)
    out = launchsvn('propget %s' % args, split_lines=False)

    return dict_from_revlist_prop(out)

def get_merge_props(dir):
    """Extract the merged revisions."""
    return get_revlist_prop(dir, opts["prop"])

def get_block_props(dir):
    """Extract the blocked revisions."""
    return get_revlist_prop(dir, opts["block-prop"])

def get_blocked_revs(dir, source_pathid):
    p = get_block_props(dir)
    if p.has_key(source_pathid):
        return RevisionSet(p[source_pathid])
    return RevisionSet("")

def format_merge_props(props, sep=" "):
    """Formats the hash PROPS as a string suitable for use as a
    Subversion property value."""
    assert sep in ["\t", "\n", " "]   # must be a whitespace
    props = props.items()
    props.sort()
    L = []
    for h, r in props:
        L.append(h + ":" + r)
    return sep.join(L)

def _run_propset(dir, prop, value):
    """Set the property 'prop' of directory 'dir' to value 'value'. We go
    through a temporary file to not run into command line length limits."""
    try:
        fd, fname = tempfile.mkstemp()
        f = os.fdopen(fd, "wb")
    except AttributeError:
        # Fallback for Python <= 2.3 which does not have mkstemp (mktemp
        # suffers from race conditions. Not that we care...)
        fname = tempfile.mktemp()
        f = open(fname, "wb")

    try:
        f.write(value)
        f.close()
        report("property data written to temp file: %s" % value)
        svn_command('propset "%s" -F "%s" "%s"' % (prop, fname, dir))
    finally:
        os.remove(fname)

def set_props(dir, name, props):
    props = format_merge_props(props)
    if props:
        _run_propset(dir, name, props)
    else:
        svn_command('propdel "%s" "%s"' % (name, dir))

def set_merge_props(dir, props):
    set_props(dir, opts["prop"], props)

def set_block_props(dir, props):
    set_props(dir, opts["block-prop"], props)

def set_blocked_revs(dir, source_pathid, revs):
    props = get_block_props(dir)
    if revs:
        props[source_pathid] = str(revs)
    elif props.has_key(source_pathid):
        del props[source_pathid]
    set_block_props(dir, props)

def is_url(url):
    """Check if url is a valid url."""
    return re.search(r"^[a-zA-Z][-+\.\w]*://", url) is not None

def is_wc(dir):
    """Check if a directory is a working copy."""
    return os.path.isdir(os.path.join(dir, ".svn")) or \
           os.path.isdir(os.path.join(dir, "_svn"))

_cache_svninfo = {}
def get_svninfo(target):
    """Extract the subversion information for a target (through 'svn info').
    This function uses an internal cache to let clients query information
    many times."""
    if _cache_svninfo.has_key(target):
        return _cache_svninfo[target]
    info = {}
    for L in launchsvn('info "%s"' % target):
        L = L.strip()
        if not L:
            continue
        key, value = L.split(": ", 1)
        info[key] = value.strip()
    _cache_svninfo[target] = info
    return info

def target_to_url(target):
    """Convert working copy path or repos URL to a repos URL."""
    if is_wc(target):
        info = get_svninfo(target)
        return info["URL"]
    return target

_cache_reporoot = {}
def get_repo_root(target):
    """Compute the root repos URL given a working-copy path, or a URL."""
    # Try using "svn info WCDIR". This works only on SVN clients >= 1.3
    if not is_url(target):
        try:
            info = get_svninfo(target)
            root = info["Repository Root"]
            _cache_reporoot[root] = None
            return root
        except KeyError:
            pass
        url = target_to_url(target)
        assert url[-1] != '/'
    else:
        url = target

    # Go through the cache of the repository roots. This avoids extra
    # server round-trips if we are asking the root of different URLs
    # in the same repository (the cache in get_svninfo() cannot detect
    # that of course and would issue a remote command).
    assert is_url(url)
    for r in _cache_reporoot:
        if url.startswith(r):
            return r

    # Try using "svn info URL". This works only on SVN clients >= 1.2
    try:
        info = get_svninfo(url)
        root = info["Repository Root"]
        _cache_reporoot[root] = None
        return root
    except LaunchError:
        pass

    # Constrained to older svn clients, we are stuck with this ugly
    # trial-and-error implementation. It could be made faster with a
    # binary search.
    while url:
        temp = os.path.dirname(url)
        try:
            launchsvn('proplist "%s"' % temp)
        except LaunchError:
            _cache_reporoot[url] = None
            return url
        url = temp

    assert False, "svn repos root not found"

def target_to_pathid(target):
    """Convert a target (either a working copy path or an URL) into a
    path identifier."""
    root = get_repo_root(target)
    url = target_to_url(target)
    assert root[-1] != "/"
    assert url[:len(root)] == root, "url=%r, root=%r" % (url, root)
    return url[len(root):]

class SvnLogParser:
    """
    Parse the "svn log", going through the XML output and using pulldom (which
    would even allow streaming the command output).
    """
    def __init__(self, xml):
        self._events = pulldom.parseString(xml)
    def __getitem__(self, idx):
        for event, node in self._events:
            if event == pulldom.START_ELEMENT and node.tagName == "logentry":
                self._events.expandNode(node)
                return self.SvnLogRevision(node)
        raise IndexError, "Could not find 'logentry' tag in xml"

    class SvnLogRevision:
        def __init__(self, xmlnode):
            self.n = xmlnode
        def revision(self):
            return self.n.getAttribute("revision")
        def author(self):
            return self.n.getElementsByTagName("author")[0].firstChild.data
        def paths(self):
            return [self.SvnLogPath(n)
                    for n in  self.n.getElementsByTagName("path")]

        class SvnLogPath:
            def __init__(self, xmlnode):
                self.n = xmlnode
            def action(self):
                return self.n.getAttribute("action")
            def pathid(self):
                return self.n.firstChild.data
            def copyfrom_rev(self):
                try: return self.n.getAttribute("copyfrom-rev")
                except KeyError: return None
            def copyfrom_pathid(self):
                try: return self.n.getAttribute("copyfrom-path")
                except KeyError: return None

def get_copyfrom(target):
    """Get copyfrom info for a given target (it represents the directory from
    where it was branched). NOTE: repos root has no copyfrom info. In this case
    None is returned.

    Returns the:
        - source file or directory from which the copy was made
        - revision from which that source was copied
        - revision in which the copy was committed
    """
    repos_path = target_to_pathid(target)
    for chg in SvnLogParser(launchsvn('log -v --xml --stop-on-copy "%s"'
                                      % target, split_lines=False)):
        for p in chg.paths():
            if p.action() == 'A' and p.pathid() == repos_path:
                # These values will be None if the corresponding elements are
                # not found in the log.
                return p.copyfrom_pathid(), p.copyfrom_rev(), chg.revision()
    return None,None,None

def get_latest_rev(url):
    """Get the latest revision of the repository of which URL is part."""
    try:
        return get_svninfo(url)["Revision"]
    except LaunchError:
        # Alternative method for latest revision checking (for svn < 1.2)
        report('checking latest revision of "%s"' % url)
        L = launchsvn('proplist --revprop -r HEAD "%s"' % opts["source-url"])[0]
        rev = re.search("revision (\d+)", L).group(1)
        report('latest revision of "%s" is %s' % (url, rev))
        return rev

def get_created_rev(url):
    """Lookup the revision at which the path identified by the
    provided URL was first created."""
    oldest_rev = -1
    report('determining oldest revision for URL "%s"' % url)
    ### TODO: Refactor this to use a modified RevisionLog class.
    lines = None
    cmd = "log -r1:HEAD --stop-on-copy -q " + url
    try:
        lines = launchsvn(cmd + " --limit=1")
    except LaunchError:
        # Assume that --limit isn't supported by the installed 'svn'.
        lines = launchsvn(cmd)
    if lines and len(lines) > 1:
        i = lines[1].find(" ")
        if i != -1:
            oldest_rev = int(lines[1][1:i])
    if oldest_rev == -1:
        error('unable to determine oldest revision for URL "%s"' % url)
    return oldest_rev

def get_commit_log(url, revnum):
    """Return the log message for a specific integer revision
    number."""
    out = launchsvn("log --incremental -r%d %s" % (revnum, url))
    return "".join(out[1:])

def construct_merged_log_message(url, revnums):
    """Return a commit log message containing all the commit messages
    in the specified revisions at the given URL.  The separator used
    in this log message is determined by searching for the longest
    svnmerge separator existing in the commit log messages and
    extending it by one more separator.  This results in a new commit
    log message that is clearer in describing merges that contain
    other merges. Trailing newlines are removed from the embedded
    log messages."""
    messages = ['']
    longest_sep = ''
    for r in revnums.sorted():
        message = get_commit_log(url, r)
        if message:
            message = re.sub(r'(\r\n|\r|\n)', "\n", message)
            message = rstrip(message, "\n") + "\n"
            messages.append(prefix_lines(LOG_LINE_PREFIX, message))
            for match in LOG_SEPARATOR_RE.findall(message):
                sep = match[1]
                if len(sep) > len(longest_sep):
                    longest_sep = sep

    longest_sep += LOG_SEPARATOR + "\n"
    messages.append('')
    return longest_sep.join(messages)

def get_default_source(branch_target, branch_props):
    """Return the default source for branch_target (given its branch_props).
    Error out if there is ambiguity."""
    if not branch_props:
        error("no integration info available")

    props = branch_props.copy()
    pathid = target_to_pathid(branch_target)

    # To make bidirectional merges easier, find the target's
    # repository local path so it can be removed from the list of
    # possible integration sources.
    if props.has_key(pathid):
        del props[pathid]

    if len(props) > 1:
        err_msg = "multiple sources found. "
        err_msg += "Explicit source argument (-S/--source) required.\n"
        err_msg += "The merge sources available are:"
        for prop in props:
          err_msg += "\n  " + prop
        error(err_msg)

    return props.keys()[0]

def check_old_prop_version(branch_target, branch_props):
    """Check if branch_props (of branch_target) are svnmerge properties in
    old format, and emit an error if so."""

    # Previous svnmerge versions allowed trailing /'s in the repository
    # local path.  Newer versions of svnmerge will trim trailing /'s
    # appearing in the command line, so if there are any properties with
    # trailing /'s, they will not be properly matched later on, so require
    # the user to change them now.
    fixed = {}
    changed = False
    for source, revs in branch_props.items():
        src = rstrip(source, "/")
        fixed[src] = revs
        if src != source:
            changed = True

    if changed:
        err_msg = "old property values detected; an upgrade is required.\n\n"
        err_msg += "Please execute and commit these changes to upgrade:\n\n"
        err_msg += 'svn propset "%s" "%s" "%s"' % \
                   (opts["prop"], format_merge_props(fixed), branch_target)
        error(err_msg)

def analyze_revs(target_pathid, url, begin=1, end=None,
                 find_reflected=False):
    """For the source of the merges in the source URL being merged into
    target_pathid, analyze the revisions in the interval begin-end (which
    defaults to 1-HEAD), to find out which revisions are changes in
    the url, which are changes elsewhere (so-called 'phantom'
    revisions), optionally which are reflected changes (to avoid
    conflicts that can occur when doing bidirectional merging between
    branches), and which revisions initialize merge tracking against other
    branches.  Return a tuple of four RevisionSet's:
        (real_revs, phantom_revs, reflected_revs, initialized_revs).

    NOTE: To maximize speed, if "end" is not provided, the function is
    not able to find phantom revisions following the last real
    revision in the URL.
    """

    begin = str(begin)
    if end is None:
        end = "HEAD"
    else:
        end = str(end)
        if long(begin) > long(end):
            return RevisionSet(""), RevisionSet(""), \
                   RevisionSet(""), RevisionSet("")

    logs[url] = RevisionLog(url, begin, end, find_reflected)
    revs = RevisionSet(logs[url].revs)

    if end == "HEAD":
        # If end is not provided, we do not know which is the latest revision
        # in the repository. So return the phantom revision set only up to
        # the latest known revision.
        end = str(list(revs)[-1])

    phantom_revs = RevisionSet("%s-%s" % (begin, end)) - revs

    if find_reflected:
        reflected_revs = logs[url].merge_metadata().changed_revs(target_pathid)
        reflected_revs += logs[url].block_metadata().changed_revs(target_pathid)
    else:
        reflected_revs = []

    initialized_revs = RevisionSet(logs[url].merge_metadata().initialized_revs())
    reflected_revs = RevisionSet(reflected_revs)

    return revs, phantom_revs, reflected_revs, initialized_revs

def analyze_source_revs(branch_target, source_url, **kwargs):
    """For the given branch and source, extract the real and phantom
    source revisions."""
    branch_url = target_to_url(branch_target)
    branch_pathid = target_to_pathid(branch_target)

    # Extract the latest repository revision from the URL of the branch
    # directory (which is already cached at this point).
    end_rev = get_latest_rev(source_url)

    # Calculate the base of analysis. If there is a "1-XX" interval in the
    # merged_revs, we do not need to check those.
    base = 1
    r = opts["merged-revs"].normalized()
    if r and r[0][0] == 1:
        base = r[0][1] + 1

    # See if the user filtered the revision set. If so, we are not
    # interested in something outside that range.
    if opts["revision"]:
        revs = RevisionSet(opts["revision"]).sorted()
        if base < revs[0]:
            base = revs[0]
        if end_rev > revs[-1]:
            end_rev = revs[-1]

    return analyze_revs(branch_pathid, source_url, base, end_rev, **kwargs)

def minimal_merge_intervals(revs, phantom_revs):
    """Produce the smallest number of intervals suitable for merging. revs
    is the RevisionSet which we want to merge, and phantom_revs are phantom
    revisions which can be used to concatenate intervals, thus minimizing the
    number of operations."""
    revnums = revs.normalized()
    ret = []

    cur = revnums.pop()
    while revnums:
        next = revnums.pop()
        assert next[1] < cur[0]      # otherwise it is not ordered
        assert cur[0] - next[1] > 1  # otherwise it is not normalized
        for i in range(next[1]+1, cur[0]):
            if i not in phantom_revs:
                ret.append(cur)
                cur = next
                break
        else:
            cur = (next[0], cur[1])

    ret.append(cur)
    ret.reverse()
    return ret

def display_revisions(revs, display_style, revisions_msg, source_url):
    """Show REVS as dictated by DISPLAY_STYLE, either numerically, in
    log format, or as diffs.  When displaying revisions numerically,
    prefix output with REVISIONS_MSG when in verbose mode.  Otherwise,
    request logs or diffs using SOURCE_URL."""
    if display_style == "revisions":
        if revs:
            report(revisions_msg)
            print revs
    elif display_style == "logs":
        for start,end in revs.normalized():
            svn_command('log --incremental -v -r %d:%d %s' % \
                        (start, end, source_url))
    elif display_style in ("diffs", "summarize"):
        if display_style == 'summarize':
            summarize = '--summarize '
        else:
            summarize = ''

        for start, end in revs.normalized():
            print
            if start == end:
                print "%s: changes in revision %d follow" % (NAME, start)
            else:
                print "%s: changes in revisions %d-%d follow" % (NAME,
                                                                 start, end)
            print

            # Note: the starting revision number to 'svn diff' is
            # NOT inclusive so we have to subtract one from ${START}.
            svn_command("diff -r %d:%d %s %s" % (start - 1, end, summarize,
                                                 source_url))
    else:
        assert False, "unhandled display style: %s" % display_style

def action_init(target_dir, target_props):
    """Initialize for merges."""
    # Check that directory is ready for being modified
    check_dir_clean(target_dir)

    # If the user hasn't specified the revisions to use, see if the
    # "source" is a copy from the current tree and if so, we can use
    # the version data obtained from it.
    revision_range = opts["revision"]
    if not revision_range:
        # Determining a default endpoint for the revision range that "init"
        # will use, since none was provided by the user.
        cf_source, cf_rev, copy_committed_in_rev = \
                                            get_copyfrom(opts["source-url"])
        target_path = target_to_pathid(target_dir)

        if target_path == cf_source:
            # If source was originally copyied from target, and we are merging
            # changes from source to target (the copy target is the merge
            # source, and the copy source is the merge target), then we want to
            # mark as integrated up to the rev in which the copy was committed
            # which created the merge source:
            report('the source "%s" is a branch of "%s"' %
                   (opts["source-url"], target_dir))
            revision_range = "1-" + copy_committed_in_rev
        else:
            # If the copy source is the merge source, and
            # the copy target is the merge target, then we want to
            # mark as integrated up to the specific rev of the merge
            # target from which the merge source was copied. Longer
            # discussion here:
            # http://subversion.tigris.org/issues/show_bug.cgi?id=2810
            target_url = target_to_url(target_dir)
            source_path = target_to_pathid(opts["source-url"])
            cf_source_path, cf_rev, copy_committed_in_rev = get_copyfrom(target_url)
            if source_path == cf_source_path:
                report('the merge source "%s" is the copy source of "%s"' %
                       (opts["source-url"], target_dir))
                revision_range = "1-" + cf_rev

    # When neither the merge source nor target is a copy of the other, and
    # the user did not specify a revision range, then choose a default which is
    # the current revision; saying, in effect, "everything has been merged, so
    # mark as integrated up to the latest rev on source url).
    revs = revision_range or "1-" + get_latest_rev(opts["source-url"])
    revs = RevisionSet(revs)

    report('marking "%s" as already containing revisions "%s" of "%s"' %
           (target_dir, revs, opts["source-url"]))

    revs = str(revs)
    # If the local svnmerge-integrated property already has an entry
    # for the source-pathid, simply error out.
    if not opts["force"] and target_props.has_key(opts["source-pathid"]):
        error('Repository-relative path %s has already been initialized at %s\n'
              'Use --force to re-initialize'
              % (opts["source-pathid"], target_dir))
    target_props[opts["source-pathid"]] = revs

    # Set property
    set_merge_props(target_dir, target_props)

    # Write out commit message if desired
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        print >>f, 'Initialized merge tracking via "%s" with revisions "%s" from ' \
            % (NAME, revs)
        print >>f, '%s' % opts["source-url"]
        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

def action_avail(branch_dir, branch_props):
    """Show commits available for merges."""
    source_revs, phantom_revs, reflected_revs, initialized_revs = \
               analyze_source_revs(branch_dir, opts["source-url"],
                                   find_reflected=opts["bidirectional"])
    report('skipping phantom revisions: %s' % phantom_revs)
    if reflected_revs:
        report('skipping reflected revisions: %s' % reflected_revs)
        report('skipping initialized revisions: %s' % initialized_revs)

    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
    avail_revs = source_revs - opts["merged-revs"] - blocked_revs - \
                 reflected_revs - initialized_revs

    # Compose the set of revisions to show
    revs = RevisionSet("")
    report_msg = "revisions available to be merged are:"
    if "avail" in opts["avail-showwhat"]:
        revs |= avail_revs
    if "blocked" in opts["avail-showwhat"]:
        revs |= blocked_revs
        report_msg = "revisions blocked are:"

    # Limit to revisions specified by -r (if any)
    if opts["revision"]:
        revs = revs & RevisionSet(opts["revision"])

    display_revisions(revs, opts["avail-display"],
                      report_msg,
                      opts["source-url"])

def action_integrated(branch_dir, branch_props):
    """Show change sets already merged.  This set of revisions is
    calculated from taking svnmerge-integrated property from the
    branch, and subtracting any revision older than the branch
    creation revision."""
    # Extract the integration info for the branch_dir
    branch_props = get_merge_props(branch_dir)
    check_old_prop_version(branch_dir, branch_props)
    revs = merge_props_to_revision_set(branch_props, opts["source-pathid"])

    # Lookup the oldest revision on the branch path.
    oldest_src_rev = get_created_rev(opts["source-url"])

    # Subtract any revisions which pre-date the branch.
    report("subtracting revisions which pre-date the source URL (%d)" %
           oldest_src_rev)
    revs = revs - RevisionSet(range(1, oldest_src_rev))

    # Limit to revisions specified by -r (if any)
    if opts["revision"]:
        revs = revs & RevisionSet(opts["revision"])

    display_revisions(revs, opts["integrated-display"],
                      "revisions already integrated are:", opts["source-url"])

def action_merge(branch_dir, branch_props):
    """Record merge meta data, and do the actual merge (if not
    requested otherwise via --record-only)."""
    # Check branch directory is ready for being modified
    check_dir_clean(branch_dir)

    source_revs, phantom_revs, reflected_revs, initialized_revs = \
               analyze_source_revs(branch_dir, opts["source-url"],
                                   find_reflected=opts["bidirectional"])

    if opts["revision"]:
        revs = RevisionSet(opts["revision"])
    else:
        revs = source_revs

    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
    merged_revs = opts["merged-revs"]

    # Show what we're doing
    if opts["verbose"]:  # just to avoid useless calculations
        if merged_revs & revs:
            report('"%s" already contains revisions %s' % (branch_dir,
                                                           merged_revs & revs))
        if phantom_revs:
            report('memorizing phantom revision(s): %s' % phantom_revs)
        if reflected_revs:
            report('memorizing reflected revision(s): %s' % reflected_revs)
        if blocked_revs & revs:
            report('skipping blocked revisions(s): %s' % (blocked_revs & revs))
        if initialized_revs:
            report('skipping initialized revision(s): %s' % initialized_revs)

    # Compute final merge set.
    revs = revs - merged_revs - blocked_revs - reflected_revs - \
           phantom_revs - initialized_revs
    if not revs:
        report('no revisions to merge, exiting')
        return

    # When manually marking revisions as merged, we only update the
    # integration meta data, and don't perform an actual merge.
    record_only = opts["record-only"]

    if record_only:
        report('recording merge of revision(s) %s from "%s"' %
               (revs, opts["source-url"]))
    else:
        report('merging in revision(s) %s from "%s"' %
               (revs, opts["source-url"]))

    # Do the merge(s). Note: the starting revision number to 'svn merge'
    # is NOT inclusive so we have to subtract one from start.
    # We try to keep the number of merge operations as low as possible,
    # because it is faster and reduces the number of conflicts.
    old_block_props = get_block_props(branch_dir)
    merge_metadata = logs[opts["source-url"]].merge_metadata()
    block_metadata = logs[opts["source-url"]].block_metadata()
    for start,end in minimal_merge_intervals(revs, phantom_revs):
        if not record_only:
            # Preset merge/blocked properties to the source value at
            # the start rev to avoid spurious property conflicts
            set_merge_props(branch_dir, merge_metadata.get(start - 1))
            set_block_props(branch_dir, block_metadata.get(start - 1))
            # Do the merge
            svn_command("merge --force -r %d:%d %s %s" % \
                        (start - 1, end, opts["source-url"], branch_dir))
            # TODO: to support graph merging, add logic to merge the property
            # meta-data manually

    # Update the set of merged revisions.
    merged_revs = merged_revs | revs | reflected_revs | phantom_revs | initialized_revs
    branch_props[opts["source-pathid"]] = str(merged_revs)
    set_merge_props(branch_dir, branch_props)
    # Reset the blocked revs
    set_block_props(branch_dir, old_block_props)

    # Write out commit message if desired
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        if record_only:
            print >>f, 'Recorded merge of revisions %s via %s from ' % \
                  (revs, NAME)
        else:
            print >>f, 'Merged revisions %s via %s from ' % \
                  (revs, NAME)
        print >>f, '%s' % opts["source-url"]
        if opts["commit-verbose"]:
            print >>f
            print >>f, construct_merged_log_message(opts["source-url"], revs),

        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

def action_block(branch_dir, branch_props):
    """Block revisions."""
    # Check branch directory is ready for being modified
    check_dir_clean(branch_dir)

    source_revs, phantom_revs, reflected_revs, initialized_revs = \
               analyze_source_revs(branch_dir, opts["source-url"])
    revs_to_block = source_revs - opts["merged-revs"]

    # Limit to revisions specified by -r (if any)
    if opts["revision"]:
        revs_to_block = RevisionSet(opts["revision"]) & revs_to_block

    if not revs_to_block:
        error('no available revisions to block')

    # Change blocked information
    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
    blocked_revs = blocked_revs | revs_to_block
    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)

    # Write out commit message if desired
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        print >>f, 'Blocked revisions %s via %s' % (revs_to_block, NAME)
        if opts["commit-verbose"]:
            print >>f
            print >>f, construct_merged_log_message(opts["source-url"],
                                                    revs_to_block),

        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

def action_unblock(branch_dir, branch_props):
    """Unblock revisions."""
    # Check branch directory is ready for being modified
    check_dir_clean(branch_dir)

    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
    revs_to_unblock = blocked_revs

    # Limit to revisions specified by -r (if any)
    if opts["revision"]:
        revs_to_unblock = revs_to_unblock & RevisionSet(opts["revision"])

    if not revs_to_unblock:
        error('no available revisions to unblock')

    # Change blocked information
    blocked_revs = blocked_revs - revs_to_unblock
    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)

    # Write out commit message if desired
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        print >>f, 'Unblocked revisions %s via %s' % (revs_to_unblock, NAME)
        if opts["commit-verbose"]:
            print >>f
            print >>f, construct_merged_log_message(opts["source-url"],
                                                    revs_to_unblock),
        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

def action_rollback(branch_dir, branch_props):
    """Rollback previously integrated revisions."""

    # Make sure the revision arguments are present
    if not opts["revision"]:
        error("The '-r' option is mandatory for rollback")

    # Check branch directory is ready for being modified
    check_dir_clean(branch_dir)

    # Extract the integration info for the branch_dir
    branch_props = get_merge_props(branch_dir)
    check_old_prop_version(branch_dir, branch_props)
    # Get the list of all revisions already merged into this source-pathid.
    merged_revs = merge_props_to_revision_set(branch_props,
                                              opts["source-pathid"])

    # At which revision was the src created?
    oldest_src_rev = get_created_rev(opts["source-url"])
    src_pre_exist_range = RevisionSet("1-%d" % oldest_src_rev)

    # Limit to revisions specified by -r (if any)
    revs = merged_revs & RevisionSet(opts["revision"])

    # make sure there's some revision to rollback
    if not revs:
        report("Nothing to rollback in revision range r%s" % opts["revision"])
        return

    # If even one specified revision lies outside the lifetime of the
    # merge source, error out.
    if revs & src_pre_exist_range:
        err_str  = "Specified revision range falls out of the rollback range.\n"
        err_str += "%s was created at r%d" % (opts["source-pathid"],
                                              oldest_src_rev)
        error(err_str)

    record_only = opts["record-only"]

    if record_only:
        report('recording rollback of revision(s) %s from "%s"' %
               (revs, opts["source-url"]))
    else:
        report('rollback of revision(s) %s from "%s"' %
               (revs, opts["source-url"]))

    # Do the reverse merge(s). Note: the starting revision number
    # to 'svn merge' is NOT inclusive so we have to subtract one from start.
    # We try to keep the number of merge operations as low as possible,
    # because it is faster and reduces the number of conflicts.
    rollback_intervals = minimal_merge_intervals(revs, [])
    # rollback in the reverse order of merge
    rollback_intervals.reverse()
    for start, end in rollback_intervals:
        if not record_only:
            # Do the merge
            svn_command("merge --force -r %d:%d %s %s" % \
                        (end, start - 1, opts["source-url"], branch_dir))

    # Write out commit message if desired
    # calculate the phantom revs first
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        if record_only:
            print >>f, 'Recorded rollback of revisions %s via %s from ' % \
                  (revs , NAME)
        else:
            print >>f, 'Rolled back revisions %s via %s from ' % \
                  (revs , NAME)
        print >>f, '%s' % opts["source-url"]

        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

    # Update the set of merged revisions.
    merged_revs = merged_revs - revs
    branch_props[opts["source-pathid"]] = str(merged_revs)
    set_merge_props(branch_dir, branch_props)

def action_uninit(branch_dir, branch_props):
    """Uninit SOURCE URL."""
    # Check branch directory is ready for being modified
    check_dir_clean(branch_dir)

    # If the source-pathid does not have an entry in the svnmerge-integrated
    # property, simply error out.
    if not branch_props.has_key(opts["source-pathid"]):
        error('Repository-relative path "%s" does not contain merge '
              'tracking information for "%s"' \
                % (opts["source-pathid"], branch_dir))

    del branch_props[opts["source-pathid"]]

    # Set merge property with the selected source deleted
    set_merge_props(branch_dir, branch_props)

    # Set blocked revisions for the selected source to None
    set_blocked_revs(branch_dir, opts["source-pathid"], None)

    # Write out commit message if desired
    if opts["commit-file"]:
        f = open(opts["commit-file"], "w")
        print >>f, 'Removed merge tracking for "%s" for ' % NAME
        print >>f, '%s' % opts["source-url"]
        f.close()
        report('wrote commit message to "%s"' % opts["commit-file"])

###############################################################################
# Command line parsing -- options and commands management
###############################################################################

class OptBase:
    def __init__(self, *args, **kwargs):
        self.help = kwargs["help"]
        del kwargs["help"]
        self.lflags = []
        self.sflags = []
        for a in args:
            if a.startswith("--"):   self.lflags.append(a)
            elif a.startswith("-"):  self.sflags.append(a)
            else:
                raise TypeError, "invalid flag name: %s" % a
        if kwargs.has_key("dest"):
            self.dest = kwargs["dest"]
            del kwargs["dest"]
        else:
            if not self.lflags:
                raise TypeError, "cannot deduce dest name without long options"
            self.dest = self.lflags[0][2:]
        if kwargs:
            raise TypeError, "invalid keyword arguments: %r" % kwargs.keys()
    def repr_flags(self):
        f = self.sflags + self.lflags
        r = f[0]
        for fl in f[1:]:
            r += " [%s]" % fl
        return r

class Option(OptBase):
    def __init__(self, *args, **kwargs):
        self.default = kwargs.setdefault("default", 0)
        del kwargs["default"]
        self.value = kwargs.setdefault("value", None)
        del kwargs["value"]
        OptBase.__init__(self, *args, **kwargs)
    def apply(self, state, value):
        assert value == ""
        if self.value is not None:
            state[self.dest] = self.value
        else:
            state[self.dest] += 1

class OptionArg(OptBase):
    def __init__(self, *args, **kwargs):
        self.default = kwargs["default"]
        del kwargs["default"]
        self.metavar = kwargs.setdefault("metavar", None)
        del kwargs["metavar"]
        OptBase.__init__(self, *args, **kwargs)

        if self.metavar is None:
            if self.dest is not None:
                self.metavar = self.dest.upper()
            else:
                self.metavar = "arg"
        if self.default:
            self.help += " (default: %s)" % self.default
    def apply(self, state, value):
        assert value is not None
        state[self.dest] = value
    def repr_flags(self):
        r = OptBase.repr_flags(self)
        return r + " " + self.metavar

class CommandOpts:
    class Cmd:
        def __init__(self, *args):
            self.name, self.func, self.usage, self.help, self.opts = args
        def short_help(self):
            return self.help.split(".")[0]
        def __str__(self):
            return self.name
        def __call__(self, *args, **kwargs):
            return self.func(*args, **kwargs)

    def __init__(self, global_opts, common_opts, command_table, version=None):
        self.progname = NAME
        self.version = version.replace("%prog", self.progname)
        self.cwidth = console_width() - 2
        self.ctable = command_table.copy()
        self.gopts = global_opts[:]
        self.copts = common_opts[:]
        self._add_builtins()
        for k in self.ctable.keys():
            cmd = self.Cmd(k, *self.ctable[k])
            opts = []
            for o in cmd.opts:
                if isinstance(o, types.StringType) or \
                   isinstance(o, types.UnicodeType):
                    o = self._find_common(o)
                opts.append(o)
            cmd.opts = opts
            self.ctable[k] = cmd

    def _add_builtins(self):
        self.gopts.append(
            Option("-h", "--help", help="show help for this command and exit"))
        if self.version is not None:
            self.gopts.append(
                Option("-V", "--version", help="show version info and exit"))
        self.ctable["help"] = (self._cmd_help,
            "help [COMMAND]",
            "Display help for a specific command. If COMMAND is omitted, "
            "display brief command description.",
            [])

    def _cmd_help(self, cmd=None, *args):
        if args:
            self.error("wrong number of arguments", "help")
        if cmd is not None:
            cmd = self._command(cmd)
            self.print_command_help(cmd)
        else:
            self.print_command_list()

    def _paragraph(self, text, width=78):
        chunks = re.split("\s+", text.strip())
        chunks.reverse()
        lines = []
        while chunks:
            L = chunks.pop()
            while chunks and len(L) + len(chunks[-1]) + 1 <= width:
                L += " " + chunks.pop()
            lines.append(L)
        return lines

    def _paragraphs(self, text, *args, **kwargs):
        pars = text.split("\n\n")
        lines = self._paragraph(pars[0], *args, **kwargs)
        for p in pars[1:]:
            lines.append("")
            lines.extend(self._paragraph(p, *args, **kwargs))
        return lines

    def _print_wrapped(self, text, indent=0):
        text = self._paragraphs(text, self.cwidth - indent)
        print text.pop(0)
        for t in text:
            print " " * indent + t

    def _find_common(self, fl):
        for o in self.copts:
            if fl in o.lflags+o.sflags:
                return o
        assert False, fl

    def _compute_flags(self, opts, check_conflicts=True):
        back = {}
        sfl = ""
        lfl = []
        for o in opts:
            sapp = lapp = ""
            if isinstance(o, OptionArg):
                sapp, lapp = ":", "="
            for s in o.sflags:
                if check_conflicts and back.has_key(s):
                    raise RuntimeError, "option conflict: %s" % s
                back[s] = o
                sfl += s[1:] + sapp
            for l in o.lflags:
                if check_conflicts and back.has_key(l):
                    raise RuntimeError, "option conflict: %s" % l
                back[l] = o
                lfl.append(l[2:] + lapp)
        return sfl, lfl, back

    def _extract_command(self, args):
        """
        Try to extract the command name from the argument list. This is
        non-trivial because we want to allow command-specific options even
        before the command itself.
        """
        opts = self.gopts[:]
        for cmd in self.ctable.values():
            opts.extend(cmd.opts)
        sfl, lfl, _ = self._compute_flags(opts, check_conflicts=False)

        lopts,largs = getopt.getopt(args, sfl, lfl)
        if not largs:
            return None
        return self._command(largs[0])

    def _fancy_getopt(self, args, opts, state=None):
        if state is None:
            state= {}
        for o in opts:
            if not state.has_key(o.dest):
                state[o.dest] = o.default

        sfl, lfl, back = self._compute_flags(opts)
        try:
            lopts,args = getopt.gnu_getopt(args, sfl, lfl)
        except AttributeError:
            # Before Python 2.3, there was no gnu_getopt support.
            # So we can't parse intermixed positional arguments
            # and options.
            lopts,args = getopt.getopt(args, sfl, lfl)

        for o,v in lopts:
            back[o].apply(state, v)
        return state, args

    def _command(self, cmd):
        if not self.ctable.has_key(cmd):
            self.error("unknown command: '%s'" % cmd)
        return self.ctable[cmd]

    def parse(self, args):
        if not args:
            self.print_small_help()
            sys.exit(0)

        cmd = None
        try:
            cmd = self._extract_command(args)
            opts = self.gopts[:]
            if cmd:
                opts.extend(cmd.opts)
                args.remove(cmd.name)
            state, args = self._fancy_getopt(args, opts)
        except getopt.GetoptError, e:
            self.error(e, cmd)

        # Handle builtins
        if self.version is not None and state["version"]:
            self.print_version()
            sys.exit(0)
        if state["help"]: # special case for --help
            if cmd:
                self.print_command_help(cmd)
                sys.exit(0)
            cmd = self.ctable["help"]
        else:
            if cmd is None:
                self.error("command argument required")
        if str(cmd) == "help":
            cmd(*args)
            sys.exit(0)
        return cmd, args, state

    def error(self, s, cmd=None):
        print >>sys.stderr, "%s: %s" % (self.progname, s)
        if cmd is not None:
            self.print_command_help(cmd)
        else:
            self.print_small_help()
        sys.exit(1)
    def print_small_help(self):
        print "Type '%s help' for usage" % self.progname
    def print_usage_line(self):
        print "usage: %s <subcommand> [options...] [args...]\n" % self.progname
    def print_command_list(self):
        print "Available commands (use '%s help COMMAND' for more details):\n" \
              % self.progname
        cmds = self.ctable.keys()
        cmds.sort()
        indent = max(map(len, cmds))
        for c in cmds:
            h = self.ctable[c].short_help()
            print "  %-*s   " % (indent, c),
            self._print_wrapped(h, indent+6)
    def print_command_help(self, cmd):
        cmd = self.ctable[str(cmd)]
        print 'usage: %s %s\n' % (self.progname, cmd.usage)
        self._print_wrapped(cmd.help)
        def print_opts(opts, self=self):
            if not opts: return
            flags = [o.repr_flags() for o in opts]
            indent = max(map(len, flags))
            for f,o in zip(flags, opts):
                print "  %-*s :" % (indent, f),
                self._print_wrapped(o.help, indent+5)
        print '\nCommand options:'
        print_opts(cmd.opts)
        print '\nGlobal options:'
        print_opts(self.gopts)

    def print_version(self):
        print self.version

###############################################################################
# Options and Commands description
###############################################################################

global_opts = [
    Option("-F", "--force",
           help="force operation even if the working copy is not clean, or "
                "there are pending updates"),
    Option("-n", "--dry-run",
           help="don't actually change anything, just pretend; "
                "implies --show-changes"),
    Option("-s", "--show-changes",
           help="show subversion commands that make changes"),
    Option("-v", "--verbose",
           help="verbose mode: output more information about progress"),
    OptionArg("-u", "--username",
              default=None,
              help="invoke subversion commands with the supplied username"),
    OptionArg("-p", "--password",
              default=None,
              help="invoke subversion commands with the supplied password"),
]

common_opts = [
    Option("-b", "--bidirectional",
           value=True,
           default=False,
           help="remove reflected and initialized revisions from merge candidates"),
    OptionArg("-f", "--commit-file", metavar="FILE",
              default="svnmerge-commit-message.txt",
              help="set the name of the file where the suggested log message "
                   "is written to"),
    Option("-M", "--record-only",
           value=True,
           default=False,
           help="do not perform an actual merge of the changes, yet record "
                "that a merge happened"),
    OptionArg("-r", "--revision",
              metavar="REVLIST",
              default="",
              help="specify a revision list, consisting of revision numbers "
                   'and ranges separated by commas, e.g., "534,537-539,540"'),
    OptionArg("-S", "--source", "--head",
              default=None,
              help="specify a merge source for this branch.  It can be either "
                   "a path, a full URL, or an unambiguous substring of one "
                   "of the paths for which merge tracking was already "
                   "initialized.  Needed only to disambiguate in case of "
                   "multiple merge sources"),
]

command_table = {
    "init": (action_init,
    "init [OPTION...] [SOURCE]",
    """Initialize merge tracking from SOURCE on the current working
    directory.

    If SOURCE is specified, all the revisions in SOURCE are marked as already
    merged; if this is not correct, you can use --revision to specify the
    exact list of already-merged revisions.

    If SOURCE is omitted, then it is computed from the "svn cp" history of the
    current working directory (searching back for the branch point); in this
    case, %s assumes that no revision has been integrated yet since
    the branch point (unless you teach it with --revision).""" % NAME,
    [
        "-f", "-r", # import common opts
    ]),

    "avail": (action_avail,
    "avail [OPTION...] [PATH]",
    """Show unmerged revisions available for PATH as a revision list.
    If --revision is given, the revisions shown will be limited to those
    also specified in the option.

    When svnmerge is used to bidirectionally merge changes between a
    branch and its source, it is necessary to not merge the same changes
    forth and back: e.g., if you committed a merge of a certain
    revision of the branch into the source, you do not want that commit
    to appear as available to merged into the branch (as the code
    originated in the branch itself!).  svnmerge can not show these
    so-called "reflected" revisions if you specify the --bidirectional
    or -b command line option.""",
    [
        Option("-A", "--all",
               dest="avail-showwhat",
               value=["blocked", "avail"],
               default=["avail"],
               help="show both available and blocked revisions (aka ignore "
                    "blocked revisions)"),
        "-b",
        Option("-B", "--blocked",
               dest="avail-showwhat",
               value=["blocked"],
               help="show the blocked revision list (see '%s block')" % NAME),
        Option("-d", "--diff",
               dest="avail-display",
               value="diffs",
               default="revisions",
               help="show corresponding diff instead of revision list"),
        Option("--summarize",
               dest="avail-display",
               value="summarize",
               help="show summarized diff instead of revision list"),
        Option("-l", "--log",
               dest="avail-display",
               value="logs",
               help="show corresponding log history instead of revision list"),
        "-r",
        "-S",
    ]),

    "integrated": (action_integrated,
    "integrated [OPTION...] [PATH]",
    """Show merged revisions available for PATH as a revision list.
    If --revision is given, the revisions shown will be limited to
    those also specified in the option.""",
    [
        Option("-d", "--diff",
               dest="integrated-display",
               value="diffs",
               default="revisions",
               help="show corresponding diff instead of revision list"),
        Option("-l", "--log",
               dest="integrated-display",
               value="logs",
               help="show corresponding log history instead of revision list"),
        "-r",
        "-S",
    ]),

    "rollback": (action_rollback,
    "rollback [OPTION...] [PATH]",
    """Rollback previously merged in revisions from PATH.  The
    --revision option is mandatory, and specifies which revisions
    will be rolled back.  Only the previously integrated merges
    will be rolled back.

    When manually rolling back changes, --record-only can be used to
    instruct %s that a manual rollback of a certain revision
    already happened, so that it can record it and offer that
    revision for merge henceforth.""" % (NAME),
    [
        "-f", "-r", "-S", "-M", # import common opts
    ]),

    "merge": (action_merge,
    "merge [OPTION...] [PATH]",
    """Merge in revisions into PATH from its source. If --revision is omitted,
    all the available revisions will be merged. In any case, already merged-in
    revisions will NOT be merged again.

    When svnmerge is used to bidirectionally merge changes between a
    branch and its source, it is necessary to not merge the same changes
    forth and back: e.g., if you committed a merge of a certain
    revision of the branch into the source, you do not want that commit
    to appear as available to merged into the branch (as the code
    originated in the branch itself!).  svnmerge can skip these
    so-called "reflected" revisions if you specify the --bidirectional
    or -b command line option.

    When manually merging changes across branches, --record-only can
    be used to instruct %s that a manual merge of a certain revision
    already happened, so that it can record it and not offer that
    revision for merge anymore.  Conversely, when there are revisions
    which should not be merged, use '%s block'.""" % (NAME, NAME),
    [
        "-b", "-f", "-r", "-S", "-M", # import common opts
    ]),

    "block": (action_block,
    "block [OPTION...] [PATH]",
    """Block revisions within PATH so that they disappear from the available
    list. This is useful to hide revisions which will not be integrated.
    If --revision is omitted, it defaults to all the available revisions.

    Do not use this option to hide revisions that were manually merged
    into the branch.  Instead, use '%s merge --record-only', which
    records that a merge happened (as opposed to a merge which should
    not happen).""" % NAME,
    [
        "-f", "-r", "-S", # import common opts
    ]),

    "unblock": (action_unblock,
    "unblock [OPTION...] [PATH]",
    """Revert the effect of '%s block'. If --revision is omitted, all the
    blocked revisions are unblocked""" % NAME,
    [
        "-f", "-r", "-S", # import common opts
    ]),

    "uninit": (action_uninit,
    "uninit [OPTION...] [PATH]",
    """Remove merge tracking information from PATH. It cleans any kind of merge
    tracking information (including the list of blocked revisions). If there
    are multiple sources, use --source to indicate which source you want to
    forget about.""",
    [
        "-f", "-S", # import common opts
    ]),
}


def main(args):
    global opts

    # Initialize default options
    opts = default_opts.copy()
    logs.clear()

    optsparser = CommandOpts(global_opts, common_opts, command_table,
                             version="%%prog r%s\n  modified: %s\n\n"
                                     "Copyright (C) 2004,2005 Awarix Inc.\n"
                                     "Copyright (C) 2005, Giovanni Bajo"
                                     % (__revision__, __date__))

    cmd, args, state = optsparser.parse(args)
    opts.update(state)

    source = opts.get("source", None)
    branch_dir = "."

    if str(cmd) == "init":
        if len(args) == 1:
            source = args[0]
        elif len(args) > 1:
            optsparser.error("wrong number of parameters", cmd)
    elif str(cmd) in command_table.keys():
        if len(args) == 1:
            branch_dir = args[0]
        elif len(args) > 1:
            optsparser.error("wrong number of parameters", cmd)
    else:
        assert False, "command not handled: %s" % cmd

    # Validate branch_dir
    if not is_wc(branch_dir):
        error('"%s" is not a subversion working directory' % branch_dir)

    # Extract the integration info for the branch_dir
    branch_props = get_merge_props(branch_dir)
    check_old_prop_version(branch_dir, branch_props)

    # Calculate source_url and source_path
    report("calculate source path for the branch")
    if not source:
        if str(cmd) == "init":
            cf_source, cf_rev, copy_committed_in_rev = get_copyfrom(branch_dir)
            if not cf_source:
                error('no copyfrom info available. '
                      'Explicit source argument (-S/--source) required.')
            opts["source-pathid"] = cf_source
            if not opts["revision"]:
                opts["revision"] = "1-" + cf_rev
        else:
            opts["source-pathid"] = get_default_source(branch_dir, branch_props)

        # (assumes pathid is a repository-relative-path)
        assert opts["source-pathid"][0] == '/'
        opts["source-url"] = get_repo_root(branch_dir) + opts["source-pathid"]
    else:
        # The source was given as a command line argument and is stored in
        # SOURCE.  Ensure that the specified source does not end in a /,
        # otherwise it's easy to have the same source path listed more
        # than once in the integrated version properties, with and without
        # trailing /'s.
        source = rstrip(source, "/")
        if not is_wc(source) and not is_url(source):
            # Check if it is a substring of a pathid recorded
            # within the branch properties.
            found = []
            for pathid in branch_props.keys():
                if pathid.find(source) > 0:
                    found.append(pathid)
            if len(found) == 1:
                # (assumes pathid is a repository-relative-path)
                source = get_repo_root(branch_dir) + found[0]
            else:
                error('"%s" is neither a valid URL, nor an unambiguous '
                      'substring of a repository path, nor a working directory'
                      % source)

        source_pathid = target_to_pathid(source)
        if str(cmd) == "init" and \
               source_pathid == target_to_pathid("."):
            error("cannot init integration source path '%s'\n"
                  "Its repository-relative path must differ from the "
                  "repository-relative path of the current directory."
                  % source_pathid)
        opts["source-pathid"] = source_pathid
        opts["source-url"] = target_to_url(source)

    # Sanity check source_url
    assert is_url(opts["source-url"])
    # SVN does not support non-normalized URL (and we should not
    # have created them)
    assert opts["source-url"].find("/..") < 0

    report('source is "%s"' % opts["source-url"])

    # Get previously merged revisions (except when command is init)
    if str(cmd) != "init":
        opts["merged-revs"] = merge_props_to_revision_set(branch_props,
                                                          opts["source-pathid"])

    # Perform the action
    cmd(branch_dir, branch_props)


if __name__ == "__main__":
    try:
        main(sys.argv[1:])
    except LaunchError, (ret, cmd, out):
        err_msg = "command execution failed (exit code: %d)\n" % ret
        err_msg += cmd + "\n"
        err_msg += "".join(out)
        error(err_msg)
    except KeyboardInterrupt:
        # Avoid traceback on CTRL+C
        print "aborted by user"
        sys.exit(1)
