# along with this program. If not, see <http://www.gnu.org/licenses/>.
from bzrlib import osutils, ui
+from bzrlib.errors import InvalidRevisionId
from bzrlib.trace import mutter
-from bzrlib.plugins.svn import mapping
-from mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path,
+from bzrlib.plugins.svn import core, constants, mapping, properties
+from bzrlib.plugins.svn.layout import RepositoryLayout
+from bzrlib.plugins.svn.mapping3.scheme import (BranchingScheme, guess_scheme_from_branch_path,
guess_scheme_from_history, ListBranchingScheme,
- parse_list_scheme_text)
+ parse_list_scheme_text, NoBranchingScheme,
+ TrunkBranchingScheme, ListBranchingScheme)
import sha
SVN_PROP_BZR_BRANCHING_SCHEME = 'bzr:branching-scheme'
# Number of revisions to evaluate when guessing the branching scheme
SCHEME_GUESS_SAMPLE_SIZE = 2000
+def expand_branch_pattern(begin, todo, check_path, get_children):
+ path = "/".join(begin)
+ if len(todo) == 0:
+ if check_path(path):
+ return [path]
+ else:
+ return []
+ if not "*" in todo[0]:
+ return expand_branch_pattern(begin+[todo[0]], todo[1:], check_path, get_children)
+ children = get_children(path)
+ if children is None:
+ return []
+ ret = []
+ for c in children:
+ if len(todo) == 1:
+ ret.append("/".join(begin+[c]))
+ else:
+ ret += expand_branch_pattern(begin+[c], todo[1:], check_path, get_children)
+ return ret
+
+
+class SchemeDerivedLayout(RepositoryLayout):
+ def __init__(self, repository, scheme):
+ self.repository = repository
+ self.scheme = scheme
+
+ def parse(self, path):
+ (bp, rp) = self.scheme.unprefix(path)
+ if self.scheme.is_tag(bp):
+ type = "tag"
+ else:
+ type = "branch"
+ return (type, "", bp, rp)
+
+ def get_branches(self, revnum, project=""):
+ def check_path(path):
+ return self.repository.transport.check_path(path, revnum) == core.NODE_DIR
+ def find_children(path):
+ try:
+ assert not path.startswith("/")
+ dirents = self.repository.transport.get_dir(path, revnum)[0]
+ except core.SubversionException, (msg, num):
+ if num == constants.ERR_FS_NOT_DIRECTORY:
+ return None
+ if num == constants.ERR_FS_NOT_FOUND:
+ return None
+ raise
+ return dirents.keys()
+
+ for pattern in self.scheme.branch_list:
+ for bp in expand_branch_pattern([], pattern.split("/"), check_path,
+ find_children):
+ yield "", bp, bp.split("/")[-1]
+
+ def is_branch_parent(self, path):
+ # Na, na, na...
+ return self.scheme.is_branch_parent(path)
+
+ def is_tag_parent(self, path):
+ # Na, na, na...
+ return self.scheme.is_tag_parent(path)
+
+
def get_stored_scheme(repository):
"""Retrieve the stored branching scheme, either in the repository
or in the configuration file.
return (None, False)
+
def get_property_scheme(repository, revnum=None):
if revnum is None:
revnum = repository.get_latest_revnum()
return None
return ListBranchingScheme(parse_list_scheme_text(text))
+
def set_property_scheme(repository, scheme):
def done(revmetadata, pool):
pass
editor = repository.transport.get_commit_editor(
- {svn.core.SVN_PROP_REVISION_LOG: "Updating branching scheme for Bazaar."},
+ {properties.PROP_REVISION_LOG: "Updating branching scheme for Bazaar."},
done, None, False)
root = editor.open_root(-1)
editor.change_dir_prop(root, SVN_PROP_BZR_BRANCHING_SCHEME,
editor.close_directory(root)
editor.close()
+
def repository_guess_scheme(repository, last_revnum, branch_path=None):
pb = ui.ui_factory.nested_progress_bar()
try:
scheme = guess_scheme_from_history(
- repository._log.iter_changes("", last_revnum, max(0, last_revnum-SCHEME_GUESS_SAMPLE_SIZE), pb=pb), last_revnum, branch_path)
+ repository._log.iter_changes(None, last_revnum, max(0, last_revnum-SCHEME_GUESS_SAMPLE_SIZE), pb=pb), last_revnum, branch_path)
finally:
pb.finished()
mutter("Guessed branching scheme: %r" % scheme)
return scheme
-def set_branching_scheme(repository, scheme, mandatory=False):
- repository.get_config().set_branching_scheme(str(scheme), mandatory=mandatory)
+def config_set_scheme(repository, scheme, mandatory=False):
+ repository.get_config().set_branching_scheme(str(scheme),
+ mandatory=mandatory)
+
+def set_branching_scheme(repository, scheme, mandatory=False):
+ repository.get_mapping().scheme = scheme
+ config_set_scheme(repository, scheme, mandatory)
class BzrSvnMappingv3(mapping.BzrSvnMapping):
self.scheme = scheme
assert not isinstance(scheme, str)
+ def get_mandated_layout(self, repository):
+ return SchemeDerivedLayout(repository, self.scheme)
+
@classmethod
def from_repository(cls, repository, _hinted_branch_path=None):
(scheme, mandatory) = get_stored_scheme(repository)
last_revnum = repository.get_latest_revnum()
scheme = repository_guess_scheme(repository, last_revnum, _hinted_branch_path)
if last_revnum > 20:
- set_branching_scheme(repository, scheme, mandatory=False)
+ config_set_scheme(repository, scheme, mandatory=False)
return cls(scheme)