Esempio n. 1
0
def get_ancestry(repository, revision_id):
    """Return a list of revision-ids integrated by a revision.

    The first element of the list is always None, indicating the origin
    revision.  This might change when we have history horizons, or
    perhaps we should have a new API.

    This is topologically sorted.
    """
    if is_null(revision_id):
        return set()
    if not repository.has_revision(revision_id):
        raise NoSuchRevision(repository, revision_id)
    repository.lock_read()
    try:
        graph = repository.get_graph()
        keys = set()
        search = graph._make_breadth_first_searcher([revision_id])
        while True:
            try:
                found, ghosts = search.next_with_ghosts()
            except StopIteration:
                break
            keys.update(found)
        if NULL_REVISION in keys:
            keys.remove(NULL_REVISION)
    finally:
        repository.unlock()
    return keys
Esempio n. 2
0
def get_ancestry(repository, revision_id):
    """Return a list of revision-ids integrated by a revision.

    The first element of the list is always None, indicating the origin
    revision.  This might change when we have history horizons, or
    perhaps we should have a new API.

    This is topologically sorted.
    """
    if is_null(revision_id):
        return set()
    if not repository.has_revision(revision_id):
        raise NoSuchRevision(repository, revision_id)
    repository.lock_read()
    try:
        graph = repository.get_graph()
        keys = set()
        search = graph._make_breadth_first_searcher([revision_id])
        while True:
            try:
                found, ghosts = search.next_with_ghosts()
            except StopIteration:
                break
            keys.update(found)
        if NULL_REVISION in keys:
            keys.remove(NULL_REVISION)
    finally:
        repository.unlock()
    return keys
    def run(self, location=None, committer=None, dry_run=False):
        if location is None:
            bzrdir = controldir.ControlDir.open_containing('.')[0]
        else:
            # Passed in locations should be exact
            bzrdir = controldir.ControlDir.open(location)
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config_stack()

        if committer is None:
            committer = branch_config.get('email')
        gpg_strategy = gpg.GPGStrategy(branch_config)

        count = 0
        repo.lock_write()
        try:
            graph = repo.get_graph()
            repo.start_write_group()
            try:
                for rev_id, parents in graph.iter_ancestry(
                    [branch.last_revision()]):
                    if _mod_revision.is_null(rev_id):
                        continue
                    if parents is None:
                        # Ignore ghosts
                        continue
                    if repo.has_signature_for_revision_id(rev_id):
                        continue
                    rev = repo.get_revision(rev_id)
                    if rev.committer != committer:
                        continue
                    # We have a revision without a signature who has a
                    # matching committer, start signing
                    self.outf.write("%s\n" % rev_id)
                    count += 1
                    if not dry_run:
                        repo.sign_revision(rev_id, gpg_strategy)
            except:
                repo.abort_write_group()
                raise
            else:
                repo.commit_write_group()
        finally:
            repo.unlock()
        self.outf.write(
            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n', count)
            % count)
    def run(self, location=None, committer=None, dry_run=False):
        if location is None:
            bzrdir = controldir.ControlDir.open_containing('.')[0]
        else:
            # Passed in locations should be exact
            bzrdir = controldir.ControlDir.open(location)
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config_stack()

        if committer is None:
            committer = branch_config.get('email')
        gpg_strategy = gpg.GPGStrategy(branch_config)

        count = 0
        repo.lock_write()
        try:
            graph = repo.get_graph()
            repo.start_write_group()
            try:
                for rev_id, parents in graph.iter_ancestry(
                        [branch.last_revision()]):
                    if _mod_revision.is_null(rev_id):
                        continue
                    if parents is None:
                        # Ignore ghosts
                        continue
                    if repo.has_signature_for_revision_id(rev_id):
                        continue
                    rev = repo.get_revision(rev_id)
                    if rev.committer != committer:
                        continue
                    # We have a revision without a signature who has a
                    # matching committer, start signing
                    self.outf.write("%s\n" % rev_id)
                    count += 1
                    if not dry_run:
                        repo.sign_revision(rev_id, gpg_strategy)
            except:
                repo.abort_write_group()
                raise
            else:
                repo.commit_write_group()
        finally:
            repo.unlock()
        self.outf.write(
            ngettext('Signed %d revision.\n', 'Signed %d revisions.\n', count) %
            count)
Esempio n. 5
0
 def initialize(self,
                a_bzrdir,
                revision_id=None,
                from_branch=None,
                accelerator_tree=None,
                hardlink=False):
     """See WorkingTreeFormat.initialize()."""
     if not isinstance(a_bzrdir.transport, LocalTransport):
         raise errors.NotLocalUrl(a_bzrdir.transport.base)
     if from_branch is not None:
         branch = from_branch
     else:
         branch = a_bzrdir.open_branch()
     if revision_id is None:
         revision_id = _mod_revision.ensure_null(branch.last_revision())
     branch.lock_write()
     try:
         branch.generate_revision_history(revision_id)
     finally:
         branch.unlock()
     inv = inventory.Inventory()
     wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
                       branch,
                       inv,
                       _internal=True,
                       _format=self,
                       _bzrdir=a_bzrdir,
                       _control_files=branch.control_files)
     basis_tree = branch.repository.revision_tree(revision_id)
     if basis_tree.get_root_id() is not None:
         wt.set_root_id(basis_tree.get_root_id())
     # set the parent list and cache the basis tree.
     if _mod_revision.is_null(revision_id):
         parent_trees = []
     else:
         parent_trees = [(revision_id, basis_tree)]
     wt.set_parent_trees(parent_trees)
     transform.build_tree(basis_tree, wt)
     for hook in MutableTree.hooks['post_build_tree']:
         hook(wt)
     return wt
Esempio n. 6
0
 def test_sprout_bzrdir_repository(self):
     tree = self.make_branch_and_tree('commit_tree')
     self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
     tree.add('foo')
     tree.commit('revision 1', rev_id='1')
     dir = self.make_bzrdir('source')
     repo = dir.create_repository()
     repo.fetch(tree.branch.repository)
     self.assertTrue(repo.has_revision('1'))
     try:
         self.assertTrue(
             _mod_revision.is_null(_mod_revision.ensure_null(
             dir.open_branch().last_revision())))
     except errors.NotBranchError:
         pass
     target = dir.sprout(self.get_url('target'))
     self.assertNotEqual(dir.transport.base, target.transport.base)
     # testing inventory isn't reasonable for repositories
     self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
                                 [
                                  './.bzr/branch',
                                  './.bzr/checkout',
                                  './.bzr/inventory',
                                  './.bzr/parent',
                                  './.bzr/repository/inventory.knit',
                                  ])
     try:
         local_inventory = dir.transport.local_abspath('inventory')
     except errors.NotLocalUrl:
         return
     try:
         # If we happen to have a tree, we'll guarantee everything
         # except for the tree root is the same.
         inventory_f = file(local_inventory, 'rb')
         self.addCleanup(inventory_f.close)
         self.assertContainsRe(inventory_f.read(),
                               '<inventory format="5">\n</inventory>\n')
     except IOError, e:
         if e.errno != errno.ENOENT:
             raise
Esempio n. 7
0
 def test_sprout_bzrdir_repository(self):
     tree = self.make_branch_and_tree('commit_tree')
     self.build_tree(['foo'], transport=tree.bzrdir.transport.clone('..'))
     tree.add('foo')
     tree.commit('revision 1', rev_id='1')
     dir = self.make_bzrdir('source')
     repo = dir.create_repository()
     repo.fetch(tree.branch.repository)
     self.assertTrue(repo.has_revision('1'))
     try:
         self.assertTrue(
             _mod_revision.is_null(_mod_revision.ensure_null(
             dir.open_branch().last_revision())))
     except errors.NotBranchError:
         pass
     target = dir.sprout(self.get_url('target'))
     self.assertNotEqual(dir.transport.base, target.transport.base)
     # testing inventory isn't reasonable for repositories
     self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
                                 [
                                  './.bzr/branch',
                                  './.bzr/checkout',
                                  './.bzr/inventory',
                                  './.bzr/parent',
                                  './.bzr/repository/inventory.knit',
                                  ])
     try:
         local_inventory = dir.transport.local_abspath('inventory')
     except errors.NotLocalUrl:
         return
     try:
         # If we happen to have a tree, we'll guarantee everything
         # except for the tree root is the same.
         inventory_f = file(local_inventory, 'rb')
         self.addCleanup(inventory_f.close)
         self.assertContainsRe(inventory_f.read(),
                               '<inventory format="5">\n</inventory>\n')
     except IOError, e:
         if e.errno != errno.ENOENT:
             raise
Esempio n. 8
0
 def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
                accelerator_tree=None, hardlink=False):
     """See WorkingTreeFormat.initialize()."""
     if not isinstance(a_bzrdir.transport, LocalTransport):
         raise errors.NotLocalUrl(a_bzrdir.transport.base)
     if from_branch is not None:
         branch = from_branch
     else:
         branch = a_bzrdir.open_branch()
     if revision_id is None:
         revision_id = _mod_revision.ensure_null(branch.last_revision())
     branch.lock_write()
     try:
         branch.generate_revision_history(revision_id)
     finally:
         branch.unlock()
     inv = inventory.Inventory()
     wt = WorkingTree2(a_bzrdir.root_transport.local_abspath('.'),
                      branch,
                      inv,
                      _internal=True,
                      _format=self,
                      _bzrdir=a_bzrdir,
                      _control_files=branch.control_files)
     basis_tree = branch.repository.revision_tree(revision_id)
     if basis_tree.get_root_id() is not None:
         wt.set_root_id(basis_tree.get_root_id())
     # set the parent list and cache the basis tree.
     if _mod_revision.is_null(revision_id):
         parent_trees = []
     else:
         parent_trees = [(revision_id, basis_tree)]
     wt.set_parent_trees(parent_trees)
     transform.build_tree(basis_tree, wt)
     for hook in MutableTree.hooks['post_build_tree']:
         hook(wt)
     return wt
Esempio n. 9
0
def uncommit(branch, dry_run=False, verbose=False, revno=None, tree=None,
             local=False):
    """Remove the last revision from the supplied branch.

    :param dry_run: Don't actually change anything
    :param verbose: Print each step as you do it
    :param revno: Remove back to this revision
    :param local: If this branch is bound, only remove the revisions from the
        local branch. If this branch is not bound, it is an error to pass
        local=True.
    """
    unlockable = []
    try:
        if tree is not None:
            tree.lock_write()
            unlockable.append(tree)
        
        branch.lock_write()
        unlockable.append(branch)

        pending_merges = []
        if tree is not None:
            pending_merges = tree.get_parent_ids()[1:]

        if local:
            master = None
            if branch.get_bound_location() is None:
                raise errors.LocalRequiresBoundBranch()
        else:
            master = branch.get_master_branch()
            if master is not None:
                master.lock_write()
                unlockable.append(master)
        old_revno, old_tip = branch.last_revision_info()
        if master is not None and old_tip != master.last_revision():
            raise BoundBranchOutOfDate(branch, master)
        if revno is None:
            revno = old_revno
        new_revno = revno - 1

        revid_iterator = branch.repository.iter_reverse_revision_history(
                            old_tip)
        cur_revno = old_revno
        new_revision_id = old_tip
        graph = branch.repository.get_graph()
        for rev_id in revid_iterator:
            if cur_revno == new_revno:
                new_revision_id = rev_id
                break
            if verbose:
                print 'Removing revno %d: %s' % (cur_revno, rev_id)
            cur_revno -= 1
            parents = graph.get_parent_map([rev_id]).get(rev_id, None)
            if not parents:
                continue
            # When we finish popping off the pending merges, we want
            # them to stay in the order that they used to be.
            # but we pop from the end, so reverse the order, and
            # then get the order right at the end
            pending_merges.extend(reversed(parents[1:]))
        else:
            # We ran off the end of revisions, which means we should be trying
            # to get to NULL_REVISION
            new_revision_id = _mod_revision.NULL_REVISION

        if not dry_run:
            if master is not None:
                master.set_last_revision_info(new_revno, new_revision_id)
            branch.set_last_revision_info(new_revno, new_revision_id)
            if master is None:
                hook_local = None
                hook_master = branch
            else:
                hook_local = branch
                hook_master = master
            for hook in Branch.hooks['post_uncommit']:
                hook_new_tip = new_revision_id
                if hook_new_tip == _mod_revision.NULL_REVISION:
                    hook_new_tip = None
                hook(hook_local, hook_master, old_revno, old_tip, new_revno,
                     hook_new_tip)
            if tree is not None:
                if not _mod_revision.is_null(new_revision_id):
                    parents = [new_revision_id]
                else:
                    parents = []
                parents.extend(reversed(pending_merges))
                tree.set_parent_ids(parents)
    finally:
        for item in reversed(unlockable):
            item.unlock()
    def run(self,
            acceptable_keys=None,
            revision=None,
            verbose=None,
            location=u'.'):
        bzrdir = controldir.ControlDir.open_containing(location)[0]
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config_stack()
        gpg_strategy = gpg.GPGStrategy(branch_config)

        gpg_strategy.set_acceptable_keys(acceptable_keys)

        def write(string):
            self.outf.write(string + "\n")

        def write_verbose(string):
            self.outf.write("  " + string + "\n")

        self.add_cleanup(repo.lock_read().unlock)
        #get our list of revisions
        revisions = []
        if revision is not None:
            if len(revision) == 1:
                revno, rev_id = revision[0].in_history(branch)
                revisions.append(rev_id)
            elif len(revision) == 2:
                from_revno, from_revid = revision[0].in_history(branch)
                to_revno, to_revid = revision[1].in_history(branch)
                if to_revid is None:
                    to_revno = branch.revno()
                if from_revno is None or to_revno is None:
                    raise errors.BzrCommandError(
                        gettext(
                            'Cannot verify a range of non-revision-history revisions'
                        ))
                for revno in range(from_revno, to_revno + 1):
                    revisions.append(branch.get_rev_id(revno))
        else:
            #all revisions by default including merges
            graph = repo.get_graph()
            revisions = []
            for rev_id, parents in graph.iter_ancestry(
                [branch.last_revision()]):
                if _mod_revision.is_null(rev_id):
                    continue
                if parents is None:
                    # Ignore ghosts
                    continue
                revisions.append(rev_id)
        count, result, all_verifiable = gpg.bulk_verify_signatures(
            repo, revisions, gpg_strategy)
        if all_verifiable:
            write(gettext("All commits signed with verifiable keys"))
            if verbose:
                for message in gpg.verbose_valid_message(result):
                    write_verbose(message)
            return 0
        else:
            write(gpg.valid_commits_message(count))
            if verbose:
                for message in gpg.verbose_valid_message(result):
                    write_verbose(message)
            write(gpg.expired_commit_message(count))
            if verbose:
                for message in gpg.verbose_expired_key_message(result, repo):
                    write_verbose(message)
            write(gpg.unknown_key_message(count))
            if verbose:
                for message in gpg.verbose_missing_key_message(result):
                    write_verbose(message)
            write(gpg.commit_not_valid_message(count))
            if verbose:
                for message in gpg.verbose_not_valid_message(result, repo):
                    write_verbose(message)
            write(gpg.commit_not_signed_message(count))
            if verbose:
                for message in gpg.verbose_not_signed_message(result, repo):
                    write_verbose(message)
            return 1
Esempio n. 11
0
    def refresh_view(self):
        """get the revisions wanted by the user, do the verifications and
        popular the tree widget with the results"""
        self.throbber.show()
        bzrdir = _mod_bzrdir.BzrDir.open_containing(self.location)[0]
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config()
        gpg_strategy = gpg.GPGStrategy(branch_config)
        gpg_strategy.set_acceptable_keys(self.acceptable_keys)

        if branch.name is None:
            header = branch.user_url
        else:
            header = branch.name
        self.ui.treeWidget.setHeaderLabels([str(header)])

        #get our list of revisions
        revisions = []
        if self.revision is not None:
            if len(self.revision) == 1:
                revno, rev_id = self.revision[0].in_history(branch)
                revisions.append(rev_id)
            elif len(sel.revision) == 2:
                from_revno, from_revid = self.revision[0].in_history(branch)
                to_revno, to_revid = self.revision[1].in_history(branch)
                if to_revid is None:
                    to_revno = branch.revno()
                if from_revno is None or to_revno is None:
                    raise errors.BzrCommandError('Cannot verify a range of '\
                                               'non-revision-history revisions')
                for revno in range(from_revno, to_revno + 1):
                    revisions.append(branch.get_rev_id(revno))
        else:
            #all revisions by default including merges
            graph = repo.get_graph()
            revisions = []
            repo.lock_read()
            for rev_id, parents in graph.iter_ancestry(
                [branch.last_revision()]):
                if _mod_revision.is_null(rev_id):
                    continue
                if parents is None:
                    # Ignore ghosts
                    continue
                revisions.append(rev_id)
            repo.unlock()
        count, result, all_verifiable =\
                                gpg_strategy.do_verifications(revisions, repo,
                                                     QApplication.processEvents)
        if all_verifiable:
            message = QTreeWidgetItem(
                [gettext("All commits signed with verifiable keys")])
            self.ui.treeWidget.addTopLevelItem(message)
            for verbose_message in gpg_strategy.verbose_valid_message(result):
                QTreeWidgetItem(message, [verbose_message])
        else:
            valid_commit_message = QTreeWidgetItem(
                [gpg_strategy.valid_commits_message(count)])
            self.ui.treeWidget.addTopLevelItem(valid_commit_message)
            for verbose_message in gpg_strategy.verbose_valid_message(result):
                QTreeWidgetItem(valid_commit_message, [verbose_message])

            expired_key_message = QTreeWidgetItem(
                [gpg_strategy.expired_commit_message(count)])
            self.ui.treeWidget.addTopLevelItem(expired_key_message)
            for verbose_message in \
                              gpg_strategy.verbose_expired_key_message(result,
                                                                         repo):
                QTreeWidgetItem(expired_key_message, [verbose_message])

            unknown_key_message = QTreeWidgetItem(
                [gpg_strategy.unknown_key_message(count)])
            self.ui.treeWidget.addTopLevelItem(unknown_key_message)
            for verbose_message in gpg_strategy.verbose_missing_key_message(
                    result):
                QTreeWidgetItem(unknown_key_message, [verbose_message])

            commit_not_valid_message = QTreeWidgetItem(
                [gpg_strategy.commit_not_valid_message(count)])
            self.ui.treeWidget.addTopLevelItem(commit_not_valid_message)
            for verbose_message in gpg_strategy.verbose_not_valid_message(
                    result, repo):
                QTreeWidgetItem(commit_not_valid_message, [verbose_message])

            commit_not_signed_message = QTreeWidgetItem(
                [gpg_strategy.commit_not_signed_message(count)])
            self.ui.treeWidget.addTopLevelItem(commit_not_signed_message)
            for verbose_message in gpg_strategy.verbose_not_signed_message(
                    result, repo):
                QTreeWidgetItem(commit_not_signed_message, [verbose_message])
        self.throbber.hide()
    def run(self, acceptable_keys=None, revision=None, verbose=None,
                                                            location=u'.'):
        bzrdir = controldir.ControlDir.open_containing(location)[0]
        branch = bzrdir.open_branch()
        repo = branch.repository
        branch_config = branch.get_config_stack()
        gpg_strategy = gpg.GPGStrategy(branch_config)

        gpg_strategy.set_acceptable_keys(acceptable_keys)

        def write(string):
            self.outf.write(string + "\n")
        def write_verbose(string):
            self.outf.write("  " + string + "\n")

        self.add_cleanup(repo.lock_read().unlock)
        #get our list of revisions
        revisions = []
        if revision is not None:
            if len(revision) == 1:
                revno, rev_id = revision[0].in_history(branch)
                revisions.append(rev_id)
            elif len(revision) == 2:
                from_revno, from_revid = revision[0].in_history(branch)
                to_revno, to_revid = revision[1].in_history(branch)
                if to_revid is None:
                    to_revno = branch.revno()
                if from_revno is None or to_revno is None:
                    raise errors.BzrCommandError(gettext(
                    'Cannot verify a range of non-revision-history revisions'))
                for revno in range(from_revno, to_revno + 1):
                    revisions.append(branch.get_rev_id(revno))
        else:
            #all revisions by default including merges
            graph = repo.get_graph()
            revisions = []
            for rev_id, parents in graph.iter_ancestry(
                    [branch.last_revision()]):
                if _mod_revision.is_null(rev_id):
                    continue
                if parents is None:
                    # Ignore ghosts
                    continue
                revisions.append(rev_id)
        count, result, all_verifiable =\
                                gpg.bulk_verify_signatures(repo, revisions, gpg_strategy)
        if all_verifiable:
               write(gettext("All commits signed with verifiable keys"))
               if verbose:
                   write(gpg.verbose_valid_message(result))
               return 0
        else:
            write(gpg.valid_commits_message(count))
            if verbose:
               for message in gpg.verbose_valid_message(result):
                   write_verbose(message)
            write(gpg.expired_commit_message(count))
            if verbose:
               for message in gpg.verbose_expired_key_message(result, repo):
                   write_verbose(message)
            write(gpg.unknown_key_message(count))
            if verbose:
                for message in gpg.verbose_missing_key_message(result):
                    write_verbose(message)
            write(gpg.commit_not_valid_message(count))
            if verbose:
                for message in gpg.verbose_not_valid_message(result, repo):
                   write_verbose(message)
            write(gpg.commit_not_signed_message(count))
            if verbose:
                for message in gpg.verbose_not_signed_message(result, repo):
                    write_verbose(message)
            return 1