/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 bzrlib/upgrade.py

  • Committer: Martin Pool
  • Date: 2005-09-06 02:26:28 UTC
  • Revision ID: mbp@sourcefrog.net-20050906022628-66d65f0feb4a9e80
- implement version 5 xml storage, and tests

  This stores files identified by the version that introduced the 
  text, and the version that introduced the name.  Entry kinds are
  given by the xml tag not an explicit kind field.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004, 2005 by Martin Pool
 
2
# Copyright (C) 2005 by Canonical Ltd
 
3
 
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
 
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
 
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
import tempfile, os, errno
 
19
                
 
20
import bzrlib.errors
 
21
import bzrlib.progress
 
22
from bzrlib.xml import serializer_v4
 
23
 
 
24
 
 
25
def upgrade(branch):
 
26
    """
 
27
    Upgrade branch to current format.
 
28
 
 
29
    This causes objects to be rewritten into the current format.
 
30
 
 
31
    If they change, their SHA-1 will of course change, which might
 
32
    break any later signatures, or backreferences that check the
 
33
    SHA-1.
 
34
 
 
35
    TODO: Check non-mainline revisions.
 
36
    """
 
37
    import sys
 
38
 
 
39
    from bzrlib.trace import mutter
 
40
    from bzrlib.errors import BzrCheckError
 
41
    import bzrlib.ui
 
42
 
 
43
    branch.lock_write()
 
44
 
 
45
    pb = bzrlib.ui.ui_factory.progress_bar()
 
46
 
 
47
    try:
 
48
        last_rev_id = None
 
49
 
 
50
        history = branch.revision_history()
 
51
        revno = 0
 
52
        revcount = len(history)
 
53
 
 
54
        updated_revisions = []
 
55
 
 
56
        # Set to True in the case that the previous revision entry
 
57
        # was updated, since this will affect future revision entries
 
58
        updated_previous_revision = False
 
59
 
 
60
        for rev_id in history:
 
61
            revno += 1
 
62
            pb.update('upgrading revision', revno, revcount)
 
63
            rev = branch.get_revision(rev_id)
 
64
            if rev.revision_id != rev_id:
 
65
                raise BzrCheckError('wrong internal revision id in revision {%s}'
 
66
                                    % rev_id)
 
67
 
 
68
            last_rev_id = rev_id
 
69
 
 
70
            # if set to true, revision must be written out
 
71
            updated = False
 
72
 
 
73
            if rev.inventory_sha1 is None:
 
74
                rev.inventory_sha1 = branch.get_inventory_sha1(rev.inventory_id)
 
75
                updated = True
 
76
                mutter("  set inventory_sha1 on {%s}" % rev_id)
 
77
 
 
78
            for prr in rev.parents:
 
79
                try:
 
80
                    actual_sha1 = branch.get_revision_sha1(prr.revision_id)
 
81
                except bzrlib.errors.NoSuchRevision:
 
82
                    mutter("parent {%s} of {%s} not present in branch; skipped"
 
83
                           % (prr.revision_id, rev_id))
 
84
                    continue
 
85
                    
 
86
                if actual_sha1 != prr.revision_sha1:
 
87
                    mutter("parent {%s} of {%s} sha1 mismatch: "
 
88
                           "%s vs %s; fixed"
 
89
                           % (prr.revision_id, rev_id,
 
90
                              actual_sha1, prr.revision_sha1))
 
91
                    prr.revision_sha1 = actual_sha1
 
92
                    updated = True
 
93
 
 
94
            if updated:
 
95
                updated_previous_revision = True
 
96
                # We had to update this revision entries hashes
 
97
                # Now we need to write out a new value
 
98
                # This is a little bit invasive, since we are *rewriting* a
 
99
                # revision entry. I'm not supremely happy about it, but
 
100
                # there should be *some* way of making old entries have
 
101
                # the full meta information.
 
102
                rev_tmp = tempfile.TemporaryFile()
 
103
                serializer_v4.write_revision(rev, rev_tmp)
 
104
                rev_tmp.seek(0)
 
105
 
 
106
                tmpfd, tmp_path = tempfile.mkstemp(prefix=rev_id, suffix='.gz',
 
107
                    dir=branch.controlfilename('revision-store'))
 
108
                os.close(tmpfd)
 
109
                def special_rename(p1, p2):
 
110
                    if sys.platform == 'win32':
 
111
                        try:
 
112
                            os.remove(p2)
 
113
                        except OSError, e:
 
114
                            if e.errno != errno.ENOENT:
 
115
                                raise
 
116
                    os.rename(p1, p2)
 
117
 
 
118
                try:
 
119
                    # TODO: We may need to handle the case where the old revision
 
120
                    # entry was not compressed (and thus did not end with .gz)
 
121
 
 
122
                    # Remove the old revision entry out of the way
 
123
                    rev_path = branch.controlfilename(['revision-store', rev_id+'.gz'])
 
124
                    special_rename(rev_path, tmp_path)
 
125
                    branch.revision_store.add(rev_tmp, rev_id) # Add the new one
 
126
                    os.remove(tmp_path) # Remove the old name
 
127
                    mutter('    Updated revision entry {%s}' % rev_id)
 
128
                except:
 
129
                    # On any exception, restore the old entry
 
130
                    special_rename(tmp_path, rev_path)
 
131
                    raise
 
132
                rev_tmp.close()
 
133
                updated_revisions.append(rev_id)
 
134
            else:
 
135
                updated_previous_revision = False
 
136
 
 
137
    finally:
 
138
        branch.unlock()
 
139
 
 
140
    pb.clear()
 
141
 
 
142
    if updated_revisions:
 
143
        print '%d revisions updated to current format' % len(updated_revisions)