thirdparty/svnmerge/svnmerge.py
author Mario Ferraro <fadinlight@gmail.com>
Sun, 15 Nov 2009 22:12:20 +0100
changeset 3093 d1be59b6b627
parent 107 ead919546298
permissions -rwxr-xr-x
GMaps related JS changed to use new google namespace. Google is going to change permanently in the future the way to load its services, so better stay safe. Also this commit shows uses of the new melange.js module. Fixes Issue 634.
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)