1
# Copyright (C) 2011 Canonical Ltd
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 2 of the License, or
6
# (at your option) any later version.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
from bzrlib.tests import TestCaseWithTransport
24
class TestRepairWorkingTree(TestCaseWithTransport):
26
def break_dirstate(self, tree, completely=False):
27
"""Write garbage into the dirstate file."""
28
# This test assumes that the format uses a DirState file, which we then
29
# manually corrupt. If we change the way to get at that dirstate file,
30
# then we can update how this is done
31
self.assertIsNot(None, getattr(tree, 'current_dirstate', None))
34
dirstate = tree.current_dirstate()
35
dirstate_path = dirstate._filename
36
self.failUnlessExists(dirstate_path)
39
# We have to have the tree unlocked at this point, so we can safely
40
# mutate the state file on all platforms.
42
f = open(dirstate_path, 'wb')
44
f = open(dirstate_path, 'ab')
46
f.write('garbage-at-end-of-file\n')
50
def make_initial_tree(self):
51
tree = self.make_branch_and_tree('tree')
52
self.build_tree(['tree/foo', 'tree/dir/', 'tree/dir/bar'])
53
tree.add(['foo', 'dir', 'dir/bar'])
57
def test_repair_refuses_uncorrupted(self):
58
tree = self.make_initial_tree()
59
# If the tree doesn't appear to be corrupt, we refuse, but prompt the
60
# user to let them know that:
61
# a) they may want to use 'bzr revert' instead of repair-workingtree
62
# b) they can use --force if they really want to do this
63
self.run_bzr_error(['The tree does not appear to be corrupt',
66
'repair-workingtree -d tree')
68
def test_repair_forced(self):
69
tree = self.make_initial_tree()
70
tree.rename_one('dir', 'alt_dir')
71
self.assertIsNot(None, tree.path2id('alt_dir'))
72
self.run_bzr('repair-workingtree -d tree --force')
73
# This requires the tree has reloaded the working state
74
self.assertIs(None, tree.path2id('alt_dir'))
75
self.failUnlessExists('tree/alt_dir')
77
def test_repair_corrupted_dirstate(self):
78
tree = self.make_initial_tree()
79
self.break_dirstate(tree)
80
self.run_bzr('repair-workingtree -d tree')
81
tree = workingtree.WorkingTree.open('tree')
82
# At this point, check should be happy
85
def test_repair_naive_destroyed_fails(self):
86
tree = self.make_initial_tree()
87
self.break_dirstate(tree, completely=True)
88
self.run_bzr_error(['the header appears corrupt, try passing'],
89
'repair-workingtree -d tree')
91
def test_repair_destroyed_with_revs_passes(self):
92
tree = self.make_initial_tree()
93
self.break_dirstate(tree, completely=True)
94
self.run_bzr('repair-workingtree -d tree -r -1')
95
tree = workingtree.WorkingTree.open('tree')
96
# At this point, check should be happy