~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

  • Committer: Robert Collins
  • Date: 2007-07-04 08:08:13 UTC
  • mfrom: (2572 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2587.
  • Revision ID: robertc@robertcollins.net-20070704080813-wzebx0r88fvwj5rq
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
#
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
21
21
from bzrlib import (
22
22
    errors,
23
23
    lockdir,
 
24
    osutils,
 
25
    tests,
24
26
    )
25
27
from bzrlib.branch import Branch
26
28
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
221
223
        wt.move(['hello'], 'a')
222
224
        r2 = 'test@rev-2'
223
225
        wt.commit('two', rev_id=r2, allow_pointless=False)
224
 
        self.check_inventory_shape(wt.read_working_inventory(),
225
 
                                   ['a', 'a/hello', 'b'])
 
226
        wt.lock_read()
 
227
        try:
 
228
            self.check_inventory_shape(wt.read_working_inventory(),
 
229
                                       ['a/', 'a/hello', 'b/'])
 
230
        finally:
 
231
            wt.unlock()
226
232
 
227
233
        wt.move(['b'], 'a')
228
234
        r3 = 'test@rev-3'
229
235
        wt.commit('three', rev_id=r3, allow_pointless=False)
230
 
        self.check_inventory_shape(wt.read_working_inventory(),
231
 
                                   ['a', 'a/hello', 'a/b'])
232
 
        self.check_inventory_shape(b.repository.get_revision_inventory(r3),
233
 
                                   ['a', 'a/hello', 'a/b'])
 
236
        wt.lock_read()
 
237
        try:
 
238
            self.check_inventory_shape(wt.read_working_inventory(),
 
239
                                       ['a/', 'a/hello', 'a/b/'])
 
240
            self.check_inventory_shape(b.repository.get_revision_inventory(r3),
 
241
                                       ['a/', 'a/hello', 'a/b/'])
 
242
        finally:
 
243
            wt.unlock()
234
244
 
235
245
        wt.move(['a/hello'], 'a/b')
236
246
        r4 = 'test@rev-4'
237
247
        wt.commit('four', rev_id=r4, allow_pointless=False)
238
 
        self.check_inventory_shape(wt.read_working_inventory(),
239
 
                                   ['a', 'a/b/hello', 'a/b'])
 
248
        wt.lock_read()
 
249
        try:
 
250
            self.check_inventory_shape(wt.read_working_inventory(),
 
251
                                       ['a/', 'a/b/hello', 'a/b/'])
 
252
        finally:
 
253
            wt.unlock()
240
254
 
241
255
        inv = b.repository.get_revision_inventory(r4)
242
256
        eq(inv['hello-id'].revision, r4)
243
257
        eq(inv['a-id'].revision, r1)
244
258
        eq(inv['b-id'].revision, r3)
245
 
        
 
259
 
246
260
    def test_removed_commit(self):
247
261
        """Commit with a removed file"""
248
262
        wt = self.make_branch_and_tree('.')
343
357
                                                      allow_pointless=True,
344
358
                                                      rev_id='B',
345
359
                                                      working_tree=wt)
346
 
            self.assertEqual(Testament.from_revision(branch.repository,
347
 
                             'B').as_short_text(),
 
360
            def sign(text):
 
361
                return bzrlib.gpg.LoopbackGPGStrategy(None).sign(text)
 
362
            self.assertEqual(sign(Testament.from_revision(branch.repository,
 
363
                             'B').as_short_text()),
348
364
                             branch.repository.get_signature_text('B'))
349
365
        finally:
350
366
            bzrlib.gpg.GPGStrategy = oldstrategy
525
541
        tree.commit('added a, b')
526
542
        tree.remove(['a', 'b'])
527
543
        tree.commit('removed a', specific_files='a')
528
 
        basis = tree.basis_tree().inventory
529
 
        self.assertIs(None, basis.path2id('a'))
530
 
        self.assertFalse(basis.path2id('b') is None)
 
544
        basis = tree.basis_tree()
 
545
        tree.lock_read()
 
546
        try:
 
547
            self.assertIs(None, basis.path2id('a'))
 
548
            self.assertFalse(basis.path2id('b') is None)
 
549
        finally:
 
550
            tree.unlock()
531
551
 
532
552
    def test_commit_saves_1ms_timestamp(self):
533
553
        """Passing in a timestamp is saved with 1ms resolution"""
552
572
        timestamp_1ms = round(timestamp, 3)
553
573
        self.assertEqual(timestamp_1ms, timestamp)
554
574
 
 
575
    def assertBasisTreeKind(self, kind, tree, file_id):
 
576
        basis = tree.basis_tree()
 
577
        basis.lock_read()
 
578
        try:
 
579
            self.assertEqual(kind, basis.kind(file_id))
 
580
        finally:
 
581
            basis.unlock()
 
582
 
 
583
    def test_commit_kind_changes(self):
 
584
        if not osutils.has_symlinks():
 
585
            raise tests.TestSkipped('Test requires symlink support')
 
586
        tree = self.make_branch_and_tree('.')
 
587
        os.symlink('target', 'name')
 
588
        tree.add('name', 'a-file-id')
 
589
        tree.commit('Added a symlink')
 
590
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
591
 
 
592
        os.unlink('name')
 
593
        self.build_tree(['name'])
 
594
        tree.commit('Changed symlink to file')
 
595
        self.assertBasisTreeKind('file', tree, 'a-file-id')
 
596
 
 
597
        os.unlink('name')
 
598
        os.symlink('target', 'name')
 
599
        tree.commit('file to symlink')
 
600
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
601
 
 
602
        os.unlink('name')
 
603
        os.mkdir('name')
 
604
        tree.commit('symlink to directory')
 
605
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
606
 
 
607
        os.rmdir('name')
 
608
        os.symlink('target', 'name')
 
609
        tree.commit('directory to symlink')
 
610
        self.assertBasisTreeKind('symlink', tree, 'a-file-id')
 
611
 
 
612
        # prepare for directory <-> file tests
 
613
        os.unlink('name')
 
614
        os.mkdir('name')
 
615
        tree.commit('symlink to directory')
 
616
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
617
 
 
618
        os.rmdir('name')
 
619
        self.build_tree(['name'])
 
620
        tree.commit('Changed directory to file')
 
621
        self.assertBasisTreeKind('file', tree, 'a-file-id')
 
622
 
 
623
        os.unlink('name')
 
624
        os.mkdir('name')
 
625
        tree.commit('file to directory')
 
626
        self.assertBasisTreeKind('directory', tree, 'a-file-id')
 
627
 
555
628
    def test_commit_unversioned_specified(self):
556
629
        """Commit should raise if specified files isn't in basis or worktree"""
557
630
        tree = self.make_branch_and_tree('.')
558
631
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
559
632
                          'message', specific_files=['bogus'])
 
633
 
 
634
    class Callback(object):
 
635
        
 
636
        def __init__(self, message, testcase):
 
637
            self.called = False
 
638
            self.message = message
 
639
            self.testcase = testcase
 
640
 
 
641
        def __call__(self, commit_obj):
 
642
            self.called = True
 
643
            self.testcase.assertTrue(isinstance(commit_obj, Commit))
 
644
            return self.message
 
645
 
 
646
    def test_commit_callback(self):
 
647
        """Commit should invoke a callback to get the message"""
 
648
 
 
649
        tree = self.make_branch_and_tree('.')
 
650
        try:
 
651
            tree.commit()
 
652
        except Exception, e:
 
653
            self.assertTrue(isinstance(e, BzrError))
 
654
            self.assertEqual('The message or message_callback keyword'
 
655
                             ' parameter is required for commit().', str(e))
 
656
        else:
 
657
            self.fail('exception not raised')
 
658
        cb = self.Callback(u'commit 1', self)
 
659
        tree.commit(message_callback=cb)
 
660
        self.assertTrue(cb.called)
 
661
        repository = tree.branch.repository
 
662
        message = repository.get_revision(tree.last_revision()).message
 
663
        self.assertEqual('commit 1', message)
 
664
 
 
665
    def test_no_callback_pointless(self):
 
666
        """Callback should not be invoked for pointless commit"""
 
667
        tree = self.make_branch_and_tree('.')
 
668
        cb = self.Callback(u'commit 2', self)
 
669
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb, 
 
670
                          allow_pointless=False)
 
671
        self.assertFalse(cb.called)
 
672
 
 
673
    def test_no_callback_netfailure(self):
 
674
        """Callback should not be invoked if connectivity fails"""
 
675
        tree = self.make_branch_and_tree('.')
 
676
        cb = self.Callback(u'commit 2', self)
 
677
        repository = tree.branch.repository
 
678
        # simulate network failure
 
679
        def raise_(self, arg, arg2):
 
680
            raise errors.NoSuchFile('foo')
 
681
        repository.add_inventory = raise_
 
682
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
 
683
        self.assertFalse(cb.called)
 
684
 
 
685
    def test_selected_file_merge_commit(self):
 
686
        """Ensure the correct error is raised"""
 
687
        tree = self.make_branch_and_tree('foo')
 
688
        # pending merge would turn into a left parent
 
689
        tree.commit('commit 1')
 
690
        tree.add_parent_tree_id('example')
 
691
        self.build_tree(['foo/bar', 'foo/baz'])
 
692
        tree.add(['bar', 'baz'])
 
693
        err = self.assertRaises(errors.CannotCommitSelectedFileMerge,
 
694
            tree.commit, 'commit 2', specific_files=['bar', 'baz'])
 
695
        self.assertEqual(['bar', 'baz'], err.files)
 
696
        self.assertEqual('Selected-file commit of merges is not supported'
 
697
                         ' yet: files bar, baz', str(err))