~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2005-2011 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
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
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
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
#
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
16
1263 by Martin Pool
- clean up imports
17
1685.1.67 by Martin Pool
Suppress warning from test of deprecated method
18
import warnings
1263 by Martin Pool
- clean up imports
19
1911.2.1 by John Arbash Meinel
Cache encode/decode operations, saves memory and time. Especially when committing a new kernel tree with 7.7M new lines to annotate
20
from bzrlib import (
4119.4.3 by Jonathan Lange
Add Revision.iter_bugs.
21
    bugtracker,
1911.2.1 by John Arbash Meinel
Cache encode/decode operations, saves memory and time. Especially when committing a new kernel tree with 7.7M new lines to annotate
22
    revision,
23
    )
4119.4.3 by Jonathan Lange
Add Revision.iter_bugs.
24
from bzrlib.errors import (
25
    InvalidBugStatus,
26
    InvalidLineInBugsProperty,
27
    )
5579.3.1 by Jelmer Vernooij
Remove unused imports.
28
from bzrlib.revision import NULL_REVISION
1911.2.1 by John Arbash Meinel
Cache encode/decode operations, saves memory and time. Especially when committing a new kernel tree with 7.7M new lines to annotate
29
from bzrlib.tests import TestCase, TestCaseWithTransport
5972.3.15 by Jelmer Vernooij
Use matchers.
30
from bzrlib.tests.matchers import MatchesAncestry
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
31
1685.1.67 by Martin Pool
Suppress warning from test of deprecated method
32
# We're allowed to test deprecated interfaces
33
warnings.filterwarnings('ignore',
34
        '.*get_intervening_revisions was deprecated',
35
        DeprecationWarning,
36
        r'bzrlib\.tests\.test_revision')
37
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
38
# XXX: Make this a method of a merge base case
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
39
def make_branches(self, format=None):
1392 by Robert Collins
reinstate testfetch test case
40
    """Create two branches
41
42
    branch 1 has 6 commits, branch 2 has 3 commits
1607.1.12 by Robert Collins
Fix common_ancestor to still calculate a common ancestor when ghosts are
43
    commit 10 is a ghosted merge merge from branch 1
1392 by Robert Collins
reinstate testfetch test case
44
45
    the object graph is
46
    B:     A:
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
47
    a..0   a..0
1392 by Robert Collins
reinstate testfetch test case
48
    a..1   a..1
49
    a..2   a..2
50
    b..3   a..3 merges b..4
51
    b..4   a..4
52
    b..5   a..5 merges b..5
1092.2.26 by Robert Collins
fetch should work with ghosts
53
    b..6 merges a4
1392 by Robert Collins
reinstate testfetch test case
54
55
    so A is missing b6 at the start
56
    and B is missing a3, a4, a5
57
    """
2696.3.3 by Martin Pool
Start setting the default format to dirstate-tags
58
    tree1 = self.make_branch_and_tree("branch1", format=format)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
59
    br1 = tree1.branch
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
60
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
61
    tree1.commit("Commit one", rev_id="a@u-0-0")
62
    tree1.commit("Commit two", rev_id="a@u-0-1")
63
    tree1.commit("Commit three", rev_id="a@u-0-2")
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
64
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
65
    tree2 = tree1.bzrdir.sprout("branch2").open_workingtree()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
66
    br2 = tree2.branch
67
    tree2.commit("Commit four", rev_id="b@u-0-3")
68
    tree2.commit("Commit five", rev_id="b@u-0-4")
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
69
    self.assertEquals(br2.last_revision(), 'b@u-0-4')
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
70
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
71
    tree1.merge_from_branch(br2)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
72
    tree1.commit("Commit six", rev_id="a@u-0-3")
73
    tree1.commit("Commit seven", rev_id="a@u-0-4")
74
    tree2.commit("Commit eight", rev_id="b@u-0-5")
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
75
    self.assertEquals(br2.last_revision(), 'b@u-0-5')
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
76
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
77
    tree1.merge_from_branch(br2)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
78
    tree1.commit("Commit nine", rev_id="a@u-0-5")
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
79
    # DO NOT MERGE HERE - we WANT a GHOST.
6165.4.25 by Jelmer Vernooij
Fix plugin use of revision_history.
80
    br1.lock_read()
81
    try:
82
        graph = br1.repository.get_graph()
83
        revhistory = list(graph.iter_lefthand_ancestry(br1.last_revision(),
84
            [revision.NULL_REVISION]))
85
        revhistory.reverse()
86
    finally:
87
        br1.unlock()
88
    tree2.add_parent_tree_id(revhistory[4])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
89
    tree2.commit("Commit ten - ghost merge", rev_id="b@u-0-6")
3830.3.23 by John Arbash Meinel
Use Branch.sprout rather than Branch.clone.
90
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
91
    return br1, br2
92
93
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
94
class TestIsAncestor(TestCaseWithTransport):
95
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
96
    def test_recorded_ancestry(self):
97
        """Test that commit records all ancestors"""
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
98
        br1, br2 = make_branches(self)
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
99
        d = [('a@u-0-0', ['a@u-0-0']),
100
             ('a@u-0-1', ['a@u-0-0', 'a@u-0-1']),
101
             ('a@u-0-2', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2']),
102
             ('b@u-0-3', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'b@u-0-3']),
1270 by Martin Pool
- fix recording of merged ancestry lines
103
             ('b@u-0-4', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'b@u-0-3',
104
                          'b@u-0-4']),
105
             ('a@u-0-3', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'b@u-0-3', 'b@u-0-4',
106
                          'a@u-0-3']),
1271 by Martin Pool
- more commit ancestry tests
107
             ('a@u-0-4', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'b@u-0-3', 'b@u-0-4',
108
                          'a@u-0-3', 'a@u-0-4']),
109
             ('b@u-0-5', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'b@u-0-3', 'b@u-0-4',
110
                          'b@u-0-5']),
111
             ('a@u-0-5', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'a@u-0-3', 'a@u-0-4',
112
                          'b@u-0-3', 'b@u-0-4',
113
                          'b@u-0-5', 'a@u-0-5']),
5972.3.22 by Jelmer Vernooij
Fix another test.
114
             ('b@u-0-6', ['a@u-0-0', 'a@u-0-1', 'a@u-0-2', 'a@u-0-4',
1271 by Martin Pool
- more commit ancestry tests
115
                          'b@u-0-3', 'b@u-0-4',
116
                          'b@u-0-5', 'b@u-0-6']),
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
117
             ]
1392 by Robert Collins
reinstate testfetch test case
118
        br1_only = ('a@u-0-3', 'a@u-0-4', 'a@u-0-5')
119
        br2_only = ('b@u-0-6',)
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
120
        for branch in br1, br2:
121
            for rev_id, anc in d:
1392 by Robert Collins
reinstate testfetch test case
122
                if rev_id in br1_only and not branch is br1:
123
                    continue
124
                if rev_id in br2_only and not branch is br2:
125
                    continue
5972.3.15 by Jelmer Vernooij
Use matchers.
126
                self.assertThat(anc,
127
                    MatchesAncestry(branch.repository, rev_id))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
128
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
129
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
130
class TestIntermediateRevisions(TestCaseWithTransport):
1092.3.2 by Robert Collins
merge from baz2bzr
131
132
    def setUp(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
133
        TestCaseWithTransport.setUp(self)
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
134
        self.br1, self.br2 = make_branches(self)
1508.1.19 by Robert Collins
Give format3 working trees their own last-revision marker.
135
        wt1 = self.br1.bzrdir.open_workingtree()
136
        wt2 = self.br2.bzrdir.open_workingtree()
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
137
        wt2.commit("Commit eleven", rev_id="b@u-0-7")
138
        wt2.commit("Commit twelve", rev_id="b@u-0-8")
139
        wt2.commit("Commit thirtteen", rev_id="b@u-0-9")
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
140
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
141
        wt1.merge_from_branch(self.br2)
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
142
        wt1.commit("Commit fourtten", rev_id="a@u-0-6")
1268 by Martin Pool
- is_ancestor now works by looking at the Branch's stored ancestry
143
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
144
        wt2.merge_from_branch(self.br1)
1534.4.36 by Robert Collins
Finish deprecating Branch.working_tree()
145
        wt2.commit("Commit fifteen", rev_id="b@u-0-10")
1092.3.2 by Robert Collins
merge from baz2bzr
146
974.2.7 by aaron.bentley at utoronto
Merged from bzr.24
147
1607.1.12 by Robert Collins
Fix common_ancestor to still calculate a common ancestor when ghosts are
148
class MockRevisionSource(object):
149
    """A RevisionSource that takes a pregenerated graph.
150
151
    This is useful for testing revision graph algorithms where
152
    the actual branch existing is irrelevant.
153
    """
154
155
    def __init__(self, full_graph):
156
        self._full_graph = full_graph
157
158
    def get_revision_graph_with_ghosts(self, revision_ids):
159
        # This is mocked out to just return a constant graph.
160
        return self._full_graph
161
162
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
163
class TestCommonAncestor(TestCaseWithTransport):
974.1.35 by aaron.bentley at utoronto
Added revision-based common-ancestor checking
164
    """Test checking whether a revision is an ancestor of another revision"""
1092.1.39 by Robert Collins
merge from mpool
165
1534.4.49 by Robert Collins
Provide a revision.get_history(repository) method for generating a synthetic revision history.
166
    def test_get_history(self):
167
        # TODO: test ghosts on the left hand branch's impact
168
        # TODO: test ghosts on all parents, we should get some
169
        # indicator. i.e. NULL_REVISION
170
        # RBC 20060608
171
        tree = self.make_branch_and_tree('.')
172
        tree.commit('1', rev_id = '1', allow_pointless=True)
173
        tree.commit('2', rev_id = '2', allow_pointless=True)
174
        tree.commit('3', rev_id = '3', allow_pointless=True)
175
        rev = tree.branch.repository.get_revision('1')
176
        history = rev.get_history(tree.branch.repository)
177
        self.assertEqual([None, '1'], history)
178
        rev = tree.branch.repository.get_revision('2')
179
        history = rev.get_history(tree.branch.repository)
180
        self.assertEqual([None, '1', '2'], history)
181
        rev = tree.branch.repository.get_revision('3')
182
        history = rev.get_history(tree.branch.repository)
183
        self.assertEqual([None, '1', '2' ,'3'], history)
1594.2.3 by Robert Collins
bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.
184
2229.2.3 by Aaron Bentley
change reserved_id to is_reserved_id, add check_not_reserved for DRY
185
186
class TestReservedId(TestCase):
187
188
    def test_is_reserved_id(self):
189
        self.assertEqual(True, revision.is_reserved_id(NULL_REVISION))
190
        self.assertEqual(True, revision.is_reserved_id(
191
            revision.CURRENT_REVISION))
192
        self.assertEqual(True, revision.is_reserved_id('arch:'))
193
        self.assertEqual(False, revision.is_reserved_id('null'))
194
        self.assertEqual(False, revision.is_reserved_id(
195
            'arch:a@example.com/c--b--v--r'))
196
        self.assertEqual(False, revision.is_reserved_id(None))
2671.5.1 by Lukáš Lalinsky
Strip leading whitespace from the commit message before using the first line as a commit summary.
197
198
199
class TestRevisionMethods(TestCase):
200
201
    def test_get_summary(self):
202
        r = revision.Revision('1')
203
        r.message = 'a'
204
        self.assertEqual('a', r.get_summary())
205
        r.message = 'a\nb'
206
        self.assertEqual('a', r.get_summary())
207
        r.message = '\na\nb'
208
        self.assertEqual('a', r.get_summary())
4398.10.1 by jszakmeister
Make Revision.get_summary() return an empty string when Revision.message is None, instead of backtracing.
209
        r.message = None
210
        self.assertEqual('', r.get_summary())
2671.5.2 by Lukáš Lalinsky
Add Revision.get_author to return the author's name, either from the property 'author' or the name of the committer.
211
4056.2.1 by James Westby
Allow specifying multiple authors for a revision.
212
    def test_get_apparent_authors(self):
213
        r = revision.Revision('1')
214
        r.committer = 'A'
215
        self.assertEqual(['A'], r.get_apparent_authors())
216
        r.properties['author'] = 'B'
217
        self.assertEqual(['B'], r.get_apparent_authors())
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
218
        r.properties['authors'] = 'C\nD'
219
        self.assertEqual(['C', 'D'], r.get_apparent_authors())
4119.4.3 by Jonathan Lange
Add Revision.iter_bugs.
220
4258.3.1 by Jelmer Vernooij
Cope with revision.committer being None.
221
    def test_get_apparent_authors_no_committer(self):
222
        r = revision.Revision('1')
223
        self.assertEqual([], r.get_apparent_authors())
224
4119.4.3 by Jonathan Lange
Add Revision.iter_bugs.
225
226
class TestRevisionBugs(TestCase):
227
    """Tests for getting the bugs that a revision is linked to."""
228
229
    def test_no_bugs(self):
230
        r = revision.Revision('1')
231
        self.assertEqual([], list(r.iter_bugs()))
232
233
    def test_some_bugs(self):
234
        r = revision.Revision(
235
            '1', properties={
236
                'bugs': bugtracker.encode_fixes_bug_urls(
237
                    ['http://example.com/bugs/1',
238
                     'http://launchpad.net/bugs/1234'])})
239
        self.assertEqual(
240
            [('http://example.com/bugs/1', bugtracker.FIXED),
241
             ('http://launchpad.net/bugs/1234', bugtracker.FIXED)],
242
            list(r.iter_bugs()))
243
244
    def test_no_status(self):
245
        r = revision.Revision(
246
            '1', properties={'bugs': 'http://example.com/bugs/1'})
247
        self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
248
249
    def test_too_much_information(self):
250
        r = revision.Revision(
251
            '1', properties={'bugs': 'http://example.com/bugs/1 fixed bar'})
252
        self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
253
254
    def test_invalid_status(self):
255
        r = revision.Revision(
256
            '1', properties={'bugs': 'http://example.com/bugs/1 faxed'})
257
        self.assertRaises(InvalidBugStatus, list, r.iter_bugs())