def __init__(self, path=None, encoded=None): if encoded is not None: path = prop_name_unquote(encoded) self.path = path.strip("/") if self.path == "": raise BzrError("NoBranchingScheme should be used") ListBranchingScheme.__init__(self, [self.path])
def etckeeper_startcommit_hook(tree): abspath = getattr(tree, "abspath", None) if abspath is None or not os.path.exists(abspath(".etckeeper")): # Only run the commit hook when this is an etckeeper branch return import subprocess ret = subprocess.call(["etckeeper", "pre-commit", abspath(".")]) if ret != 0: raise BzrError("etckeeper pre-commit failed")
def create_svn_keywords_filter(value): if not value: return kws = value.split(" ") for k in kws: if not k in keywords: raise BzrError(gettext("Unknown svn keyword %s") % k) if kws == []: return [] return [SubversionKeywordContentFilter(kws)]
def get_use_cache(self): try: if self.get_bool("use-cache"): return set(["log", "fileids", "revids", "revinfo"]) return set() except ValueError: val = self._get_user_option("use-cache") if not isinstance(val, list): ret = set([val]) else: ret = set(val) if len(ret - set(["log", "fileids", "revids", "revinfo"])) != 0: raise BzrError("Invalid setting 'use-cache': %r" % val) return ret except KeyError: return None
def __init__(self, source_repos, output_url, layout=None, create_shared_repo=True, working_trees=False, all=False, format=None, filter_branch=None, keep=False, incremental=False, to_revnum=None, prefix=None, colocated=False, remember_parent=True): """Convert a Subversion repository and its' branches to a Bazaar repository. :param source_repos: Subversion repository :param output_url: URL to write Bazaar repository to. :param layout: Repository layout (object) to use :param create_shared_repo: Whether to create a shared Bazaar repository :param working_trees: Whether to create working trees :param all: Whether old revisions, even those not part of any existing branches, should be imported. :param format: Format to use :param remember_parent: Remember parent branch location """ assert not all or create_shared_repo if format is None: self._format = controldir.format_registry.make_controldir( 'default') else: self._format = format self.dirs = {} self.to_transport = get_transport(output_url) try: self.to_transport.mkdir('.') except FileExists: pass if layout is not None: source_repos.set_layout(layout) else: layout = source_repos.get_layout() try: target_dir = controldir.ControlDir.open_from_transport( self.to_transport) except NotBranchError: target_dir = None else: format = target_dir._format if colocated is None: colocated = getattr(format, "colocated_branches", False) if target_dir is None and (colocated or create_shared_repo): target_dir = self.get_dir(prefix, prefix) if create_shared_repo: try: target_repos = target_dir.open_repository() target_repos_is_empty = False # FIXME: Call Repository.is_empty() ? if not layout.is_branch(u"") and not target_repos.is_shared( ) and not colocated: raise BzrError("Repository %r is not shared." % target_repos) except NoRepositoryPresent: target_repos = target_dir.create_repository(shared=True) target_repos_is_empty = True target_repos.set_make_working_trees(working_trees) else: target_repos = None target_repos_is_empty = False with source_repos.lock_read(): if incremental and target_repos is not None: from_revnum = get_latest_svn_import_revision( target_repos, source_repos.uuid) else: from_revnum = 0 if to_revnum is None: to_revnum = source_repos.get_latest_revnum() if to_revnum < from_revnum: return mapping = source_repos.get_mapping() existing_branches = {} deleted = set() it = source_repos._revmeta_provider.iter_all_changes( layout, mapping.is_branch_or_tag, to_revnum, from_revnum, prefix=prefix) if create_shared_repo: revfinder = FetchRevisionFinder(source_repos, target_repos, target_repos_is_empty) revmetas = [] else: revmetas = None if all: heads = None else: heads = set() with ui.ui_factory.nested_progress_bar() as pb: for kind, item in it: if kind == "revision": pb.update("finding branches", to_revnum - item.metarev.revnum, to_revnum - from_revnum) if (not item.metarev.branch_path in existing_branches and layout.is_branch(item.metarev.branch_path) and not contains_parent_path( deleted, item.metarev.branch_path)): existing_branches[ item.metarev.branch_path] = SvnBranch( source_repos, None, item.metarev.branch_path, revnum=item.metarev.revnum, _skip_check=True, mapping=mapping) if heads is not None: heads.add(item) if revmetas is not None: revmetas.append(item) elif kind == "delete": (path, revnum) = item deleted.add(path) if create_shared_repo: if not InterFromSvnToInventoryRepository.is_compatible( source_repos, target_repos): raise IncompatibleRepositories(source_repos, target_repos) inter = InterFromSvnToInventoryRepository.get( source_repos, target_repos) self._fetch_to_shared_repo(inter, prefix, from_revnum, revmetas, revfinder, mapping, heads) if not keep: self._remove_branches(deleted, existing_branches.keys()) existing_branches = existing_branches.values() if filter_branch is not None: existing_branches = filter(filter_branch, existing_branches) self._create_branches(existing_branches, prefix, create_shared_repo, working_trees, colocated, remember_parent) if target_repos is not None: put_latest_svn_import_revision(target_repos, source_repos.uuid, to_revnum)
create_auth_baton, ) from .changes import ( common_prefix, ) from .errors import ( convert_svn_error, DavRequestFailed, NoSvnRepositoryPresent, convert_error, ) try: svn_config = get_config() except subvertpy.SubversionException as e: msg, num = e.args if num == subvertpy.ERR_MALFORMED_FILE: raise BzrError(msg) raise # This variable is here to allow tests to temporarily disable features # to see how bzr-svn copes with that disabled_capabilities = set() # Don't run any tests on SvnTransport as it is not intended to be # a full implementation of Transport def get_test_permutations(): return [] _warned_codeplex = False
def copy_content(self, revision_id=None, pb=None, project=None, mapping=None, limit=None, lossy=False, exclude_non_mainline=None): """See InterRepository.copy_content.""" with self.source.lock_read(), self.target.lock_write(): graph = self.get_graph() if revision_id is not None: heads = [revision_id] else: heads = graph.heads(self.source.all_revision_ids()) exclude_non_mainline = False todo = [] # Go back over the LHS parent until we reach a revid we know for head in heads: try: for revid in graph.iter_lefthand_ancestry(head, (NULL_REVISION, None)): if self._target_has_revision(revid): break todo.append(revid) except RevisionNotPresent as e: raise NoSuchRevision(self.source, e.revision_id) todo.reverse() if limit is not None: # FIXME: This only considers mainline revisions. # Properly keeping track of how many revisions have been # pushed will be fairly complicated though, so for the # moment this is reasonable enough (and passes tests). todo = todo[:limit] mutter("pushing %r into svn", todo) base_foreign_info = None layout = self.target.get_layout() for rev in self.source.get_revisions(todo): if pb is not None: pb.update("pushing revisions", todo.index(rev.revision_id), len(todo)) mutter('pushing %r', rev.revision_id) if base_foreign_info is None: if rev.parent_ids: base_revid = rev.parent_ids[0] else: base_revid = NULL_REVISION base_foreign_info = self._get_foreign_revision_info( base_revid) (base_foreign_revid, base_mapping) = base_foreign_info if base_foreign_revid is None: target_project = None else: (_, target_project, _, _) = layout.parse( base_foreign_revid[1]) bp = determine_branch_path(rev, layout, target_project) mutter("pushing revision include %r to %s", rev.revision_id, bp) target_config = self._get_branch_config(bp) can_push_merged = layout.push_merged_revisions(target_project) if exclude_non_mainline is None: push_merged = can_push_merged and ( target_config.get('push_merged_revisions')) else: push_merged = (not exclude_non_mainline) if push_merged and not can_push_merged: raise BzrError( "Unable to push merged revisions, layout " "does not provide branch path") append_revisions_only = target_config.get('append_revisions_only') if append_revisions_only is None: append_revisions_only = True root_action = self._get_root_action(bp, rev.parent_ids, overwrite=False, append_revisions_only=append_revisions_only, create_prefix=True) (pushed_revid, base_foreign_info) = self.push_revision_inclusive( bp, target_config, rev, push_metadata=not lossy, push_merged=push_merged, root_action=root_action, layout=layout, project=target_project, base_foreign_info=base_foreign_info)
def push_revision_tree(graph, target_repo, branch_path, config_stack, source_repo, base_revid, revision_id, rev, base_foreign_revid, base_mapping, push_metadata, root_action): """Push a revision tree into a target repository. :param graph: Repository graph. :param target_repo: Target repository. :param branch_path: Branch path. :param config_stack: Branch configuration. :param source_repo: Source repository. :param base_revid: Base revision id. :param revision_id: Revision id to push. :param rev: Revision object of revision to push. :param push_metadata: Whether to push metadata. :param root_action: Action to take on the tree root :return: Revision id of newly created revision. """ if not isinstance(branch_path, text_type): raise TypeError(branch_path) if target_repo._lock_mode != 'w': raise NotWriteLocked(target_repo) assert rev.revision_id in (None, revision_id) old_tree = source_repo.revision_tree(revision_id) if rev.parent_ids: base_tree = source_repo.revision_tree(rev.parent_ids[0]) else: base_tree = source_repo.revision_tree(NULL_REVISION) if push_metadata: base_revids = rev.parent_ids else: base_revids = [base_revid] try: opt_signature = source_repo.get_signature_text(rev.revision_id) except NoSuchRevision: opt_signature = None if push_metadata: testament = StrictTestament.from_revision_tree(old_tree) else: testament = None builder = SvnCommitBuilder(target_repo, branch_path, base_revids, config_stack, rev.timestamp, rev.timezone, rev.committer, rev.properties, revision_id, base_foreign_revid, base_mapping, root_action, base_tree, push_metadata=push_metadata, graph=graph, opt_signature=opt_signature, testament=testament, _rich_root_bump=not source_repo.supports_rich_root()) target_repo.start_write_group() try: builder.will_record_deletes() iter_changes = old_tree.iter_changes(base_tree) iter_changes = _filter_iter_changes(iter_changes) for path, fs_hash in builder.record_iter_changes( old_tree, base_tree.get_revision_id(), iter_changes): pass builder.finish_inventory() except BaseException: builder.abort() raise try: revid = builder.commit(rev.message) except SubversionException as e: builder.abort() if e.args[1] == ERR_FS_TXN_OUT_OF_DATE: raise DivergedBranches(source_repo, target_repo) raise except ChangesRootLHSHistory: raise BzrError("Unable to push revision %r because it would change " "the ordering of existing revisions on the Subversion repository " "root. Use rebase and try again or push to a non-root path" % revision_id) return revid, (builder.result_foreign_revid, builder.mapping)
pass builder.finish_inventory() except: builder.abort() raise try: revid = builder.commit(rev.message) except SubversionException, (msg, num): builder.abort() if num == ERR_FS_TXN_OUT_OF_DATE: raise DivergedBranches(source_repo, target_repo) raise except ChangesRootLHSHistory: raise BzrError( "Unable to push revision %r because it would change " "the ordering of existing revisions on the Subversion repository " "root. Use rebase and try again or push to a non-root path" % revision_id) return revid, (builder.result_foreign_revid, builder.mapping) class InterToSvnRepository(InterRepository): """Any to Subversion repository actions.""" _matching_repo_format = SvnRepositoryFormat() def __init__(self, source, target, graph=None): InterRepository.__init__(self, source, target) self._graph = graph # Dictionary: revid -> branch_path -> (foreign_revid, mapping)
def set_default_stack_on(self, value): raise BzrError("Cannot set configuration")