#!/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
#   Dustin J. Mitchell <dustin at zmanda dot com> - support for multiple
#     location identifier formats
#
# $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.
# - Can use a variety of location-identifier formats
#
# 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, locale
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 * ' '

# Set python to the default locale as per environment settings, same as svn
# TODO we should really parse config and if log-encoding is specified, set
# the locale to match that encoding
locale.setlocale(locale.LC_ALL, '')

# We want the svn output (such as svn info) to be non-localized
# Using LC_MESSAGES should not affect localized output of svn log, for example
if os.environ.has_key("LC_ALL"):
    del os.environ["LC_ALL"]
os.environ["LC_MESSAGES"] = "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,
    "verbose": 0,
}
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
    if os.isatty(1):
        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."""
    sys.stderr.write("%s: %s\n" % (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"

def recode_stdout_to_file(s):
    if locale.getdefaultlocale()[1] is None or not hasattr(sys.stdout, "encoding") \
            or sys.stdout.encoding is None:
        return s
    u = s.decode(sys.stdout.encoding)
    return u.encode(locale.getdefaultlocale()[1])

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 as 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']:
            import popen2
            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 = password = configdir = ""
    if opts.get("username", None):
        username = "--username=" + opts["username"]
    if opts.get("password", None):
        password = "--password=" + opts["password"]
    if opts.get("config-dir", None):
        configdir = "--config-dir=" + opts["config-dir"]
    cmd = ' '.join(filter(None, [opts["svn"], "--non-interactive",
                                 username, password, configdir, 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. (Lines starting
    # with "X" must be skipped, since they just indicate externals.)
    out = launchsvn("status -q %s" % dir)
    while out and out[0].strip():
        if not out[0].startswith("X"):
            error('"%s" has local modifications; it must be clean' % dir)
        out.pop(0)

class PathIdentifier:
    """Abstraction for a path identifier, so that we can start talking
    about it before we know the form that it takes in the properties (its
    external_form).  Objects are referenced in the class variable 'locobjs',
    keyed by all known forms."""

    # a map of UUID (or None) to repository root URL.
    repo_hints = {}

    # a map from any known string form to the corresponding PathIdentifier
    locobjs = {}

    def __init__(self, repo_relative_path, uuid=None, url=None, external_form=None):
        self.repo_relative_path = repo_relative_path
        self.uuid = uuid
        self.url = url
        self.external_form = external_form

    def __repr__(self):
        return "<PathIdentifier " + ', '.join(['%s=%r' % i for i in self.__dict__.items()]) + '>'

    def __str__(self):
        """Return a printable string representation"""
        if self.external_form:
            return self.external_form
        if self.url:
            return self.format('url')
        if self.uuid:
            return self.format('uuid')
        return self.format('path')

    def from_pathid(pathid_str):
        """convert pathid_str to a PathIdentifier"""
        if not PathIdentifier.locobjs.has_key(pathid_str):
            if is_url(pathid_str):
                # we can determine every form; PathIdentifier.hint knows how to do that
                PathIdentifier.hint(pathid_str)
            elif pathid_str[:7] == 'uuid://':
                mo = re.match('uuid://([^/]*)(.*)', pathid_str)
                if not mo:
                    error("Invalid path identifier '%s'" % pathid_str)
                uuid, repo_relative_path = mo.groups()
                pathid = PathIdentifier(repo_relative_path, uuid=uuid)
                # we can cache this by uuid:// pathid and by repo-relative path
                PathIdentifier.locobjs[pathid_str] = PathIdentifier.locobjs[repo_relative_path] = pathid
            elif pathid_str and pathid_str[0] == '/':
                # strip any trailing slashes
                pathid_str = pathid_str.rstrip('/')
                pathid = PathIdentifier(repo_relative_path=pathid_str)
                # we can only cache this by repo-relative path
                PathIdentifier.locobjs[pathid_str] = pathid
            else:
                if not opts["ignore-invalid-entries"]:
                    error("Invalid path identifier '%s'" % pathid_str)
        if PathIdentifier.locobjs.has_key(pathid_str):
            return PathIdentifier.locobjs[pathid_str]
        return None
    from_pathid = staticmethod(from_pathid)

    def from_target(target):
        """Convert a target (either a working copy path or an URL) into a
        path identifier."""
        # prime the cache first if we don't know about this target yet
        if not PathIdentifier.locobjs.has_key(target):
            PathIdentifier.hint(target)

        try:
            return PathIdentifier.locobjs[target]
        except KeyError:
            error("Could not recognize path identifier '%s'" % target)
    from_target = staticmethod(from_target)

    def hint(target):
        """Cache some information about target, as it may be referenced by
        repo-relative path in subversion properties; the cache can help to
        expand such a relative path to a full path identifier."""
        if PathIdentifier.locobjs.has_key(target): return
        if not is_url(target) and not is_wc(target): return

        url = target_to_url(target)

        root = get_repo_root(url)
        assert root[-1] != "/"
        assert url[:len(root)] == root, "url=%r, root=%r" % (url, root)
        repo_relative_path = url[len(root):]

        try:
            uuid = get_svninfo(target)['Repository UUID']
            uuid_pathid = 'uuid://%s%s' % (uuid, repo_relative_path)
        except KeyError:
            uuid = None
            uuid_pathid = None

        locobj = PathIdentifier.locobjs.get(url) or \
                 (uuid_pathid and PathIdentifier.locobjs.get(uuid_pathid))
        if not locobj:
            locobj = PathIdentifier(repo_relative_path, uuid=uuid, url=url)

        PathIdentifier.repo_hints[uuid] = root # (uuid may be None)

        PathIdentifier.locobjs[target] = locobj
        PathIdentifier.locobjs[url] = locobj
        if uuid_pathid:
            PathIdentifier.locobjs[uuid_pathid] = locobj
        if not PathIdentifier.locobjs.has_key(repo_relative_path):
            PathIdentifier.locobjs[repo_relative_path] = locobj
    hint = staticmethod(hint)

    def format(self, fmt):
        if fmt == 'path':
            return self.repo_relative_path
        elif fmt == 'uuid':
            return "uuid://%s%s" % (self.uuid, self.repo_relative_path)
        elif fmt == 'url':
            return self.url
        else:
            error("Unkonwn path type '%s'" % fmt)

    def match_substring(self, str):
        """Test whether str is a substring of any representation of this
        PathIdentifier."""
        if self.repo_relative_path.find(str) >= 0:
            return True

        if self.uuid:
            if ("uuid://%s%s" % (self.uuid, self.repo_relative_path)).find(str) >= 0:
                return True

        if self.url:
            if (self.url + self.repo_relative_path).find(str) >= 0:
                return True

        return False

    def get_url(self):
        """Convert a pathid into a URL.  If this is not possible, error out."""
        if self.url:
            return self.url
        # if we have a uuid and happen to know the URL for it, use that
        elif self.uuid and PathIdentifier.repo_hints.has_key(self.uuid):
            self.url = PathIdentifier.repo_hints[self.uuid] + self.repo_relative_path
            PathIdentifier.locobjs[self.url] = self
            return self.url
        # if we've only seen one rep, use that (a guess, but an educated one)
        elif not self.uuid and len(PathIdentifier.repo_hints) == 1:
            uuid, root = PathIdentifier.repo_hints.items()[0]
            if uuid:
                self.uuid = uuid
                PathIdentifier.locobjs['uuid://%s%s' % (uuid, self.repo_relative_path)] = self
            self.url = root + self.repo_relative_path
            PathIdentifier.locobjs[self.url] = self
            report("Guessing that '%s' refers to '%s'" % (self, self.url))
            return self.url
        else:
            error("Cannot determine URL for '%s'; " % self +
                  "Explicit source argument (-S/--source) required.\n")

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 = PathIdentifier.from_target(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.repo_relative_path:
                    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(lstrip(rev_or_revs[0], 'r'))] = 1
                    elif len(rev_or_revs) == 2:
                        for rev in range(int(lstrip(rev_or_revs[0], 'r')),
                                         int(lstrip(rev_or_revs[1], 'r'))+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.
        pathid_str, revs = rsplit(L.strip(), ":", 1)

        pathid = PathIdentifier.from_pathid(pathid_str)

        # cache the "external" form we saw
        if pathid:
            pathid.external_form = pathid_str
            prop[pathid] = 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("%s:%s" % (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:
        # Check if NAME exists on DIR before trying to delete it.
        # As of 1.6 propdel no longer supports deleting a
        # non-existent property.
        out = launchsvn('propget "%s" "%s"' % (name, dir))
        if out:
            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 looks like a valid url."""
    return re.search(r"^[a-zA-Z][-+\.\w]*://[^\s]+$", url) is not None and url[:4] != 'uuid'

def check_url(url):
    """Similar to is_url, but actually invoke get_svninfo to find out"""
    return get_svninfo(url) != {}

def is_pathid(pathid):
    return isinstance(pathid, PathIdentifier)

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)
        # info may be {}, in which case we'll see KeyError here
        root = info["Repository Root"]
        _cache_reporoot[root] = None
        return root
    except (KeyError, 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 rstrip(url, "/")
        url = temp

    error("svn repos root of %s not found" % target)

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 int(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
    repository-relative path 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 = PathIdentifier.from_target(target).repo_relative_path
    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:
        info = get_svninfo(url)
        if not info.has_key("Revision"):
            error("Not a valid URL: %s" % url)
        return info["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 recode_stdout_to_file("".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 = PathIdentifier.from_target(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  " + str(prop)
        error(err_msg)

    return props.keys()[0]

def should_find_reflected(branch_dir):
    should_find_reflected = opts["bidirectional"]

    # If the source has integration info for the target, set find_reflected
    # even if --bidirectional wasn't specified
    if not should_find_reflected:
        source_props = get_merge_props(opts["source-url"])
        should_find_reflected = source_props.has_key(PathIdentifier.from_target(branch_dir))

    return should_find_reflected

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 = PathIdentifier.from_target(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)

    target_pathid = PathIdentifier.from_target(target_dir)
    source_pathid = opts['source-pathid']
    if source_pathid == target_pathid:
        error("cannot init integration source path '%s'\nIts path identifier does not "
              "differ from the path identifier of the current directory, '%s'."
              % (source_pathid, target_pathid))

    source_url = opts['source-url']

    # 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:
        # If source was originally copied 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:
        cf_source, cf_rev, copy_committed_in_rev = get_copyfrom(source_url)

        cf_pathid = None
        if cf_source:
            cf_url = get_repo_root(source_url) + cf_source
            if is_url(cf_url) and check_url(cf_url):
                cf_pathid = PathIdentifier.from_target(cf_url)

        if target_pathid == cf_pathid:
            report('the source "%s" was copied from "%s" in rev %s and committed in rev %s' %
                   (source_url, target_dir, cf_rev, copy_committed_in_rev))
            revision_range = "1-" + str(copy_committed_in_rev)

    if not revision_range:
        # If the reverse is true: 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 at:
        # https://issues.apache.org/jira/browse/SVN-2810  )
        cf_source, cf_rev, copy_committed_in_rev = get_copyfrom(target_dir)

        cf_pathid = None
        if cf_source:
            cf_url = get_repo_root(target_dir) + cf_source
            if is_url(cf_url) and check_url(cf_url):
                cf_pathid = PathIdentifier.from_target(cf_url)

        source_pathid = PathIdentifier.from_target(source_url)
        if source_pathid == cf_pathid:
            report('the target "%s" was copied the source "%s" in rev %s and committed in rev %s' %
                   (target_dir, source_url, cf_rev, copy_committed_in_rev))
            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).
    if not revision_range:
        revision_range = "1-" + get_latest_rev(source_url)

    revs = RevisionSet(revision_range)

    report('marking "%s" as already containing revisions "%s" of "%s"' %
           (target_dir, revs, 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(source_pathid):
        error('Repository-relative path %s has already been initialized at %s\n'
              'Use --force to re-initialize' % (source_pathid, target_dir))
    # set the pathid's external_form based on the user's options
    source_pathid.external_form = source_pathid.format(opts['location-type'])

    revs = str(revs)
    target_props[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")
        f.write('Initialized merge tracking via "%s" with revisions "%s" from \n' \
            % (NAME, revs))
        f.write('%s\n' % 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=
                                       should_find_reflected(branch_dir))
    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)
    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=
                                       should_find_reflected(branch_dir))

    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:
            f.write('Recorded merge of revisions %s via %s from \n' % \
                    (revs, NAME))
        else:
            f.write('Merged revisions %s via %s from \n' % \
                    (revs, NAME))
        f.write('%s\n' % opts["source-url"])
        if opts["commit-verbose"]:
            f.write("\n")
            f.write(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")
        f.write('Blocked revisions %s via %s\n' % (revs_to_block, NAME))
        if opts["commit-verbose"]:
            f.write("\n")
            f.write(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")
        f.write('Unblocked revisions %s via %s\n' % (revs_to_unblock, NAME))
        if opts["commit-verbose"]:
            f.write("\n")
            f.write(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)
    # 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:
            f.write('Recorded rollback of revisions %s via %s from \n' % \
                    (revs , NAME))
        else:
            f.write('Rolled back revisions %s via %s from \n' % \
                    (revs , NAME))
        f.write('%s\n' % 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")
        f.write('Removed merge tracking for "%s" for \n' % NAME)
        f.write('%s\n' % 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 as 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):
        sys.stderr.write("%s: %s\n" % (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()
            sys.stdout.write("  %-*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):
                sys.stdout.write("  %-*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("-i", "--ignore-invalid-entries",
           help="ignore invalid svnmerge indexes"),
    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"),
    OptionArg("-c", "--config-dir", metavar="DIR",
              default=None,
              help="cause subversion commands to consult runtime config directory DIR"),
]

common_opts = [
    Option("-b", "--bidirectional",
           value=True,
           default=False,
           help="remove reflected and initialized revisions from merge candidates.  "
                "Not required but may be specified to speed things up slightly"),
    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 working directory path, a full URL, or an unambiguous "
                   "substring of one of the locations 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
        OptionArg("-L", "--location-type",
               dest="location-type",
               default="path",
               help="Use this type of location identifier in the new " +
                    "Subversion properties; 'uuid', 'url', or 'path' " +
                    "(default)"),
    ]),

    "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 will automatically
    exclude these so-called "reflected" revisions.""",
    [
        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 will automatically
    exclude these so-called "reflected" revisions.

    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):
        if str(cmd) == "avail":
            info = None
            # it should be noted here that svn info does not error exit
            # if an invalid target is specified to it (as is
            # intuitive). so the try, except code is not absolutely
            # necessary. but, I retain it to indicate the intuitive
            # handling.
            try:
                info = get_svninfo(branch_dir)
            except LaunchError:
                pass
            # test that we definitely targeted a subversion directory,
            # mirroring the purpose of the earlier is_wc() call
            if info is None or not info.has_key("Node Kind") or info["Node Kind"] != "directory":
                error('"%s" is neither a valid URL, nor a working directory' % branch_dir)
        else:
            error('"%s" is not a subversion working directory' % branch_dir)

    # give out some hints as to potential pathids
    PathIdentifier.hint(branch_dir)
    if source: PathIdentifier.hint(source)

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

    # 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-url"] = get_repo_root(branch_dir) + cf_source
            opts["source-pathid"] = PathIdentifier.from_target(opts["source-url"])

            if not opts["revision"]:
                opts["revision"] = "1-" + cf_rev
        else:
            opts["source-pathid"] = get_default_source(branch_dir, branch_props)
            opts["source-url"] = opts["source-pathid"].get_url()

        assert is_pathid(opts["source-pathid"])
        assert is_url(opts["source-url"])
    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.match_substring(source):
                    found.append(pathid)
            if len(found) == 1:
                # (assumes pathid is a repository-relative-path)
                source_pathid = found[0]
                source = source_pathid.get_url()
            else:
                error('"%s" is neither a valid URL, nor an unambiguous '
                      'substring of a repository path, nor a working directory'
                      % source)
        else:
            source_pathid = PathIdentifier.from_target(source)

        source_pathid = PathIdentifier.from_target(source)
        if str(cmd) == "init" and \
               source_pathid == PathIdentifier.from_target("."):
            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 as (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)
