/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
1
# Copyright (C) 2009 Canonical Ltd
2
#
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.
7
#
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.
12
#
13
# You should have received a copy of the GNU General Public License
0.64.334 by Jelmer Vernooij
Remove old FSF address. Thanks Dan Callaghan.
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
15
16
"""An object that updates a bunch of branches based on data imported."""
17
0.82.1 by Ian Clatworthy
nicer and round-trippable mapping of git ref names to bzr branch names
18
from operator import itemgetter
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
19
6670.4.1 by Jelmer Vernooij
Update imports.
20
from ... import errors, osutils, transport
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
21
from ...trace import show_error, note
0.82.1 by Ian Clatworthy
nicer and round-trippable mapping of git ref names to bzr branch names
22
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
23
from .helpers import (
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
24
    best_format_for_objects_in_a_repository,
0.139.1 by Jelmer Vernooij
Import helper functions that have been removed from python-fastimport.
25
    single_plural,
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
26
    )
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
27
28
29
class BranchUpdater(object):
30
31
    def __init__(self, repo, branch, cache_mgr, heads_by_ref, last_ref, tags):
32
        """Create an object responsible for updating branches.
33
34
        :param heads_by_ref: a dictionary where
35
          names are git-style references like refs/heads/master;
36
          values are one item lists of commits marks.
37
        """
38
        self.repo = repo
39
        self.branch = branch
40
        self.cache_mgr = cache_mgr
41
        self.heads_by_ref = heads_by_ref
42
        self.last_ref = last_ref
43
        self.tags = tags
0.64.193 by Ian Clatworthy
Smarter selection of branch format based on shared repository format
44
        self._branch_format = \
0.123.1 by Jelmer Vernooij
Move pure-fastimport code into its own directory, in preparation of splitting it into a separate package.
45
            best_format_for_objects_in_a_repository(repo)
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
46
47
    def update(self):
48
        """Update the Bazaar branches and tips matching the heads.
49
50
        If the repository is shared, this routine creates branches
51
        as required. If it isn't, warnings are produced about the
52
        lost of information.
53
54
        :return: updated, lost_heads where
0.95.3 by Ian Clatworthy
Update the working tree for trunk implicitly
55
          updated = the list of branches updated ('trunk' is first)
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
56
          lost_heads = a list of (bazaar-name,revision) for branches that
57
            would have been created had the repository been shared
58
        """
59
        updated = []
60
        branch_tips, lost_heads = self._get_matching_branches()
61
        for br, tip in branch_tips:
62
            if self._update_branch(br, tip):
63
                updated.append(br)
64
        return updated, lost_heads
65
66
    def _get_matching_branches(self):
67
        """Get the Bazaar branches.
68
0.95.3 by Ian Clatworthy
Update the working tree for trunk implicitly
69
        :return: branch_tips, lost_heads where
70
          branch_tips = a list of (branch,tip) tuples for branches. The
71
            first tip is the 'trunk'.
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
72
          lost_heads = a list of (bazaar-name,revision) for branches that
73
            would have been created had the repository been shared and
74
            everything succeeded
75
        """
76
        branch_tips = []
77
        lost_heads = []
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
78
        ref_names = list(self.heads_by_ref)
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
79
        if self.branch is not None:
80
            trunk = self.select_trunk(ref_names)
81
            default_tip = self.heads_by_ref[trunk][0]
82
            branch_tips.append((self.branch, default_tip))
83
            ref_names.remove(trunk)
84
0.95.3 by Ian Clatworthy
Update the working tree for trunk implicitly
85
        # Convert the reference names into Bazaar speak. If we haven't
86
        # already put the 'trunk' first, do it now.
0.112.3 by Max Bowsher
Make BranchMapper just map one name per call.
87
        git_to_bzr_map = {}
88
        for ref_name in ref_names:
7143.15.2 by Jelmer Vernooij
Run autopep8.
89
            git_to_bzr_map[ref_name] = self.cache_mgr.branch_mapper.git_to_bzr(
90
                ref_name)
0.95.3 by Ian Clatworthy
Update the working tree for trunk implicitly
91
        if ref_names and self.branch is None:
92
            trunk = self.select_trunk(ref_names)
93
            git_bzr_items = [(trunk, git_to_bzr_map[trunk])]
94
            del git_to_bzr_map[trunk]
95
        else:
96
            git_bzr_items = []
97
        git_bzr_items.extend(sorted(git_to_bzr_map.items(), key=itemgetter(1)))
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
98
99
        # Policy for locating branches
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
100
        def dir_under_current(name):
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
101
            # Using the Bazaar name, get a directory under the current one
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
102
            repo_base = self.repo.controldir.transport.base
0.95.3 by Ian Clatworthy
Update the working tree for trunk implicitly
103
            return osutils.pathjoin(repo_base, "..", name)
7143.15.2 by Jelmer Vernooij
Run autopep8.
104
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
105
        def dir_sister_branch(name):
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
106
            # Using the Bazaar name, get a sister directory to the branch
107
            return osutils.pathjoin(self.branch.base, "..", name)
108
        if self.branch is not None:
109
            dir_policy = dir_sister_branch
110
        else:
111
            dir_policy = dir_under_current
112
113
        # Create/track missing branches
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
114
        can_create_branches = (
7143.15.2 by Jelmer Vernooij
Run autopep8.
115
            self.repo.is_shared() or
116
            self.repo.controldir._format.colocated_branches)
0.82.1 by Ian Clatworthy
nicer and round-trippable mapping of git ref names to bzr branch names
117
        for ref_name, name in git_bzr_items:
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
118
            tip = self.heads_by_ref[ref_name][0]
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
119
            if can_create_branches:
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
120
                try:
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
121
                    br = self.make_branch(name, ref_name, dir_policy)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
122
                    branch_tips.append((br, tip))
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
123
                    continue
6855.3.1 by Jelmer Vernooij
Several more fixes.
124
                except errors.BzrError as ex:
0.64.322 by Jelmer Vernooij
error has been renamed to show_error.
125
                    show_error("ERROR: failed to create branch %s: %s",
7143.15.2 by Jelmer Vernooij
Run autopep8.
126
                               name, ex)
0.129.2 by Jelmer Vernooij
Use lookup functions for committish.
127
            lost_head = self.cache_mgr.lookup_committish(tip)
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
128
            lost_info = (name, lost_head)
129
            lost_heads.append(lost_info)
130
        return branch_tips, lost_heads
131
132
    def select_trunk(self, ref_names):
133
        """Given a set of ref names, choose one as the trunk."""
134
        for candidate in ['refs/heads/master']:
135
            if candidate in ref_names:
136
                return candidate
137
        # Use the last reference in the import stream
138
        return self.last_ref
139
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
140
    def make_branch(self, name, ref_name, dir_policy):
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
141
        """Make a branch in the repository if not already there."""
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
142
        if self.repo.is_shared():
143
            location = dir_policy(name)
144
            to_transport = transport.get_transport(location)
145
            to_transport.create_prefix()
146
            try:
147
                return controldir.ControlDir.open(location).open_branch()
6855.3.1 by Jelmer Vernooij
Several more fixes.
148
            except errors.NotBranchError as ex:
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
149
                return controldir.ControlDir.create_branch_convenience(
150
                    location,
151
                    format=self._branch_format,
152
                    possible_transports=[to_transport])
153
        else:
154
            try:
155
                return self.repo.controldir.open_branch(name)
6855.3.1 by Jelmer Vernooij
Several more fixes.
156
            except errors.NotBranchError as ex:
6846.4.1 by Jelmer Vernooij
Support colocated branches in ``brz fast-import``.
157
                return self.repo.controldir.create_branch(name)
158
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
159
    def _update_branch(self, br, last_mark):
160
        """Update a branch with last revision and tag information.
0.129.2 by Jelmer Vernooij
Use lookup functions for committish.
161
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
162
        :return: whether the branch was changed or not
163
        """
0.129.2 by Jelmer Vernooij
Use lookup functions for committish.
164
        last_rev_id = self.cache_mgr.lookup_committish(last_mark)
6754.8.4 by Jelmer Vernooij
Use new context stuff.
165
        with self.repo.lock_read():
0.64.324 by Jelmer Vernooij
Avoid deprecated Repository.iter_reverse_revision_history.
166
            graph = self.repo.get_graph()
167
            revno = graph.find_distance_to_null(last_rev_id, [])
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
168
        existing_revno, existing_last_rev_id = br.last_revision_info()
169
        changed = False
170
        if revno != existing_revno or last_rev_id != existing_last_rev_id:
171
            br.set_last_revision_info(revno, last_rev_id)
172
            changed = True
173
        # apply tags known in this branch
174
        my_tags = {}
175
        if self.tags:
0.137.1 by Zygmunt Krynicki
The get_ancestry() method was removed from bzr sometime in the past.
176
            graph = self.repo.get_graph()
7143.15.2 by Jelmer Vernooij
Run autopep8.
177
            ancestry = [r for (r, ps) in graph.iter_ancestry(
178
                [last_rev_id]) if ps is not None]
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
179
            for tag, rev in self.tags.items():
0.108.1 by Max Bowsher
Store tags on entire branch ancestry, not just left-hand ancestry.
180
                if rev in ancestry:
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
181
                    my_tags[tag] = rev
182
            if my_tags:
183
                br.tags._set_tag_dict(my_tags)
184
                changed = True
185
        if changed:
186
            tagno = len(my_tags)
187
            note("\t branch %s now has %d %s and %d %s", br.nick,
7143.15.2 by Jelmer Vernooij
Run autopep8.
188
                 revno, single_plural(revno, "revision", "revisions"),
189
                 tagno, single_plural(tagno, "tag", "tags"))
0.78.4 by Ian Clatworthy
move GenericBranchUpdater into its own module
190
        return changed