1
# Copyright (C) 2004, 2005 by Martin Pool
2
# Copyright (C) 2005 by Canonical Ltd
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.
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.
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
23
Upgrade branch to current format.
25
This causes objects to be rewritten into the current format.
27
If they change, their SHA-1 will of course change, which might
28
break any later signatures, or backreferences that check the
33
from bzrlib.trace import mutter
34
from bzrlib.errors import BzrCheckError
35
from bzrlib.progress import ProgressBar
40
pb = ProgressBar(show_spinner=True)
44
history = branch.revision_history()
46
revcount = len(history)
48
updated_revisions = []
50
# Set to True in the case that the previous revision entry
51
# was updated, since this will affect future revision entries
52
updated_previous_revision = False
56
pb.update('upgrading revision', revno, revcount)
57
mutter(' revision {%s}' % rid)
58
rev = branch.get_revision(rid)
59
if rev.revision_id != rid:
60
raise BzrCheckError('wrong internal revision id in revision {%s}' % rid)
61
if rev.precursor != last_ptr:
62
raise BzrCheckError('mismatched precursor in revision {%s}' % rid)
64
if rid in checked_revs:
65
raise BzrCheckError('repeated revision {%s}' % rid)
66
checked_revs[rid] = True
68
## TODO: Check all the required fields are present on the revision.
71
if rev.inventory_sha1:
72
#mutter(' checking inventory hash {%s}' % rev.inventory_sha1)
73
inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
74
if inv_sha1 != rev.inventory_sha1:
75
raise BzrCheckError('Inventory sha1 hash doesn\'t match'
76
' value in revision {%s}' % rid)
78
inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
79
rev.inventory_sha1 = inv_sha1
83
if rev.precursor_sha1:
84
precursor_sha1 = branch.get_revision_sha1(rev.precursor)
85
if updated_previous_revision:
86
# we don't expect the hashes to match, because
87
# we had to modify the previous revision_history entry.
88
rev.precursor_sha1 = precursor_sha1
91
#mutter(' checking precursor hash {%s}' % rev.precursor_sha1)
92
if rev.precursor_sha1 != precursor_sha1:
93
raise BzrCheckError('Precursor sha1 hash doesn\'t match'
94
' value in revision {%s}' % rid)
96
precursor_sha1 = branch.get_revision_sha1(rev.precursor)
97
rev.precursor_sha1 = precursor_sha1
101
updated_previous_revision = True
102
# We had to update this revision entries hashes
103
# Now we need to write out a new value
104
# This is a little bit invasive, since we are *rewriting* a
105
# revision entry. I'm not supremely happy about it, but
106
# there should be *some* way of making old entries have
107
# the full meta information.
108
import tempfile, os, errno
109
rev_tmp = tempfile.TemporaryFile()
110
rev.write_xml(rev_tmp)
113
tmpfd, tmp_path = tempfile.mkstemp(prefix=rid, suffix='.gz',
114
dir=branch.controlfilename('revision-store'))
116
def special_rename(p1, p2):
117
if sys.platform == 'win32':
121
if e.errno != errno.ENOENT:
126
# TODO: We may need to handle the case where the old revision
127
# entry was not compressed (and thus did not end with .gz)
129
# Remove the old revision entry out of the way
130
rev_path = branch.controlfilename(['revision-store', rid+'.gz'])
131
special_rename(rev_path, tmp_path)
132
branch.revision_store.add(rev_tmp, rid) # Add the new one
133
os.remove(tmp_path) # Remove the old name
134
mutter(' Updated revision entry {%s}' % rid)
136
# On any exception, restore the old entry
137
special_rename(tmp_path, rev_path)
140
updated_revisions.append(rid)
142
updated_previous_revision = False
149
if updated_revisions:
150
print '%d revisions updated to current format' % len(updated_revisions)