/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
6670.1.1 by Jelmer Vernooij
Add missing import.
22
from ... import (
23
    controldir,
24
    )
25
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
26
27
def escape_commit_message(message):
28
    """Replace xml-incompatible control characters."""
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
29
    # This really ought to be provided by breezy.
30
    # 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.
31
32
    # Python strings can include characters that can't be
33
    # represented in well-formed XML; escape characters that
34
    # aren't listed in the XML specification
35
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
36
    import re
37
    message, _ = re.subn(
38
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
39
        lambda match: match.group(0).encode('unicode_escape'),
40
        message)
41
    return message
42
43
44
def best_format_for_objects_in_a_repository(repo):
45
    """Find the high-level format for branches and trees given a repository.
46
47
    When creating branches and working trees within a repository, Bazaar
48
    defaults to using the default format which may not be the best choice.
49
    This routine does a reverse lookup of the high-level format registry
50
    to find the high-level format that a shared repository was most likely
51
    created via.
52
53
    :return: the BzrDirFormat or None if no matches were found.
54
    """
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
55
    # Based on code from breezy/info.py ...
56
    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.
57
    repo_format = repo._format
58
    candidates  = []
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
59
    non_aliases = set(controldir.format_registry.keys())
60
    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.
61
    for key in non_aliases:
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
62
        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.
63
        # LocalGitBzrDirFormat has no repository_format
64
        if hasattr(format, "repository_format"):
65
            if format.repository_format == repo_format:
66
                candidates.append((key, format))
67
    if len(candidates):
68
        # Assume the first one. Is there any reason not to do that?
69
        name, format = candidates[0]
70
        return format
71
    else:
72
        return None
73
74
75
def open_destination_directory(location, format=None, verbose=True):
76
    """Open a destination directory and return the BzrDir.
77
78
    If destination has a control directory, it will be returned.
79
    Otherwise, the destination should be empty or non-existent and
80
    a shared repository will be created there.
81
82
    :param location: the destination directory
83
    :param format: the format to use or None for the default
84
    :param verbose: display the format used if a repository is created.
85
    :return: BzrDir for the destination
86
    """
87
    import os
6667.2.1 by Jelmer Vernooij
Some cleanup; s/BzrDir/ControlDir/, remove some unused imports.
88
    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.
89
    try:
6667.2.1 by Jelmer Vernooij
Some cleanup; s/BzrDir/ControlDir/, remove some unused imports.
90
        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.
91
        # XXX: Check the relpath is None here?
92
        return control
93
    except errors.NotBranchError:
94
        pass
95
96
    # If the directory exists, check it is empty. Otherwise create it.
97
    if os.path.exists(location):
98
        contents = os.listdir(location)
99
        if contents:
100
            errors.BzrCommandError("Destination must have a .bzr directory, "
101
                " not yet exist or be empty - files found in %s" % (location,))
102
    else:
103
        try:
104
            os.mkdir(location)
105
        except IOError, ex:
106
            errors.BzrCommandError("Unable to create %s: %s" %
107
                (location, ex))
108
109
    # Create a repository for the nominated format.
110
    trace.note("Creating destination repository ...")
111
    if format is None:
6658.5.2 by Jelmer Vernooij
Remove breezy.bzrdir.format_registry.
112
        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.
113
    to_transport = transport.get_transport(location)
114
    to_transport.ensure_base()
115
    control = format.initialize_on_transport(to_transport)
116
    repo = control.create_repository(shared=True)
117
    if verbose:
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
118
        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.
119
        show_bzrdir_info(repo.bzrdir, verbose=0)
120
    return control
0.123.8 by Jelmer Vernooij
Use modes for FileModifyCommand.
121
122
123
def kind_to_mode(kind, executable):
124
    if kind == "file":
125
        if executable == True:
126
            return stat.S_IFREG | 0755
127
        elif executable == False:
128
            return stat.S_IFREG | 0644
129
        else:
130
            raise AssertionError("Executable %r invalid" % executable)
131
    elif kind == "symlink":
132
        return stat.S_IFLNK
133
    elif kind == "directory":
134
        return stat.S_IFDIR
135
    elif kind == "tree-reference":
136
        return 0160000
137
    else:
138
        raise AssertionError("Unknown file kind '%s'" % kind)
139
140
141
def mode_to_kind(mode):
142
    # Note: Output from git-fast-export slightly different to spec
143
    if mode in (0644, 0100644):
144
        return 'file', False
145
    elif mode in (0755, 0100755):
146
        return 'file', True
147
    elif mode == 0040000:
148
        return 'directory', False
149
    elif mode == 0120000:
150
        return 'symlink', False
151
    elif mode == 0160000:
152
        return 'tree-reference', False
153
    else:
154
        raise AssertionError("invalid mode %o" % mode)
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
155
156
157
def binary_stream(stream):
158
    """Ensure a stream is binary on Windows.
159
160
    :return: the stream
161
    """
162
    try:
163
        import os
164
        if os.name == 'nt':
165
            fileno = getattr(stream, 'fileno', None)
166
            if fileno:
167
                no = fileno()
168
                if no >= 0:     # -1 means we're working as subprocess
169
                    import msvcrt
170
                    msvcrt.setmode(no, os.O_BINARY)
171
    except ImportError:
172
        pass
173
    return stream
174
175
176
def single_plural(n, single, plural):
177
    """Return a single or plural form of a noun based on number."""
178
    if n == 1:
179
        return single
180
    else:
181
        return plural
182
183
184
def invert_dictset(d):
185
    """Invert a dictionary with keys matching a set of values, turned into lists."""
186
    # Based on recipe from ASPN
187
    result = {}
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
188
    for k, c in d.items():
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
189
        for v in c:
190
            keys = result.setdefault(v, [])
191
            keys.append(k)
192
    return result
193
194
195
def invert_dict(d):
196
    """Invert a dictionary with keys matching each value turned into a list."""
197
    # Based on recipe from ASPN
198
    result = {}
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
199
    for k, v in d.items():
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
200
        keys = result.setdefault(v, [])
201
        keys.append(k)
202
    return result
203
204