1
# Copyright (C) 2006-2007, 2010-2011 Aaron Bentley <aaron@aaronbentley.com>
2
# Copyright (C) 2007 Charlie Shepherd <masterdriverz@gentoo.org>
3
# Copyright (C) 2011 Canonical Ltd.
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from shutil import rmtree
23
revision as _mod_revision,
25
from bzrlib.branch import Branch
26
from bzrlib.errors import BzrCommandError, NoWorkingTree, NotBranchError
27
from bzrlib import registry
28
from bzrlib.workingtree import WorkingTree
30
from errors import (NotCheckout, UncommittedCheckout, ParentMissingRevisions,
34
class AllowChanged(object):
37
def check_changed(klass, wt, remove_branch):
41
class CheckChanged(object):
44
def check_changed(klass, wt, remove_branch):
45
delta = wt.changes_from(wt.basis_tree(), want_unchanged=False)
46
if delta.has_changed():
47
klass.handle_changed(wt, remove_branch)
50
class HaltOnChange(CheckChanged):
53
def handle_changed(wt, remove_branch):
54
raise UncommittedCheckout()
57
class StoreChanges(CheckChanged):
60
def handle_changed(wt, remove_branch):
61
from bzrlib.plugins.pipeline.pipeline import PipeManager
63
raise BzrCommandError('Cannot store changes in deleted branch.')
64
PipeManager.from_checkout(wt).store_uncommitted()
67
change_policy_registry = registry.Registry()
70
change_policy_registry.register('force', AllowChanged,
71
'Delete tree even if contents are modified.')
74
change_policy_registry.register('store', StoreChanges,
75
'Store changes in branch. (Requires'
79
change_policy_registry.register('check', HaltOnChange,
80
'Stop if tree contents are modified.')
83
change_policy_registry.default_key = 'check'
86
def zap(path, remove_branch=False, policy=HaltOnChange):
88
wt = bzrdir.BzrDir.open(path).open_workingtree(path,
89
recommend_upgrade=False)
90
except (NoWorkingTree, NotBranchError):
91
raise NotCheckout(path)
92
tree_base = wt.bzrdir.transport.base
94
branch_base = branch.bzrdir.transport.base
95
if tree_base == branch_base:
96
raise NotCheckout(path)
97
policy.check_changed(wt, remove_branch)
99
parent_loc = branch.get_parent()
100
if parent_loc is None:
102
parent = Branch.open(parent_loc)
103
last_revision = _mod_revision.ensure_null(parent.last_revision())
104
p_ancestry = parent.repository.get_ancestry(last_revision)
105
if (last_revision != _mod_revision.NULL_REVISION and
106
branch.last_revision() not in p_ancestry):
107
raise ParentMissingRevisions(branch.get_parent())
110
t = branch.bzrdir.transport
111
while t.base != branch_base:
119
from unittest import makeSuite
121
from bzrlib.tests import TestCaseInTempDir
124
class PipelinePluginFeature:
129
import bzrlib.plugins.pipeline
136
class TestZap(TestCaseInTempDir):
138
def make_checkout(self):
139
wt = bzrdir.BzrDir.create_standalone_workingtree('source')
140
return wt.branch.create_checkout('checkout', lightweight=True)
142
def make_checkout2(self):
143
wt = self.make_checkout()
144
wt2 = wt.branch.bzrdir.sprout('source2').open_workingtree()
145
return wt2.branch.create_checkout('checkout2', lightweight=True)
147
def test_is_checkout(self):
148
self.assertRaises(NotCheckout, zap, '.')
149
wt = bzrdir.BzrDir.create_standalone_workingtree('.')
150
self.assertRaises(NotCheckout, zap, '.')
152
def test_zap_works(self):
154
self.assertIs(True, os.path.exists('checkout'))
156
self.assertIs(False, os.path.exists('checkout'))
157
self.assertIs(True, os.path.exists('source'))
159
def test_zap_branch(self):
160
self.make_checkout2()
161
base = WorkingTree.open('checkout').branch.base
162
self.assertIs(True, os.path.exists('checkout'))
163
self.assertRaises(NoParent, zap, 'checkout', remove_branch=True)
164
self.assertIs(True, os.path.exists('checkout'))
165
self.assertIs(True, os.path.exists('source'))
166
zap('checkout2', remove_branch=True)
167
self.assertIs(False, os.path.exists('checkout2'))
168
self.assertIs(False, os.path.exists('source2'))
170
def test_checks_modified(self):
171
checkout = self.make_checkout()
172
os.mkdir('checkout/foo')
174
self.assertRaises(UncommittedCheckout, zap, 'checkout')
175
checkout.commit('commit changes to branch')
178
def make_modified_checkout(self):
179
checkout = self.make_checkout()
180
os.mkdir('checkout/foo')
184
def test_allow_modified(self):
185
self.make_modified_checkout()
186
self.assertRaises(UncommittedCheckout, zap, 'checkout')
187
zap('checkout', policy=AllowChanged)
189
def test_store(self):
190
self.requireFeature(PipelinePluginFeature)
191
checkout = self.make_modified_checkout()
192
zap('checkout', policy=StoreChanges)
193
self.assertIn('stored-transform',
194
checkout.branch.bzrdir.transport.list_dir('branch'))
196
def test_store_remove_branch(self):
197
self.requireFeature(PipelinePluginFeature)
198
checkout = self.make_modified_checkout()
199
branch = self.make_branch('branch')
200
checkout.branch.set_parent(branch.base)
201
e = self.assertRaises(BzrCommandError, zap, 'checkout',
202
policy=StoreChanges, remove_branch=True)
203
self.assertEqual('Cannot store changes in deleted branch.', str(e))
205
def test_store_remove_branch_unmodified(self):
206
self.requireFeature(PipelinePluginFeature)
207
checkout = self.make_checkout()
208
branch = self.make_branch('branch')
209
checkout.branch.set_parent(branch.base)
210
zap('checkout', policy=StoreChanges, remove_branch=True)
212
return makeSuite(TestZap)