~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_log.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
2
 
# -*- coding: utf-8 -*-
3
 
# vim: encoding=utf-8
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
4
2
#
5
3
# This program is free software; you can redistribute it and/or modify
6
4
# it under the terms of the GNU General Public License as published by
19
17
import os
20
18
from cStringIO import StringIO
21
19
 
 
20
from bzrlib import log
22
21
from bzrlib.tests import BzrTestBase, TestCaseWithTransport
23
22
from bzrlib.log import (show_log, 
24
23
                        get_view_revisions, 
400
399
        self.assertEqual([('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
401
400
            ('4b', '4', 0)],
402
401
            revisions)
 
402
 
 
403
 
 
404
class TestGetRevisionsTouchingFileID(TestCaseWithTransport):
 
405
 
 
406
    def create_tree_with_single_merge(self):
 
407
        """Create a branch with a moderate layout.
 
408
 
 
409
        The revision graph looks like:
 
410
 
 
411
           A
 
412
           |\
 
413
           B C
 
414
           |/
 
415
           D
 
416
 
 
417
        In this graph, A introduced files f1 and f2 and f3.
 
418
        B modifies f1 and f3, and C modifies f2 and f3.
 
419
        D merges the changes from B and C and resolves the conflict for f3.
 
420
        """
 
421
        # TODO: jam 20070218 This seems like it could really be done
 
422
        #       with make_branch_and_memory_tree() if we could just
 
423
        #       create the content of those files.
 
424
        # TODO: jam 20070218 Another alternative is that we would really
 
425
        #       like to only create this tree 1 time for all tests that
 
426
        #       use it. Since 'log' only uses the tree in a readonly
 
427
        #       fashion, it seems a shame to regenerate an identical
 
428
        #       tree for each test.
 
429
        tree = self.make_branch_and_tree('tree')
 
430
        tree.lock_write()
 
431
        self.addCleanup(tree.unlock)
 
432
 
 
433
        self.build_tree_contents([('tree/f1', 'A\n'),
 
434
                                  ('tree/f2', 'A\n'),
 
435
                                  ('tree/f3', 'A\n'),
 
436
                                 ])
 
437
        tree.add(['f1', 'f2', 'f3'], ['f1-id', 'f2-id', 'f3-id'])
 
438
        tree.commit('A', rev_id='A')
 
439
 
 
440
        self.build_tree_contents([('tree/f2', 'A\nC\n'),
 
441
                                  ('tree/f3', 'A\nC\n'),
 
442
                                 ])
 
443
        tree.commit('C', rev_id='C')
 
444
        # Revert back to A to build the other history.
 
445
        tree.set_last_revision('A')
 
446
        tree.branch.set_last_revision_info(1, 'A')
 
447
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
 
448
                                  ('tree/f2', 'A\n'),
 
449
                                  ('tree/f3', 'A\nB\n'),
 
450
                                 ])
 
451
        tree.commit('B', rev_id='B')
 
452
        tree.set_parent_ids(['B', 'C'])
 
453
        self.build_tree_contents([('tree/f1', 'A\nB\n'),
 
454
                                  ('tree/f2', 'A\nC\n'),
 
455
                                  ('tree/f3', 'A\nB\nC\n'),
 
456
                                 ])
 
457
        tree.commit('D', rev_id='D')
 
458
 
 
459
        # Switch to a read lock for this tree.
 
460
        # We still have addCleanup(unlock)
 
461
        tree.unlock()
 
462
        tree.lock_read()
 
463
        return tree
 
464
 
 
465
    def test_tree_with_single_merge(self):
 
466
        """Make sure the tree layout is correct."""
 
467
        tree = self.create_tree_with_single_merge()
 
468
        rev_A_tree = tree.branch.repository.revision_tree('A')
 
469
        rev_B_tree = tree.branch.repository.revision_tree('B')
 
470
 
 
471
        f1_changed = (u'f1', 'f1-id', 'file', True, False)
 
472
        f2_changed = (u'f2', 'f2-id', 'file', True, False)
 
473
        f3_changed = (u'f3', 'f3-id', 'file', True, False)
 
474
 
 
475
        delta = rev_B_tree.changes_from(rev_A_tree)
 
476
        self.assertEqual([f1_changed, f3_changed], delta.modified)
 
477
        self.assertEqual([], delta.renamed)
 
478
        self.assertEqual([], delta.added)
 
479
        self.assertEqual([], delta.removed)
 
480
 
 
481
        rev_C_tree = tree.branch.repository.revision_tree('C')
 
482
        delta = rev_C_tree.changes_from(rev_A_tree)
 
483
        self.assertEqual([f2_changed, f3_changed], delta.modified)
 
484
        self.assertEqual([], delta.renamed)
 
485
        self.assertEqual([], delta.added)
 
486
        self.assertEqual([], delta.removed)
 
487
 
 
488
        rev_D_tree = tree.branch.repository.revision_tree('D')
 
489
        delta = rev_D_tree.changes_from(rev_B_tree)
 
490
        self.assertEqual([f2_changed, f3_changed], delta.modified)
 
491
        self.assertEqual([], delta.renamed)
 
492
        self.assertEqual([], delta.added)
 
493
        self.assertEqual([], delta.removed)
 
494
 
 
495
        delta = rev_D_tree.changes_from(rev_C_tree)
 
496
        self.assertEqual([f1_changed, f3_changed], delta.modified)
 
497
        self.assertEqual([], delta.renamed)
 
498
        self.assertEqual([], delta.added)
 
499
        self.assertEqual([], delta.removed)
 
500
 
 
501
    def assertAllRevisionsForFileID(self, tree, file_id, revisions):
 
502
        """Make sure _get_revisions_touching_file_id returns the right values.
 
503
 
 
504
        Get the return value from _get_revisions_touching_file_id and make
 
505
        sure they are correct.
 
506
        """
 
507
        # The api for _get_revisions_touching_file_id is a little crazy,
 
508
        # So we do the setup here.
 
509
        mainline = tree.branch.revision_history()
 
510
        mainline.insert(0, None)
 
511
        revnos = dict((rev, idx+1) for idx, rev in enumerate(mainline))
 
512
        view_revs_iter = log.get_view_revisions(mainline, revnos, tree.branch,
 
513
                                                'reverse', True)
 
514
        actual_revs = log._get_revisions_touching_file_id(tree.branch, file_id,
 
515
                                                          mainline,
 
516
                                                          view_revs_iter)
 
517
        self.assertEqual(revisions, [r for r, revno, depth in actual_revs])
 
518
 
 
519
    def test_file_id_f1(self):
 
520
        tree = self.create_tree_with_single_merge()
 
521
        # f1 should be marked as modified by revisions A and B
 
522
        self.assertAllRevisionsForFileID(tree, 'f1-id', ['B', 'A'])
 
523
 
 
524
    def test_file_id_f2(self):
 
525
        tree = self.create_tree_with_single_merge()
 
526
        # f2 should be marked as modified by revisions A, C, and D
 
527
        # because D merged the changes from C.
 
528
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])
 
529
 
 
530
    def test_file_id_f3(self):
 
531
        tree = self.create_tree_with_single_merge()
 
532
        # f3 should be marked as modified by revisions A, B, C, and D
 
533
        self.assertAllRevisionsForFileID(tree, 'f2-id', ['D', 'C', 'A'])