1 # Copyright (C) 2008 Canonical Ltd
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.
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.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 """Miscellaneous useful stuff."""
21 def escape_commit_message(message
):
22 """Replace xml-incompatible control characters."""
23 # This really ought to be provided by bzrlib.
24 # Code copied from bzrlib.commit.
26 # Python strings can include characters that can't be
27 # represented in well-formed XML; escape characters that
28 # aren't listed in the XML specification
29 # (http://www.w3.org/TR/REC-xml/#NT-Char).
32 u
'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
33 lambda match
: match
.group(0).encode('unicode_escape'),
38 def best_format_for_objects_in_a_repository(repo
):
39 """Find the high-level format for branches and trees given a repository.
41 When creating branches and working trees within a repository, Bazaar
42 defaults to using the default format which may not be the best choice.
43 This routine does a reverse lookup of the high-level format registry
44 to find the high-level format that a shared repository was most likely
47 :return: the BzrDirFormat or None if no matches were found.
49 # Based on code from bzrlib/info.py ...
50 from bzrlib
import bzrdir
51 repo_format
= repo
._format
53 non_aliases
= set(bzrdir
.format_registry
.keys())
54 non_aliases
.difference_update(bzrdir
.format_registry
.aliases())
55 for key
in non_aliases
:
56 format
= bzrdir
.format_registry
.make_bzrdir(key
)
57 # LocalGitBzrDirFormat has no repository_format
58 if hasattr(format
, "repository_format"):
59 if format
.repository_format
== repo_format
:
60 candidates
.append((key
, format
))
62 # Assume the first one. Is there any reason not to do that?
63 name
, format
= candidates
[0]
69 def open_destination_directory(location
, format
=None, verbose
=True):
70 """Open a destination directory and return the BzrDir.
72 If destination has a control directory, it will be returned.
73 Otherwise, the destination should be empty or non-existent and
74 a shared repository will be created there.
76 :param location: the destination directory
77 :param format: the format to use or None for the default
78 :param verbose: display the format used if a repository is created.
79 :return: BzrDir for the destination
82 from bzrlib
import bzrdir
, errors
, trace
, transport
84 control
, relpath
= bzrdir
.BzrDir
.open_containing(location
)
85 # XXX: Check the relpath is None here?
87 except errors
.NotBranchError
:
90 # If the directory exists, check it is empty. Otherwise create it.
91 if os
.path
.exists(location
):
92 contents
= os
.listdir(location
)
94 errors
.BzrCommandError("Destination must have a .bzr directory, "
95 " not yet exist or be empty - files found in %s" % (location
,))
100 errors
.BzrCommandError("Unable to create %s: %s" %
103 # Create a repository for the nominated format.
104 trace
.note("Creating destination repository ...")
106 format
= bzrdir
.format_registry
.make_bzrdir('default')
107 to_transport
= transport
.get_transport(location
)
108 to_transport
.ensure_base()
109 control
= format
.initialize_on_transport(to_transport
)
110 repo
= control
.create_repository(shared
=True)
112 from bzrlib
.info
import show_bzrdir_info
113 show_bzrdir_info(repo
.bzrdir
, verbose
=0)
117 def kind_to_mode(kind
, executable
):
119 if executable
== True:
120 return stat
.S_IFREG |
0755
121 elif executable
== False:
122 return stat
.S_IFREG |
0644
124 raise AssertionError("Executable %r invalid" % executable
)
125 elif kind
== "symlink":
127 elif kind
== "directory":
129 elif kind
== "tree-reference":
132 raise AssertionError("Unknown file kind '%s'" % kind
)
135 def mode_to_kind(mode
):
136 # Note: Output from git-fast-export slightly different to spec
137 if mode
in (0644, 0100644):
139 elif mode
in (0755, 0100755):
141 elif mode
== 0040000:
142 return 'directory', False
143 elif mode
== 0120000:
144 return 'symlink', False
145 elif mode
== 0160000:
146 return 'tree-reference', False
148 raise AssertionError("invalid mode %o" % mode
)