/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_commit.py

Seperate SmartServer{Pipe,Socket}StreamMedium out of SmartServerStreamMedium.  Use recv to make the socket server medium better.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2006 by Canonical Ltd
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
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.
12
 
 
 
12
#
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
18
18
import os
19
19
 
20
20
import bzrlib
 
21
from bzrlib import errors
21
22
from bzrlib.tests import TestCaseWithTransport
22
23
from bzrlib.branch import Branch
23
24
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
24
25
from bzrlib.workingtree import WorkingTree
25
 
from bzrlib.commit import Commit
 
26
from bzrlib.commit import Commit, NullCommitReporter
26
27
from bzrlib.config import BranchConfig
27
28
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
28
29
                           LockContention)
45
46
        return "bzrlib.ahook bzrlib.ahook"
46
47
 
47
48
 
 
49
class CapturingReporter(NullCommitReporter):
 
50
    """This reporter captures the calls made to it for evaluation later."""
 
51
 
 
52
    def __init__(self):
 
53
        # a list of the calls this received
 
54
        self.calls = []
 
55
 
 
56
    def snapshot_change(self, change, path):
 
57
        self.calls.append(('change', change, path))
 
58
 
 
59
    def deleted(self, file_id):
 
60
        self.calls.append(('deleted', file_id))
 
61
 
 
62
    def missing(self, path):
 
63
        self.calls.append(('missing', path))
 
64
 
 
65
    def renamed(self, change, old_path, new_path):
 
66
        self.calls.append(('renamed', change, old_path, new_path))
 
67
 
 
68
 
48
69
class TestCommit(TestCaseWithTransport):
49
70
 
50
71
    def test_simple_commit(self):
392
413
            self.assertRaises(LockContention, wt.commit, 'silly')
393
414
        finally:
394
415
            master_branch.unlock()
 
416
 
 
417
    def test_commit_bound_merge(self):
 
418
        # see bug #43959; commit of a merge in a bound branch fails to push
 
419
        # the new commit into the master
 
420
        master_branch = self.make_branch('master')
 
421
        bound_tree = self.make_branch_and_tree('bound')
 
422
        bound_tree.branch.bind(master_branch)
 
423
 
 
424
        self.build_tree_contents([('bound/content_file', 'initial contents\n')])
 
425
        bound_tree.add(['content_file'])
 
426
        bound_tree.commit(message='woo!')
 
427
 
 
428
        other_bzrdir = master_branch.bzrdir.sprout('other')
 
429
        other_tree = other_bzrdir.open_workingtree()
 
430
 
 
431
        # do a commit to the the other branch changing the content file so
 
432
        # that our commit after merging will have a merged revision in the
 
433
        # content file history.
 
434
        self.build_tree_contents([('other/content_file', 'change in other\n')])
 
435
        other_tree.commit('change in other')
 
436
 
 
437
        # do a merge into the bound branch from other, and then change the
 
438
        # content file locally to force a new revision (rather than using the
 
439
        # revision from other). This forces extra processing in commit.
 
440
        bound_tree.merge_from_branch(other_tree.branch)
 
441
        self.build_tree_contents([('bound/content_file', 'change in bound\n')])
 
442
 
 
443
        # before #34959 was fixed, this failed with 'revision not present in
 
444
        # weave' when trying to implicitly push from the bound branch to the master
 
445
        bound_tree.commit(message='commit of merge in bound tree')
 
446
 
 
447
    def test_commit_reporting_after_merge(self):
 
448
        # when doing a commit of a merge, the reporter needs to still 
 
449
        # be called for each item that is added/removed/deleted.
 
450
        this_tree = self.make_branch_and_tree('this')
 
451
        # we need a bunch of files and dirs, to perform one action on each.
 
452
        self.build_tree([
 
453
            'this/dirtorename/',
 
454
            'this/dirtoreparent/',
 
455
            'this/dirtoleave/',
 
456
            'this/dirtoremove/',
 
457
            'this/filetoreparent',
 
458
            'this/filetorename',
 
459
            'this/filetomodify',
 
460
            'this/filetoremove',
 
461
            'this/filetoleave']
 
462
            )
 
463
        this_tree.add([
 
464
            'dirtorename',
 
465
            'dirtoreparent',
 
466
            'dirtoleave',
 
467
            'dirtoremove',
 
468
            'filetoreparent',
 
469
            'filetorename',
 
470
            'filetomodify',
 
471
            'filetoremove',
 
472
            'filetoleave']
 
473
            )
 
474
        this_tree.commit('create_files')
 
475
        other_dir = this_tree.bzrdir.sprout('other')
 
476
        other_tree = other_dir.open_workingtree()
 
477
        other_tree.lock_write()
 
478
        # perform the needed actions on the files and dirs.
 
479
        try:
 
480
            other_tree.rename_one('dirtorename', 'renameddir')
 
481
            other_tree.rename_one('dirtoreparent', 'renameddir/reparenteddir')
 
482
            other_tree.rename_one('filetorename', 'renamedfile')
 
483
            other_tree.rename_one('filetoreparent', 'renameddir/reparentedfile')
 
484
            other_tree.remove(['dirtoremove', 'filetoremove'])
 
485
            self.build_tree_contents([
 
486
                ('other/newdir/', ),
 
487
                ('other/filetomodify', 'new content'),
 
488
                ('other/newfile', 'new file content')])
 
489
            other_tree.add('newfile')
 
490
            other_tree.add('newdir/')
 
491
            other_tree.commit('modify all sample files and dirs.')
 
492
        finally:
 
493
            other_tree.unlock()
 
494
        this_tree.merge_from_branch(other_tree.branch)
 
495
        reporter = CapturingReporter()
 
496
        this_tree.commit('do the commit', reporter=reporter)
 
497
        self.assertEqual([
 
498
            ('change', 'unchanged', ''),
 
499
            ('change', 'unchanged', 'dirtoleave'),
 
500
            ('change', 'unchanged', 'filetoleave'),
 
501
            ('change', 'modified', 'filetomodify'),
 
502
            ('change', 'added', 'newdir'),
 
503
            ('change', 'added', 'newfile'),
 
504
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
 
505
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
 
506
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
 
507
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
 
508
            ('deleted', 'dirtoremove'),
 
509
            ('deleted', 'filetoremove'),
 
510
            ],
 
511
            reporter.calls)
 
512
 
 
513
    def test_commit_removals_respects_filespec(self):
 
514
        """Commit respects the specified_files for removals."""
 
515
        tree = self.make_branch_and_tree('.')
 
516
        self.build_tree(['a', 'b'])
 
517
        tree.add(['a', 'b'])
 
518
        tree.commit('added a, b')
 
519
        tree.remove(['a', 'b'])
 
520
        tree.commit('removed a', specific_files='a')
 
521
        basis = tree.basis_tree().inventory
 
522
        self.assertIs(None, basis.path2id('a'))
 
523
        self.assertFalse(basis.path2id('b') is None)
 
524
 
 
525
    def test_commit_saves_1ms_timestamp(self):
 
526
        """Passing in a timestamp is saved with 1ms resolution"""
 
527
        tree = self.make_branch_and_tree('.')
 
528
        self.build_tree(['a'])
 
529
        tree.add('a')
 
530
        tree.commit('added a', timestamp=1153248633.4186721, timezone=0,
 
531
                    rev_id='a1')
 
532
 
 
533
        rev = tree.branch.repository.get_revision('a1')
 
534
        self.assertEqual(1153248633.419, rev.timestamp)
 
535
 
 
536
    def test_commit_has_1ms_resolution(self):
 
537
        """Allowing commit to generate the timestamp also has 1ms resolution"""
 
538
        tree = self.make_branch_and_tree('.')
 
539
        self.build_tree(['a'])
 
540
        tree.add('a')
 
541
        tree.commit('added a', rev_id='a1')
 
542
 
 
543
        rev = tree.branch.repository.get_revision('a1')
 
544
        timestamp = rev.timestamp
 
545
        timestamp_1ms = round(timestamp, 3)
 
546
        self.assertEqual(timestamp_1ms, timestamp)
 
547
 
 
548
    def test_commit_unversioned_specified(self):
 
549
        """Commit should raise if specified files isn't in basis or worktree"""
 
550
        tree = self.make_branch_and_tree('.')
 
551
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
 
552
                          'message', specific_files=['bogus'])