/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 breezy/plugins/rewrite/upgrade.py

  • Committer: Robert Collins
  • Date: 2005-10-19 10:11:57 UTC
  • mfrom: (1185.16.78)
  • mto: This revision was merged to the branch mainline in revision 1470.
  • Revision ID: robertc@robertcollins.net-20051019101157-17438d311e746b4f
mergeĀ fromĀ upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2009 by Jelmer Vernooij
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 3 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
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
 
18
 
"""Upgrading revisions made with older versions of the mapping."""
19
 
 
20
 
from __future__ import absolute_import
21
 
 
22
 
from ... import (
23
 
    osutils,
24
 
    trace,
25
 
    ui,
26
 
    )
27
 
from ...errors import (
28
 
    BzrError,
29
 
    )
30
 
from .rebase import (
31
 
    generate_transpose_plan,
32
 
    CommitBuilderRevisionRewriter,
33
 
    rebase,
34
 
    rebase_todo,
35
 
    )
36
 
 
37
 
 
38
 
class UpgradeChangesContent(BzrError):
39
 
    """Inconsistency was found upgrading the mapping of a revision."""
40
 
    _fmt = """Upgrade will change contents in revision %(revid)s. Use --allow-changes to override."""
41
 
 
42
 
    def __init__(self, revid):
43
 
        self.revid = revid
44
 
 
45
 
 
46
 
def create_deterministic_revid(revid, new_parents):
47
 
    """Create a new deterministic revision id with specified new parents.
48
 
 
49
 
    Prevents suffix to be appended needlessly.
50
 
 
51
 
    :param revid: Original revision id.
52
 
    :return: New revision id
53
 
    """
54
 
    if "-rebase-" in revid:
55
 
        revid = revid[0:revid.rfind("-rebase-")]
56
 
    return revid + "-rebase-" + osutils.sha_string(":".join(new_parents))[:8]
57
 
 
58
 
 
59
 
def upgrade_tags(tags, repository, generate_rebase_map, determine_new_revid,
60
 
                 allow_changes=False, verbose=False, branch_renames=None,
61
 
                 branch_ancestry=None):
62
 
    """Upgrade a tags dictionary."""
63
 
    renames = {}
64
 
    if branch_renames is not None:
65
 
        renames.update(branch_renames)
66
 
    pb = ui.ui_factory.nested_progress_bar()
67
 
    try:
68
 
        tags_dict = tags.get_tag_dict()
69
 
        for i, (name, revid) in enumerate(tags_dict.iteritems()):
70
 
            pb.update("upgrading tags", i, len(tags_dict))
71
 
            if revid not in renames:
72
 
                try:
73
 
                    repository.lock_read()
74
 
                    revid_exists = repository.has_revision(revid)
75
 
                finally:
76
 
                    repository.unlock()
77
 
                if revid_exists:
78
 
                    renames.update(upgrade_repository(
79
 
                        repository,
80
 
                        generate_rebase_map, determine_new_revid,
81
 
                        revision_id=revid, allow_changes=allow_changes,
82
 
                        verbose=verbose))
83
 
            if (revid in renames and
84
 
                    (branch_ancestry is None or revid not in branch_ancestry)):
85
 
                tags.set_tag(name, renames[revid])
86
 
    finally:
87
 
        pb.finished()
88
 
 
89
 
 
90
 
def upgrade_branch(branch, generate_rebase_map, determine_new_revid,
91
 
                   allow_changes=False, verbose=False):
92
 
    """Upgrade a branch to the current mapping version.
93
 
 
94
 
    :param branch: Branch to upgrade.
95
 
    :param foreign_repository: Repository to fetch new revisions from
96
 
    :param allow_changes: Allow changes in mappings.
97
 
    :param verbose: Whether to print verbose list of rewrites
98
 
    """
99
 
    revid = branch.last_revision()
100
 
    renames = upgrade_repository(
101
 
        branch.repository, generate_rebase_map,
102
 
        determine_new_revid, revision_id=revid,
103
 
        allow_changes=allow_changes, verbose=verbose)
104
 
    if revid in renames:
105
 
        branch.generate_revision_history(renames[revid])
106
 
    ancestry = branch.repository.get_ancestry(
107
 
        branch.last_revision(), topo_sorted=False)
108
 
    upgrade_tags(
109
 
        branch.tags, branch.repository, generate_rebase_map,
110
 
        determine_new_revid, allow_changes=allow_changes, verbose=verbose,
111
 
        branch_renames=renames, branch_ancestry=ancestry)
112
 
    return renames
113
 
 
114
 
 
115
 
def check_revision_changed(oldrev, newrev):
116
 
    """Check if two revisions are different. This is exactly the same
117
 
    as Revision.equals() except that it does not check the revision_id."""
118
 
    if (newrev.inventory_sha1 != oldrev.inventory_sha1 or
119
 
            newrev.timestamp != oldrev.timestamp or
120
 
            newrev.message != oldrev.message or
121
 
            newrev.timezone != oldrev.timezone or
122
 
            newrev.committer != oldrev.committer or
123
 
            newrev.properties != oldrev.properties):
124
 
        raise UpgradeChangesContent(oldrev.revision_id)
125
 
 
126
 
 
127
 
def create_upgrade_plan(repository, generate_rebase_map, determine_new_revid,
128
 
                        revision_id=None, allow_changes=False):
129
 
    """Generate a rebase plan for upgrading revisions.
130
 
 
131
 
    :param repository: Repository to do upgrade in
132
 
    :param foreign_repository: Subversion repository to fetch new revisions
133
 
        from.
134
 
    :param new_mapping: New mapping to use.
135
 
    :param revision_id: Revision to upgrade (None for all revisions in
136
 
        repository.)
137
 
    :param allow_changes: Whether an upgrade is allowed to change the contents
138
 
        of revisions.
139
 
    :return: Tuple with a rebase plan and map of renamed revisions.
140
 
    """
141
 
 
142
 
    graph = repository.get_graph()
143
 
    upgrade_map = generate_rebase_map(revision_id)
144
 
 
145
 
    if not allow_changes:
146
 
        for oldrevid, newrevid in upgrade_map.iteritems():
147
 
            oldrev = repository.get_revision(oldrevid)
148
 
            newrev = repository.get_revision(newrevid)
149
 
            check_revision_changed(oldrev, newrev)
150
 
 
151
 
    if revision_id is None:
152
 
        heads = repository.all_revision_ids()
153
 
    else:
154
 
        heads = [revision_id]
155
 
 
156
 
    plan = generate_transpose_plan(
157
 
        graph.iter_ancestry(heads), upgrade_map, graph, determine_new_revid)
158
 
    def remove_parents(entry):
159
 
        (oldrevid, (newrevid, parents)) = entry
160
 
        return (oldrevid, newrevid)
161
 
    upgrade_map.update(dict(map(remove_parents, plan.iteritems())))
162
 
 
163
 
    return (plan, upgrade_map)
164
 
 
165
 
 
166
 
def upgrade_repository(repository, generate_rebase_map,
167
 
                       determine_new_revid, revision_id=None,
168
 
                       allow_changes=False, verbose=False):
169
 
    """Upgrade the revisions in repository until the specified stop revision.
170
 
 
171
 
    :param repository: Repository in which to upgrade.
172
 
    :param foreign_repository: Repository to fetch new revisions from.
173
 
    :param new_mapping: New mapping.
174
 
    :param revision_id: Revision id up until which to upgrade, or None for
175
 
                        all revisions.
176
 
    :param allow_changes: Allow changes to mappings.
177
 
    :param verbose: Whether to print list of rewrites
178
 
    :return: Dictionary of mapped revisions
179
 
    """
180
 
    # Find revisions that need to be upgraded, create
181
 
    # dictionary with revision ids in key, new parents in value
182
 
    with repository.lock_write():
183
 
        (plan, revid_renames) = create_upgrade_plan(
184
 
            repository, generate_rebase_map, determine_new_revid,
185
 
            revision_id=revision_id, allow_changes=allow_changes)
186
 
        if verbose:
187
 
            for revid in rebase_todo(repository, plan):
188
 
                trace.note("%s -> %s" % (revid, plan[revid][0]))
189
 
        rebase(repository, plan, CommitBuilderRevisionRewriter(repository))
190
 
        return revid_renames