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