/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.5 by John Arbash Meinel
Merge bzr.dev 5021 to resolve NEWS
1
# Copyright (C) 2006-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
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
#
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
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
#
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
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
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
16
17
"""Tests for branch.pull behaviour."""
18
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
19
from breezy import (
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
20
    branch,
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
21
    controldir,
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
22
    errors,
23
    memorytree,
24
    revision,
25
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
26
from breezy.tests import (
5651.5.1 by Andrew Bennetts
Make 'bzr reconfigure --unstacked' fetch tagged revisions too. (#401646)
27
    fixtures,
28
    per_branch,
29
    TestNotApplicable,
30
    )
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
31
32
33
class TestPull(per_branch.TestCaseWithBranch):
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
34
35
    def test_pull_convergence_simple(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
36
        # when revisions are pulled, the left-most accessible parents must
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
37
        # become the revision-history.
38
        parent = self.make_branch_and_tree('parent')
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
39
        p1 = parent.commit('1st post', allow_pointless=True)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
40
        mine = parent.controldir.sprout('mine').open_workingtree()
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
41
        m1 = mine.commit('my change', allow_pointless=True)
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
42
        parent.merge_from_branch(mine.branch)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
43
        p2 = parent.commit('merge my change')
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
44
        mine.pull(parent.branch)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
45
        self.assertEqual(p2, mine.branch.last_revision())
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
46
47
    def test_pull_merged_indirect(self):
48
        # it should be possible to do a pull from one branch into another
49
        # when the tip of the target was merged into the source branch
50
        # via a third branch - so its buried in the ancestry and is not
51
        # directly accessible.
52
        parent = self.make_branch_and_tree('parent')
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
53
        p1 = parent.commit('1st post', allow_pointless=True)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
54
        mine = parent.controldir.sprout('mine').open_workingtree()
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
55
        m1 = mine.commit('my change', allow_pointless=True)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
56
        other = parent.controldir.sprout('other').open_workingtree()
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
57
        other.merge_from_branch(mine.branch)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
58
        o2 = other.commit('merge my change')
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
59
        parent.merge_from_branch(other.branch)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
60
        p2 = parent.commit('merge other')
1649.1.1 by Robert Collins
* 'pull' and 'push' now normalise the revision history, so that any two
61
        mine.pull(parent.branch)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
62
        self.assertEqual(p2, mine.branch.last_revision())
2245.2.1 by Robert Collins
Split branch pushing out of branch pulling.
63
64
    def test_pull_updates_checkout_and_master(self):
65
        """Pulling into a checkout updates the checkout and the master branch"""
66
        master_tree = self.make_branch_and_tree('master')
67
        rev1 = master_tree.commit('master')
68
        checkout = master_tree.branch.create_checkout('checkout')
69
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
70
        other = master_tree.branch.controldir.sprout('other').open_workingtree()
2245.2.1 by Robert Collins
Split branch pushing out of branch pulling.
71
        rev2 = other.commit('other commit')
72
        # now pull, which should update both checkout and master.
73
        checkout.branch.pull(other.branch)
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
74
        self.assertEqual(rev2, checkout.branch.last_revision())
75
        self.assertEqual(rev2, master_tree.branch.last_revision())
2245.2.1 by Robert Collins
Split branch pushing out of branch pulling.
76
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
77
    def test_pull_local_updates_checkout_only(self):
78
        """Pulling --local into a checkout updates the checkout and not the
79
        master branch"""
80
        master_tree = self.make_branch_and_tree('master')
81
        rev1 = master_tree.commit('master')
82
        checkout = master_tree.branch.create_checkout('checkout')
83
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
84
        other = master_tree.branch.controldir.sprout('other').open_workingtree()
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
85
        rev2 = other.commit('other commit')
4335.1.1 by Ian Clatworthy
(igc) pull --local (Gary van der Merwe)
86
        # now pull local, which should update checkout but not master.
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
87
        checkout.branch.pull(other.branch, local = True)
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
88
        self.assertEqual(rev2, checkout.branch.last_revision())
89
        self.assertEqual(rev1, master_tree.branch.last_revision())
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
90
91
    def test_pull_local_raises_LocalRequiresBoundBranch_on_unbound(self):
92
        """Pulling --local into a branch that is not bound should fail."""
93
        master_tree = self.make_branch_and_tree('branch')
94
        rev1 = master_tree.commit('master')
95
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
96
        other = master_tree.branch.controldir.sprout('other').open_workingtree()
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
97
        rev2 = other.commit('other commit')
98
        # now pull --local, which should raise LocalRequiresBoundBranch error.
99
        self.assertRaises(errors.LocalRequiresBoundBranch,
100
                          master_tree.branch.pull, other.branch, local = True)
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
101
        self.assertEqual(rev1, master_tree.branch.last_revision())
4056.6.3 by Gary van der Merwe
Add local args to pull methods, and add more tests
102
3482.1.1 by John Arbash Meinel
Fix bug #238149, RemoteBranch.pull needs to return the _real_branch's pull result.
103
    def test_pull_returns_result(self):
104
        parent = self.make_branch_and_tree('parent')
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
105
        p1 = parent.commit('1st post')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
106
        mine = parent.controldir.sprout('mine').open_workingtree()
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
107
        m1 = mine.commit('my change')
3482.1.1 by John Arbash Meinel
Fix bug #238149, RemoteBranch.pull needs to return the _real_branch's pull result.
108
        result = parent.branch.pull(mine.branch)
109
        self.assertIsNot(None, result)
110
        self.assertIs(mine.branch, result.source_branch)
111
        self.assertIs(parent.branch, result.target_branch)
112
        self.assertIs(parent.branch, result.master_branch)
113
        self.assertIs(None, result.local_branch)
114
        self.assertEqual(1, result.old_revno)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
115
        self.assertEqual(p1, result.old_revid)
3482.1.1 by John Arbash Meinel
Fix bug #238149, RemoteBranch.pull needs to return the _real_branch's pull result.
116
        self.assertEqual(2, result.new_revno)
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
117
        self.assertEqual(m1, result.new_revid)
6112.4.7 by Jelmer Vernooij
Fix tests.
118
        self.assertEqual([], result.tag_conflicts)
3482.1.1 by John Arbash Meinel
Fix bug #238149, RemoteBranch.pull needs to return the _real_branch's pull result.
119
1551.10.23 by Aaron Bentley
Update test case per review
120
    def test_pull_overwrite(self):
121
        tree_a = self.make_branch_and_tree('tree_a')
122
        tree_a.commit('message 1')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
123
        tree_b = tree_a.controldir.sprout('tree_b').open_workingtree()
6862.1.1 by Jelmer Vernooij
Add some uniqueness to commit messages.
124
        rev2a = tree_a.commit('message 2a')
125
        rev2b = tree_b.commit('message 2b')
1551.10.23 by Aaron Bentley
Update test case per review
126
        self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
3052.5.2 by John Arbash Meinel
Use a Graph.heads() check to determine if the ancestries are compatible.
127
        self.assertRaises(errors.DivergedBranches,
128
                          tree_a.branch.pull, tree_b.branch,
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
129
                          overwrite=False, stop_revision=rev2b)
3052.5.2 by John Arbash Meinel
Use a Graph.heads() check to determine if the ancestries are compatible.
130
        # It should not have updated the branch tip, but it should have fetched
6217.4.1 by Jelmer Vernooij
Add RepositoryFormat.supports_invisible_revisions.
131
        # the revision if the repository supports "invisible" revisions
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
132
        self.assertEqual(rev2a, tree_a.branch.last_revision())
6217.4.2 by Jelmer Vernooij
s/invisible/unreferenced.
133
        if tree_a.branch.repository._format.supports_unreferenced_revisions:
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
134
            self.assertTrue(tree_a.branch.repository.has_revision(rev2b))
2975.1.1 by Robert Collins
Minor fixes for foreign format friendliness.
135
        tree_a.branch.pull(tree_b.branch, overwrite=True,
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
136
                           stop_revision=rev2b)
137
        self.assertEqual(rev2b, tree_a.branch.last_revision())
6165.4.4 by Jelmer Vernooij
Avoid .revision_history().
138
        self.assertEqual(tree_b.branch.last_revision(),
139
                         tree_a.branch.last_revision())
1551.10.23 by Aaron Bentley
Update test case per review
140
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
141
    def test_pull_merges_and_fetches_tags(self):
142
        """Tags are updated by br.pull(source), and revisions named in those
143
        tags are fetched.
144
        """
145
        # Make a source, sprout a target off it
146
        try:
147
            builder = self.make_branch_builder('source')
148
        except errors.UninitializableFormat:
149
            raise TestNotApplicable('uninitializeable format')
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
150
        source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(builder)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
151
        target = source.controldir.sprout('target').open_branch()
5651.5.2 by Andrew Bennetts
Simplify new fixture slightly, and other test tweaks.
152
        # Add a tag to the source, then pull from source
153
        try:
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
154
            source.tags.set_tag('tag-a', rev2)
5651.5.2 by Andrew Bennetts
Simplify new fixture slightly, and other test tweaks.
155
        except errors.TagsNotSupported:
156
            raise TestNotApplicable('format does not support tags.')
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
157
        source.tags.set_tag('tag-a', rev2)
6404.1.1 by Vincent Ladeuil
Migrate branch.fetch_tags
158
        source.get_config_stack().set('branch.fetch_tags', True)
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
159
        target.pull(source)
160
        # The tag is present, and so is its revision.
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
161
        self.assertEqual(rev2, target.tags.lookup_tag('tag-a'))
162
        target.repository.get_revision(rev2)
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
163
164
    def test_pull_stop_revision_merges_and_fetches_tags(self):
165
        """br.pull(source, stop_revision=REV) updates and fetches tags."""
166
        # Make a source, sprout a target off it
167
        try:
168
            builder = self.make_branch_builder('source')
169
        except errors.UninitializableFormat:
170
            raise TestNotApplicable('uninitializeable format')
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
171
        source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(builder)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
172
        target = source.controldir.sprout('target').open_branch()
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
173
        # Add a new commit to the ancestry
6747.2.1 by Jelmer Vernooij
Avoid setting revision_ids.
174
        rev_2_again = builder.build_commit(message="Rev 2 again")
175
        # Add a tag to the source, then pull rev_2_again from source
5651.5.2 by Andrew Bennetts
Simplify new fixture slightly, and other test tweaks.
176
        try:
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
177
            source.tags.set_tag('tag-a', rev2)
5651.5.2 by Andrew Bennetts
Simplify new fixture slightly, and other test tweaks.
178
        except errors.TagsNotSupported:
179
            raise TestNotApplicable('format does not support tags.')
6404.1.1 by Vincent Ladeuil
Migrate branch.fetch_tags
180
        source.get_config_stack().set('branch.fetch_tags', True)
7029.4.2 by Jelmer Vernooij
Fix more merge tests.
181
        target.pull(source, stop_revision=rev_2_again)
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
182
        # The tag is present, and so is its revision.
6747.3.2 by Jelmer Vernooij
Avoid more uses of revision_id.
183
        self.assertEqual(rev2, target.tags.lookup_tag('tag-a'))
184
        target.repository.get_revision(rev2)
5535.3.29 by Andrew Bennetts
Add some per-branch tests.
185
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
186
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
187
class TestPullHook(per_branch.TestCaseWithBranch):
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
188
189
    def setUp(self):
190
        self.hook_calls = []
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
191
        super(TestPullHook, self).setUp()
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
192
2297.1.1 by Martin Pool
Pull now returns a PullResult rather than just an integer.
193
    def capture_post_pull_hook(self, result):
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
194
        """Capture post pull hook calls to self.hook_calls.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
195
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
196
        The call is logged, as is some state of the two branches.
197
        """
2297.1.6 by Martin Pool
Add docs for Results, give some members cleaner names
198
        if result.local_branch:
199
            local_locked = result.local_branch.is_locked()
200
            local_base = result.local_branch.base
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
201
        else:
202
            local_locked = None
203
            local_base = None
204
        self.hook_calls.append(
2297.1.6 by Martin Pool
Add docs for Results, give some members cleaner names
205
            ('post_pull', result.source_branch, local_base,
206
             result.master_branch.base, result.old_revno,
2297.1.1 by Martin Pool
Pull now returns a PullResult rather than just an integer.
207
             result.old_revid,
2297.1.6 by Martin Pool
Add docs for Results, give some members cleaner names
208
             result.new_revno, result.new_revid,
209
             result.source_branch.is_locked(), local_locked,
210
             result.master_branch.is_locked()))
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
211
212
    def test_post_pull_empty_history(self):
213
        target = self.make_branch('target')
214
        source = self.make_branch('source')
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
215
        branch.Branch.hooks.install_named_hook(
216
            'post_pull', self.capture_post_pull_hook, None)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
217
        target.pull(source)
218
        # with nothing there we should still get a notification, and
219
        # have both branches locked at the notification time.
220
        self.assertEqual([
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
221
            ('post_pull', source, None, target.base, 0, revision.NULL_REVISION,
222
             0, revision.NULL_REVISION, True, None, True)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
223
            ],
224
            self.hook_calls)
225
226
    def test_post_pull_bound_branch(self):
227
        # pulling to a bound branch should pass in the master branch to the
228
        # hook, allowing the correct number of emails to be sent, while still
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
229
        # allowing hooks that want to modify the target to do so to both
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
230
        # instances.
231
        target = self.make_branch('target')
232
        local = self.make_branch('local')
233
        try:
234
            local.bind(target)
235
        except errors.UpgradeRequired:
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
236
            # We can't bind this format to itself- typically it is the local
237
            # branch that doesn't support binding.  As of May 2007
238
            # remotebranches can't be bound.  Let's instead make a new local
239
            # branch of the default type, which does allow binding.
240
            # See https://bugs.launchpad.net/bzr/+bug/112020
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
241
            local = controldir.ControlDir.create_branch_convenience('local2')
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
242
            local.bind(target)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
243
        source = self.make_branch('source')
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
244
        branch.Branch.hooks.install_named_hook(
245
            'post_pull', self.capture_post_pull_hook, None)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
246
        local.pull(source)
247
        # with nothing there we should still get a notification, and
248
        # have both branches locked at the notification time.
249
        self.assertEqual([
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
250
            ('post_pull', source, local.base, target.base, 0,
251
             revision.NULL_REVISION, 0, revision.NULL_REVISION,
252
             True, True, True)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
253
            ],
254
            self.hook_calls)
255
256
    def test_post_pull_nonempty_history(self):
257
        target = self.make_branch_and_memory_tree('target')
258
        target.lock_write()
259
        target.add('')
260
        rev1 = target.commit('rev 1')
261
        target.unlock()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
262
        sourcedir = target.controldir.clone(self.get_url('source'))
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
263
        source = memorytree.MemoryTree.create_on_branch(sourcedir.open_branch())
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
264
        rev2 = source.commit('rev 2')
5010.2.17 by Vincent Ladeuil
Fix imports in per_branch/test_pull.py.
265
        branch.Branch.hooks.install_named_hook(
266
            'post_pull', self.capture_post_pull_hook, None)
2246.1.3 by Robert Collins
New branch hooks: post_push, post_pull, post_commit, post_uncommit. These
267
        target.branch.pull(source.branch)
268
        # with nothing there we should still get a notification, and
269
        # have both branches locked at the notification time.
270
        self.assertEqual([
271
            ('post_pull', source.branch, None, target.branch.base, 1, rev1,
272
             2, rev2, True, None, True)
273
            ],
274
            self.hook_calls)