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."""
19 from fastimport
.helpers
import (
24 def common_directory(paths
):
25 """Find the deepest common directory of a list of paths.
27 :return: if no paths are provided, None is returned;
28 if there is no common directory, '' is returned;
29 otherwise the common directory with a trailing / is returned.
31 from bzrlib
import osutils
32 def get_dir_with_slash(path
):
33 if path
== '' or path
.endswith('/'):
36 dirname
, basename
= osutils
.split(path
)
45 return get_dir_with_slash(paths
[0])
47 common
= common_path(paths
[0], paths
[1])
48 for path
in paths
[2:]:
49 common
= common_path(common
, path
)
50 return get_dir_with_slash(common
)
53 def escape_commit_message(message
):
54 """Replace xml-incompatible control characters."""
55 # This really ought to be provided by bzrlib.
56 # Code copied from bzrlib.commit.
58 # Python strings can include characters that can't be
59 # represented in well-formed XML; escape characters that
60 # aren't listed in the XML specification
61 # (http://www.w3.org/TR/REC-xml/#NT-Char).
64 u
'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
65 lambda match
: match
.group(0).encode('unicode_escape'),
70 def best_format_for_objects_in_a_repository(repo
):
71 """Find the high-level format for branches and trees given a repository.
73 When creating branches and working trees within a repository, Bazaar
74 defaults to using the default format which may not be the best choice.
75 This routine does a reverse lookup of the high-level format registry
76 to find the high-level format that a shared repository was most likely
79 :return: the BzrDirFormat or None if no matches were found.
81 # Based on code from bzrlib/info.py ...
82 from bzrlib
import bzrdir
83 repo_format
= repo
._format
85 non_aliases
= set(bzrdir
.format_registry
.keys())
86 non_aliases
.difference_update(bzrdir
.format_registry
.aliases())
87 for key
in non_aliases
:
88 format
= bzrdir
.format_registry
.make_bzrdir(key
)
89 # LocalGitBzrDirFormat has no repository_format
90 if hasattr(format
, "repository_format"):
91 if format
.repository_format
== repo_format
:
92 candidates
.append((key
, format
))
94 # Assume the first one. Is there any reason not to do that?
95 name
, format
= candidates
[0]
101 def open_destination_directory(location
, format
=None, verbose
=True):
102 """Open a destination directory and return the BzrDir.
104 If destination has a control directory, it will be returned.
105 Otherwise, the destination should be empty or non-existent and
106 a shared repository will be created there.
108 :param location: the destination directory
109 :param format: the format to use or None for the default
110 :param verbose: display the format used if a repository is created.
111 :return: BzrDir for the destination
114 from bzrlib
import bzrdir
, errors
, trace
, transport
116 control
, relpath
= bzrdir
.BzrDir
.open_containing(location
)
117 # XXX: Check the relpath is None here?
119 except errors
.NotBranchError
:
122 # If the directory exists, check it is empty. Otherwise create it.
123 if os
.path
.exists(location
):
124 contents
= os
.listdir(location
)
126 errors
.BzrCommandError("Destination must have a .bzr directory, "
127 " not yet exist or be empty - files found in %s" % (location
,))
132 errors
.BzrCommandError("Unable to create %s: %s" %
135 # Create a repository for the nominated format.
136 trace
.note("Creating destination repository ...")
138 format
= bzrdir
.format_registry
.make_bzrdir('default')
139 to_transport
= transport
.get_transport(location
)
140 to_transport
.ensure_base()
141 control
= format
.initialize_on_transport(to_transport
)
142 repo
= control
.create_repository(shared
=True)
144 from bzrlib
.info
import show_bzrdir_info
145 show_bzrdir_info(repo
.bzrdir
, verbose
=0)