thirdparty/svnmerge/svnmerge.py
author Pawel Solyga <Pawel.Solyga@gmail.com>
Sat, 22 Nov 2008 18:16:42 +0000
changeset 559 44e50e92621e
parent 107 ead919546298
permissions -rwxr-xr-x
Fix names of methods in soc.views.model.site. Patch by: Pawel Solyga
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
64
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     1
#!/usr/bin/env python
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     3
# Copyright (c) 2005, Giovanni Bajo
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     4
# Copyright (c) 2004-2005, Awarix, Inc.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     5
# All rights reserved.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     6
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     7
# This program is free software; you can redistribute it and/or
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     8
# modify it under the terms of the GNU General Public License
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     9
# as published by the Free Software Foundation; either version 2
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    10
# of the License, or (at your option) any later version.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    11
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    12
# This program is distributed in the hope that it will be useful,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    15
# GNU General Public License for more details.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    16
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    17
# You should have received a copy of the GNU General Public License
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    18
# along with this program; if not, write to the Free Software
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    19
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    20
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    21
# Author: Archie Cobbs <archie at awarix dot com>
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    22
# Rewritten in Python by: Giovanni Bajo <rasky at develer dot com>
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    23
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    24
# Acknowledgments:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    25
#   John Belmonte <john at neggie dot net> - metadata and usability
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    26
#     improvements
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    27
#   Blair Zajac <blair at orcaware dot com> - random improvements
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    28
#   Raman Gupta <rocketraman at fastmail dot fm> - bidirectional and transitive
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    29
#     merging support
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    30
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    31
# $HeadURL$
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    32
# $LastChangedDate$
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    33
# $LastChangedBy$
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    34
# $LastChangedRevision$
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    35
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    36
# Requisites:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    37
# svnmerge.py has been tested with all SVN major versions since 1.1 (both
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    38
# client and server). It is unknown if it works with previous versions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    39
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    40
# Differences from svnmerge.sh:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    41
# - More portable: tested as working in FreeBSD and OS/2.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    42
# - Add double-verbose mode, which shows every svn command executed (-v -v).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    43
# - "svnmerge avail" now only shows commits in source, not also commits in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    44
#   other parts of the repository.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    45
# - Add "svnmerge block" to flag some revisions as blocked, so that
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    46
#   they will not show up anymore in the available list.  Added also
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    47
#   the complementary "svnmerge unblock".
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    48
# - "svnmerge avail" has grown two new options:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    49
#   -B to display a list of the blocked revisions
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    50
#   -A to display both the blocked and the available revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    51
# - Improved generated commit message to make it machine parsable even when
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    52
#   merging commits which are themselves merges.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    53
# - Add --force option to skip working copy check
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    54
# - Add --record-only option to "svnmerge merge" to avoid performing
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    55
#   an actual merge, yet record that a merge happened.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    56
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    57
# TODO:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    58
#  - Add "svnmerge avail -R": show logs in reverse order
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    59
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    60
# Information for Hackers:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    61
#
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    62
# Identifiers for branches:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    63
#  A branch is identified in three ways within this source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    64
#  - as a working copy (variable name usually includes 'dir')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    65
#  - as a fully qualified URL
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    66
#  - as a path identifier (an opaque string indicating a particular path
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    67
#    in a particular repository; variable name includes 'pathid')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    68
#  A "target" is generally user-specified, and may be a working copy or
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    69
#  a URL.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    70
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    71
import sys, os, getopt, re, types, tempfile, time, popen2, locale
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    72
from bisect import bisect
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    73
from xml.dom import pulldom
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    74
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    75
NAME = "svnmerge"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    76
if not hasattr(sys, "version_info") or sys.version_info < (2, 0):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    77
    error("requires Python 2.0 or newer")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    78
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    79
# Set up the separator used to separate individual log messages from
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    80
# each revision merged into the target location.  Also, create a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    81
# regular expression that will find this same separator in already
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    82
# committed log messages, so that the separator used for this run of
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    83
# svnmerge.py will have one more LOG_SEPARATOR appended to the longest
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    84
# separator found in all the commits.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    85
LOG_SEPARATOR = 8 * '.'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    86
LOG_SEPARATOR_RE = re.compile('^((%s)+)' % re.escape(LOG_SEPARATOR),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    87
                              re.MULTILINE)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    88
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    89
# Each line of the embedded log messages will be prefixed by LOG_LINE_PREFIX.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    90
LOG_LINE_PREFIX = 2 * ' '
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    91
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    92
# Set python to the default locale as per environment settings, same as svn
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    93
# TODO we should really parse config and if log-encoding is specified, set
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    94
# the locale to match that encoding
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    95
locale.setlocale(locale.LC_ALL, '')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    96
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    97
# We want the svn output (such as svn info) to be non-localized
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    98
# Using LC_MESSAGES should not affect localized output of svn log, for example
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    99
if os.environ.has_key("LC_ALL"):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   100
    del os.environ["LC_ALL"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   101
os.environ["LC_MESSAGES"] = "C"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   102
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   103
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   104
# Support for older Python versions
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   105
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   106
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   107
# True/False constants are Python 2.2+
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   108
try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   109
    True, False
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   110
except NameError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   111
    True, False = 1, 0
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   112
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   113
def lstrip(s, ch):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   114
    """Replacement for str.lstrip (support for arbitrary chars to strip was
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   115
    added in Python 2.2.2)."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   116
    i = 0
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   117
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   118
        while s[i] == ch:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   119
            i = i+1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   120
        return s[i:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   121
    except IndexError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   122
        return ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   123
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   124
def rstrip(s, ch):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   125
    """Replacement for str.rstrip (support for arbitrary chars to strip was
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   126
    added in Python 2.2.2)."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   127
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   128
        if s[-1] != ch:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   129
            return s
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   130
        i = -2
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   131
        while s[i] == ch:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   132
            i = i-1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   133
        return s[:i+1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   134
    except IndexError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   135
        return ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   136
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   137
def strip(s, ch):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   138
    """Replacement for str.strip (support for arbitrary chars to strip was
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   139
    added in Python 2.2.2)."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   140
    return lstrip(rstrip(s, ch), ch)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   141
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   142
def rsplit(s, sep, maxsplits=0):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   143
    """Like str.rsplit, which is Python 2.4+ only."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   144
    L = s.split(sep)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   145
    if not 0 < maxsplits <= len(L):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   146
        return L
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   147
    return [sep.join(L[0:-maxsplits])] + L[-maxsplits:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   148
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   149
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   150
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   151
def kwextract(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   152
    """Extract info from a svn keyword string."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   153
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   154
        return strip(s, "$").strip().split(": ")[1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   155
    except IndexError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   156
        return "<unknown>"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   157
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   158
__revision__ = kwextract('$Rev$')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   159
__date__ = kwextract('$Date$')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   160
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   161
# Additional options, not (yet?) mapped to command line flags
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   162
default_opts = {
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   163
    "svn": "svn",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   164
    "prop": NAME + "-integrated",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   165
    "block-prop": NAME + "-blocked",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   166
    "commit-verbose": True,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   167
}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   168
logs = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   169
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   170
def console_width():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   171
    """Get the width of the console screen (if any)."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   172
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   173
        return int(os.environ["COLUMNS"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   174
    except (KeyError, ValueError):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   175
        pass
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   176
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   177
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   178
        # Call the Windows API (requires ctypes library)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   179
        from ctypes import windll, create_string_buffer
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   180
        h = windll.kernel32.GetStdHandle(-11)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   181
        csbi = create_string_buffer(22)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   182
        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   183
        if res:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   184
            import struct
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   185
            (bufx, bufy,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   186
             curx, cury, wattr,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   187
             left, top, right, bottom,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   188
             maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   189
            return right - left + 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   190
    except ImportError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   191
        pass
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   192
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   193
    # Parse the output of stty -a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   194
    out = os.popen("stty -a").read()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   195
    m = re.search(r"columns (\d+);", out)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   196
    if m:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   197
        return int(m.group(1))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   198
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   199
    # sensible default
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   200
    return 80
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   201
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   202
def error(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   203
    """Subroutine to output an error and bail."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   204
    print >> sys.stderr, "%s: %s" % (NAME, s)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   205
    sys.exit(1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   206
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   207
def report(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   208
    """Subroutine to output progress message, unless in quiet mode."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   209
    if opts["verbose"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   210
        print "%s: %s" % (NAME, s)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   211
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   212
def prefix_lines(prefix, lines):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   213
    """Given a string representing one or more lines of text, insert the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   214
    specified prefix at the beginning of each line, and return the result.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   215
    The input must be terminated by a newline."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   216
    assert lines[-1] == "\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   217
    return prefix + lines[:-1].replace("\n", "\n"+prefix) + "\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   218
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   219
def recode_stdout_to_file(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   220
    if locale.getdefaultlocale()[1] is None or not hasattr(sys.stdout, "encoding") \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   221
            or sys.stdout.encoding is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   222
        return s
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   223
    u = s.decode(sys.stdout.encoding)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   224
    return u.encode(locale.getdefaultlocale()[1])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   225
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   226
class LaunchError(Exception):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   227
    """Signal a failure in execution of an external command. Parameters are the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   228
    exit code of the process, the original command line, and the output of the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   229
    command."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   230
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   231
try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   232
    """Launch a sub-process. Return its output (both stdout and stderr),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   233
    optionally split by lines (if split_lines is True). Raise a LaunchError
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   234
    exception if the exit code of the process is non-zero (failure).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   235
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   236
    This function has two implementations, one based on subprocess (preferred),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   237
    and one based on popen (for compatibility).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   238
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   239
    import subprocess
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   240
    import shlex
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   241
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   242
    def launch(cmd, split_lines=True):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   243
        # Requiring python 2.4 or higher, on some platforms we get
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   244
        # much faster performance from the subprocess module (where python
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   245
        # doesn't try to close an exhorbitant number of file descriptors)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   246
        stdout = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   247
        stderr = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   248
        try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   249
            if os.name == 'nt':
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   250
                p = subprocess.Popen(cmd, stdout=subprocess.PIPE, \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   251
                                     close_fds=False, stderr=subprocess.PIPE)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   252
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   253
                # Use shlex to break up the parameters intelligently,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   254
                # respecting quotes. shlex can't handle unicode.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   255
                args = shlex.split(cmd.encode('ascii'))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   256
                p = subprocess.Popen(args, stdout=subprocess.PIPE, \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   257
                                     close_fds=False, stderr=subprocess.PIPE)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   258
            stdoutAndErr = p.communicate()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   259
            stdout = stdoutAndErr[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   260
            stderr = stdoutAndErr[1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   261
        except OSError, inst:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   262
            # Using 1 as failure code; should get actual number somehow? For
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   263
            # examples see svnmerge_test.py's TestCase_launch.test_failure and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   264
            # TestCase_launch.test_failurecode.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   265
            raise LaunchError(1, cmd, stdout + " " + stderr + ": " + str(inst))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   266
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   267
        if p.returncode == 0:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   268
            if split_lines:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   269
                # Setting keepends=True for compatibility with previous logic
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   270
                # (where file.readlines() preserves newlines)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   271
                return stdout.splitlines(True)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   272
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   273
                return stdout
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   274
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   275
            raise LaunchError(p.returncode, cmd, stdout + stderr)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   276
except ImportError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   277
    # support versions of python before 2.4 (slower on some systems)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   278
    def launch(cmd, split_lines=True):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   279
        if os.name not in ['nt', 'os2']:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   280
            p = popen2.Popen4(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   281
            p.tochild.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   282
            if split_lines:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   283
                out = p.fromchild.readlines()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   284
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   285
                out = p.fromchild.read()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   286
            ret = p.wait()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   287
            if ret == 0:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   288
                ret = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   289
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   290
                ret >>= 8
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   291
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   292
            i,k = os.popen4(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   293
            i.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   294
            if split_lines:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   295
                out = k.readlines()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   296
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   297
                out = k.read()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   298
            ret = k.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   299
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   300
        if ret is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   301
            return out
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   302
        raise LaunchError(ret, cmd, out)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   303
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   304
def launchsvn(s, show=False, pretend=False, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   305
    """Launch SVN and grab its output."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   306
    username = opts.get("username", None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   307
    password = opts.get("password", None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   308
    if username:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   309
        username = " --username=" + username
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   310
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   311
        username = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   312
    if password:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   313
        password = " --password=" + password
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   314
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   315
        password = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   316
    cmd = opts["svn"] + " --non-interactive" + username + password + " " + s
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   317
    if show or opts["verbose"] >= 2:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   318
        print cmd
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   319
    if pretend:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   320
        return None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   321
    return launch(cmd, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   322
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   323
def svn_command(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   324
    """Do (or pretend to do) an SVN command."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   325
    out = launchsvn(s, show=opts["show-changes"] or opts["dry-run"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   326
                    pretend=opts["dry-run"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   327
                    split_lines=False)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   328
    if not opts["dry-run"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   329
        print out
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   330
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   331
def check_dir_clean(dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   332
    """Check the current status of dir for local mods."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   333
    if opts["force"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   334
        report('skipping status check because of --force')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   335
        return
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   336
    report('checking status of "%s"' % dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   337
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   338
    # Checking with -q does not show unversioned files or external
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   339
    # directories.  Though it displays a debug message for external
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   340
    # directories, after a blank line.  So, practically, the first line
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   341
    # matters: if it's non-empty there is a modification.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   342
    out = launchsvn("status -q %s" % dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   343
    if out and out[0].strip():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   344
        error('"%s" has local modifications; it must be clean' % dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   345
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   346
class RevisionLog:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   347
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   348
    A log of the revisions which affected a given URL between two
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   349
    revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   350
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   351
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   352
    def __init__(self, url, begin, end, find_propchanges=False):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   353
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   354
        Create a new RevisionLog object, which stores, in self.revs, a list
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   355
        of the revisions which affected the specified URL between begin and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   356
        end. If find_propchanges is True, self.propchange_revs will contain a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   357
        list of the revisions which changed properties directly on the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   358
        specified URL. URL must be the URL for a directory in the repository.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   359
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   360
        self.url = url
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   361
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   362
        # Setup the log options (--quiet, so we don't show log messages)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   363
        log_opts = '--xml --quiet -r%s:%s "%s"' % (begin, end, url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   364
        if find_propchanges:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   365
            # The --verbose flag lets us grab merge tracking information
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   366
            # by looking at propchanges
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   367
            log_opts = "--verbose " + log_opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   368
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   369
        # Read the log to look for revision numbers and merge-tracking info
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   370
        self.revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   371
        self.propchange_revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   372
        repos_pathid = target_to_pathid(url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   373
        for chg in SvnLogParser(launchsvn("log %s" % log_opts,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   374
                                          split_lines=False)):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   375
            self.revs.append(chg.revision())
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   376
            for p in chg.paths():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   377
                if p.action() == 'M' and p.pathid() == repos_pathid:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   378
                    self.propchange_revs.append(chg.revision())
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   379
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   380
        # Save the range of the log
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   381
        self.begin = int(begin)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   382
        if end == "HEAD":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   383
            # If end is not provided, we do not know which is the latest
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   384
            # revision in the repository. So we set 'end' to the latest
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   385
            # known revision.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   386
            self.end = self.revs[-1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   387
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   388
            self.end = int(end)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   389
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   390
        self._merges = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   391
        self._blocks = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   392
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   393
    def merge_metadata(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   394
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   395
        Return a VersionedProperty object, with a cached view of the merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   396
        metadata in the range of this log.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   397
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   398
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   399
        # Load merge metadata if necessary
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   400
        if not self._merges:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   401
            self._merges = VersionedProperty(self.url, opts["prop"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   402
            self._merges.load(self)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   403
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   404
        return self._merges
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   405
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   406
    def block_metadata(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   407
        if not self._blocks:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   408
            self._blocks = VersionedProperty(self.url, opts["block-prop"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   409
            self._blocks.load(self)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   410
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   411
        return self._blocks
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   412
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   413
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   414
class VersionedProperty:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   415
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   416
    A read-only, cached view of a versioned property.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   417
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   418
    self.revs contains a list of the revisions in which the property changes.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   419
    self.values stores the new values at each corresponding revision. If the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   420
    value of the property is unknown, it is set to None.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   421
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   422
    Initially, we set self.revs to [0] and self.values to [None]. This
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   423
    indicates that, as of revision zero, we know nothing about the value of
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   424
    the property.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   425
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   426
    Later, if you run self.load(log), we cache the value of this property over
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   427
    the entire range of the log by noting each revision in which the property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   428
    was changed. At the end of the range of the log, we invalidate our cache
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   429
    by adding the value "None" to our cache for any revisions which fall out
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   430
    of the range of our log.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   431
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   432
    Once self.revs and self.values are filled, we can find the value of the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   433
    property at any arbitrary revision using a binary search on self.revs.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   434
    Once we find the last revision during which the property was changed,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   435
    we can lookup the associated value in self.values. (If the associated
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   436
    value is None, the associated value was not cached and we have to do
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   437
    a full propget.)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   438
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   439
    An example: We know that the 'svnmerge' property was added in r10, and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   440
    changed in r21. We gathered log info up until r40.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   441
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   442
    revs = [0, 10, 21, 40]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   443
    values = [None, "val1", "val2", None]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   444
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   445
    What these values say:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   446
    - From r0 to r9, we know nothing about the property.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   447
    - In r10, the property was set to "val1". This property stayed the same
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   448
      until r21, when it was changed to "val2".
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   449
    - We don't know what happened after r40.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   450
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   451
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   452
    def __init__(self, url, name):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   453
        """View the history of a versioned property at URL with name"""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   454
        self.url = url
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   455
        self.name = name
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   456
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   457
        # We know nothing about the value of the property. Setup revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   458
        # and values to indicate as such.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   459
        self.revs = [0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   460
        self.values = [None]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   461
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   462
        # We don't have any revisions cached
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   463
        self._initial_value = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   464
        self._changed_revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   465
        self._changed_values = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   466
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   467
    def load(self, log):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   468
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   469
        Load the history of property changes from the specified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   470
        RevisionLog object.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   471
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   472
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   473
        # Get the property value before the range of the log
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   474
        if log.begin > 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   475
            self.revs.append(log.begin-1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   476
            try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   477
                self._initial_value = self.raw_get(log.begin-1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   478
            except LaunchError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   479
                # The specified URL might not exist before the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   480
                # range of the log. If so, we can safely assume
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   481
                # that the property was empty at that time.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   482
                self._initial_value = { }
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   483
            self.values.append(self._initial_value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   484
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   485
            self._initial_value = { }
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   486
            self.values[0] = self._initial_value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   487
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   488
        # Cache the property values in the log range
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   489
        old_value = self._initial_value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   490
        for rev in log.propchange_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   491
            new_value = self.raw_get(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   492
            if new_value != old_value:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   493
                self._changed_revs.append(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   494
                self._changed_values.append(new_value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   495
                self.revs.append(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   496
                self.values.append(new_value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   497
                old_value = new_value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   498
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   499
        # Indicate that we know nothing about the value of the property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   500
        # after the range of the log.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   501
        if log.revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   502
            self.revs.append(log.end+1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   503
            self.values.append(None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   504
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   505
    def raw_get(self, rev=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   506
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   507
        Get the property at revision REV. If rev is not specified, get
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   508
        the property at revision HEAD.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   509
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   510
        return get_revlist_prop(self.url, self.name, rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   511
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   512
    def get(self, rev=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   513
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   514
        Get the property at revision REV. If rev is not specified, get
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   515
        the property at revision HEAD.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   516
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   517
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   518
        if rev is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   519
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   520
            # Find the index using a binary search
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   521
            i = bisect(self.revs, rev) - 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   522
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   523
            # Return the value of the property, if it was cached
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   524
            if self.values[i] is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   525
                return self.values[i]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   526
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   527
        # Get the current value of the property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   528
        return self.raw_get(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   529
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   530
    def changed_revs(self, key=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   531
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   532
        Get a list of the revisions in which the specified dictionary
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   533
        key was changed in this property. If key is not specified,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   534
        return a list of revisions in which any key was changed.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   535
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   536
        if key is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   537
            return self._changed_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   538
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   539
            changed_revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   540
            old_val = self._initial_value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   541
            for rev, val in zip(self._changed_revs, self._changed_values):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   542
                if val.get(key) != old_val.get(key):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   543
                    changed_revs.append(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   544
                    old_val = val
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   545
            return changed_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   546
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   547
    def initialized_revs(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   548
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   549
        Get a list of the revisions in which keys were added or
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   550
        removed in this property.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   551
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   552
        initialized_revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   553
        old_len = len(self._initial_value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   554
        for rev, val in zip(self._changed_revs, self._changed_values):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   555
            if len(val) != old_len:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   556
                initialized_revs.append(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   557
                old_len = len(val)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   558
        return initialized_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   559
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   560
class RevisionSet:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   561
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   562
    A set of revisions, held in dictionary form for easy manipulation. If we
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   563
    were to rewrite this script for Python 2.3+, we would subclass this from
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   564
    set (or UserSet).  As this class does not include branch
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   565
    information, it's assumed that one instance will be used per
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   566
    branch.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   567
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   568
    def __init__(self, parm):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   569
        """Constructs a RevisionSet from a string in property form, or from
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   570
        a dictionary whose keys are the revisions. Raises ValueError if the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   571
        input string is invalid."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   572
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   573
        self._revs = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   574
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   575
        revision_range_split_re = re.compile('[-:]')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   576
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   577
        if isinstance(parm, types.DictType):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   578
            self._revs = parm.copy()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   579
        elif isinstance(parm, types.ListType):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   580
            for R in parm:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   581
                self._revs[int(R)] = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   582
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   583
            parm = parm.strip()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   584
            if parm:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   585
                for R in parm.split(","):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   586
                    rev_or_revs = re.split(revision_range_split_re, R)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   587
                    if len(rev_or_revs) == 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   588
                        self._revs[int(rev_or_revs[0])] = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   589
                    elif len(rev_or_revs) == 2:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   590
                        for rev in range(int(rev_or_revs[0]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   591
                                         int(rev_or_revs[1])+1):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   592
                            self._revs[rev] = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   593
                    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   594
                        raise ValueError, 'Ill formatted revision range: ' + R
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   595
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   596
    def sorted(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   597
        revnums = self._revs.keys()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   598
        revnums.sort()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   599
        return revnums
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   600
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   601
    def normalized(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   602
        """Returns a normalized version of the revision set, which is an
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   603
        ordered list of couples (start,end), with the minimum number of
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   604
        intervals."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   605
        revnums = self.sorted()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   606
        revnums.reverse()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   607
        ret = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   608
        while revnums:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   609
            s = e = revnums.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   610
            while revnums and revnums[-1] in (e, e+1):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   611
                e = revnums.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   612
            ret.append((s, e))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   613
        return ret
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   614
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   615
    def __str__(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   616
        """Convert the revision set to a string, using its normalized form."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   617
        L = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   618
        for s,e in self.normalized():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   619
            if s == e:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   620
                L.append(str(s))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   621
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   622
                L.append(str(s) + "-" + str(e))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   623
        return ",".join(L)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   624
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   625
    def __contains__(self, rev):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   626
        return self._revs.has_key(rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   627
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   628
    def __sub__(self, rs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   629
        """Compute subtraction as in sets."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   630
        revs = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   631
        for r in self._revs.keys():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   632
            if r not in rs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   633
                revs[r] = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   634
        return RevisionSet(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   635
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   636
    def __and__(self, rs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   637
        """Compute intersections as in sets."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   638
        revs = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   639
        for r in self._revs.keys():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   640
            if r in rs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   641
                revs[r] = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   642
        return RevisionSet(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   643
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   644
    def __nonzero__(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   645
        return len(self._revs) != 0
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   646
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   647
    def __len__(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   648
        """Return the number of revisions in the set."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   649
        return len(self._revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   650
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   651
    def __iter__(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   652
        return iter(self.sorted())
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   653
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   654
    def __or__(self, rs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   655
        """Compute set union."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   656
        revs = self._revs.copy()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   657
        revs.update(rs._revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   658
        return RevisionSet(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   659
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   660
def merge_props_to_revision_set(merge_props, pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   661
    """A converter which returns a RevisionSet instance containing the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   662
    revisions from PATH as known to BRANCH_PROPS.  BRANCH_PROPS is a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   663
    dictionary of pathid -> revision set branch integration information
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   664
    (as returned by get_merge_props())."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   665
    if not merge_props.has_key(pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   666
        error('no integration info available for path "%s"' % pathid)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   667
    return RevisionSet(merge_props[pathid])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   668
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   669
def dict_from_revlist_prop(propvalue):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   670
    """Given a property value as a string containing per-source revision
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   671
    lists, return a dictionary whose key is a source path identifier
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   672
    and whose value is the revisions for that source."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   673
    prop = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   674
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   675
    # Multiple sources are separated by any whitespace.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   676
    for L in propvalue.split():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   677
        # We use rsplit to play safe and allow colons in pathids.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   678
        source, revs = rsplit(L.strip(), ":", 1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   679
        prop[source] = revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   680
    return prop
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   681
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   682
def get_revlist_prop(url_or_dir, propname, rev=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   683
    """Given a repository URL or working copy path and a property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   684
    name, extract the values of the property which store per-source
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   685
    revision lists and return a dictionary whose key is a source path
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   686
    identifier, and whose value is the revisions for that source."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   687
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   688
    # Note that propget does not return an error if the property does
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   689
    # not exist, it simply does not output anything. So we do not need
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   690
    # to check for LaunchError here.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   691
    args = '--strict "%s" "%s"' % (propname, url_or_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   692
    if rev:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   693
        args = '-r %s %s' % (rev, args)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   694
    out = launchsvn('propget %s' % args, split_lines=False)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   695
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   696
    return dict_from_revlist_prop(out)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   697
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   698
def get_merge_props(dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   699
    """Extract the merged revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   700
    return get_revlist_prop(dir, opts["prop"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   701
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   702
def get_block_props(dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   703
    """Extract the blocked revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   704
    return get_revlist_prop(dir, opts["block-prop"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   705
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   706
def get_blocked_revs(dir, source_pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   707
    p = get_block_props(dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   708
    if p.has_key(source_pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   709
        return RevisionSet(p[source_pathid])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   710
    return RevisionSet("")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   711
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   712
def format_merge_props(props, sep=" "):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   713
    """Formats the hash PROPS as a string suitable for use as a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   714
    Subversion property value."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   715
    assert sep in ["\t", "\n", " "]   # must be a whitespace
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   716
    props = props.items()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   717
    props.sort()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   718
    L = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   719
    for h, r in props:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   720
        L.append(h + ":" + r)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   721
    return sep.join(L)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   722
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   723
def _run_propset(dir, prop, value):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   724
    """Set the property 'prop' of directory 'dir' to value 'value'. We go
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   725
    through a temporary file to not run into command line length limits."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   726
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   727
        fd, fname = tempfile.mkstemp()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   728
        f = os.fdopen(fd, "wb")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   729
    except AttributeError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   730
        # Fallback for Python <= 2.3 which does not have mkstemp (mktemp
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   731
        # suffers from race conditions. Not that we care...)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   732
        fname = tempfile.mktemp()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   733
        f = open(fname, "wb")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   734
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   735
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   736
        f.write(value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   737
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   738
        report("property data written to temp file: %s" % value)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   739
        svn_command('propset "%s" -F "%s" "%s"' % (prop, fname, dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   740
    finally:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   741
        os.remove(fname)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   742
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   743
def set_props(dir, name, props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   744
    props = format_merge_props(props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   745
    if props:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   746
        _run_propset(dir, name, props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   747
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   748
        svn_command('propdel "%s" "%s"' % (name, dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   749
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   750
def set_merge_props(dir, props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   751
    set_props(dir, opts["prop"], props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   752
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   753
def set_block_props(dir, props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   754
    set_props(dir, opts["block-prop"], props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   755
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   756
def set_blocked_revs(dir, source_pathid, revs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   757
    props = get_block_props(dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   758
    if revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   759
        props[source_pathid] = str(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   760
    elif props.has_key(source_pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   761
        del props[source_pathid]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   762
    set_block_props(dir, props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   763
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   764
def is_url(url):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   765
    """Check if url is a valid url."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   766
    return re.search(r"^[a-zA-Z][-+\.\w]*://[^\s]+$", url) is not None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   767
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   768
def is_wc(dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   769
    """Check if a directory is a working copy."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   770
    return os.path.isdir(os.path.join(dir, ".svn")) or \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   771
           os.path.isdir(os.path.join(dir, "_svn"))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   772
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   773
_cache_svninfo = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   774
def get_svninfo(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   775
    """Extract the subversion information for a target (through 'svn info').
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   776
    This function uses an internal cache to let clients query information
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   777
    many times."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   778
    if _cache_svninfo.has_key(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   779
        return _cache_svninfo[target]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   780
    info = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   781
    for L in launchsvn('info "%s"' % target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   782
        L = L.strip()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   783
        if not L:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   784
            continue
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   785
        key, value = L.split(": ", 1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   786
        info[key] = value.strip()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   787
    _cache_svninfo[target] = info
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   788
    return info
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   789
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   790
def target_to_url(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   791
    """Convert working copy path or repos URL to a repos URL."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   792
    if is_wc(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   793
        info = get_svninfo(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   794
        return info["URL"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   795
    return target
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   796
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   797
_cache_reporoot = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   798
def get_repo_root(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   799
    """Compute the root repos URL given a working-copy path, or a URL."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   800
    # Try using "svn info WCDIR". This works only on SVN clients >= 1.3
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   801
    if not is_url(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   802
        try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   803
            info = get_svninfo(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   804
            root = info["Repository Root"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   805
            _cache_reporoot[root] = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   806
            return root
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   807
        except KeyError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   808
            pass
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   809
        url = target_to_url(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   810
        assert url[-1] != '/'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   811
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   812
        url = target
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   813
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   814
    # Go through the cache of the repository roots. This avoids extra
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   815
    # server round-trips if we are asking the root of different URLs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   816
    # in the same repository (the cache in get_svninfo() cannot detect
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   817
    # that of course and would issue a remote command).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   818
    assert is_url(url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   819
    for r in _cache_reporoot:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   820
        if url.startswith(r):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   821
            return r
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   822
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   823
    # Try using "svn info URL". This works only on SVN clients >= 1.2
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   824
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   825
        info = get_svninfo(url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   826
        root = info["Repository Root"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   827
        _cache_reporoot[root] = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   828
        return root
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   829
    except LaunchError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   830
        pass
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   831
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   832
    # Constrained to older svn clients, we are stuck with this ugly
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   833
    # trial-and-error implementation. It could be made faster with a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   834
    # binary search.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   835
    while url:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   836
        temp = os.path.dirname(url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   837
        try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   838
            launchsvn('proplist "%s"' % temp)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   839
        except LaunchError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   840
            _cache_reporoot[url] = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   841
            return url
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   842
        url = temp
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   843
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   844
    assert False, "svn repos root not found"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   845
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   846
def target_to_pathid(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   847
    """Convert a target (either a working copy path or an URL) into a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   848
    path identifier."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   849
    root = get_repo_root(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   850
    url = target_to_url(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   851
    assert root[-1] != "/"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   852
    assert url[:len(root)] == root, "url=%r, root=%r" % (url, root)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   853
    return url[len(root):]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   854
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   855
class SvnLogParser:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   856
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   857
    Parse the "svn log", going through the XML output and using pulldom (which
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   858
    would even allow streaming the command output).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   859
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   860
    def __init__(self, xml):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   861
        self._events = pulldom.parseString(xml)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   862
    def __getitem__(self, idx):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   863
        for event, node in self._events:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   864
            if event == pulldom.START_ELEMENT and node.tagName == "logentry":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   865
                self._events.expandNode(node)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   866
                return self.SvnLogRevision(node)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   867
        raise IndexError, "Could not find 'logentry' tag in xml"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   868
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   869
    class SvnLogRevision:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   870
        def __init__(self, xmlnode):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   871
            self.n = xmlnode
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   872
        def revision(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   873
            return int(self.n.getAttribute("revision"))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   874
        def author(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   875
            return self.n.getElementsByTagName("author")[0].firstChild.data
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   876
        def paths(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   877
            return [self.SvnLogPath(n)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   878
                    for n in  self.n.getElementsByTagName("path")]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   879
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   880
        class SvnLogPath:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   881
            def __init__(self, xmlnode):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   882
                self.n = xmlnode
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   883
            def action(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   884
                return self.n.getAttribute("action")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   885
            def pathid(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   886
                return self.n.firstChild.data
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   887
            def copyfrom_rev(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   888
                try: return self.n.getAttribute("copyfrom-rev")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   889
                except KeyError: return None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   890
            def copyfrom_pathid(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   891
                try: return self.n.getAttribute("copyfrom-path")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   892
                except KeyError: return None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   893
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   894
def get_copyfrom(target):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   895
    """Get copyfrom info for a given target (it represents the directory from
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   896
    where it was branched). NOTE: repos root has no copyfrom info. In this case
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   897
    None is returned.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   898
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   899
    Returns the:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   900
        - source file or directory from which the copy was made
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   901
        - revision from which that source was copied
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   902
        - revision in which the copy was committed
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   903
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   904
    repos_path = target_to_pathid(target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   905
    for chg in SvnLogParser(launchsvn('log -v --xml --stop-on-copy "%s"'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   906
                                      % target, split_lines=False)):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   907
        for p in chg.paths():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   908
            if p.action() == 'A' and p.pathid() == repos_path:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   909
                # These values will be None if the corresponding elements are
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   910
                # not found in the log.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   911
                return p.copyfrom_pathid(), p.copyfrom_rev(), chg.revision()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   912
    return None,None,None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   913
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   914
def get_latest_rev(url):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   915
    """Get the latest revision of the repository of which URL is part."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   916
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   917
        return get_svninfo(url)["Revision"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   918
    except LaunchError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   919
        # Alternative method for latest revision checking (for svn < 1.2)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   920
        report('checking latest revision of "%s"' % url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   921
        L = launchsvn('proplist --revprop -r HEAD "%s"' % opts["source-url"])[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   922
        rev = re.search("revision (\d+)", L).group(1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   923
        report('latest revision of "%s" is %s' % (url, rev))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   924
        return rev
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   925
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   926
def get_created_rev(url):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   927
    """Lookup the revision at which the path identified by the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   928
    provided URL was first created."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   929
    oldest_rev = -1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   930
    report('determining oldest revision for URL "%s"' % url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   931
    ### TODO: Refactor this to use a modified RevisionLog class.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   932
    lines = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   933
    cmd = "log -r1:HEAD --stop-on-copy -q " + url
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   934
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   935
        lines = launchsvn(cmd + " --limit=1")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   936
    except LaunchError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   937
        # Assume that --limit isn't supported by the installed 'svn'.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   938
        lines = launchsvn(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   939
    if lines and len(lines) > 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   940
        i = lines[1].find(" ")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   941
        if i != -1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   942
            oldest_rev = int(lines[1][1:i])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   943
    if oldest_rev == -1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   944
        error('unable to determine oldest revision for URL "%s"' % url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   945
    return oldest_rev
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   946
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   947
def get_commit_log(url, revnum):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   948
    """Return the log message for a specific integer revision
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   949
    number."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   950
    out = launchsvn("log --incremental -r%d %s" % (revnum, url))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   951
    return recode_stdout_to_file("".join(out[1:]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   952
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   953
def construct_merged_log_message(url, revnums):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   954
    """Return a commit log message containing all the commit messages
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   955
    in the specified revisions at the given URL.  The separator used
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   956
    in this log message is determined by searching for the longest
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   957
    svnmerge separator existing in the commit log messages and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   958
    extending it by one more separator.  This results in a new commit
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   959
    log message that is clearer in describing merges that contain
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   960
    other merges. Trailing newlines are removed from the embedded
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   961
    log messages."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   962
    messages = ['']
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   963
    longest_sep = ''
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   964
    for r in revnums.sorted():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   965
        message = get_commit_log(url, r)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   966
        if message:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   967
            message = re.sub(r'(\r\n|\r|\n)', "\n", message)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   968
            message = rstrip(message, "\n") + "\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   969
            messages.append(prefix_lines(LOG_LINE_PREFIX, message))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   970
            for match in LOG_SEPARATOR_RE.findall(message):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   971
                sep = match[1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   972
                if len(sep) > len(longest_sep):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   973
                    longest_sep = sep
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   974
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   975
    longest_sep += LOG_SEPARATOR + "\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   976
    messages.append('')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   977
    return longest_sep.join(messages)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   978
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   979
def get_default_source(branch_target, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   980
    """Return the default source for branch_target (given its branch_props).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   981
    Error out if there is ambiguity."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   982
    if not branch_props:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   983
        error("no integration info available")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   984
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   985
    props = branch_props.copy()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   986
    pathid = target_to_pathid(branch_target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   987
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   988
    # To make bidirectional merges easier, find the target's
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   989
    # repository local path so it can be removed from the list of
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   990
    # possible integration sources.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   991
    if props.has_key(pathid):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   992
        del props[pathid]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   993
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   994
    if len(props) > 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   995
        err_msg = "multiple sources found. "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   996
        err_msg += "Explicit source argument (-S/--source) required.\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   997
        err_msg += "The merge sources available are:"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   998
        for prop in props:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   999
          err_msg += "\n  " + prop
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1000
        error(err_msg)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1001
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1002
    return props.keys()[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1003
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1004
def check_old_prop_version(branch_target, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1005
    """Check if branch_props (of branch_target) are svnmerge properties in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1006
    old format, and emit an error if so."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1007
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1008
    # Previous svnmerge versions allowed trailing /'s in the repository
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1009
    # local path.  Newer versions of svnmerge will trim trailing /'s
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1010
    # appearing in the command line, so if there are any properties with
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1011
    # trailing /'s, they will not be properly matched later on, so require
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1012
    # the user to change them now.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1013
    fixed = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1014
    changed = False
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1015
    for source, revs in branch_props.items():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1016
        src = rstrip(source, "/")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1017
        fixed[src] = revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1018
        if src != source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1019
            changed = True
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1020
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1021
    if changed:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1022
        err_msg = "old property values detected; an upgrade is required.\n\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1023
        err_msg += "Please execute and commit these changes to upgrade:\n\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1024
        err_msg += 'svn propset "%s" "%s" "%s"' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1025
                   (opts["prop"], format_merge_props(fixed), branch_target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1026
        error(err_msg)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1027
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1028
def should_find_reflected(branch_dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1029
    should_find_reflected = opts["bidirectional"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1030
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1031
    # If the source has integration info for the target, set find_reflected
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1032
    # even if --bidirectional wasn't specified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1033
    if not should_find_reflected:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1034
        source_props = get_merge_props(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1035
        should_find_reflected = source_props.has_key(target_to_pathid(branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1036
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1037
    return should_find_reflected
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1038
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1039
def analyze_revs(target_pathid, url, begin=1, end=None,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1040
                 find_reflected=False):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1041
    """For the source of the merges in the source URL being merged into
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1042
    target_pathid, analyze the revisions in the interval begin-end (which
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1043
    defaults to 1-HEAD), to find out which revisions are changes in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1044
    the url, which are changes elsewhere (so-called 'phantom'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1045
    revisions), optionally which are reflected changes (to avoid
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1046
    conflicts that can occur when doing bidirectional merging between
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1047
    branches), and which revisions initialize merge tracking against other
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1048
    branches.  Return a tuple of four RevisionSet's:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1049
        (real_revs, phantom_revs, reflected_revs, initialized_revs).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1050
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1051
    NOTE: To maximize speed, if "end" is not provided, the function is
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1052
    not able to find phantom revisions following the last real
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1053
    revision in the URL.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1054
    """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1055
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1056
    begin = str(begin)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1057
    if end is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1058
        end = "HEAD"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1059
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1060
        end = str(end)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1061
        if long(begin) > long(end):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1062
            return RevisionSet(""), RevisionSet(""), \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1063
                   RevisionSet(""), RevisionSet("")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1064
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1065
    logs[url] = RevisionLog(url, begin, end, find_reflected)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1066
    revs = RevisionSet(logs[url].revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1067
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1068
    if end == "HEAD":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1069
        # If end is not provided, we do not know which is the latest revision
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1070
        # in the repository. So return the phantom revision set only up to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1071
        # the latest known revision.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1072
        end = str(list(revs)[-1])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1073
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1074
    phantom_revs = RevisionSet("%s-%s" % (begin, end)) - revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1075
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1076
    if find_reflected:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1077
        reflected_revs = logs[url].merge_metadata().changed_revs(target_pathid)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1078
        reflected_revs += logs[url].block_metadata().changed_revs(target_pathid)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1079
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1080
        reflected_revs = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1081
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1082
    initialized_revs = RevisionSet(logs[url].merge_metadata().initialized_revs())
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1083
    reflected_revs = RevisionSet(reflected_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1084
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1085
    return revs, phantom_revs, reflected_revs, initialized_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1086
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1087
def analyze_source_revs(branch_target, source_url, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1088
    """For the given branch and source, extract the real and phantom
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1089
    source revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1090
    branch_url = target_to_url(branch_target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1091
    branch_pathid = target_to_pathid(branch_target)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1092
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1093
    # Extract the latest repository revision from the URL of the branch
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1094
    # directory (which is already cached at this point).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1095
    end_rev = get_latest_rev(source_url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1096
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1097
    # Calculate the base of analysis. If there is a "1-XX" interval in the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1098
    # merged_revs, we do not need to check those.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1099
    base = 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1100
    r = opts["merged-revs"].normalized()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1101
    if r and r[0][0] == 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1102
        base = r[0][1] + 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1103
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1104
    # See if the user filtered the revision set. If so, we are not
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1105
    # interested in something outside that range.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1106
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1107
        revs = RevisionSet(opts["revision"]).sorted()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1108
        if base < revs[0]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1109
            base = revs[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1110
        if end_rev > revs[-1]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1111
            end_rev = revs[-1]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1112
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1113
    return analyze_revs(branch_pathid, source_url, base, end_rev, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1114
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1115
def minimal_merge_intervals(revs, phantom_revs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1116
    """Produce the smallest number of intervals suitable for merging. revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1117
    is the RevisionSet which we want to merge, and phantom_revs are phantom
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1118
    revisions which can be used to concatenate intervals, thus minimizing the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1119
    number of operations."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1120
    revnums = revs.normalized()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1121
    ret = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1122
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1123
    cur = revnums.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1124
    while revnums:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1125
        next = revnums.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1126
        assert next[1] < cur[0]      # otherwise it is not ordered
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1127
        assert cur[0] - next[1] > 1  # otherwise it is not normalized
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1128
        for i in range(next[1]+1, cur[0]):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1129
            if i not in phantom_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1130
                ret.append(cur)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1131
                cur = next
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1132
                break
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1133
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1134
            cur = (next[0], cur[1])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1135
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1136
    ret.append(cur)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1137
    ret.reverse()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1138
    return ret
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1139
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1140
def display_revisions(revs, display_style, revisions_msg, source_url):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1141
    """Show REVS as dictated by DISPLAY_STYLE, either numerically, in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1142
    log format, or as diffs.  When displaying revisions numerically,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1143
    prefix output with REVISIONS_MSG when in verbose mode.  Otherwise,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1144
    request logs or diffs using SOURCE_URL."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1145
    if display_style == "revisions":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1146
        if revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1147
            report(revisions_msg)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1148
            print revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1149
    elif display_style == "logs":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1150
        for start,end in revs.normalized():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1151
            svn_command('log --incremental -v -r %d:%d %s' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1152
                        (start, end, source_url))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1153
    elif display_style in ("diffs", "summarize"):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1154
        if display_style == 'summarize':
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1155
            summarize = '--summarize '
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1156
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1157
            summarize = ''
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1158
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1159
        for start, end in revs.normalized():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1160
            print
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1161
            if start == end:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1162
                print "%s: changes in revision %d follow" % (NAME, start)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1163
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1164
                print "%s: changes in revisions %d-%d follow" % (NAME,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1165
                                                                 start, end)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1166
            print
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1167
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1168
            # Note: the starting revision number to 'svn diff' is
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1169
            # NOT inclusive so we have to subtract one from ${START}.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1170
            svn_command("diff -r %d:%d %s %s" % (start - 1, end, summarize,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1171
                                                 source_url))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1172
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1173
        assert False, "unhandled display style: %s" % display_style
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1174
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1175
def action_init(target_dir, target_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1176
    """Initialize for merges."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1177
    # Check that directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1178
    check_dir_clean(target_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1179
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1180
    # If the user hasn't specified the revisions to use, see if the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1181
    # "source" is a copy from the current tree and if so, we can use
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1182
    # the version data obtained from it.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1183
    revision_range = opts["revision"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1184
    if not revision_range:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1185
        # Determining a default endpoint for the revision range that "init"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1186
        # will use, since none was provided by the user.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1187
        cf_source, cf_rev, copy_committed_in_rev = \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1188
                                            get_copyfrom(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1189
        target_path = target_to_pathid(target_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1190
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1191
        if target_path == cf_source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1192
            # If source was originally copyied from target, and we are merging
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1193
            # changes from source to target (the copy target is the merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1194
            # source, and the copy source is the merge target), then we want to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1195
            # mark as integrated up to the rev in which the copy was committed
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1196
            # which created the merge source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1197
            report('the source "%s" is a branch of "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1198
                   (opts["source-url"], target_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1199
            revision_range = "1-" + str(copy_committed_in_rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1200
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1201
            # If the copy source is the merge source, and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1202
            # the copy target is the merge target, then we want to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1203
            # mark as integrated up to the specific rev of the merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1204
            # target from which the merge source was copied. Longer
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1205
            # discussion here:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1206
            # http://subversion.tigris.org/issues/show_bug.cgi?id=2810
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1207
            target_url = target_to_url(target_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1208
            source_path = target_to_pathid(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1209
            cf_source_path, cf_rev, copy_committed_in_rev = get_copyfrom(target_url)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1210
            if source_path == cf_source_path:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1211
                report('the merge source "%s" is the copy source of "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1212
                       (opts["source-url"], target_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1213
                revision_range = "1-" + cf_rev
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1214
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1215
    # When neither the merge source nor target is a copy of the other, and
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1216
    # the user did not specify a revision range, then choose a default which is
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1217
    # the current revision; saying, in effect, "everything has been merged, so
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1218
    # mark as integrated up to the latest rev on source url).
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1219
    revs = revision_range or "1-" + get_latest_rev(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1220
    revs = RevisionSet(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1221
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1222
    report('marking "%s" as already containing revisions "%s" of "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1223
           (target_dir, revs, opts["source-url"]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1224
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1225
    revs = str(revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1226
    # If the local svnmerge-integrated property already has an entry
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1227
    # for the source-pathid, simply error out.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1228
    if not opts["force"] and target_props.has_key(opts["source-pathid"]):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1229
        error('Repository-relative path %s has already been initialized at %s\n'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1230
              'Use --force to re-initialize'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1231
              % (opts["source-pathid"], target_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1232
    target_props[opts["source-pathid"]] = revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1233
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1234
    # Set property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1235
    set_merge_props(target_dir, target_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1236
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1237
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1238
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1239
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1240
        print >>f, 'Initialized merge tracking via "%s" with revisions "%s" from ' \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1241
            % (NAME, revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1242
        print >>f, '%s' % opts["source-url"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1243
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1244
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1245
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1246
def action_avail(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1247
    """Show commits available for merges."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1248
    source_revs, phantom_revs, reflected_revs, initialized_revs = \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1249
               analyze_source_revs(branch_dir, opts["source-url"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1250
                                   find_reflected=
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1251
                                       should_find_reflected(branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1252
    report('skipping phantom revisions: %s' % phantom_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1253
    if reflected_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1254
        report('skipping reflected revisions: %s' % reflected_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1255
        report('skipping initialized revisions: %s' % initialized_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1256
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1257
    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1258
    avail_revs = source_revs - opts["merged-revs"] - blocked_revs - \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1259
                 reflected_revs - initialized_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1260
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1261
    # Compose the set of revisions to show
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1262
    revs = RevisionSet("")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1263
    report_msg = "revisions available to be merged are:"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1264
    if "avail" in opts["avail-showwhat"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1265
        revs |= avail_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1266
    if "blocked" in opts["avail-showwhat"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1267
        revs |= blocked_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1268
        report_msg = "revisions blocked are:"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1269
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1270
    # Limit to revisions specified by -r (if any)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1271
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1272
        revs = revs & RevisionSet(opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1273
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1274
    display_revisions(revs, opts["avail-display"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1275
                      report_msg,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1276
                      opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1277
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1278
def action_integrated(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1279
    """Show change sets already merged.  This set of revisions is
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1280
    calculated from taking svnmerge-integrated property from the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1281
    branch, and subtracting any revision older than the branch
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1282
    creation revision."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1283
    # Extract the integration info for the branch_dir
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1284
    branch_props = get_merge_props(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1285
    check_old_prop_version(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1286
    revs = merge_props_to_revision_set(branch_props, opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1287
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1288
    # Lookup the oldest revision on the branch path.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1289
    oldest_src_rev = get_created_rev(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1290
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1291
    # Subtract any revisions which pre-date the branch.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1292
    report("subtracting revisions which pre-date the source URL (%d)" %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1293
           oldest_src_rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1294
    revs = revs - RevisionSet(range(1, oldest_src_rev))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1295
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1296
    # Limit to revisions specified by -r (if any)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1297
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1298
        revs = revs & RevisionSet(opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1299
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1300
    display_revisions(revs, opts["integrated-display"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1301
                      "revisions already integrated are:", opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1302
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1303
def action_merge(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1304
    """Record merge meta data, and do the actual merge (if not
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1305
    requested otherwise via --record-only)."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1306
    # Check branch directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1307
    check_dir_clean(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1308
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1309
    source_revs, phantom_revs, reflected_revs, initialized_revs = \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1310
               analyze_source_revs(branch_dir, opts["source-url"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1311
                                   find_reflected=
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1312
                                       should_find_reflected(branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1313
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1314
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1315
        revs = RevisionSet(opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1316
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1317
        revs = source_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1318
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1319
    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1320
    merged_revs = opts["merged-revs"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1321
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1322
    # Show what we're doing
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1323
    if opts["verbose"]:  # just to avoid useless calculations
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1324
        if merged_revs & revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1325
            report('"%s" already contains revisions %s' % (branch_dir,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1326
                                                           merged_revs & revs))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1327
        if phantom_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1328
            report('memorizing phantom revision(s): %s' % phantom_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1329
        if reflected_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1330
            report('memorizing reflected revision(s): %s' % reflected_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1331
        if blocked_revs & revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1332
            report('skipping blocked revisions(s): %s' % (blocked_revs & revs))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1333
        if initialized_revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1334
            report('skipping initialized revision(s): %s' % initialized_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1335
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1336
    # Compute final merge set.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1337
    revs = revs - merged_revs - blocked_revs - reflected_revs - \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1338
           phantom_revs - initialized_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1339
    if not revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1340
        report('no revisions to merge, exiting')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1341
        return
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1342
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1343
    # When manually marking revisions as merged, we only update the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1344
    # integration meta data, and don't perform an actual merge.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1345
    record_only = opts["record-only"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1346
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1347
    if record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1348
        report('recording merge of revision(s) %s from "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1349
               (revs, opts["source-url"]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1350
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1351
        report('merging in revision(s) %s from "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1352
               (revs, opts["source-url"]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1353
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1354
    # Do the merge(s). Note: the starting revision number to 'svn merge'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1355
    # is NOT inclusive so we have to subtract one from start.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1356
    # We try to keep the number of merge operations as low as possible,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1357
    # because it is faster and reduces the number of conflicts.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1358
    old_block_props = get_block_props(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1359
    merge_metadata = logs[opts["source-url"]].merge_metadata()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1360
    block_metadata = logs[opts["source-url"]].block_metadata()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1361
    for start,end in minimal_merge_intervals(revs, phantom_revs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1362
        if not record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1363
            # Preset merge/blocked properties to the source value at
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1364
            # the start rev to avoid spurious property conflicts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1365
            set_merge_props(branch_dir, merge_metadata.get(start - 1))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1366
            set_block_props(branch_dir, block_metadata.get(start - 1))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1367
            # Do the merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1368
            svn_command("merge --force -r %d:%d %s %s" % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1369
                        (start - 1, end, opts["source-url"], branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1370
            # TODO: to support graph merging, add logic to merge the property
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1371
            # meta-data manually
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1372
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1373
    # Update the set of merged revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1374
    merged_revs = merged_revs | revs | reflected_revs | phantom_revs | initialized_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1375
    branch_props[opts["source-pathid"]] = str(merged_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1376
    set_merge_props(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1377
    # Reset the blocked revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1378
    set_block_props(branch_dir, old_block_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1379
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1380
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1381
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1382
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1383
        if record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1384
            print >>f, 'Recorded merge of revisions %s via %s from ' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1385
                  (revs, NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1386
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1387
            print >>f, 'Merged revisions %s via %s from ' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1388
                  (revs, NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1389
        print >>f, '%s' % opts["source-url"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1390
        if opts["commit-verbose"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1391
            print >>f
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1392
            print >>f, construct_merged_log_message(opts["source-url"], revs),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1393
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1394
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1395
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1396
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1397
def action_block(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1398
    """Block revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1399
    # Check branch directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1400
    check_dir_clean(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1401
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1402
    source_revs, phantom_revs, reflected_revs, initialized_revs = \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1403
               analyze_source_revs(branch_dir, opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1404
    revs_to_block = source_revs - opts["merged-revs"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1405
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1406
    # Limit to revisions specified by -r (if any)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1407
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1408
        revs_to_block = RevisionSet(opts["revision"]) & revs_to_block
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1409
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1410
    if not revs_to_block:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1411
        error('no available revisions to block')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1412
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1413
    # Change blocked information
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1414
    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1415
    blocked_revs = blocked_revs | revs_to_block
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1416
    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1417
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1418
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1419
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1420
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1421
        print >>f, 'Blocked revisions %s via %s' % (revs_to_block, NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1422
        if opts["commit-verbose"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1423
            print >>f
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1424
            print >>f, construct_merged_log_message(opts["source-url"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1425
                                                    revs_to_block),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1426
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1427
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1428
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1429
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1430
def action_unblock(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1431
    """Unblock revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1432
    # Check branch directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1433
    check_dir_clean(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1434
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1435
    blocked_revs = get_blocked_revs(branch_dir, opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1436
    revs_to_unblock = blocked_revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1437
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1438
    # Limit to revisions specified by -r (if any)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1439
    if opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1440
        revs_to_unblock = revs_to_unblock & RevisionSet(opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1441
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1442
    if not revs_to_unblock:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1443
        error('no available revisions to unblock')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1444
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1445
    # Change blocked information
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1446
    blocked_revs = blocked_revs - revs_to_unblock
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1447
    set_blocked_revs(branch_dir, opts["source-pathid"], blocked_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1448
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1449
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1450
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1451
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1452
        print >>f, 'Unblocked revisions %s via %s' % (revs_to_unblock, NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1453
        if opts["commit-verbose"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1454
            print >>f
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1455
            print >>f, construct_merged_log_message(opts["source-url"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1456
                                                    revs_to_unblock),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1457
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1458
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1459
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1460
def action_rollback(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1461
    """Rollback previously integrated revisions."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1462
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1463
    # Make sure the revision arguments are present
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1464
    if not opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1465
        error("The '-r' option is mandatory for rollback")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1466
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1467
    # Check branch directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1468
    check_dir_clean(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1469
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1470
    # Extract the integration info for the branch_dir
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1471
    branch_props = get_merge_props(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1472
    check_old_prop_version(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1473
    # Get the list of all revisions already merged into this source-pathid.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1474
    merged_revs = merge_props_to_revision_set(branch_props,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1475
                                              opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1476
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1477
    # At which revision was the src created?
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1478
    oldest_src_rev = get_created_rev(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1479
    src_pre_exist_range = RevisionSet("1-%d" % oldest_src_rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1480
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1481
    # Limit to revisions specified by -r (if any)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1482
    revs = merged_revs & RevisionSet(opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1483
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1484
    # make sure there's some revision to rollback
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1485
    if not revs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1486
        report("Nothing to rollback in revision range r%s" % opts["revision"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1487
        return
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1488
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1489
    # If even one specified revision lies outside the lifetime of the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1490
    # merge source, error out.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1491
    if revs & src_pre_exist_range:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1492
        err_str  = "Specified revision range falls out of the rollback range.\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1493
        err_str += "%s was created at r%d" % (opts["source-pathid"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1494
                                              oldest_src_rev)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1495
        error(err_str)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1496
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1497
    record_only = opts["record-only"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1498
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1499
    if record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1500
        report('recording rollback of revision(s) %s from "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1501
               (revs, opts["source-url"]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1502
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1503
        report('rollback of revision(s) %s from "%s"' %
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1504
               (revs, opts["source-url"]))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1505
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1506
    # Do the reverse merge(s). Note: the starting revision number
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1507
    # to 'svn merge' is NOT inclusive so we have to subtract one from start.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1508
    # We try to keep the number of merge operations as low as possible,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1509
    # because it is faster and reduces the number of conflicts.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1510
    rollback_intervals = minimal_merge_intervals(revs, [])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1511
    # rollback in the reverse order of merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1512
    rollback_intervals.reverse()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1513
    for start, end in rollback_intervals:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1514
        if not record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1515
            # Do the merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1516
            svn_command("merge --force -r %d:%d %s %s" % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1517
                        (end, start - 1, opts["source-url"], branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1518
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1519
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1520
    # calculate the phantom revs first
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1521
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1522
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1523
        if record_only:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1524
            print >>f, 'Recorded rollback of revisions %s via %s from ' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1525
                  (revs , NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1526
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1527
            print >>f, 'Rolled back revisions %s via %s from ' % \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1528
                  (revs , NAME)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1529
        print >>f, '%s' % opts["source-url"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1530
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1531
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1532
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1533
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1534
    # Update the set of merged revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1535
    merged_revs = merged_revs - revs
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1536
    branch_props[opts["source-pathid"]] = str(merged_revs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1537
    set_merge_props(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1538
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1539
def action_uninit(branch_dir, branch_props):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1540
    """Uninit SOURCE URL."""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1541
    # Check branch directory is ready for being modified
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1542
    check_dir_clean(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1543
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1544
    # If the source-pathid does not have an entry in the svnmerge-integrated
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1545
    # property, simply error out.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1546
    if not branch_props.has_key(opts["source-pathid"]):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1547
        error('Repository-relative path "%s" does not contain merge '
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1548
              'tracking information for "%s"' \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1549
                % (opts["source-pathid"], branch_dir))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1550
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1551
    del branch_props[opts["source-pathid"]]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1552
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1553
    # Set merge property with the selected source deleted
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1554
    set_merge_props(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1555
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1556
    # Set blocked revisions for the selected source to None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1557
    set_blocked_revs(branch_dir, opts["source-pathid"], None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1558
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1559
    # Write out commit message if desired
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1560
    if opts["commit-file"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1561
        f = open(opts["commit-file"], "w")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1562
        print >>f, 'Removed merge tracking for "%s" for ' % NAME
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1563
        print >>f, '%s' % opts["source-url"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1564
        f.close()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1565
        report('wrote commit message to "%s"' % opts["commit-file"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1566
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1567
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1568
# Command line parsing -- options and commands management
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1569
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1570
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1571
class OptBase:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1572
    def __init__(self, *args, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1573
        self.help = kwargs["help"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1574
        del kwargs["help"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1575
        self.lflags = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1576
        self.sflags = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1577
        for a in args:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1578
            if a.startswith("--"):   self.lflags.append(a)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1579
            elif a.startswith("-"):  self.sflags.append(a)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1580
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1581
                raise TypeError, "invalid flag name: %s" % a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1582
        if kwargs.has_key("dest"):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1583
            self.dest = kwargs["dest"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1584
            del kwargs["dest"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1585
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1586
            if not self.lflags:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1587
                raise TypeError, "cannot deduce dest name without long options"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1588
            self.dest = self.lflags[0][2:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1589
        if kwargs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1590
            raise TypeError, "invalid keyword arguments: %r" % kwargs.keys()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1591
    def repr_flags(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1592
        f = self.sflags + self.lflags
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1593
        r = f[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1594
        for fl in f[1:]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1595
            r += " [%s]" % fl
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1596
        return r
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1597
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1598
class Option(OptBase):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1599
    def __init__(self, *args, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1600
        self.default = kwargs.setdefault("default", 0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1601
        del kwargs["default"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1602
        self.value = kwargs.setdefault("value", None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1603
        del kwargs["value"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1604
        OptBase.__init__(self, *args, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1605
    def apply(self, state, value):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1606
        assert value == ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1607
        if self.value is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1608
            state[self.dest] = self.value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1609
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1610
            state[self.dest] += 1
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1611
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1612
class OptionArg(OptBase):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1613
    def __init__(self, *args, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1614
        self.default = kwargs["default"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1615
        del kwargs["default"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1616
        self.metavar = kwargs.setdefault("metavar", None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1617
        del kwargs["metavar"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1618
        OptBase.__init__(self, *args, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1619
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1620
        if self.metavar is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1621
            if self.dest is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1622
                self.metavar = self.dest.upper()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1623
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1624
                self.metavar = "arg"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1625
        if self.default:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1626
            self.help += " (default: %s)" % self.default
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1627
    def apply(self, state, value):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1628
        assert value is not None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1629
        state[self.dest] = value
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1630
    def repr_flags(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1631
        r = OptBase.repr_flags(self)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1632
        return r + " " + self.metavar
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1633
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1634
class CommandOpts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1635
    class Cmd:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1636
        def __init__(self, *args):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1637
            self.name, self.func, self.usage, self.help, self.opts = args
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1638
        def short_help(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1639
            return self.help.split(".")[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1640
        def __str__(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1641
            return self.name
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1642
        def __call__(self, *args, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1643
            return self.func(*args, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1644
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1645
    def __init__(self, global_opts, common_opts, command_table, version=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1646
        self.progname = NAME
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1647
        self.version = version.replace("%prog", self.progname)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1648
        self.cwidth = console_width() - 2
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1649
        self.ctable = command_table.copy()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1650
        self.gopts = global_opts[:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1651
        self.copts = common_opts[:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1652
        self._add_builtins()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1653
        for k in self.ctable.keys():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1654
            cmd = self.Cmd(k, *self.ctable[k])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1655
            opts = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1656
            for o in cmd.opts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1657
                if isinstance(o, types.StringType) or \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1658
                   isinstance(o, types.UnicodeType):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1659
                    o = self._find_common(o)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1660
                opts.append(o)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1661
            cmd.opts = opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1662
            self.ctable[k] = cmd
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1663
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1664
    def _add_builtins(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1665
        self.gopts.append(
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1666
            Option("-h", "--help", help="show help for this command and exit"))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1667
        if self.version is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1668
            self.gopts.append(
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1669
                Option("-V", "--version", help="show version info and exit"))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1670
        self.ctable["help"] = (self._cmd_help,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1671
            "help [COMMAND]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1672
            "Display help for a specific command. If COMMAND is omitted, "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1673
            "display brief command description.",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1674
            [])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1675
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1676
    def _cmd_help(self, cmd=None, *args):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1677
        if args:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1678
            self.error("wrong number of arguments", "help")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1679
        if cmd is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1680
            cmd = self._command(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1681
            self.print_command_help(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1682
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1683
            self.print_command_list()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1684
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1685
    def _paragraph(self, text, width=78):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1686
        chunks = re.split("\s+", text.strip())
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1687
        chunks.reverse()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1688
        lines = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1689
        while chunks:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1690
            L = chunks.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1691
            while chunks and len(L) + len(chunks[-1]) + 1 <= width:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1692
                L += " " + chunks.pop()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1693
            lines.append(L)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1694
        return lines
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1695
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1696
    def _paragraphs(self, text, *args, **kwargs):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1697
        pars = text.split("\n\n")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1698
        lines = self._paragraph(pars[0], *args, **kwargs)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1699
        for p in pars[1:]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1700
            lines.append("")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1701
            lines.extend(self._paragraph(p, *args, **kwargs))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1702
        return lines
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1703
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1704
    def _print_wrapped(self, text, indent=0):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1705
        text = self._paragraphs(text, self.cwidth - indent)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1706
        print text.pop(0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1707
        for t in text:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1708
            print " " * indent + t
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1709
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1710
    def _find_common(self, fl):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1711
        for o in self.copts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1712
            if fl in o.lflags+o.sflags:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1713
                return o
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1714
        assert False, fl
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1715
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1716
    def _compute_flags(self, opts, check_conflicts=True):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1717
        back = {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1718
        sfl = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1719
        lfl = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1720
        for o in opts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1721
            sapp = lapp = ""
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1722
            if isinstance(o, OptionArg):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1723
                sapp, lapp = ":", "="
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1724
            for s in o.sflags:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1725
                if check_conflicts and back.has_key(s):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1726
                    raise RuntimeError, "option conflict: %s" % s
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1727
                back[s] = o
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1728
                sfl += s[1:] + sapp
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1729
            for l in o.lflags:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1730
                if check_conflicts and back.has_key(l):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1731
                    raise RuntimeError, "option conflict: %s" % l
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1732
                back[l] = o
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1733
                lfl.append(l[2:] + lapp)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1734
        return sfl, lfl, back
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1735
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1736
    def _extract_command(self, args):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1737
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1738
        Try to extract the command name from the argument list. This is
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1739
        non-trivial because we want to allow command-specific options even
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1740
        before the command itself.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1741
        """
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1742
        opts = self.gopts[:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1743
        for cmd in self.ctable.values():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1744
            opts.extend(cmd.opts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1745
        sfl, lfl, _ = self._compute_flags(opts, check_conflicts=False)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1746
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1747
        lopts,largs = getopt.getopt(args, sfl, lfl)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1748
        if not largs:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1749
            return None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1750
        return self._command(largs[0])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1751
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1752
    def _fancy_getopt(self, args, opts, state=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1753
        if state is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1754
            state= {}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1755
        for o in opts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1756
            if not state.has_key(o.dest):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1757
                state[o.dest] = o.default
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1758
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1759
        sfl, lfl, back = self._compute_flags(opts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1760
        try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1761
            lopts,args = getopt.gnu_getopt(args, sfl, lfl)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1762
        except AttributeError:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1763
            # Before Python 2.3, there was no gnu_getopt support.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1764
            # So we can't parse intermixed positional arguments
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1765
            # and options.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1766
            lopts,args = getopt.getopt(args, sfl, lfl)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1767
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1768
        for o,v in lopts:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1769
            back[o].apply(state, v)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1770
        return state, args
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1771
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1772
    def _command(self, cmd):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1773
        if not self.ctable.has_key(cmd):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1774
            self.error("unknown command: '%s'" % cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1775
        return self.ctable[cmd]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1776
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1777
    def parse(self, args):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1778
        if not args:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1779
            self.print_small_help()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1780
            sys.exit(0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1781
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1782
        cmd = None
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1783
        try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1784
            cmd = self._extract_command(args)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1785
            opts = self.gopts[:]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1786
            if cmd:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1787
                opts.extend(cmd.opts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1788
                args.remove(cmd.name)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1789
            state, args = self._fancy_getopt(args, opts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1790
        except getopt.GetoptError, e:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1791
            self.error(e, cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1792
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1793
        # Handle builtins
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1794
        if self.version is not None and state["version"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1795
            self.print_version()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1796
            sys.exit(0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1797
        if state["help"]: # special case for --help
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1798
            if cmd:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1799
                self.print_command_help(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1800
                sys.exit(0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1801
            cmd = self.ctable["help"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1802
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1803
            if cmd is None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1804
                self.error("command argument required")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1805
        if str(cmd) == "help":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1806
            cmd(*args)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1807
            sys.exit(0)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1808
        return cmd, args, state
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1809
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1810
    def error(self, s, cmd=None):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1811
        print >>sys.stderr, "%s: %s" % (self.progname, s)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1812
        if cmd is not None:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1813
            self.print_command_help(cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1814
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1815
            self.print_small_help()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1816
        sys.exit(1)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1817
    def print_small_help(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1818
        print "Type '%s help' for usage" % self.progname
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1819
    def print_usage_line(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1820
        print "usage: %s <subcommand> [options...] [args...]\n" % self.progname
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1821
    def print_command_list(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1822
        print "Available commands (use '%s help COMMAND' for more details):\n" \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1823
              % self.progname
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1824
        cmds = self.ctable.keys()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1825
        cmds.sort()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1826
        indent = max(map(len, cmds))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1827
        for c in cmds:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1828
            h = self.ctable[c].short_help()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1829
            print "  %-*s   " % (indent, c),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1830
            self._print_wrapped(h, indent+6)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1831
    def print_command_help(self, cmd):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1832
        cmd = self.ctable[str(cmd)]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1833
        print 'usage: %s %s\n' % (self.progname, cmd.usage)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1834
        self._print_wrapped(cmd.help)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1835
        def print_opts(opts, self=self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1836
            if not opts: return
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1837
            flags = [o.repr_flags() for o in opts]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1838
            indent = max(map(len, flags))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1839
            for f,o in zip(flags, opts):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1840
                print "  %-*s :" % (indent, f),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1841
                self._print_wrapped(o.help, indent+5)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1842
        print '\nCommand options:'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1843
        print_opts(cmd.opts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1844
        print '\nGlobal options:'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1845
        print_opts(self.gopts)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1846
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1847
    def print_version(self):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1848
        print self.version
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1849
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1850
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1851
# Options and Commands description
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1852
###############################################################################
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1853
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1854
global_opts = [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1855
    Option("-F", "--force",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1856
           help="force operation even if the working copy is not clean, or "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1857
                "there are pending updates"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1858
    Option("-n", "--dry-run",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1859
           help="don't actually change anything, just pretend; "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1860
                "implies --show-changes"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1861
    Option("-s", "--show-changes",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1862
           help="show subversion commands that make changes"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1863
    Option("-v", "--verbose",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1864
           help="verbose mode: output more information about progress"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1865
    OptionArg("-u", "--username",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1866
              default=None,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1867
              help="invoke subversion commands with the supplied username"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1868
    OptionArg("-p", "--password",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1869
              default=None,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1870
              help="invoke subversion commands with the supplied password"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1871
]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1872
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1873
common_opts = [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1874
    Option("-b", "--bidirectional",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1875
           value=True,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1876
           default=False,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1877
           help="remove reflected and initialized revisions from merge candidates.  "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1878
                "Not required but may be specified to speed things up slightly"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1879
    OptionArg("-f", "--commit-file", metavar="FILE",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1880
              default="svnmerge-commit-message.txt",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1881
              help="set the name of the file where the suggested log message "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1882
                   "is written to"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1883
    Option("-M", "--record-only",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1884
           value=True,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1885
           default=False,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1886
           help="do not perform an actual merge of the changes, yet record "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1887
                "that a merge happened"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1888
    OptionArg("-r", "--revision",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1889
              metavar="REVLIST",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1890
              default="",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1891
              help="specify a revision list, consisting of revision numbers "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1892
                   'and ranges separated by commas, e.g., "534,537-539,540"'),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1893
    OptionArg("-S", "--source", "--head",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1894
              default=None,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1895
              help="specify a merge source for this branch.  It can be either "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1896
                   "a path, a full URL, or an unambiguous substring of one "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1897
                   "of the paths for which merge tracking was already "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1898
                   "initialized.  Needed only to disambiguate in case of "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1899
                   "multiple merge sources"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1900
]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1901
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1902
command_table = {
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1903
    "init": (action_init,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1904
    "init [OPTION...] [SOURCE]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1905
    """Initialize merge tracking from SOURCE on the current working
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1906
    directory.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1907
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1908
    If SOURCE is specified, all the revisions in SOURCE are marked as already
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1909
    merged; if this is not correct, you can use --revision to specify the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1910
    exact list of already-merged revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1911
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1912
    If SOURCE is omitted, then it is computed from the "svn cp" history of the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1913
    current working directory (searching back for the branch point); in this
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1914
    case, %s assumes that no revision has been integrated yet since
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1915
    the branch point (unless you teach it with --revision).""" % NAME,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1916
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1917
        "-f", "-r", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1918
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1919
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1920
    "avail": (action_avail,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1921
    "avail [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1922
    """Show unmerged revisions available for PATH as a revision list.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1923
    If --revision is given, the revisions shown will be limited to those
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1924
    also specified in the option.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1925
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1926
    When svnmerge is used to bidirectionally merge changes between a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1927
    branch and its source, it is necessary to not merge the same changes
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1928
    forth and back: e.g., if you committed a merge of a certain
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1929
    revision of the branch into the source, you do not want that commit
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1930
    to appear as available to merged into the branch (as the code
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1931
    originated in the branch itself!).  svnmerge will automatically
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1932
    exclude these so-called "reflected" revisions.""",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1933
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1934
        Option("-A", "--all",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1935
               dest="avail-showwhat",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1936
               value=["blocked", "avail"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1937
               default=["avail"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1938
               help="show both available and blocked revisions (aka ignore "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1939
                    "blocked revisions)"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1940
        "-b",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1941
        Option("-B", "--blocked",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1942
               dest="avail-showwhat",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1943
               value=["blocked"],
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1944
               help="show the blocked revision list (see '%s block')" % NAME),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1945
        Option("-d", "--diff",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1946
               dest="avail-display",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1947
               value="diffs",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1948
               default="revisions",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1949
               help="show corresponding diff instead of revision list"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1950
        Option("--summarize",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1951
               dest="avail-display",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1952
               value="summarize",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1953
               help="show summarized diff instead of revision list"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1954
        Option("-l", "--log",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1955
               dest="avail-display",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1956
               value="logs",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1957
               help="show corresponding log history instead of revision list"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1958
        "-r",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1959
        "-S",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1960
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1961
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1962
    "integrated": (action_integrated,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1963
    "integrated [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1964
    """Show merged revisions available for PATH as a revision list.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1965
    If --revision is given, the revisions shown will be limited to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1966
    those also specified in the option.""",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1967
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1968
        Option("-d", "--diff",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1969
               dest="integrated-display",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1970
               value="diffs",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1971
               default="revisions",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1972
               help="show corresponding diff instead of revision list"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1973
        Option("-l", "--log",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1974
               dest="integrated-display",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1975
               value="logs",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1976
               help="show corresponding log history instead of revision list"),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1977
        "-r",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1978
        "-S",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1979
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1980
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1981
    "rollback": (action_rollback,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1982
    "rollback [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1983
    """Rollback previously merged in revisions from PATH.  The
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1984
    --revision option is mandatory, and specifies which revisions
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1985
    will be rolled back.  Only the previously integrated merges
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1986
    will be rolled back.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1987
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1988
    When manually rolling back changes, --record-only can be used to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1989
    instruct %s that a manual rollback of a certain revision
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1990
    already happened, so that it can record it and offer that
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1991
    revision for merge henceforth.""" % (NAME),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1992
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1993
        "-f", "-r", "-S", "-M", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1994
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1995
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1996
    "merge": (action_merge,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1997
    "merge [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1998
    """Merge in revisions into PATH from its source. If --revision is omitted,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  1999
    all the available revisions will be merged. In any case, already merged-in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2000
    revisions will NOT be merged again.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2001
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2002
    When svnmerge is used to bidirectionally merge changes between a
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2003
    branch and its source, it is necessary to not merge the same changes
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2004
    forth and back: e.g., if you committed a merge of a certain
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2005
    revision of the branch into the source, you do not want that commit
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2006
    to appear as available to merged into the branch (as the code
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2007
    originated in the branch itself!).  svnmerge will automatically
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2008
    exclude these so-called "reflected" revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2009
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2010
    When manually merging changes across branches, --record-only can
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2011
    be used to instruct %s that a manual merge of a certain revision
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2012
    already happened, so that it can record it and not offer that
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2013
    revision for merge anymore.  Conversely, when there are revisions
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2014
    which should not be merged, use '%s block'.""" % (NAME, NAME),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2015
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2016
        "-b", "-f", "-r", "-S", "-M", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2017
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2018
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2019
    "block": (action_block,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2020
    "block [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2021
    """Block revisions within PATH so that they disappear from the available
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2022
    list. This is useful to hide revisions which will not be integrated.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2023
    If --revision is omitted, it defaults to all the available revisions.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2024
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2025
    Do not use this option to hide revisions that were manually merged
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2026
    into the branch.  Instead, use '%s merge --record-only', which
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2027
    records that a merge happened (as opposed to a merge which should
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2028
    not happen).""" % NAME,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2029
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2030
        "-f", "-r", "-S", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2031
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2032
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2033
    "unblock": (action_unblock,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2034
    "unblock [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2035
    """Revert the effect of '%s block'. If --revision is omitted, all the
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2036
    blocked revisions are unblocked""" % NAME,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2037
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2038
        "-f", "-r", "-S", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2039
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2040
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2041
    "uninit": (action_uninit,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2042
    "uninit [OPTION...] [PATH]",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2043
    """Remove merge tracking information from PATH. It cleans any kind of merge
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2044
    tracking information (including the list of blocked revisions). If there
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2045
    are multiple sources, use --source to indicate which source you want to
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2046
    forget about.""",
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2047
    [
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2048
        "-f", "-S", # import common opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2049
    ]),
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2050
}
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2051
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2052
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2053
def main(args):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2054
    global opts
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2055
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2056
    # Initialize default options
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2057
    opts = default_opts.copy()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2058
    logs.clear()
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2059
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2060
    optsparser = CommandOpts(global_opts, common_opts, command_table,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2061
                             version="%%prog r%s\n  modified: %s\n\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2062
                                     "Copyright (C) 2004,2005 Awarix Inc.\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2063
                                     "Copyright (C) 2005, Giovanni Bajo"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2064
                                     % (__revision__, __date__))
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2065
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2066
    cmd, args, state = optsparser.parse(args)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2067
    opts.update(state)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2068
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2069
    source = opts.get("source", None)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2070
    branch_dir = "."
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2071
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2072
    if str(cmd) == "init":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2073
        if len(args) == 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2074
            source = args[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2075
        elif len(args) > 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2076
            optsparser.error("wrong number of parameters", cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2077
    elif str(cmd) in command_table.keys():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2078
        if len(args) == 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2079
            branch_dir = args[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2080
        elif len(args) > 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2081
            optsparser.error("wrong number of parameters", cmd)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2082
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2083
        assert False, "command not handled: %s" % cmd
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2084
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2085
    # Validate branch_dir
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2086
    if not is_wc(branch_dir):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2087
        error('"%s" is not a subversion working directory' % branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2088
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2089
    # Extract the integration info for the branch_dir
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2090
    branch_props = get_merge_props(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2091
    check_old_prop_version(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2092
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2093
    # Calculate source_url and source_path
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2094
    report("calculate source path for the branch")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2095
    if not source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2096
        if str(cmd) == "init":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2097
            cf_source, cf_rev, copy_committed_in_rev = get_copyfrom(branch_dir)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2098
            if not cf_source:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2099
                error('no copyfrom info available. '
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2100
                      'Explicit source argument (-S/--source) required.')
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2101
            opts["source-pathid"] = cf_source
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2102
            if not opts["revision"]:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2103
                opts["revision"] = "1-" + cf_rev
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2104
        else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2105
            opts["source-pathid"] = get_default_source(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2106
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2107
        # (assumes pathid is a repository-relative-path)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2108
        assert opts["source-pathid"][0] == '/'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2109
        opts["source-url"] = get_repo_root(branch_dir) + opts["source-pathid"]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2110
    else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2111
        # The source was given as a command line argument and is stored in
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2112
        # SOURCE.  Ensure that the specified source does not end in a /,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2113
        # otherwise it's easy to have the same source path listed more
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2114
        # than once in the integrated version properties, with and without
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2115
        # trailing /'s.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2116
        source = rstrip(source, "/")
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2117
        if not is_wc(source) and not is_url(source):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2118
            # Check if it is a substring of a pathid recorded
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2119
            # within the branch properties.
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2120
            found = []
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2121
            for pathid in branch_props.keys():
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2122
                if pathid.find(source) > 0:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2123
                    found.append(pathid)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2124
            if len(found) == 1:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2125
                # (assumes pathid is a repository-relative-path)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2126
                source = get_repo_root(branch_dir) + found[0]
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2127
            else:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2128
                error('"%s" is neither a valid URL, nor an unambiguous '
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2129
                      'substring of a repository path, nor a working directory'
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2130
                      % source)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2131
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2132
        source_pathid = target_to_pathid(source)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2133
        if str(cmd) == "init" and \
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2134
               source_pathid == target_to_pathid("."):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2135
            error("cannot init integration source path '%s'\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2136
                  "Its repository-relative path must differ from the "
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2137
                  "repository-relative path of the current directory."
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2138
                  % source_pathid)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2139
        opts["source-pathid"] = source_pathid
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2140
        opts["source-url"] = target_to_url(source)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2141
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2142
    # Sanity check source_url
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2143
    assert is_url(opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2144
    # SVN does not support non-normalized URL (and we should not
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2145
    # have created them)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2146
    assert opts["source-url"].find("/..") < 0
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2147
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2148
    report('source is "%s"' % opts["source-url"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2149
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2150
    # Get previously merged revisions (except when command is init)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2151
    if str(cmd) != "init":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2152
        opts["merged-revs"] = merge_props_to_revision_set(branch_props,
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2153
                                                          opts["source-pathid"])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2154
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2155
    # Perform the action
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2156
    cmd(branch_dir, branch_props)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2157
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2158
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2159
if __name__ == "__main__":
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2160
    try:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2161
        main(sys.argv[1:])
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2162
    except LaunchError, (ret, cmd, out):
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2163
        err_msg = "command execution failed (exit code: %d)\n" % ret
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2164
        err_msg += cmd + "\n"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2165
        err_msg += "".join(out)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2166
        error(err_msg)
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2167
    except KeyboardInterrupt:
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2168
        # Avoid traceback on CTRL+C
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2169
        print "aborted by user"
b73eec62825a Remove last remnants of /thirdparty/.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
  2170
        sys.exit(1)