/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
1
# Copyright (C) 2004-2006 by Canonical Ltd
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 2 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
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
16
17
from StringIO import StringIO
18
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
19
from bzrlib.builtins import merge
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
20
from bzrlib.bzrdir import BzrDir
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
21
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
22
from bzrlib.bundle.read_bundle import BundleTree
23
from bzrlib.bundle.serializer import write_bundle, read_bundle
1185.82.90 by Aaron Bentley
Reorganized test suite
24
from bzrlib.diff import internal_diff
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
25
from bzrlib.errors import BzrError, TestamentMismatch, NotABundle
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
26
from bzrlib.merge import Merge3Merger
1185.82.87 by Aaron Bentley
Got symlink adding working
27
from bzrlib.osutils import has_symlinks, sha_file
1185.82.137 by Aaron Bentley
Skip unicode changeset test
28
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
1185.82.66 by Aaron Bentley
Handle new executable files
29
from bzrlib.transform import TreeTransform
1185.82.17 by Aaron Bentley
More API updates
30
from bzrlib.workingtree import WorkingTree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
31
1185.82.90 by Aaron Bentley
Reorganized test suite
32
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
33
class MockTree(object):
34
    def __init__(self):
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
35
        from bzrlib.inventory import RootEntry, ROOT_ID
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
36
        object.__init__(self)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
37
        self.paths = {ROOT_ID: ""}
38
        self.ids = {"": ROOT_ID}
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
39
        self.contents = {}
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
40
        self.root = RootEntry(ROOT_ID)
41
42
    inventory = property(lambda x:x)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
43
44
    def __iter__(self):
45
        return self.paths.iterkeys()
46
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
47
    def __getitem__(self, file_id):
48
        if file_id == self.root.file_id:
49
            return self.root
50
        else:
51
            return self.make_entry(file_id, self.paths[file_id])
52
53
    def parent_id(self, file_id):
54
        from os.path import dirname
55
        parent_dir = dirname(self.paths[file_id])
56
        if parent_dir == "":
57
            return None
58
        return self.ids[parent_dir]
59
60
    def iter_entries(self):
61
        for path, file_id in self.ids.iteritems():
62
            yield path, self[file_id]
63
64
    def get_file_kind(self, file_id):
65
        if file_id in self.contents:
66
            kind = 'file'
67
        else:
68
            kind = 'directory'
69
        return kind
70
71
    def make_entry(self, file_id, path):
72
        from os.path import basename
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
73
        from bzrlib.inventory import (InventoryEntry, InventoryFile
74
                                    , InventoryDirectory, InventoryLink)
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
75
        name = basename(path)
76
        kind = self.get_file_kind(file_id)
77
        parent_id = self.parent_id(file_id)
78
        text_sha_1, text_size = self.contents_stats(file_id)
0.5.119 by John Arbash Meinel
Recreated the factory. We really need InventoryEntry.create()
79
        if kind == 'directory':
80
            ie = InventoryDirectory(file_id, name, parent_id)
81
        elif kind == 'file':
82
            ie = InventoryFile(file_id, name, parent_id)
83
        elif kind == 'symlink':
84
            ie = InventoryLink(file_id, name, parent_id)
85
        else:
86
            raise BzrError('unknown kind %r' % kind)
0.5.91 by Aaron Bentley
Updated to match API change
87
        ie.text_sha1 = text_sha_1
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
88
        ie.text_size = text_size
89
        return ie
90
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
91
    def add_dir(self, file_id, path):
92
        self.paths[file_id] = path
93
        self.ids[path] = file_id
94
    
95
    def add_file(self, file_id, path, contents):
96
        self.add_dir(file_id, path)
97
        self.contents[file_id] = contents
98
99
    def path2id(self, path):
100
        return self.ids.get(path)
101
102
    def id2path(self, file_id):
103
        return self.paths.get(file_id)
104
105
    def has_id(self, file_id):
106
        return self.id2path(file_id) is not None
107
108
    def get_file(self, file_id):
109
        result = StringIO()
110
        result.write(self.contents[file_id])
111
        result.seek(0,0)
112
        return result
113
0.6.1 by Aaron Bentley
Fleshed out MockTree, fixed all test failures
114
    def contents_stats(self, file_id):
115
        if file_id not in self.contents:
116
            return None, None
117
        text_sha1 = sha_file(self.get_file(file_id))
118
        return text_sha1, len(self.contents[file_id])
119
120
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
121
class BTreeTester(TestCase):
122
    """A simple unittest tester for the BundleTree class."""
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
123
124
    def make_tree_1(self):
125
        mtree = MockTree()
126
        mtree.add_dir("a", "grandparent")
127
        mtree.add_dir("b", "grandparent/parent")
128
        mtree.add_file("c", "grandparent/parent/file", "Hello\n")
129
        mtree.add_dir("d", "grandparent/alt_parent")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
130
        return BundleTree(mtree, ''), mtree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
131
        
132
    def test_renames(self):
133
        """Ensure that file renames have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
134
        btree = self.make_tree_1()[0]
135
        self.assertEqual(btree.old_path("grandparent"), "grandparent")
136
        self.assertEqual(btree.old_path("grandparent/parent"), 
137
                         "grandparent/parent")
138
        self.assertEqual(btree.old_path("grandparent/parent/file"),
139
                         "grandparent/parent/file")
140
141
        self.assertEqual(btree.id2path("a"), "grandparent")
142
        self.assertEqual(btree.id2path("b"), "grandparent/parent")
143
        self.assertEqual(btree.id2path("c"), "grandparent/parent/file")
144
145
        self.assertEqual(btree.path2id("grandparent"), "a")
146
        self.assertEqual(btree.path2id("grandparent/parent"), "b")
147
        self.assertEqual(btree.path2id("grandparent/parent/file"), "c")
148
149
        assert btree.path2id("grandparent2") is None
150
        assert btree.path2id("grandparent2/parent") is None
151
        assert btree.path2id("grandparent2/parent/file") is None
152
153
        btree.note_rename("grandparent", "grandparent2")
154
        assert btree.old_path("grandparent") is None
155
        assert btree.old_path("grandparent/parent") is None
156
        assert btree.old_path("grandparent/parent/file") is None
157
158
        self.assertEqual(btree.id2path("a"), "grandparent2")
159
        self.assertEqual(btree.id2path("b"), "grandparent2/parent")
160
        self.assertEqual(btree.id2path("c"), "grandparent2/parent/file")
161
162
        self.assertEqual(btree.path2id("grandparent2"), "a")
163
        self.assertEqual(btree.path2id("grandparent2/parent"), "b")
164
        self.assertEqual(btree.path2id("grandparent2/parent/file"), "c")
165
166
        assert btree.path2id("grandparent") is None
167
        assert btree.path2id("grandparent/parent") is None
168
        assert btree.path2id("grandparent/parent/file") is None
169
170
        btree.note_rename("grandparent/parent", "grandparent2/parent2")
171
        self.assertEqual(btree.id2path("a"), "grandparent2")
172
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
173
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file")
174
175
        self.assertEqual(btree.path2id("grandparent2"), "a")
176
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
177
        self.assertEqual(btree.path2id("grandparent2/parent2/file"), "c")
178
179
        assert btree.path2id("grandparent2/parent") is None
180
        assert btree.path2id("grandparent2/parent/file") is None
181
182
        btree.note_rename("grandparent/parent/file", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
183
                          "grandparent2/parent2/file2")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
184
        self.assertEqual(btree.id2path("a"), "grandparent2")
185
        self.assertEqual(btree.id2path("b"), "grandparent2/parent2")
186
        self.assertEqual(btree.id2path("c"), "grandparent2/parent2/file2")
187
188
        self.assertEqual(btree.path2id("grandparent2"), "a")
189
        self.assertEqual(btree.path2id("grandparent2/parent2"), "b")
190
        self.assertEqual(btree.path2id("grandparent2/parent2/file2"), "c")
191
192
        assert btree.path2id("grandparent2/parent2/file") is None
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
193
194
    def test_moves(self):
195
        """Ensure that file moves have the proper effect on children"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
196
        btree = self.make_tree_1()[0]
197
        btree.note_rename("grandparent/parent/file", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
198
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
199
        self.assertEqual(btree.id2path("c"), "grandparent/alt_parent/file")
200
        self.assertEqual(btree.path2id("grandparent/alt_parent/file"), "c")
201
        assert btree.path2id("grandparent/parent/file") is None
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
202
203
    def unified_diff(self, old, new):
204
        out = StringIO()
205
        internal_diff("old", old, "new", new, out)
206
        out.seek(0,0)
207
        return out.read()
208
209
    def make_tree_2(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
210
        btree = self.make_tree_1()[0]
211
        btree.note_rename("grandparent/parent/file", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
212
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
213
        assert btree.id2path("e") is None
214
        assert btree.path2id("grandparent/parent/file") is None
215
        btree.note_id("e", "grandparent/parent/file")
216
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
217
218
    def test_adds(self):
219
        """File/inventory adds"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
220
        btree = self.make_tree_2()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
221
        add_patch = self.unified_diff([], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
222
        btree.note_patch("grandparent/parent/file", add_patch)
223
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
224
        btree.note_target('grandparent/parent/symlink', 'venus')
225
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
226
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
227
    def adds_test(self, btree):
228
        self.assertEqual(btree.id2path("e"), "grandparent/parent/file")
229
        self.assertEqual(btree.path2id("grandparent/parent/file"), "e")
230
        self.assertEqual(btree.get_file("e").read(), "Extra cheese\n")
231
        self.assertEqual(btree.get_symlink_target('f'), 'venus')
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
232
233
    def test_adds2(self):
234
        """File/inventory adds, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
235
        btree = self.make_tree_2()
236
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
237
        add_patch = self.unified_diff(["Hello\n"], ["Extra cheese\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
238
        btree.note_patch("grandparent/parent/file", add_patch)
239
        btree.note_id('f', 'grandparent/parent/symlink', kind='symlink')
240
        btree.note_target('grandparent/parent/symlink', 'venus')
241
        self.adds_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
242
243
    def make_tree_3(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
244
        btree, mtree = self.make_tree_1()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
245
        mtree.add_file("e", "grandparent/parent/topping", "Anchovies\n")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
246
        btree.note_rename("grandparent/parent/file", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
247
                          "grandparent/alt_parent/file")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
248
        btree.note_rename("grandparent/parent/topping", 
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
249
                          "grandparent/alt_parent/stopping")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
250
        return btree
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
251
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
252
    def get_file_test(self, btree):
253
        self.assertEqual(btree.get_file("e").read(), "Lemon\n")
254
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
255
256
    def test_get_file(self):
257
        """Get file contents"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
258
        btree = self.make_tree_3()
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
259
        mod_patch = self.unified_diff(["Anchovies\n"], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
260
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
261
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
262
263
    def test_get_file2(self):
264
        """Get file contents, with patch-compatibile renames"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
265
        btree = self.make_tree_3()
266
        btree.contents_by_id = False
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
267
        mod_patch = self.unified_diff([], ["Lemon\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
268
        btree.note_patch("grandparent/alt_parent/stopping", mod_patch)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
269
        mod_patch = self.unified_diff([], ["Hello\n"])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
270
        btree.note_patch("grandparent/alt_parent/file", mod_patch)
271
        self.get_file_test(btree)
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
272
273
    def test_delete(self):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
274
        "Deletion by bundle"
275
        btree = self.make_tree_1()[0]
276
        self.assertEqual(btree.get_file("c").read(), "Hello\n")
277
        btree.note_deletion("grandparent/parent/file")
278
        assert btree.id2path("c") is None
279
        assert btree.path2id("grandparent/parent/file") is None
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
280
281
    def sorted_ids(self, tree):
282
        ids = list(tree)
283
        ids.sort()
284
        return ids
285
286
    def test_iteration(self):
287
        """Ensure that iteration through ids works properly"""
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
288
        btree = self.make_tree_1()[0]
289
        self.assertEqual(self.sorted_ids(btree), ['a', 'b', 'c', 'd'])
290
        btree.note_deletion("grandparent/parent/file")
291
        btree.note_id("e", "grandparent/alt_parent/fool", kind="directory")
292
        btree.note_last_changed("grandparent/alt_parent/fool", 
1185.82.95 by Aaron Bentley
Restore path-orientation of ChangesetTree
293
                                "revisionidiguess")
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
294
        self.assertEqual(self.sorted_ids(btree), ['a', 'b', 'd', 'e'])
0.5.66 by John Arbash Meinel
Refactoring, moving test code into test (switching back to assert is None)
295
1185.82.7 by John Arbash Meinel
Adding patches.py into bzrlib, including the tests into the test suite.
296
0.5.97 by Aaron Bentley
Updated tests
297
class CSetTester(TestCaseInTempDir):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
298
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
299
    def get_valid_bundle(self, base_rev_id, rev_id, checkout_dir=None,
300
                         message=None):
301
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
302
        Make sure that the text generated is valid, and that it
303
        can be applied against the base, and generate the same information.
304
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
305
        :return: The in-memory bundle 
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
306
        """
307
        from cStringIO import StringIO
308
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
309
        bundle_txt = StringIO()
310
        rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id, 
311
                               bundle_txt)
312
        bundle_txt.seek(0)
313
        self.assertEqual(bundle_txt.readline(), 
314
                         '# Bazaar revision bundle v0.7\n')
315
        self.assertEqual(bundle_txt.readline(), '#\n')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
316
1185.82.14 by Aaron Bentley
API updates
317
        rev = self.b1.repository.get_revision(rev_id)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
318
        self.assertEqual(bundle_txt.readline().decode('utf-8'),
319
                         u'# message:\n')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
320
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
321
        open(',,bundle', 'wb').write(bundle_txt.getvalue())
322
        bundle_txt.seek(0)
323
        # This should also validate the generated bundle 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
324
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
325
        repository = self.b1.repository
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
326
        for bundle_rev in bundle.real_revisions:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
327
            # These really should have already been checked when we read the
328
            # bundle, since it computes the sha1 hash for the revision, which
329
            # only will match if everything is okay, but lets be explicit about
330
            # it
331
            branch_rev = repository.get_revision(bundle_rev.revision_id)
1185.82.33 by Aaron Bentley
Strengthen tests
332
            for a in ('inventory_sha1', 'revision_id', 'parent_ids',
333
                      'timestamp', 'timezone', 'message', 'committer', 
334
                      'parent_ids', 'properties'):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
335
                self.assertEqual(getattr(branch_rev, a), 
336
                                 getattr(bundle_rev, a))
337
            self.assertEqual(len(branch_rev.parent_ids), 
338
                             len(bundle_rev.parent_ids))
1185.82.47 by Aaron Bentley
Ensure all intended rev_ids end up in the revision
339
        self.assertEqual(rev_ids, 
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
340
                         [r.revision_id for r in bundle.real_revisions])
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
341
        self.valid_apply_bundle(base_rev_id, bundle,
1185.82.89 by Aaron Bentley
Remove auto_commit stuff
342
                                   checkout_dir=checkout_dir)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
343
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
344
        return bundle
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
345
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
346
    def get_invalid_bundle(self, base_rev_id, rev_id):
347
        """Create a bundle from base_rev_id -> rev_id in built-in branch.
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
348
        Munge the text so that it's invalid.
349
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
350
        :return: The in-memory bundle
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
351
        """
352
        from cStringIO import StringIO
353
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
354
        bundle_txt = StringIO()
355
        rev_ids = write_bundle(self.b1.repository, rev_id, base_rev_id, 
356
                               bundle_txt)
357
        bundle_txt.seek(0)
358
        open(',,bundle', 'wb').write(bundle_txt.getvalue())
359
        bundle_txt.seek(0)
360
        new_text = bundle_txt.getvalue().replace('executable:no', 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
361
                                               'executable:yes')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
362
        bundle_txt = StringIO(new_text)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
363
        bundle = read_bundle(bundle_txt)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
364
        self.valid_apply_bundle(base_rev_id, bundle)
365
        return bundle 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
366
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
367
    def test_non_bundle(self):
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
368
        self.assertRaises(NotABundle, read_bundle, StringIO('#!/bin/sh\n'))
1185.82.139 by Aaron Bentley
Raise NotABundle when a non-bundle is supplied
369
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
370
    def get_checkout(self, rev_id, checkout_dir=None):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
371
        """Get a new tree, with the specified revision in it.
372
        """
0.5.102 by John Arbash Meinel
Updated to latest bzr.dev changes (serialization, test cases, etc)
373
        from bzrlib.branch import Branch
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
374
        import tempfile
375
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
376
        if checkout_dir is None:
377
            checkout_dir = tempfile.mkdtemp(prefix='test-branch-', dir='.')
0.5.89 by John Arbash Meinel
Updating for explicitly defined directories.
378
        else:
379
            import os
380
            if not os.path.exists(checkout_dir):
381
                os.mkdir(checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
382
        tree = BzrDir.create_standalone_workingtree(checkout_dir)
383
        s = StringIO()
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
384
        ancestors = write_bundle(self.b1.repository, rev_id, None, s)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
385
        s.seek(0)
1185.82.135 by Aaron Bentley
Ensure that bundles are bytestrings
386
        assert isinstance(s.getvalue(), str), (
387
            "Bundle isn't a bytestring:\n %s..." % repr(s.getvalue())[:40])
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
388
        install_bundle(tree.branch.repository, read_bundle(s))
1185.82.41 by Aaron Bentley
More work on installing changesets
389
        for ancestor in ancestors:
390
            old = self.b1.repository.revision_tree(ancestor)
391
            new = tree.branch.repository.revision_tree(ancestor)
392
            for inventory_id in old:
393
                try:
394
                    old_file = old.get_file(inventory_id)
395
                except:
396
                    continue
397
                if old_file is None:
398
                    continue
399
                self.assertEqual(old_file.read(),
400
                                 new.get_file(inventory_id).read())
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
401
        if rev_id is not None:
402
            rh = self.b1.revision_history()
403
            tree.branch.set_revision_history(rh[:rh.index(rev_id)+1])
404
            tree.update()
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
405
        return tree
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
406
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
407
    def valid_apply_bundle(self, base_rev_id, info, checkout_dir=None):
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
408
        """Get the base revision, apply the changes, and make
409
        sure everything matches the builtin branch.
410
        """
1185.82.17 by Aaron Bentley
More API updates
411
        to_tree = self.get_checkout(base_rev_id, checkout_dir=checkout_dir)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
412
        repository = to_tree.branch.repository
1185.82.41 by Aaron Bentley
More work on installing changesets
413
        self.assertIs(repository.has_revision(base_rev_id), True)
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
414
        for rev in info.real_revisions:
415
            self.assert_(not repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
416
                'Revision {%s} present before applying bundle' 
1185.82.40 by Aaron Bentley
Started work on testing install_revisions/handling empty changesets
417
                % rev.revision_id)
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
418
        merge_bundle(info, to_tree, True, Merge3Merger, False, False)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
419
420
        for rev in info.real_revisions:
1185.82.17 by Aaron Bentley
More API updates
421
            self.assert_(repository.has_revision(rev.revision_id),
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
422
                'Missing revision {%s} after applying bundle' 
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
423
                % rev.revision_id)
424
1185.82.17 by Aaron Bentley
More API updates
425
        self.assert_(to_tree.branch.repository.has_revision(info.target))
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
426
        # Do we also want to verify that all the texts have been added?
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
427
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
428
        self.assert_(info.target in to_tree.pending_merges())
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
429
430
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
431
        rev = info.real_revisions[-1]
1185.82.17 by Aaron Bentley
More API updates
432
        base_tree = self.b1.repository.revision_tree(rev.revision_id)
433
        to_tree = to_tree.branch.repository.revision_tree(rev.revision_id)
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
434
        
435
        # TODO: make sure the target tree is identical to base tree
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
436
        #       we might also check the working tree.
437
438
        base_files = list(base_tree.list_files())
439
        to_files = list(to_tree.list_files())
440
        self.assertEqual(len(base_files), len(to_files))
1185.82.66 by Aaron Bentley
Handle new executable files
441
        for base_file, to_file in zip(base_files, to_files):
442
            self.assertEqual(base_file, to_file)
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
443
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
444
        for path, status, kind, fileid, entry in base_files:
0.5.86 by John Arbash Meinel
Updated the auto-commit functionality, and adding to pending-merges, more testing.
445
            # Check that the meta information is the same
446
            self.assertEqual(base_tree.get_file_size(fileid),
447
                    to_tree.get_file_size(fileid))
448
            self.assertEqual(base_tree.get_file_sha1(fileid),
449
                    to_tree.get_file_sha1(fileid))
450
            # Check that the contents are the same
451
            # This is pretty expensive
452
            # self.assertEqual(base_tree.get_file(fileid).read(),
453
            #         to_tree.get_file(fileid).read())
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
454
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
455
    def test_bundle(self):
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
456
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
457
        import os, sys
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
458
        pjoin = os.path.join
459
1185.82.14 by Aaron Bentley
API updates
460
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
461
        self.b1 = self.tree1.branch
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
462
463
        open(pjoin('b1/one'), 'wb').write('one\n')
1185.82.14 by Aaron Bentley
API updates
464
        self.tree1.add('one')
465
        self.tree1.commit('add one', rev_id='a@cset-0-1')
0.5.78 by John Arbash Meinel
Working on test cases, starting with the empty project issues.
466
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
467
        bundle = self.get_valid_bundle(None, 'a@cset-0-1')
468
        bundle = self.get_valid_bundle(None, 'a@cset-0-1',
0.5.103 by John Arbash Meinel
Updated to having a changeset specific message.
469
                message='With a specialized message')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
470
471
        # Make sure we can handle files with spaces, tabs, other
472
        # bogus characters
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
473
        self.build_tree([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
474
                'b1/with space.txt'
475
                , 'b1/dir/'
476
                , 'b1/dir/filein subdir.c'
477
                , 'b1/dir/WithCaps.txt'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
478
                , 'b1/dir/trailing space '
0.5.84 by John Arbash Meinel
(broken) problem with removes.
479
                , 'b1/sub/'
480
                , 'b1/sub/sub/'
481
                , 'b1/sub/sub/nonempty.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
482
                # Tabs are not valid in filenames on windows
483
                #'b1/with\ttab.txt'
484
                ])
0.5.84 by John Arbash Meinel
(broken) problem with removes.
485
        open('b1/sub/sub/emptyfile.txt', 'wb').close()
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
486
        open('b1/dir/nolastnewline.txt', 'wb').write('bloop')
1185.82.66 by Aaron Bentley
Handle new executable files
487
        tt = TreeTransform(self.tree1)
488
        tt.new_file('executable', tt.root, '#!/bin/sh\n', 'exe-1', True)
489
        tt.apply()
1185.82.14 by Aaron Bentley
API updates
490
        self.tree1.add([
0.5.84 by John Arbash Meinel
(broken) problem with removes.
491
                'with space.txt'
492
                , 'dir'
493
                , 'dir/filein subdir.c'
494
                , 'dir/WithCaps.txt'
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
495
                , 'dir/trailing space '
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
496
                , 'dir/nolastnewline.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
497
                , 'sub'
498
                , 'sub/sub'
499
                , 'sub/sub/nonempty.txt'
500
                , 'sub/sub/emptyfile.txt'
0.5.82 by John Arbash Meinel
Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids
501
                ])
1185.82.14 by Aaron Bentley
API updates
502
        self.tree1.commit('add whitespace', rev_id='a@cset-0-2')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
503
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
504
        bundle = self.get_valid_bundle('a@cset-0-1', 'a@cset-0-2')
0.5.117 by John Arbash Meinel
Almost there. Just need to track down a few remaining bugs.
505
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
506
        # Check a rollup bundle 
507
        bundle = self.get_valid_bundle(None, 'a@cset-0-2')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
508
509
        # Now delete entries
1185.82.21 by Aaron Bentley
Stop using deprecated function
510
        self.tree1.remove(
0.5.118 by John Arbash Meinel
Got most of test_changeset to work. Still needs work for Aaron's test code.
511
                ['sub/sub/nonempty.txt'
0.5.84 by John Arbash Meinel
(broken) problem with removes.
512
                , 'sub/sub/emptyfile.txt'
0.5.118 by John Arbash Meinel
Got most of test_changeset to work. Still needs work for Aaron's test code.
513
                , 'sub/sub'
514
                ])
1185.82.68 by Aaron Bentley
Handle execute bit on modified files
515
        tt = TreeTransform(self.tree1)
516
        trans_id = tt.trans_id_tree_file_id('exe-1')
517
        tt.set_executability(False, trans_id)
518
        tt.apply()
1185.82.19 by Aaron Bentley
More API updates
519
        self.tree1.commit('removed', rev_id='a@cset-0-3')
0.5.80 by John Arbash Meinel
Starting to write tests for changeset, discovering some errors as I go.
520
        
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
521
        bundle = self.get_valid_bundle('a@cset-0-2', 'a@cset-0-3')
522
        self.assertRaises(TestamentMismatch, self.get_invalid_bundle, 
1185.82.118 by Aaron Bentley
Ensure that StrictTestament handles execute bit differences
523
                          'a@cset-0-2', 'a@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
524
        # Check a rollup bundle 
525
        bundle = self.get_valid_bundle(None, 'a@cset-0-3')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
526
527
528
        # Now move the directory
1185.82.19 by Aaron Bentley
More API updates
529
        self.tree1.rename_one('dir', 'sub/dir')
530
        self.tree1.commit('rename dir', rev_id='a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
531
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
532
        bundle = self.get_valid_bundle('a@cset-0-3', 'a@cset-0-4')
533
        # Check a rollup bundle 
534
        bundle = self.get_valid_bundle(None, 'a@cset-0-4')
0.5.84 by John Arbash Meinel
(broken) problem with removes.
535
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
536
        # Modified files
537
        open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
0.5.88 by John Arbash Meinel
Fixed a bug in the rename code, added more tests.
538
        open('b1/sub/dir/trailing space ', 'ab').write('\nAdding some\nDOS format lines\n')
0.5.94 by Aaron Bentley
Switched to native patch application, added tests for terminating newlines
539
        open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
1185.82.19 by Aaron Bentley
More API updates
540
        self.tree1.rename_one('sub/dir/trailing space ', 
541
                              'sub/ start and end space ')
542
        self.tree1.commit('Modified files', rev_id='a@cset-0-5')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
543
        bundle = self.get_valid_bundle('a@cset-0-4', 'a@cset-0-5')
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
544
545
        # Handle international characters
1185.82.137 by Aaron Bentley
Skip unicode changeset test
546
        try:
547
            f = open(u'b1/with Dod\xe9', 'wb')
548
        except UnicodeEncodeError:
549
            raise TestSkipped("Filesystem doesn't support unicode")
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
550
        f.write((u'A file\n'
551
            u'With international man of mystery\n'
552
            u'William Dod\xe9\n').encode('utf-8'))
1185.82.19 by Aaron Bentley
More API updates
553
        self.tree1.add([u'with Dod\xe9'])
0.5.87 by John Arbash Meinel
Handling international characters, added more test cases.
554
        # BUG: (sort of) You must set verbose=False, so that python doesn't try
555
        #       and print the name of William Dode as part of the commit
1185.82.19 by Aaron Bentley
More API updates
556
        self.tree1.commit(u'i18n commit from William Dod\xe9', 
557
                          rev_id='a@cset-0-6', committer=u'William Dod\xe9',
558
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
559
        bundle = self.get_valid_bundle('a@cset-0-5', 'a@cset-0-6')
1185.82.70 by Aaron Bentley
Handle renamed files better
560
        self.tree1.rename_one('sub/dir/WithCaps.txt', 'temp')
561
        self.tree1.rename_one('with space.txt', 'WithCaps.txt')
562
        self.tree1.rename_one('temp', 'with space.txt')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
563
        self.tree1.commit(u'swap filenames', rev_id='a@cset-0-7',
1185.82.70 by Aaron Bentley
Handle renamed files better
564
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
565
        bundle = self.get_valid_bundle('a@cset-0-6', 'a@cset-0-7')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
566
        other = self.get_checkout('a@cset-0-6')
567
        other.rename_one('sub/dir/nolastnewline.txt', 'sub/nolastnewline.txt')
568
        other.commit('rename file', rev_id='a@cset-0-7b')
569
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
570
        self.tree1.commit(u'Merge', rev_id='a@cset-0-8',
571
                          verbose=False)
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
572
        bundle = self.get_valid_bundle('a@cset-0-7', 'a@cset-0-8')
1185.82.72 by Aaron Bentley
Always use leftmost base for changesets
573
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
574
    def test_symlink_bundle(self):
1185.82.87 by Aaron Bentley
Got symlink adding working
575
        if not has_symlinks():
576
            raise TestSkipped("No symlink support")
577
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
578
        self.b1 = self.tree1.branch
579
        tt = TreeTransform(self.tree1)
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
580
        tt.new_symlink('link', tt.root, 'bar/foo', 'link-1')
1185.82.87 by Aaron Bentley
Got symlink adding working
581
        tt.apply()
582
        self.tree1.commit('add symlink', rev_id='l@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
583
        self.get_valid_bundle(None, 'l@cset-0-1')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
584
        tt = TreeTransform(self.tree1)
585
        trans_id = tt.trans_id_tree_file_id('link-1')
586
        tt.adjust_path('link2', tt.root, trans_id)
587
        tt.delete_contents(trans_id)
588
        tt.create_symlink('mars', trans_id)
589
        tt.apply()
590
        self.tree1.commit('rename and change symlink', rev_id='l@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
591
        self.get_valid_bundle('l@cset-0-1', 'l@cset-0-2')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
592
        tt = TreeTransform(self.tree1)
593
        trans_id = tt.trans_id_tree_file_id('link-1')
594
        tt.delete_contents(trans_id)
595
        tt.create_symlink('jupiter', trans_id)
596
        tt.apply()
597
        self.tree1.commit('just change symlink target', rev_id='l@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
598
        self.get_valid_bundle('l@cset-0-2', 'l@cset-0-3')
1185.82.88 by Aaron Bentley
Get symlink modification, renames and deletion under test
599
        tt = TreeTransform(self.tree1)
600
        trans_id = tt.trans_id_tree_file_id('link-1')
601
        tt.delete_contents(trans_id)
602
        tt.apply()
603
        self.tree1.commit('Delete symlink', rev_id='l@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
604
        self.get_valid_bundle('l@cset-0-3', 'l@cset-0-4')
1185.82.96 by Aaron Bentley
Got first binary test passing
605
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
606
    def test_binary_bundle(self):
1185.82.96 by Aaron Bentley
Got first binary test passing
607
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
608
        self.b1 = self.tree1.branch
609
        tt = TreeTransform(self.tree1)
610
        tt.new_file('file', tt.root, '\x00\xff', 'binary-1')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
611
        tt.new_file('file2', tt.root, '\x00\xff', 'binary-2')
1185.82.96 by Aaron Bentley
Got first binary test passing
612
        tt.apply()
613
        self.tree1.commit('add binary', rev_id='b@cset-0-1')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
614
        self.get_valid_bundle(None, 'b@cset-0-1')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
615
        tt = TreeTransform(self.tree1)
616
        trans_id = tt.trans_id_tree_file_id('binary-1')
617
        tt.delete_contents(trans_id)
618
        tt.apply()
619
        self.tree1.commit('delete binary', rev_id='b@cset-0-2')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
620
        self.get_valid_bundle('b@cset-0-1', 'b@cset-0-2')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
621
        tt = TreeTransform(self.tree1)
622
        trans_id = tt.trans_id_tree_file_id('binary-2')
623
        tt.adjust_path('file3', tt.root, trans_id)
624
        tt.delete_contents(trans_id)
625
        tt.create_file('filecontents\x00', trans_id)
626
        tt.apply()
627
        self.tree1.commit('rename and modify binary', rev_id='b@cset-0-3')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
628
        self.get_valid_bundle('b@cset-0-2', 'b@cset-0-3')
1185.82.97 by Aaron Bentley
Got binary files working for adds, renames, modifications
629
        tt = TreeTransform(self.tree1)
630
        trans_id = tt.trans_id_tree_file_id('binary-2')
631
        tt.delete_contents(trans_id)
632
        tt.create_file('\x00filecontents', trans_id)
633
        tt.apply()
634
        self.tree1.commit('just modify binary', rev_id='b@cset-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
635
        self.get_valid_bundle('b@cset-0-3', 'b@cset-0-4')
1185.82.115 by Aaron Bentley
Add test for last-changed special cases
636
637
    def test_last_modified(self):
638
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
639
        self.b1 = self.tree1.branch
640
        tt = TreeTransform(self.tree1)
641
        tt.new_file('file', tt.root, 'file', 'file')
642
        tt.apply()
643
        self.tree1.commit('create file', rev_id='a@lmod-0-1')
644
645
        tt = TreeTransform(self.tree1)
646
        trans_id = tt.trans_id_tree_file_id('file')
647
        tt.delete_contents(trans_id)
648
        tt.create_file('file2', trans_id)
649
        tt.apply()
650
        self.tree1.commit('modify text', rev_id='a@lmod-0-2a')
651
652
        other = self.get_checkout('a@lmod-0-1')
653
        tt = TreeTransform(other)
654
        trans_id = tt.trans_id_tree_file_id('file')
655
        tt.delete_contents(trans_id)
656
        tt.create_file('file2', trans_id)
657
        tt.apply()
658
        other.commit('modify text in another tree', rev_id='a@lmod-0-2b')
659
        merge([other.basedir, -1], [None, None], this_dir=self.tree1.basedir)
660
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-3',
661
                          verbose=False)
662
        self.tree1.commit(u'Merge', rev_id='a@lmod-0-4')
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
663
        bundle = self.get_valid_bundle('a@lmod-0-2a', 'a@lmod-0-4')
1185.84.3 by Aaron Bentley
Hide diffs for old revisions in bundles
664
665
    def test_hide_history(self):
666
        import os, sys
667
        pjoin = os.path.join
668
669
        self.tree1 = BzrDir.create_standalone_workingtree('b1')
670
        self.b1 = self.tree1.branch
671
672
        open(pjoin('b1/one'), 'wb').write('one\n')
673
        self.tree1.add('one')
674
        self.tree1.commit('add file', rev_id='a@cset-0-1')
675
        open(pjoin('b1/one'), 'wb').write('two\n')
676
        self.tree1.commit('modify', rev_id='a@cset-0-2')
677
        open(pjoin('b1/one'), 'wb').write('three\n')
678
        self.tree1.commit('modify', rev_id='a@cset-0-3')
679
        bundle_file = StringIO()
680
        rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
681
                               'a@cset-0-1', bundle_file)
682
        self.assertNotContainsRe(bundle_file.getvalue(), 'two')
683
        self.assertContainsRe(bundle_file.getvalue(), 'one')
684
        self.assertContainsRe(bundle_file.getvalue(), 'three')