/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to upgrade.py

  • Committer: Jelmer Vernooij
  • Date: 2008-11-25 03:16:20 UTC
  • mto: (0.219.2 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20081125031620-h4plmbufgsdjcqiw
Remove elements pending to be included in bzrlib.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2009 by Jelmer Vernooij
 
1
# Copyright (C) 2006,2008 by Jelmer Vernooij
2
2
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
"""Upgrading revisions made with older versions of the mapping."""
17
17
 
18
 
from bzrlib import (
19
 
    trace,
20
 
    ui,
21
 
    )
22
 
from bzrlib.errors import (
23
 
    DependencyNotPresent,
24
 
    BzrError,
25
 
    InvalidRevisionId,
26
 
    NoSuchRevision,
27
 
    )
 
18
from bzrlib import ui
 
19
from bzrlib.errors import BzrError, InvalidRevisionId, DependencyNotPresent
 
20
from bzrlib.trace import info
28
21
 
29
22
import itertools
30
23
 
45
38
    """
46
39
    try:
47
40
        from bzrlib.plugins.rebase import version_info as rebase_version_info
48
 
        if rebase_version_info[:len(min_version)] < min_version:
 
41
        if rebase_version_info[:2] < min_version:
49
42
            raise RebaseNotPresent("Version %r present, at least %r required" 
50
43
                                   % (rebase_version_info, min_version))
51
44
    except ImportError, e:
76
69
        return revid + mapping_suffix + upgrade_suffix
77
70
 
78
71
 
79
 
def determine_fileid_renames(old_inv, new_inv):
80
 
    """Determine the file ids based on a old and a new inventory that 
81
 
    are equal in content.
82
 
 
83
 
    :param old_inv: Old inventory
84
 
    :param new_inv: New inventory
85
 
    :return: Dictionary a (old_id, new_id) tuple for each path in the 
86
 
        inventories.
87
 
    """
88
 
    ret = {}
89
 
    if len(old_inv) != len(new_inv):
90
 
        raise AssertionError("Inventories are not of the same size")
91
 
    for old_file_id in old_inv:
92
 
        new_file_id = new_inv.path2id(old_inv.id2path(old_file_id))
93
 
        if new_file_id is None:
94
 
            raise AssertionError(
95
 
                "Unable to find %s in new inventory" % old_file_id)
96
 
        ret[new_inv.id2path(new_file_id)] = (old_file_id, new_file_id)
97
 
    return ret
98
 
 
99
 
 
100
 
def update_workinginv_fileids(wt, old_inv, new_inv):
101
 
    """Update all file ids in wt according to old_tree/new_tree. 
102
 
 
103
 
    old_tree and new_tree should be two RevisionTree's that differ only
104
 
    in file ids.
105
 
    """
106
 
    fileid_renames = determine_fileid_renames(old_inv, new_inv)
107
 
    old_fileids = []
108
 
    new_fileids = []
109
 
    new_root_id = None
110
 
    # Adjust file ids in working tree
111
 
    # Sorted, so we process parents before children
112
 
    for path in sorted(fileid_renames.keys()):
113
 
        if path != "":
114
 
            old_fileids.append(fileid_renames[path][0])
115
 
            new_fileids.append((path, fileid_renames[path][1]))
116
 
        else:
117
 
            new_root_id = fileid_renames[path][1]
118
 
    new_fileids.reverse()
119
 
    wt.unversion(old_fileids)
120
 
    if new_root_id is not None:
121
 
        wt.set_root_id(new_root_id)
122
 
    wt.add([x[0] for x in new_fileids], [x[1] for x in new_fileids])
123
 
    wt.set_last_revision(new_inv.revision_id)
124
 
 
125
 
 
126
 
def upgrade_workingtree(wt, foreign_repository, new_mapping, 
 
72
def determine_fileid_renames(old_tree, new_tree):
 
73
    for old_file_id in old_tree:
 
74
        new_file_id = new_tree.path2id(old_tree.id2path(old_file_id))
 
75
        if old_file_id == new_file_id:
 
76
            continue
 
77
        if new_file_id is not None:
 
78
            yield new_tree.id2path(new_file_id), old_file_id, new_file_id
 
79
 
 
80
 
 
81
def upgrade_workingtree(wt, foreign_repository, new_mapping, mapping_registry, 
127
82
                        allow_changes=False, verbose=False):
128
83
    """Upgrade a working tree.
129
84
 
133
88
    try:
134
89
        old_revid = wt.last_revision()
135
90
        revid_renames = upgrade_branch(wt.branch, foreign_repository, new_mapping=new_mapping,
 
91
                                 mapping_registry=mapping_registry,
136
92
                                 allow_changes=allow_changes, verbose=verbose)
137
93
        last_revid = wt.branch.last_revision()
138
94
        if old_revid == last_revid:
139
95
            return revid_renames
140
 
        old_inv = wt.branch.repository.get_inventory(old_revid)
141
 
        new_inv = wt.branch.repository.get_inventory(last_revid)
142
 
        update_workinginv_fileids(wt, old_inv, new_inv)
 
96
 
 
97
        fileid_renames = dict([(path, (old_fileid, new_fileid)) for (path, old_fileid, new_fileid) in determine_fileid_renames(wt.branch.repository.revision_tree(old_revid), wt.branch.repository.revision_tree(last_revid))])
 
98
        old_fileids = []
 
99
        new_fileids = []
 
100
        new_root_id = None
 
101
        # Adjust file ids in working tree
 
102
        for path in sorted(fileid_renames.keys(), reverse=True):
 
103
            if path != "":
 
104
                old_fileids.append(fileid_renames[path][0])
 
105
                new_fileids.append((path, fileid_renames[path][1]))
 
106
            else:
 
107
                new_root_id = fileid_renames[path][1]
 
108
        new_fileids.reverse()
 
109
        wt.unversion(old_fileids)
 
110
        if new_root_id is not None:
 
111
            wt.set_root_id(new_root_id)
 
112
        wt.add([x[0] for x in new_fileids], [x[1] for x in new_fileids])
 
113
        wt.set_last_revision(last_revid)
143
114
    finally:
144
115
        wt.unlock()
145
116
 
146
117
    return revid_renames
147
118
 
148
119
 
149
 
def upgrade_tags(tags, repository, foreign_repository, new_mapping, 
150
 
                 allow_changes=False, verbose=False, branch_renames=None,
151
 
                 branch_ancestry=None):
 
120
def upgrade_tags(tags, repository, foreign_repository, new_mapping, mapping_registry, 
 
121
                 allow_changes=False, verbose=False, branch_renames=None):
152
122
    """Upgrade a tags dictionary."""
153
 
    renames = {}
154
 
    if branch_renames is not None:
155
 
        renames.update(branch_renames)
156
123
    pb = ui.ui_factory.nested_progress_bar()
157
124
    try:
158
125
        tags_dict = tags.get_tag_dict()
159
126
        for i, (name, revid) in enumerate(tags_dict.items()):
160
127
            pb.update("upgrading tags", i, len(tags_dict))
161
 
            if not revid in renames:
162
 
                renames.update(upgrade_repository(repository, foreign_repository, 
 
128
            if branch_renames is not None and revid in branch_renames:
 
129
                renames = branch_renames
 
130
            else:
 
131
                renames = upgrade_repository(repository, foreign_repository, 
163
132
                      revision_id=revid, new_mapping=new_mapping,
164
 
                      allow_changes=allow_changes, verbose=verbose))
165
 
            if revid in renames and (branch_ancestry is None or not revid in branch_ancestry):
 
133
                      mapping_registry=mapping_registry,
 
134
                      allow_changes=allow_changes, verbose=verbose)
 
135
            if revid in renames:
166
136
                tags.set_tag(name, renames[revid])
167
137
    finally:
168
138
        pb.finished()
169
139
 
170
140
 
171
141
def upgrade_branch(branch, foreign_repository, new_mapping, 
172
 
                   allow_changes=False, verbose=False):
 
142
                   mapping_registry, allow_changes=False, verbose=False):
173
143
    """Upgrade a branch to the current mapping version.
174
144
    
175
145
    :param branch: Branch to upgrade.
180
150
    revid = branch.last_revision()
181
151
    renames = upgrade_repository(branch.repository, foreign_repository, 
182
152
              revision_id=revid, new_mapping=new_mapping,
 
153
              mapping_registry=mapping_registry,
183
154
              allow_changes=allow_changes, verbose=verbose)
184
 
    if revid in renames:
 
155
    upgrade_tags(branch.tags, branch.repository, foreign_repository, 
 
156
           new_mapping=new_mapping, mapping_registry=mapping_registry, 
 
157
           allow_changes=allow_changes, verbose=verbose)
 
158
    if len(renames) > 0:
185
159
        branch.generate_revision_history(renames[revid])
186
 
    ancestry = branch.repository.get_ancestry(branch.last_revision(), topo_sorted=False)
187
 
    upgrade_tags(branch.tags, branch.repository, foreign_repository, 
188
 
           new_mapping=new_mapping, 
189
 
           allow_changes=allow_changes, verbose=verbose, branch_renames=renames,
190
 
           branch_ancestry=ancestry)
191
160
    return renames
192
161
 
193
162
 
203
172
        raise UpgradeChangesContent(oldrev.revision_id)
204
173
 
205
174
 
206
 
def generate_upgrade_map(revs, vcs, determine_upgraded_revid):
 
175
def generate_upgrade_map(new_mapping, revs, mapping_registry):
207
176
    """Generate an upgrade map for use by bzr-rebase.
208
177
 
209
178
    :param new_mapping: Mapping to upgrade revisions to.
210
 
    :param vcs: The foreign vcs
211
179
    :param revs: Iterator over revisions to upgrade.
212
180
    :return: Map from old revids as keys, new revids as values stored in a 
213
181
             dictionary.
217
185
    for revid in revs:
218
186
        assert isinstance(revid, str)
219
187
        try:
220
 
            (foreign_revid, old_mapping) = vcs.mapping_registry.parse_revision_id(revid)
 
188
            (foreign_revid, _) = mapping_registry.parse_revision_id(revid)
221
189
        except InvalidRevisionId:
222
190
            # Not a foreign revision, nothing to do
223
191
            continue
224
 
        newrevid = determine_upgraded_revid(foreign_revid)
225
 
        if newrevid in (revid, None):
 
192
        newrevid = new_mapping.revision_id_foreign_to_bzr(foreign_revid)
 
193
        if revid == newrevid:
226
194
            continue
227
195
        rename_map[revid] = newrevid
 
196
 
228
197
    return rename_map
229
198
 
230
 
MIN_REBASE_VERSION = (0, 4, 3)
 
199
MIN_REBASE_VERSION = (0, 4)
231
200
 
232
201
def create_upgrade_plan(repository, foreign_repository, new_mapping,
233
 
                        revision_id=None, allow_changes=False):
 
202
                        mapping_registry, revision_id=None, allow_changes=False):
234
203
    """Generate a rebase plan for upgrading revisions.
235
204
 
236
205
    :param repository: Repository to do upgrade in
251
220
    else:
252
221
        potential = itertools.imap(lambda (rev, parents): rev, 
253
222
                graph.iter_ancestry([revision_id]))
254
 
 
255
 
    def determine_upgraded_revid(foreign_revid):
256
 
        # FIXME: Try all mappings until new_mapping rather than just new_mapping
257
 
        new_revid = foreign_repository.upgrade_foreign_revision_id(foreign_revid, new_mapping)
258
 
        if new_revid is None:
259
 
            return None
260
 
        # Make sure the revision is there
261
 
        if not repository.has_revision(new_revid):
262
 
            try:
263
 
                repository.fetch(foreign_repository, new_revid)
264
 
            except NoSuchRevision:
265
 
                return None
266
 
            if not repository.has_revision(new_revid):
267
 
                return None
268
 
        return new_revid
269
 
 
270
 
    upgrade_map = generate_upgrade_map(potential, foreign_repository.vcs, 
271
 
                                       determine_upgraded_revid)
 
223
    upgrade_map = generate_upgrade_map(new_mapping, potential, mapping_registry)
272
224
   
 
225
    # Make sure all the required current version revisions are present
 
226
    for revid in upgrade_map.values():
 
227
        if not repository.has_revision(revid):
 
228
            repository.fetch(foreign_repository, revid)
 
229
 
273
230
    if not allow_changes:
274
231
        for oldrevid, newrevid in upgrade_map.iteritems():
275
232
            oldrev = repository.get_revision(oldrevid)
281
238
    else:
282
239
        heads = [revision_id]
283
240
 
284
 
    def determine_new_revid(old_revid):
285
 
        # If this revision id already exists round-tripped upstream, 
286
 
        # leave it alone.
287
 
        if foreign_repository.has_revision(old_revid):
288
 
            return old_revid
289
 
        # if not, return old_revid'
290
 
        return create_upgraded_revid(old_revid, new_mapping.upgrade_suffix)
291
 
 
292
241
    plan = generate_transpose_plan(graph.iter_ancestry(heads), upgrade_map, 
293
 
      graph, determine_new_revid)
 
242
      graph, lambda revid: create_upgraded_revid(revid, new_mapping.upgrade_suffix))
294
243
    def remove_parents((oldrevid, (newrevid, parents))):
295
244
        return (oldrevid, newrevid)
296
245
    upgrade_map.update(dict(map(remove_parents, plan.iteritems())))
299
248
 
300
249
 
301
250
def upgrade_repository(repository, foreign_repository, new_mapping, 
302
 
                       revision_id=None, allow_changes=False, 
 
251
                       mapping_registry, revision_id=None, allow_changes=False, 
303
252
                       verbose=False):
304
253
    """Upgrade the revisions in repository until the specified stop revision.
305
254
 
322
271
        repository.lock_write()
323
272
        foreign_repository.lock_read()
324
273
        (plan, revid_renames) = create_upgrade_plan(repository, foreign_repository, 
325
 
                                                    new_mapping, 
 
274
                                                    new_mapping, mapping_registry,
326
275
                                                    revision_id=revision_id,
327
276
                                                    allow_changes=allow_changes)
328
277
        if verbose:
329
278
            for revid in rebase_todo(repository, plan):
330
 
                trace.info("%s -> %s" % (revid, plan[revid][0]))
331
 
        rebase(repository, plan, replay_snapshot)
 
279
                info("%s -> %s" % (revid, plan[revid][0]))
 
280
        def fix_revid(revid):
 
281
            try:
 
282
                (foreign_revid, mapping) = mapping_registry.parse_revision_id(revid)
 
283
            except InvalidRevisionId:
 
284
                return revid
 
285
            return new_mapping.revision_id_foreign_to_bzr(foreign_revid)
 
286
        def replay(repository, oldrevid, newrevid, new_parents):
 
287
            return replay_snapshot(repository, oldrevid, newrevid, new_parents,
 
288
                                   revid_renames, fix_revid)
 
289
        rebase(repository, plan, replay)
332
290
        return revid_renames
333
291
    finally:
334
292
        repository.unlock()