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, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 """Miscellaneous useful stuff."""
22 def escape_commit_message(message
):
23 """Replace xml-incompatible control characters."""
24 # This really ought to be provided by bzrlib.
25 # Code copied from bzrlib.commit.
27 # Python strings can include characters that can't be
28 # represented in well-formed XML; escape characters that
29 # aren't listed in the XML specification
30 # (http://www.w3.org/TR/REC-xml/#NT-Char).
33 u
'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
34 lambda match
: match
.group(0).encode('unicode_escape'),
39 def best_format_for_objects_in_a_repository(repo
):
40 """Find the high-level format for branches and trees given a repository.
42 When creating branches and working trees within a repository, Bazaar
43 defaults to using the default format which may not be the best choice.
44 This routine does a reverse lookup of the high-level format registry
45 to find the high-level format that a shared repository was most likely
48 :return: the BzrDirFormat or None if no matches were found.
50 # Based on code from bzrlib/info.py ...
51 from bzrlib
import bzrdir
52 repo_format
= repo
._format
54 non_aliases
= set(bzrdir
.format_registry
.keys())
55 non_aliases
.difference_update(bzrdir
.format_registry
.aliases())
56 for key
in non_aliases
:
57 format
= bzrdir
.format_registry
.make_bzrdir(key
)
58 # LocalGitBzrDirFormat has no repository_format
59 if hasattr(format
, "repository_format"):
60 if format
.repository_format
== repo_format
:
61 candidates
.append((key
, format
))
63 # Assume the first one. Is there any reason not to do that?
64 name
, format
= candidates
[0]
70 def open_destination_directory(location
, format
=None, verbose
=True):
71 """Open a destination directory and return the BzrDir.
73 If destination has a control directory, it will be returned.
74 Otherwise, the destination should be empty or non-existent and
75 a shared repository will be created there.
77 :param location: the destination directory
78 :param format: the format to use or None for the default
79 :param verbose: display the format used if a repository is created.
80 :return: BzrDir for the destination
83 from bzrlib
import bzrdir
, errors
, trace
, transport
85 control
, relpath
= bzrdir
.BzrDir
.open_containing(location
)
86 # XXX: Check the relpath is None here?
88 except errors
.NotBranchError
:
91 # If the directory exists, check it is empty. Otherwise create it.
92 if os
.path
.exists(location
):
93 contents
= os
.listdir(location
)
95 errors
.BzrCommandError("Destination must have a .bzr directory, "
96 " not yet exist or be empty - files found in %s" % (location
,))
101 errors
.BzrCommandError("Unable to create %s: %s" %
104 # Create a repository for the nominated format.
105 trace
.note("Creating destination repository ...")
107 format
= bzrdir
.format_registry
.make_bzrdir('default')
108 to_transport
= transport
.get_transport(location
)
109 to_transport
.ensure_base()
110 control
= format
.initialize_on_transport(to_transport
)
111 repo
= control
.create_repository(shared
=True)
113 from bzrlib
.info
import show_bzrdir_info
114 show_bzrdir_info(repo
.bzrdir
, verbose
=0)
118 def kind_to_mode(kind
, executable
):
120 if executable
== True:
121 return stat
.S_IFREG |
0755
122 elif executable
== False:
123 return stat
.S_IFREG |
0644
125 raise AssertionError("Executable %r invalid" % executable
)
126 elif kind
== "symlink":
128 elif kind
== "directory":
130 elif kind
== "tree-reference":
133 raise AssertionError("Unknown file kind '%s'" % kind
)
136 def mode_to_kind(mode
):
137 # Note: Output from git-fast-export slightly different to spec
138 if mode
in (0644, 0100644):
140 elif mode
in (0755, 0100755):
142 elif mode
== 0040000:
143 return 'directory', False
144 elif mode
== 0120000:
145 return 'symlink', False
146 elif mode
== 0160000:
147 return 'tree-reference', False
149 raise AssertionError("invalid mode %o" % mode
)