1
# Copyright (C) 2004, 2005 by Canonical Ltd
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
from bzrlib.builtins import merge
21
from bzrlib.branch import Branch
22
from bzrlib.tests import TestCaseWithTransport
23
from bzrlib.errors import NoCommonAncestor, NoCommits
24
from bzrlib.errors import NoSuchRevision
25
from bzrlib.revisionspec import RevisionSpec
28
class TestRevisionNamespaces(TestCaseWithTransport):
30
def test_revision_namespaces(self):
31
"""Test revision specifiers.
33
These identify revisions by date, etc."""
34
wt = self.make_branch_and_tree('.')
37
wt.commit('Commit one', rev_id='a@r-0-1', timestamp=time.time() - 60*60*24)
38
wt.commit('Commit two', rev_id='a@r-0-2')
39
wt.commit('Commit three', rev_id='a@r-0-3')
41
self.assertEquals(RevisionSpec(None).in_history(b), (0, None))
42
self.assertEquals(RevisionSpec(1).in_history(b), (1, 'a@r-0-1'))
43
self.assertEquals(RevisionSpec('revno:1').in_history(b),
45
self.assertEquals(RevisionSpec('revid:a@r-0-1').in_history(b),
47
self.assertRaises(NoSuchRevision,
48
RevisionSpec('revid:a@r-0-0').in_history, b)
49
self.assertRaises(TypeError, RevisionSpec, object)
51
self.assertEquals(RevisionSpec('date:today').in_history(b),
53
self.assertEquals(RevisionSpec('date:yesterday').in_history(b),
55
self.assertEquals(RevisionSpec('before:date:today').in_history(b),
58
self.assertEquals(RevisionSpec('last:1').in_history(b),
60
self.assertEquals(RevisionSpec('-1').in_history(b), (3, 'a@r-0-3'))
61
# self.assertEquals(b.get_revision_info('last:1'), (3, 'a@r-0-3'))
62
# self.assertEquals(b.get_revision_info('-1'), (3, 'a@r-0-3'))
64
self.assertEquals(RevisionSpec('ancestor:.').in_history(b).rev_id,
68
wt2 = self.make_branch_and_tree('newbranch')
70
self.assertRaises(NoCommits, RevisionSpec('ancestor:.').in_history, b2)
72
d3 = b.bzrdir.sprout('copy')
74
wt3 = d3.open_workingtree()
75
wt3.commit('Commit four', rev_id='b@r-0-4')
76
self.assertEquals(RevisionSpec('ancestor:.').in_history(b3).rev_id,
78
merge(['copy', -1], [None, None])
79
wt.commit('Commit five', rev_id='a@r-0-4')
80
self.assertEquals(RevisionSpec('ancestor:copy').in_history(b).rev_id,
82
self.assertEquals(RevisionSpec('ancestor:.').in_history(b3).rev_id,
85
# This should be in the revision store, but not in revision-history
86
self.assertEquals((None, 'b@r-0-4'),
87
RevisionSpec('revid:b@r-0-4').in_history(b))
89
def test_branch_namespace(self):
90
"""Ensure that the branch namespace pulls in the requisite content."""
91
self.build_tree(['branch1/', 'branch1/file', 'branch2/'])
92
wt = self.make_branch_and_tree('branch1')
96
d2 = branch.bzrdir.sprout('branch2')
97
print >> open('branch2/file', 'w'), 'new content'
98
branch2 = d2.open_branch()
99
d2.open_workingtree().commit('update file', rev_id='A')
100
spec = RevisionSpec('branch:./branch2/.bzr/../')
101
rev_info = spec.in_history(branch)
102
self.assertEqual(rev_info, (None, 'A'))
27
from bzrlib.tests import TestCase, TestCaseWithTransport
28
from bzrlib.revisionspec import (
35
def spec_in_history(spec, branch):
36
"""A simple helper to change a revision spec into a branch search"""
37
return RevisionSpec.from_string(spec).in_history(branch)
40
# Basic class, which just creates a really basic set of revisions
41
class TestRevisionSpec(TestCaseWithTransport):
44
super(TestRevisionSpec, self).setUp()
45
# this sets up a revision graph:
50
self.tree = self.make_branch_and_tree('tree')
51
self.build_tree(['tree/a'])
52
self.tree.lock_write()
53
self.addCleanup(self.tree.unlock)
55
self.tree.commit('a', rev_id='r1')
57
self.tree2 = self.tree.bzrdir.sprout('tree2').open_workingtree()
58
self.tree2.commit('alt', rev_id='alt_r2')
60
self.tree.merge_from_branch(self.tree2.branch)
61
self.tree.commit('second', rev_id='r2')
63
def get_in_history(self, revision_spec):
64
return spec_in_history(revision_spec, self.tree.branch)
66
def assertInHistoryIs(self, exp_revno, exp_revision_id, revision_spec):
67
rev_info = self.get_in_history(revision_spec)
68
self.assertEqual(exp_revno, rev_info.revno,
69
'Revision spec: %r returned wrong revno: %r != %r'
70
% (revision_spec, exp_revno, rev_info.revno))
71
self.assertEqual(exp_revision_id, rev_info.rev_id,
72
'Revision spec: %r returned wrong revision id:'
74
% (revision_spec, exp_revision_id, rev_info.rev_id))
76
def assertInvalid(self, revision_spec, extra=''):
78
self.get_in_history(revision_spec)
79
except errors.InvalidRevisionSpec, e:
80
self.assertEqual(revision_spec, e.spec)
81
self.assertEqual(extra, e.extra)
83
self.fail('Expected InvalidRevisionSpec to be raised for %s'
86
def assertAsRevisionId(self, revision_id, revision_spec):
87
"""Calling as_revision_id() should return the specified id."""
88
spec = RevisionSpec.from_string(revision_spec)
89
self.assertEqual(revision_id,
90
spec.as_revision_id(self.tree.branch))
93
class RevisionSpecMatchOnTrap(RevisionSpec):
95
def _match_on(self, branch, revs):
96
self.last_call = (branch, revs)
97
return super(RevisionSpecMatchOnTrap, self)._match_on(branch, revs)
100
class TestRevisionSpecBase(TestRevisionSpec):
102
def test_wants_revision_history(self):
103
# If wants_revision_history = True, then _match_on should get the
104
# branch revision history
105
spec = RevisionSpecMatchOnTrap('foo', _internal=True)
106
spec.in_history(self.tree.branch)
108
self.assertEqual((self.tree.branch, ['r1' ,'r2']),
111
def test_wants_no_revision_history(self):
112
# If wants_revision_history = False, then _match_on should get None for
113
# the branch revision history
114
spec = RevisionSpecMatchOnTrap('foo', _internal=True)
115
spec.wants_revision_history = False
116
spec.in_history(self.tree.branch)
118
self.assertEqual((self.tree.branch, None), spec.last_call)
122
class TestOddRevisionSpec(TestRevisionSpec):
123
"""Test things that aren't normally thought of as revision specs"""
126
self.assertInHistoryIs(None, None, None)
128
def test_object(self):
129
self.assertRaises(TypeError, RevisionSpec.from_string, object())
131
def test_unregistered_spec(self):
132
self.assertRaises(errors.NoSuchRevisionSpec,
133
RevisionSpec.from_string, 'foo')
134
self.assertRaises(errors.NoSuchRevisionSpec,
135
RevisionSpec.from_string, '123a')
139
class TestRevnoFromString(TestCase):
141
def test_from_string_dotted_decimal(self):
142
self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '-1.1')
143
self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '.1')
144
self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1..1')
145
self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1.2..1')
146
self.assertRaises(errors.NoSuchRevisionSpec, RevisionSpec.from_string, '1.')
147
self.assertIsInstance(RevisionSpec.from_string('1.1'), RevisionSpec_revno)
148
self.assertIsInstance(RevisionSpec.from_string('1.1.3'), RevisionSpec_revno)
151
class TestRevisionSpec_revno(TestRevisionSpec):
153
def test_positive_int(self):
154
self.assertInHistoryIs(0, 'null:', '0')
155
self.assertInHistoryIs(1, 'r1', '1')
156
self.assertInHistoryIs(2, 'r2', '2')
157
self.assertInvalid('3')
159
def test_dotted_decimal(self):
160
self.assertInHistoryIs(None, 'alt_r2', '1.1.1')
162
def test_negative_int(self):
163
self.assertInHistoryIs(2, 'r2', '-1')
164
self.assertInHistoryIs(1, 'r1', '-2')
166
self.assertInHistoryIs(1, 'r1', '-3')
167
self.assertInHistoryIs(1, 'r1', '-4')
168
self.assertInHistoryIs(1, 'r1', '-100')
170
def test_positive(self):
171
self.assertInHistoryIs(0, 'null:', 'revno:0')
172
self.assertInHistoryIs(1, 'r1', 'revno:1')
173
self.assertInHistoryIs(2, 'r2', 'revno:2')
175
self.assertInvalid('revno:3')
177
def test_negative(self):
178
self.assertInHistoryIs(2, 'r2', 'revno:-1')
179
self.assertInHistoryIs(1, 'r1', 'revno:-2')
181
self.assertInHistoryIs(1, 'r1', 'revno:-3')
182
self.assertInHistoryIs(1, 'r1', 'revno:-4')
184
def test_invalid_number(self):
185
# Get the right exception text
188
except ValueError, e:
190
self.assertInvalid('revno:X', extra='\n' + str(e))
192
def test_missing_number_and_branch(self):
193
self.assertInvalid('revno::',
194
extra='\ncannot have an empty revno and no branch')
196
def test_invalid_number_with_branch(self):
199
except ValueError, e:
201
self.assertInvalid('revno:X:tree2', extra='\n' + str(e))
203
def test_non_exact_branch(self):
204
# It seems better to require an exact path to the branch
205
# Branch.open() rather than using Branch.open_containing()
206
spec = RevisionSpec.from_string('revno:2:tree2/a')
207
self.assertRaises(errors.NotBranchError,
208
spec.in_history, self.tree.branch)
210
def test_with_branch(self):
211
# Passing a URL overrides the supplied branch path
212
revinfo = self.get_in_history('revno:2:tree2')
213
self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
214
self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
215
self.assertEqual(2, revinfo.revno)
216
self.assertEqual('alt_r2', revinfo.rev_id)
218
def test_int_with_branch(self):
219
revinfo = self.get_in_history('2:tree2')
220
self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
221
self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
222
self.assertEqual(2, revinfo.revno)
223
self.assertEqual('alt_r2', revinfo.rev_id)
225
def test_with_url(self):
226
url = self.get_url() + '/tree2'
227
revinfo = self.get_in_history('revno:2:%s' % (url,))
228
self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
229
self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
230
self.assertEqual(2, revinfo.revno)
231
self.assertEqual('alt_r2', revinfo.rev_id)
233
def test_negative_with_url(self):
234
url = self.get_url() + '/tree2'
235
revinfo = self.get_in_history('revno:-1:%s' % (url,))
236
self.assertNotEqual(self.tree.branch.base, revinfo.branch.base)
237
self.assertEqual(self.tree2.branch.base, revinfo.branch.base)
238
self.assertEqual(2, revinfo.revno)
239
self.assertEqual('alt_r2', revinfo.rev_id)
241
def test_different_history_lengths(self):
242
# Make sure we use the revisions and offsets in the supplied branch
243
# not the ones in the original branch.
244
self.tree2.commit('three', rev_id='r3')
245
self.assertInHistoryIs(3, 'r3', 'revno:3:tree2')
246
self.assertInHistoryIs(3, 'r3', 'revno:-1:tree2')
248
def test_invalid_branch(self):
249
self.assertRaises(errors.NotBranchError,
250
self.get_in_history, 'revno:-1:tree3')
252
def test_invalid_revno_in_branch(self):
253
self.tree.commit('three', rev_id='r3')
254
self.assertInvalid('revno:3:tree2')
256
def test_revno_n_path(self):
257
"""Old revno:N:path tests"""
258
wta = self.make_branch_and_tree('a')
261
wta.commit('Commit one', rev_id='a@r-0-1')
262
wta.commit('Commit two', rev_id='a@r-0-2')
263
wta.commit('Commit three', rev_id='a@r-0-3')
265
wtb = self.make_branch_and_tree('b')
268
wtb.commit('Commit one', rev_id='b@r-0-1')
269
wtb.commit('Commit two', rev_id='b@r-0-2')
270
wtb.commit('Commit three', rev_id='b@r-0-3')
273
self.assertEqual((1, 'a@r-0-1'),
274
spec_in_history('revno:1:a/', ba))
275
# The argument of in_history should be ignored since it is
276
# redundant with the path in the spec.
277
self.assertEqual((1, 'a@r-0-1'),
278
spec_in_history('revno:1:a/', None))
279
self.assertEqual((1, 'a@r-0-1'),
280
spec_in_history('revno:1:a/', bb))
281
self.assertEqual((2, 'b@r-0-2'),
282
spec_in_history('revno:2:b/', None))
284
def test_as_revision_id(self):
285
self.assertAsRevisionId('null:', '0')
286
self.assertAsRevisionId('r1', '1')
287
self.assertAsRevisionId('r2', '2')
288
self.assertAsRevisionId('r1', '-2')
289
self.assertAsRevisionId('r2', '-1')
290
self.assertAsRevisionId('alt_r2', '1.1.1')
293
class TestRevisionSpec_revid(TestRevisionSpec):
295
def test_in_history(self):
296
# We should be able to access revisions that are directly
298
self.assertInHistoryIs(1, 'r1', 'revid:r1')
299
self.assertInHistoryIs(2, 'r2', 'revid:r2')
301
def test_missing(self):
302
self.assertInvalid('revid:r3')
304
def test_merged(self):
305
"""We can reach revisions in the ancestry"""
306
self.assertInHistoryIs(None, 'alt_r2', 'revid:alt_r2')
308
def test_not_here(self):
309
self.tree2.commit('alt third', rev_id='alt_r3')
310
# It exists in tree2, but not in tree
311
self.assertInvalid('revid:alt_r3')
313
def test_in_repository(self):
314
"""We can get any revision id in the repository"""
315
# XXX: This may change in the future, but for now, it is true
316
self.tree2.commit('alt third', rev_id='alt_r3')
317
self.tree.branch.repository.fetch(self.tree2.branch.repository,
318
revision_id='alt_r3')
319
self.assertInHistoryIs(None, 'alt_r3', 'revid:alt_r3')
321
def test_unicode(self):
322
"""We correctly convert a unicode ui string to an encoded revid."""
323
revision_id = u'\N{SNOWMAN}'.encode('utf-8')
324
self.tree.commit('unicode', rev_id=revision_id)
325
self.assertInHistoryIs(3, revision_id, u'revid:\N{SNOWMAN}')
326
self.assertInHistoryIs(3, revision_id, 'revid:' + revision_id)
328
def test_as_revision_id(self):
329
self.assertAsRevisionId('r1', 'revid:r1')
330
self.assertAsRevisionId('r2', 'revid:r2')
331
self.assertAsRevisionId('alt_r2', 'revid:alt_r2')
334
class TestRevisionSpec_last(TestRevisionSpec):
336
def test_positive(self):
337
self.assertInHistoryIs(2, 'r2', 'last:1')
338
self.assertInHistoryIs(1, 'r1', 'last:2')
339
self.assertInHistoryIs(0, 'null:', 'last:3')
341
def test_empty(self):
342
self.assertInHistoryIs(2, 'r2', 'last:')
344
def test_negative(self):
345
self.assertInvalid('last:-1',
346
extra='\nyou must supply a positive value')
348
def test_missing(self):
349
self.assertInvalid('last:4')
351
def test_no_history(self):
352
tree = self.make_branch_and_tree('tree3')
354
self.assertRaises(errors.NoCommits,
355
spec_in_history, 'last:', tree.branch)
357
def test_not_a_number(self):
360
except ValueError, e:
362
self.assertInvalid('last:Y', extra='\n' + str(e))
364
def test_as_revision_id(self):
365
self.assertAsRevisionId('r2', 'last:1')
366
self.assertAsRevisionId('r1', 'last:2')
369
class TestRevisionSpec_before(TestRevisionSpec):
372
self.assertInHistoryIs(1, 'r1', 'before:2')
373
self.assertInHistoryIs(1, 'r1', 'before:-1')
375
def test_before_one(self):
376
self.assertInHistoryIs(0, 'null:', 'before:1')
378
def test_before_none(self):
379
self.assertInvalid('before:0',
380
extra='\ncannot go before the null: revision')
382
def test_revid(self):
383
self.assertInHistoryIs(1, 'r1', 'before:revid:r2')
386
self.assertInHistoryIs(1, 'r1', 'before:last:1')
388
def test_alt_revid(self):
389
# This will grab the left-most ancestor for alternate histories
390
self.assertInHistoryIs(1, 'r1', 'before:revid:alt_r2')
392
def test_alt_no_parents(self):
393
new_tree = self.make_branch_and_tree('new_tree')
394
new_tree.commit('first', rev_id='new_r1')
395
self.tree.branch.repository.fetch(new_tree.branch.repository,
396
revision_id='new_r1')
397
self.assertInHistoryIs(0, 'null:', 'before:revid:new_r1')
399
def test_as_revision_id(self):
400
self.assertAsRevisionId('r1', 'before:revid:r2')
401
self.assertAsRevisionId('r1', 'before:2')
402
self.assertAsRevisionId('r1', 'before:1.1.1')
403
self.assertAsRevisionId('r1', 'before:revid:alt_r2')
406
class TestRevisionSpec_tag(TestRevisionSpec):
408
def make_branch_and_tree(self, relpath):
409
# override format as the default one may not support tags
410
return TestRevisionSpec.make_branch_and_tree(
411
self, relpath, format='dirstate-tags')
413
def test_from_string_tag(self):
414
spec = RevisionSpec.from_string('tag:bzr-0.14')
415
self.assertIsInstance(spec, RevisionSpec_tag)
416
self.assertEqual(spec.spec, 'bzr-0.14')
418
def test_lookup_tag(self):
419
self.tree.branch.tags.set_tag('bzr-0.14', 'r1')
420
self.assertInHistoryIs(1, 'r1', 'tag:bzr-0.14')
421
self.tree.branch.tags.set_tag('null_rev', 'null:')
422
self.assertInHistoryIs(0, 'null:', 'tag:null_rev')
424
def test_failed_lookup(self):
425
# tags that don't exist give a specific message: arguably we should
426
# just give InvalidRevisionSpec but I think this is more helpful
427
self.assertRaises(errors.NoSuchTag,
429
'tag:some-random-tag')
431
def test_as_revision_id(self):
432
self.tree.branch.tags.set_tag('my-tag', 'r2')
433
self.tree.branch.tags.set_tag('null_rev', 'null:')
434
self.assertAsRevisionId('r2', 'tag:my-tag')
435
self.assertAsRevisionId('null:', 'tag:null_rev')
436
self.assertAsRevisionId('r1', 'before:tag:my-tag')
439
class TestRevisionSpec_date(TestRevisionSpec):
442
super(TestRevisionSpec, self).setUp()
444
new_tree = self.make_branch_and_tree('new_tree')
445
new_tree.commit('Commit one', rev_id='new_r1',
446
timestamp=time.time() - 60*60*24)
447
new_tree.commit('Commit two', rev_id='new_r2')
448
new_tree.commit('Commit three', rev_id='new_r3')
452
def test_tomorrow(self):
453
self.assertInvalid('date:tomorrow')
455
def test_today(self):
456
self.assertInHistoryIs(2, 'new_r2', 'date:today')
457
self.assertInHistoryIs(1, 'new_r1', 'before:date:today')
459
def test_yesterday(self):
460
self.assertInHistoryIs(1, 'new_r1', 'date:yesterday')
462
def test_invalid(self):
463
self.assertInvalid('date:foobar', extra='\ninvalid date')
464
# You must have '-' between year/month/day
465
self.assertInvalid('date:20040404', extra='\ninvalid date')
466
# Need 2 digits for each date piece
467
self.assertInvalid('date:2004-4-4', extra='\ninvalid date')
470
now = datetime.datetime.now()
471
self.assertInHistoryIs(2, 'new_r2',
472
'date:%04d-%02d-%02d' % (now.year, now.month, now.day))
474
def test_as_revision_id(self):
475
self.assertAsRevisionId('new_r2', 'date:today')
478
class TestRevisionSpec_ancestor(TestRevisionSpec):
480
def test_non_exact_branch(self):
481
# It seems better to require an exact path to the branch
482
# Branch.open() rather than using Branch.open_containing()
483
self.assertRaises(errors.NotBranchError,
484
self.get_in_history, 'ancestor:tree2/a')
486
def test_simple(self):
487
# Common ancestor of trees is 'alt_r2'
488
self.assertInHistoryIs(None, 'alt_r2', 'ancestor:tree2')
490
# Going the other way, we get a valid revno
492
self.tree = self.tree2
494
self.assertInHistoryIs(2, 'alt_r2', 'ancestor:tree')
497
self.assertInHistoryIs(2, 'r2', 'ancestor:tree')
499
def test_unrelated(self):
500
new_tree = self.make_branch_and_tree('new_tree')
502
new_tree.commit('Commit one', rev_id='new_r1')
503
new_tree.commit('Commit two', rev_id='new_r2')
504
new_tree.commit('Commit three', rev_id='new_r3')
506
# With no common ancestor, we should raise another user error
507
self.assertRaises(errors.NoCommonAncestor,
508
self.get_in_history, 'ancestor:new_tree')
510
def test_no_commits(self):
511
new_tree = self.make_branch_and_tree('new_tree')
512
self.assertRaises(errors.NoCommits,
513
spec_in_history, 'ancestor:new_tree',
516
self.assertRaises(errors.NoCommits,
517
spec_in_history, 'ancestor:tree',
520
def test_as_revision_id(self):
521
self.assertAsRevisionId('alt_r2', 'ancestor:tree2')
524
class TestRevisionSpec_branch(TestRevisionSpec):
526
def test_non_exact_branch(self):
527
# It seems better to require an exact path to the branch
528
# Branch.open() rather than using Branch.open_containing()
529
self.assertRaises(errors.NotBranchError,
530
self.get_in_history, 'branch:tree2/a')
532
def test_simple(self):
533
self.assertInHistoryIs(None, 'alt_r2', 'branch:tree2')
536
self.assertInHistoryIs(2, 'r2', 'branch:tree')
538
def test_unrelated(self):
539
new_tree = self.make_branch_and_tree('new_tree')
541
new_tree.commit('Commit one', rev_id='new_r1')
542
new_tree.commit('Commit two', rev_id='new_r2')
543
new_tree.commit('Commit three', rev_id='new_r3')
545
self.assertInHistoryIs(None, 'new_r3', 'branch:new_tree')
547
# XXX: Right now, we use fetch() to make sure the remote revisions
548
# have been pulled into the local branch. We may change that
549
# behavior in the future.
550
self.failUnless(self.tree.branch.repository.has_revision('new_r3'))
552
def test_no_commits(self):
553
new_tree = self.make_branch_and_tree('new_tree')
554
self.assertRaises(errors.NoCommits,
555
self.get_in_history, 'branch:new_tree')
557
def test_as_revision_id(self):
558
self.assertAsRevisionId('alt_r2', 'branch:tree2')
561
class TestRevisionSpec_submit(TestRevisionSpec):
563
def test_submit_branch(self):
564
# Common ancestor of trees is 'alt_r2'
565
self.assertRaises(errors.NoSubmitBranch, self.get_in_history,
567
self.tree.branch.set_parent('../tree2')
568
self.assertInHistoryIs(None, 'alt_r2', 'submit:')
569
self.tree.branch.set_parent('bogus')
570
self.assertRaises(errors.NotBranchError, self.get_in_history,
572
# submit branch overrides parent branch
573
self.tree.branch.set_submit_branch('tree2')
574
self.assertInHistoryIs(None, 'alt_r2', 'submit:')
576
def test_as_revision_id(self):
577
self.tree.branch.set_submit_branch('tree2')
578
self.assertAsRevisionId('alt_r2', 'branch:tree2')