/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
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
16
17
"""Tests for InterRepository implementastions."""
18
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
19
import sys
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
20
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
21
import bzrlib
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
22
import bzrlib.bzrdir as bzrdir
23
from bzrlib.branch import Branch, needs_read_lock, needs_write_lock
24
import bzrlib.errors as errors
25
from bzrlib.errors import (FileExists,
26
                           NoSuchRevision,
27
                           NoSuchFile,
28
                           UninitializableFormat,
29
                           NotBranchError,
30
                           )
1731.1.1 by Aaron Bentley
Make root entry an InventoryDirectory, make EmptyTree really empty
31
from bzrlib.inventory import Inventory
2321.2.3 by Alexander Belchenko
fix for check_repo_format_for_funky_id_on_win32 after Martin's refactoring of repository format
32
import bzrlib.repofmt.weaverepo as weaverepo
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
33
import bzrlib.repository as repository
1694.2.6 by Martin Pool
[merge] bzr.dev
34
from bzrlib.revision import NULL_REVISION, Revision
2814.1.1 by Robert Collins
* Pushing, pulling and branching branches with subtree references was not
35
from bzrlib.tests import (
36
    TestCase,
37
    TestCaseWithTransport,
38
    TestNotApplicable,
39
    TestSkipped,
40
    )
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
41
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
42
from bzrlib.transport import get_transport
43
44
45
class TestCaseWithInterRepository(TestCaseWithBzrDir):
46
47
    def setUp(self):
48
        super(TestCaseWithInterRepository, self).setUp()
49
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
50
    def make_branch(self, relpath, format=None):
51
        repo = self.make_repository(relpath, format=format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
52
        return repo.bzrdir.create_branch()
53
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
54
    def make_bzrdir(self, relpath, format=None):
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
55
        try:
56
            url = self.get_url(relpath)
57
            segments = url.split('/')
58
            if segments and segments[-1] not in ('', '.'):
59
                parent = '/'.join(segments[:-1])
60
                t = get_transport(parent)
61
                try:
62
                    t.mkdir(segments[-1])
63
                except FileExists:
64
                    pass
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
65
            if format is None:
66
                format = self.repository_format._matchingbzrdir
67
            return format.initialize(url)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
68
        except UninitializableFormat:
1684.1.4 by Martin Pool
(patch) better warnings when tests are skipped (Alexander)
69
            raise TestSkipped("Format %s is not initializable." % format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
70
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
71
    def make_repository(self, relpath, format=None):
72
        made_control = self.make_bzrdir(relpath, format=format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
73
        return self.repository_format.initialize(made_control)
74
75
    def make_to_repository(self, relpath):
76
        made_control = self.make_bzrdir(relpath,
77
            self.repository_format_to._matchingbzrdir)
1534.1.30 by Robert Collins
Test that we get the right optimiser back in the InterRepository tests.
78
        return self.repository_format_to.initialize(made_control)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
79
80
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
81
def check_old_format_lock_error(repository_format):
82
    """Potentially ignore LockError on old formats.
83
84
    On win32, with the old OS locks, we get a failure of double-lock when
85
    we open a object in 2 objects and try to lock both.
86
87
    On new formats, LockError would be invalid, but for old formats
88
    this was not supported on Win32.
89
    """
90
    if sys.platform != 'win32':
91
        raise
92
93
    description = repository_format.get_format_description()
94
    if description in ("Repository format 4",
95
                       "Weave repository format 5",
96
                       "Weave repository format 6"):
1711.7.30 by John Arbash Meinel
Switch to using TestSkipped for old win32 problems
97
        # jam 20060701
98
        # win32 OS locks are not re-entrant. So one process cannot
99
        # open the same repository twice and lock them both.
100
        raise TestSkipped('%s on win32 cannot open the same'
101
                          ' repository twice in different objects'
102
                          % description)
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
103
    raise
104
105
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
106
def check_repo_format_for_funky_id_on_win32(repo):
2321.2.3 by Alexander Belchenko
fix for check_repo_format_for_funky_id_on_win32 after Martin's refactoring of repository format
107
    if (isinstance(repo, (weaverepo.AllInOneRepository,
108
                          weaverepo.WeaveMetaDirRepository))
109
        and sys.platform == 'win32'):
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
110
            raise TestSkipped("funky chars does not permitted"
111
                              " on this platform in repository"
112
                              " %s" % repo.__class__.__name__)
113
114
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
115
class TestInterRepository(TestCaseWithInterRepository):
116
1534.1.30 by Robert Collins
Test that we get the right optimiser back in the InterRepository tests.
117
    def test_interrepository_get_returns_correct_optimiser(self):
118
        # we assume the optimising code paths are triggered
119
        # by the type of the repo not the transport - at this point.
120
        # we may need to update this test if this changes.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
121
        #
122
        # XXX: This code tests that we get an InterRepository when we try to
123
        # convert between the two repositories that it wants to be tested with
124
        # -- but that's not necessarily correct.  So for now this is disabled.
125
        # mbp 20070206
126
        ## source_repo = self.make_repository("source")
127
        ## target_repo = self.make_to_repository("target")
128
        ## interrepo = repository.InterRepository.get(source_repo, target_repo)
129
        ## self.assertEqual(self.interrepo_class, interrepo.__class__)
130
        pass
1534.1.30 by Robert Collins
Test that we get the right optimiser back in the InterRepository tests.
131
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
132
    def test_fetch(self):
133
        tree_a = self.make_branch_and_tree('a')
134
        self.build_tree(['a/foo'])
135
        tree_a.add('foo', 'file1')
136
        tree_a.commit('rev1', rev_id='rev1')
137
        def check_push_rev1(repo):
138
            # ensure the revision is missing.
139
            self.assertRaises(NoSuchRevision, repo.get_revision, 'rev1')
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
140
            # fetch with a limit of NULL_REVISION and an explicit progress bar.
141
            repo.fetch(tree_a.branch.repository,
142
                       revision_id=NULL_REVISION,
143
                       pb=bzrlib.progress.DummyProgress())
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
144
            # nothing should have been pushed
145
            self.assertFalse(repo.has_revision('rev1'))
146
            # fetch with a default limit (grab everything)
147
            repo.fetch(tree_a.branch.repository)
148
            # check that b now has all the data from a's first commit.
149
            rev = repo.get_revision('rev1')
150
            tree = repo.revision_tree('rev1')
2592.3.214 by Robert Collins
Merge bzr.dev.
151
            tree.lock_read()
152
            self.addCleanup(tree.unlock)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
153
            tree.get_file_text('file1')
154
            for file_id in tree:
155
                if tree.inventory[file_id].kind == "file":
156
                    tree.get_file(file_id).read()
157
1534.1.31 by Robert Collins
Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.
158
        # makes a target version repo 
159
        repo_b = self.make_to_repository('b')
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
160
        check_push_rev1(repo_b)
3035.2.2 by John Arbash Meinel
Add an interrepository test that when we are missing a basis text,
161
162
    def test_fetch_missing_basis_text(self):
163
        """If fetching a delta, we should die if a basis is not present."""
164
        tree = self.make_branch_and_tree('tree')
165
        self.build_tree(['tree/a'])
166
        tree.add(['a'], ['a-id'])
167
        tree.commit('one', rev_id='rev-one')
168
        self.build_tree_contents([('tree/a', 'new contents\n')])
169
        tree.commit('two', rev_id='rev-two')
170
171
        to_repo = self.make_to_repository('to_repo')
172
        # We build a broken revision so that we can test the fetch code dies
173
        # properly. So copy the inventory and revision, but not the text.
174
        to_repo.lock_write()
175
        try:
176
            to_repo.start_write_group()
177
            inv = tree.branch.repository.get_inventory('rev-one')
178
            to_repo.add_inventory('rev-one', inv, [])
179
            rev = tree.branch.repository.get_revision('rev-one')
180
            to_repo.add_revision('rev-one', rev, inv=inv)
181
            to_repo.commit_write_group()
182
        finally:
183
            to_repo.unlock()
184
185
        # Implementations can either copy the missing basis text, or raise an
186
        # exception
187
        try:
188
            to_repo.fetch(tree.branch.repository, 'rev-two')
3035.2.6 by John Arbash Meinel
Suggested by Robert: Move the missing externals check into part of Packer.pack()
189
        except errors.RevisionNotPresent, e:
3035.2.2 by John Arbash Meinel
Add an interrepository test that when we are missing a basis text,
190
            # If an exception is raised, the revision should not be in the
191
            # target.
192
            self.assertRaises((errors.NoSuchRevision, errors.RevisionNotPresent),
193
                              to_repo.revision_tree, 'rev-two')
194
        else:
195
            # If not exception is raised, then the basis text should be
196
            # available.
197
            to_repo.lock_read()
198
            try:
199
                rt = to_repo.revision_tree('rev-one')
200
                self.assertEqual('contents of tree/a\n',
201
                                 rt.get_file_text('a-id'))
202
            finally:
203
                to_repo.unlock()
204
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
205
    def test_fetch_missing_revision_same_location_fails(self):
206
        repo_a = self.make_repository('.')
207
        repo_b = repository.Repository.open('.')
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
208
        try:
209
            self.assertRaises(errors.NoSuchRevision, repo_b.fetch, repo_a, revision_id='XXX')
210
        except errors.LockError, e:
211
            check_old_format_lock_error(self.repository_format)
1534.1.29 by Robert Collins
Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.
212
213
    def test_fetch_same_location_trivial_works(self):
214
        repo_a = self.make_repository('.')
215
        repo_b = repository.Repository.open('.')
1711.7.18 by John Arbash Meinel
Old repository formats didn't support double locking on win32, don't raise errors
216
        try:
217
            repo_a.fetch(repo_b)
218
        except errors.LockError, e:
219
            check_old_format_lock_error(self.repository_format)
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
220
1694.2.6 by Martin Pool
[merge] bzr.dev
221
    def test_fetch_missing_text_other_location_fails(self):
222
        source_tree = self.make_branch_and_tree('source')
223
        source = source_tree.branch.repository
224
        target = self.make_to_repository('target')
225
    
2592.3.145 by Robert Collins
Fix test_fetch_missing_text_other_location_fails for pack repositories.
226
        # start by adding a file so the data knit for the file exists in
227
        # repositories that have specific files for each fileid.
1694.2.6 by Martin Pool
[merge] bzr.dev
228
        self.build_tree(['source/id'])
229
        source_tree.add(['id'], ['id'])
230
        source_tree.commit('a', rev_id='a')
231
        # now we manually insert a revision with an inventory referencing
232
        # 'id' at revision 'b', but we do not insert revision b.
233
        # this should ensure that the new versions of files are being checked
234
        # for during pull operations
235
        inv = source.get_inventory('a')
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
236
        source.lock_write()
237
        source.start_write_group()
1694.2.6 by Martin Pool
[merge] bzr.dev
238
        inv['id'].revision = 'b'
1740.2.6 by Aaron Bentley
Update test for new interface
239
        inv.revision_id = 'b'
2592.3.119 by Robert Collins
Merge some test fixes from Martin.
240
        sha1 = source.add_inventory('b', inv, ['a'])
1694.2.6 by Martin Pool
[merge] bzr.dev
241
        rev = Revision(timestamp=0,
242
                       timezone=None,
243
                       committer="Foo Bar <foo@example.com>",
244
                       message="Message",
245
                       inventory_sha1=sha1,
246
                       revision_id='b')
247
        rev.parent_ids = ['a']
248
        source.add_revision('b', rev)
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
249
        source.commit_write_group()
250
        source.unlock()
1694.2.6 by Martin Pool
[merge] bzr.dev
251
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
252
        self.assertFalse(target.has_revision('b'))
253
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
254
    def test_fetch_funky_file_id(self):
255
        from_tree = self.make_branch_and_tree('tree')
2240.1.3 by Alexander Belchenko
win32: skip tests that try to use funky chars in fileid in Weave-based repositories
256
        if sys.platform == 'win32':
257
            from_repo = from_tree.branch.repository
258
            check_repo_format_for_funky_id_on_win32(from_repo)
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
259
        self.build_tree(['tree/filename'])
260
        from_tree.add('filename', 'funky-chars<>%&;"\'')
261
        from_tree.commit('commit filename')
262
        to_repo = self.make_to_repository('to')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
263
        to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
264
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
265
266
class TestCaseWithComplexRepository(TestCaseWithInterRepository):
267
268
    def setUp(self):
269
        super(TestCaseWithComplexRepository, self).setUp()
270
        tree_a = self.make_branch_and_tree('a')
271
        self.bzrdir = tree_a.branch.bzrdir
272
        # add a corrupt inventory 'orphan'
2592.3.91 by Robert Collins
Incrementally closing in on a correct fetch for packs.
273
        tree_a.branch.repository.lock_write()
274
        tree_a.branch.repository.start_write_group()
275
        inv_file = tree_a.branch.repository.get_inventory_weave()
1563.2.10 by Robert Collins
Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.
276
        inv_file.add_lines('orphan', [], [])
2592.3.91 by Robert Collins
Incrementally closing in on a correct fetch for packs.
277
        tree_a.branch.repository.commit_write_group()
278
        tree_a.branch.repository.unlock()
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
279
        # add a real revision 'rev1'
280
        tree_a.commit('rev1', rev_id='rev1', allow_pointless=True)
281
        # add a real revision 'rev2' based on rev1
282
        tree_a.commit('rev2', rev_id='rev2', allow_pointless=True)
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
283
        # and sign 'rev2'
2592.3.96 by Robert Collins
Merge index improvements (includes bzr.dev).
284
        tree_a.branch.repository.lock_write()
285
        tree_a.branch.repository.start_write_group()
286
        tree_a.branch.repository.sign_revision('rev2', bzrlib.gpg.LoopbackGPGStrategy(None))
287
        tree_a.branch.repository.commit_write_group()
288
        tree_a.branch.repository.unlock()
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
289
290
    def test_missing_revision_ids(self):
291
        # revision ids in repository A but not B are returned, fake ones
292
        # are stripped. (fake meaning no revision object, but an inventory 
2592.3.146 by Robert Collins
Typo.
293
        # as some formats keyed off inventory data in the past.)
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
294
        # make a repository to compare against that claims to have rev1
295
        repo_b = self.make_to_repository('rev1_only')
296
        repo_a = self.bzrdir.open_repository()
297
        repo_b.fetch(repo_a, 'rev1')
298
        # check the test will be valid
299
        self.assertFalse(repo_b.has_revision('rev2'))
300
        self.assertEqual(['rev2'],
301
                         repo_b.missing_revision_ids(repo_a))
302
3010.1.5 by Robert Collins
Test that missing_revision_ids handles the case of the source not having the requested revision correctly with and without find_ghosts.
303
    def test_missing_revision_ids_absent_requested_raises(self):
304
        # Asking for missing revisions with a tip that is itself absent in the
305
        # source raises NoSuchRevision.
306
        repo_b = self.make_to_repository('target')
307
        repo_a = self.bzrdir.open_repository()
308
        # No pizza revisions anywhere
309
        self.assertFalse(repo_a.has_revision('pizza'))
310
        self.assertFalse(repo_b.has_revision('pizza'))
311
        # Asking specifically for an absent revision errors.
312
        self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
313
            revision_id='pizza', find_ghosts=True)
314
        self.assertRaises(NoSuchRevision, repo_b.missing_revision_ids, repo_a,
315
            revision_id='pizza', find_ghosts=False)
316
1534.1.34 by Robert Collins
Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.
317
    def test_missing_revision_ids_revision_limited(self):
318
        # revision ids in repository A that are not referenced by the
319
        # requested revision are not returned.
320
        # make a repository to compare against that is empty
321
        repo_b = self.make_to_repository('empty')
322
        repo_a = self.bzrdir.open_repository()
323
        self.assertEqual(['rev1'],
324
                         repo_b.missing_revision_ids(repo_a, revision_id='rev1'))
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
325
        
2592.3.91 by Robert Collins
Incrementally closing in on a correct fetch for packs.
326
    def test_fetch_fetches_signatures_too(self):
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
327
        from_repo = self.bzrdir.open_repository()
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
328
        from_signature = from_repo.get_signature_text('rev2')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
329
        to_repo = self.make_to_repository('target')
330
        to_repo.fetch(from_repo)
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
331
        to_signature = to_repo.get_signature_text('rev2')
1556.1.4 by Robert Collins
Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.
332
        self.assertEqual(from_signature, to_signature)
333
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
334
335
class TestCaseWithGhosts(TestCaseWithInterRepository):
336
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
337
    def test_fetch_all_fixes_up_ghost(self):
338
        # we want two repositories at this point:
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
339
        # one with a revision that is a ghost in the other
340
        # repository.
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
341
        # 'ghost' is present in has_ghost, 'ghost' is absent in 'missing_ghost'.
342
        # 'references' is present in both repositories, and 'tip' is present
343
        # just in has_ghost.
344
        # has_ghost       missing_ghost
345
        #------------------------------
346
        # 'ghost'             -
347
        # 'references'    'references'
348
        # 'tip'               -
349
        # In this test we fetch 'tip' which should not fetch 'ghost'
350
        has_ghost = self.make_repository('has_ghost')
351
        missing_ghost = self.make_repository('missing_ghost')
352
        if [True, True] != [repo._format.supports_ghosts for repo in
353
            (has_ghost, missing_ghost)]:
354
            raise TestNotApplicable("Need ghost support.")
355
356
        def add_commit(repo, revision_id, parent_ids):
357
            repo.lock_write()
358
            repo.start_write_group()
359
            inv = Inventory(revision_id=revision_id)
360
            inv.root.revision = revision_id
361
            root_id = inv.root.file_id
362
            sha1 = repo.add_inventory(revision_id, inv, parent_ids)
363
            vf = repo.weave_store.get_weave_or_empty(root_id,
364
                repo.get_transaction())
365
            vf.add_lines(revision_id, [], [])
366
            rev = bzrlib.revision.Revision(timestamp=0,
367
                                           timezone=None,
368
                                           committer="Foo Bar <foo@example.com>",
369
                                           message="Message",
370
                                           inventory_sha1=sha1,
371
                                           revision_id=revision_id)
372
            rev.parent_ids = parent_ids
373
            repo.add_revision(revision_id, rev)
374
            repo.commit_write_group()
375
            repo.unlock()
376
        add_commit(has_ghost, 'ghost', [])
377
        add_commit(has_ghost, 'references', ['ghost'])
378
        add_commit(missing_ghost, 'references', ['ghost'])
379
        add_commit(has_ghost, 'tip', ['references'])
380
        missing_ghost.fetch(has_ghost, 'tip', find_ghosts=True)
381
        # missing ghost now has tip and ghost.
382
        rev = missing_ghost.get_revision('tip')
383
        inv = missing_ghost.get_inventory('tip')
384
        rev = missing_ghost.get_revision('ghost')
385
        inv = missing_ghost.get_inventory('ghost')
1570.1.14 by Robert Collins
Enforce repository consistency during 'fetch' operations.
386
        # rev must not be corrupt now
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
387
        self.assertEqual([None, 'ghost', 'references', 'tip'],
388
            missing_ghost.get_ancestry('tip'))
2814.1.1 by Robert Collins
* Pushing, pulling and branching branches with subtree references was not
389
390
391
class TestFetchDependentData(TestCaseWithInterRepository):
392
393
    def test_reference(self):
394
        from_tree = self.make_branch_and_tree('tree')
395
        to_repo = self.make_to_repository('to')
396
        if (not from_tree.supports_tree_reference() or
397
            not from_tree.branch.repository._format.supports_tree_reference or
398
            not to_repo._format.supports_tree_reference):
399
            raise TestNotApplicable("Need subtree support.")
400
        subtree = self.make_branch_and_tree('tree/subtree')
401
        subtree.commit('subrev 1')
402
        from_tree.add_reference(subtree)
403
        tree_rev = from_tree.commit('foo')
404
        # now from_tree has a last-modified of subtree of the rev id of the
405
        # commit for foo, and a reference revision of the rev id of the commit
406
        # for subrev 1
407
        to_repo.fetch(from_tree.branch.repository, tree_rev)
408
        # to_repo should have a file_graph for from_tree.path2id('subtree') and
409
        # revid tree_rev.
2998.2.2 by John Arbash Meinel
implement a faster path for copying from packs back to knits.
410
        to_repo.lock_read()
411
        try:
412
            file_vf = to_repo.weave_store.get_weave(
413
                from_tree.path2id('subtree'), to_repo.get_transaction())
414
            self.assertEqual([tree_rev], file_vf.get_ancestry([tree_rev]))
415
        finally:
416
            to_repo.unlock()