/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
0.64.334 by Jelmer Vernooij
Remove old FSF address. Thanks Dan Callaghan.
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
15
16
"""Miscellaneous useful stuff."""
17
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
18
from __future__ import absolute_import
19
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
20
import stat
21
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
22
23
def escape_commit_message(message):
24
    """Replace xml-incompatible control characters."""
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
25
    # This really ought to be provided by breezy.
26
    # Code copied from breezy.commit.
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
27
28
    # Python strings can include characters that can't be
29
    # represented in well-formed XML; escape characters that
30
    # aren't listed in the XML specification
31
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
32
    import re
33
    message, _ = re.subn(
34
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
35
        lambda match: match.group(0).encode('unicode_escape'),
36
        message)
37
    return message
38
39
40
def best_format_for_objects_in_a_repository(repo):
41
    """Find the high-level format for branches and trees given a repository.
42
43
    When creating branches and working trees within a repository, Bazaar
44
    defaults to using the default format which may not be the best choice.
45
    This routine does a reverse lookup of the high-level format registry
46
    to find the high-level format that a shared repository was most likely
47
    created via.
48
49
    :return: the BzrDirFormat or None if no matches were found.
50
    """
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
51
    # Based on code from breezy/info.py ...
52
    from ... import bzrdir
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
53
    repo_format = repo._format
54
    candidates  = []
55
    non_aliases = set(bzrdir.format_registry.keys())
56
    non_aliases.difference_update(bzrdir.format_registry.aliases())
57
    for key in non_aliases:
58
        format = bzrdir.format_registry.make_bzrdir(key)
59
        # LocalGitBzrDirFormat has no repository_format
60
        if hasattr(format, "repository_format"):
61
            if format.repository_format == repo_format:
62
                candidates.append((key, format))
63
    if len(candidates):
64
        # Assume the first one. Is there any reason not to do that?
65
        name, format = candidates[0]
66
        return format
67
    else:
68
        return None
69
70
71
def open_destination_directory(location, format=None, verbose=True):
72
    """Open a destination directory and return the BzrDir.
73
74
    If destination has a control directory, it will be returned.
75
    Otherwise, the destination should be empty or non-existent and
76
    a shared repository will be created there.
77
78
    :param location: the destination directory
79
    :param format: the format to use or None for the default
80
    :param verbose: display the format used if a repository is created.
81
    :return: BzrDir for the destination
82
    """
83
    import os
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
84
    from ... import bzrdir, errors, trace, transport
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
85
    try:
86
        control, relpath = bzrdir.BzrDir.open_containing(location)
87
        # XXX: Check the relpath is None here?
88
        return control
89
    except errors.NotBranchError:
90
        pass
91
92
    # If the directory exists, check it is empty. Otherwise create it.
93
    if os.path.exists(location):
94
        contents = os.listdir(location)
95
        if contents:
96
            errors.BzrCommandError("Destination must have a .bzr directory, "
97
                " not yet exist or be empty - files found in %s" % (location,))
98
    else:
99
        try:
100
            os.mkdir(location)
101
        except IOError, ex:
102
            errors.BzrCommandError("Unable to create %s: %s" %
103
                (location, ex))
104
105
    # Create a repository for the nominated format.
106
    trace.note("Creating destination repository ...")
107
    if format is None:
108
        format = bzrdir.format_registry.make_bzrdir('default')
109
    to_transport = transport.get_transport(location)
110
    to_transport.ensure_base()
111
    control = format.initialize_on_transport(to_transport)
112
    repo = control.create_repository(shared=True)
113
    if verbose:
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
114
        from ...info import show_bzrdir_info
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
115
        show_bzrdir_info(repo.bzrdir, verbose=0)
116
    return control
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
117
118
119
def kind_to_mode(kind, executable):
120
    if kind == "file":
121
        if executable == True:
122
            return stat.S_IFREG | 0755
123
        elif executable == False:
124
            return stat.S_IFREG | 0644
125
        else:
126
            raise AssertionError("Executable %r invalid" % executable)
127
    elif kind == "symlink":
128
        return stat.S_IFLNK
129
    elif kind == "directory":
130
        return stat.S_IFDIR
131
    elif kind == "tree-reference":
132
        return 0160000
133
    else:
134
        raise AssertionError("Unknown file kind '%s'" % kind)
135
136
137
def mode_to_kind(mode):
138
    # Note: Output from git-fast-export slightly different to spec
139
    if mode in (0644, 0100644):
140
        return 'file', False
141
    elif mode in (0755, 0100755):
142
        return 'file', True
143
    elif mode == 0040000:
144
        return 'directory', False
145
    elif mode == 0120000:
146
        return 'symlink', False
147
    elif mode == 0160000:
148
        return 'tree-reference', False
149
    else:
150
        raise AssertionError("invalid mode %o" % mode)
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
151
152
153
def binary_stream(stream):
154
    """Ensure a stream is binary on Windows.
155
156
    :return: the stream
157
    """
158
    try:
159
        import os
160
        if os.name == 'nt':
161
            fileno = getattr(stream, 'fileno', None)
162
            if fileno:
163
                no = fileno()
164
                if no >= 0:     # -1 means we're working as subprocess
165
                    import msvcrt
166
                    msvcrt.setmode(no, os.O_BINARY)
167
    except ImportError:
168
        pass
169
    return stream
170
171
172
def single_plural(n, single, plural):
173
    """Return a single or plural form of a noun based on number."""
174
    if n == 1:
175
        return single
176
    else:
177
        return plural
178
179
180
def invert_dictset(d):
181
    """Invert a dictionary with keys matching a set of values, turned into lists."""
182
    # Based on recipe from ASPN
183
    result = {}
184
    for k, c in d.iteritems():
185
        for v in c:
186
            keys = result.setdefault(v, [])
187
            keys.append(k)
188
    return result
189
190
191
def invert_dict(d):
192
    """Invert a dictionary with keys matching each value turned into a list."""
193
    # Based on recipe from ASPN
194
    result = {}
195
    for k, v in d.iteritems():
196
        keys = result.setdefault(v, [])
197
        keys.append(k)
198
    return result
199
200