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