/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  = []
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
55
    non_aliases = set(controldir.format_registry.keys())
56
    non_aliases.difference_update(controldir.format_registry.aliases())
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
57
    for key in non_aliases:
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
58
        format = controldir.format_registry.make_bzrdir(key)
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
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
6667.2.1 by Jelmer Vernooij
Some cleanup; s/BzrDir/ControlDir/, remove some unused imports.
84
    from ... import controldir, 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:
6667.2.1 by Jelmer Vernooij
Some cleanup; s/BzrDir/ControlDir/, remove some unused imports.
86
        control, relpath = controldir.ControlDir.open_containing(location)
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
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:
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
108
        format = controldir.format_registry.make_bzrdir('default')
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
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 = {}
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
184
    for k, c in d.items():
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
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 = {}
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
195
    for k, v in d.items():
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
196
        keys = result.setdefault(v, [])
197
        keys.append(k)
198
    return result
199
200