23
23
from bzrlib.branch import Branch
24
from bzrlib.directory_service import directories
25
from bzrlib.osutils import pathjoin
26
24
from bzrlib.tests.blackbox import ExternalBase
27
25
from bzrlib.uncommit import uncommit
28
from bzrlib.workingtree import WorkingTree
29
26
from bzrlib import urlutils
32
29
class TestPull(ExternalBase):
34
def example_branch(self, path='.'):
35
tree = self.make_branch_and_tree(path)
36
self.build_tree_contents([
37
(pathjoin(path, 'hello'), 'foo'),
38
(pathjoin(path, 'goodbye'), 'baz')])
40
tree.commit(message='setup')
42
tree.commit(message='setup')
31
def example_branch(test):
33
file('hello', 'wt').write('foo')
34
test.runbzr('add hello')
35
test.runbzr('commit -m setup hello')
36
file('goodbye', 'wt').write('baz')
37
test.runbzr('add goodbye')
38
test.runbzr('commit -m setup goodbye')
45
40
def test_pull(self):
46
41
"""Pull changes from one branch to another."""
47
a_tree = self.example_branch('a')
49
self.run_bzr('pull', retcode=3)
50
self.run_bzr('missing', retcode=3)
51
self.run_bzr('missing .')
52
self.run_bzr('missing')
46
self.runbzr('pull', retcode=3)
47
self.runbzr('missing', retcode=3)
48
self.runbzr('missing .')
49
self.runbzr('missing')
53
50
# this will work on windows because we check for the same branch
54
51
# in pull - if it fails, it is a regression
56
self.run_bzr('pull /', retcode=3)
53
self.runbzr('pull /', retcode=3)
57
54
if sys.platform not in ('win32', 'cygwin'):
61
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
58
self.runbzr('branch a b')
66
b_tree.commit(message='blah', allow_pointless=True)
71
self.assertEqual(a.revision_history(), b.revision_history()[:-1])
74
self.run_bzr('pull ../b')
75
self.assertEqual(a.revision_history(), b.revision_history())
76
a_tree.commit(message='blah2', allow_pointless=True)
77
b_tree.commit(message='blah3', allow_pointless=True)
62
self.runbzr('add subdir')
63
self.runbzr('commit -m blah --unchanged')
66
b = Branch.open('../b')
67
self.assertEquals(a.revision_history(), b.revision_history()[:-1])
68
self.runbzr('pull ../b')
69
self.assertEquals(a.revision_history(), b.revision_history())
70
self.runbzr('commit -m blah2 --unchanged')
72
self.runbzr('commit -m blah3 --unchanged')
80
self.run_bzr('pull ../a', retcode=3)
74
self.runbzr('pull ../a', retcode=3)
82
b_tree.bzrdir.sprout('overwriteme')
76
self.runbzr('branch b overwriteme')
83
77
os.chdir('overwriteme')
84
self.run_bzr('pull --overwrite ../a')
78
self.runbzr('pull --overwrite ../a')
85
79
overwritten = Branch.open('.')
86
80
self.assertEqual(overwritten.revision_history(),
87
81
a.revision_history())
88
a_tree.merge_from_branch(b_tree.branch)
89
a_tree.commit(message="blah4", allow_pointless=True)
83
self.runbzr('merge ../b')
84
self.runbzr('commit -m blah4 --unchanged')
90
85
os.chdir('../b/subdir')
91
self.run_bzr('pull ../../a')
92
self.assertEqual(a.revision_history()[-1], b.revision_history()[-1])
93
sub_tree = WorkingTree.open_containing('.')[0]
94
sub_tree.commit(message="blah5", allow_pointless=True)
95
sub_tree.commit(message="blah6", allow_pointless=True)
86
self.runbzr('pull ../../a')
87
self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
88
self.runbzr('commit -m blah5 --unchanged')
89
self.runbzr('commit -m blah6 --unchanged')
97
self.run_bzr('pull ../a')
91
self.runbzr('pull ../a')
99
a_tree.commit(message="blah7", allow_pointless=True)
100
a_tree.merge_from_branch(b_tree.branch)
101
a_tree.commit(message="blah8", allow_pointless=True)
102
self.run_bzr('pull ../b')
103
self.run_bzr('pull ../b')
93
self.runbzr('commit -m blah7 --unchanged')
94
self.runbzr('merge ../b')
95
self.runbzr('commit -m blah8 --unchanged')
96
self.runbzr('pull ../b')
97
self.runbzr('pull ../b')
105
99
def test_pull_dash_d(self):
106
self.example_branch('a')
107
self.make_branch_and_tree('b')
108
self.make_branch_and_tree('c')
102
self.example_branch()
103
self.runbzr('init ../b')
104
self.runbzr('init ../c')
109
105
# pull into that branch
110
self.run_bzr('pull -d b a')
106
self.runbzr('pull -d ../b .')
111
107
# pull into a branch specified by a url
112
c_url = urlutils.local_path_to_url('c')
108
c_url = urlutils.local_path_to_url('../c')
113
109
self.assertStartsWith(c_url, 'file://')
114
self.run_bzr(['pull', '-d', c_url, 'a'])
110
self.runbzr('pull -d %s .' % c_url)
116
112
def test_pull_revision(self):
117
113
"""Pull some changes from one branch to another."""
118
a_tree = self.example_branch('a')
119
self.build_tree_contents([
121
('a/goodbye2', 'baz')])
123
a_tree.commit(message="setup")
124
a_tree.add('goodbye2')
125
a_tree.commit(message="setup")
127
b_tree = a_tree.bzrdir.sprout('b',
128
revision_id=a_tree.branch.get_rev_id(1)).open_workingtree()
117
self.example_branch()
118
file('hello2', 'wt').write('foo')
119
self.runbzr('add hello2')
120
self.runbzr('commit -m setup hello2')
121
file('goodbye2', 'wt').write('baz')
122
self.runbzr('add goodbye2')
123
self.runbzr('commit -m setup goodbye2')
126
self.runbzr('branch -r 1 a b')
130
self.run_bzr('pull -r 2')
128
self.runbzr('pull -r 2')
131
129
a = Branch.open('../a')
132
130
b = Branch.open('.')
133
self.assertEqual(a.revno(),4)
134
self.assertEqual(b.revno(),2)
135
self.run_bzr('pull -r 3')
136
self.assertEqual(b.revno(),3)
137
self.run_bzr('pull -r 4')
138
self.assertEqual(a.revision_history(), b.revision_history())
131
self.assertEquals(a.revno(),4)
132
self.assertEquals(b.revno(),2)
133
self.runbzr('pull -r 3')
134
self.assertEquals(b.revno(),3)
135
self.runbzr('pull -r 4')
136
self.assertEquals(a.revision_history(), b.revision_history())
141
139
def test_overwrite_uptodate(self):
142
140
# Make sure pull --overwrite overwrites
143
141
# even if the target branch has merged
144
142
# everything already.
145
a_tree = self.make_branch_and_tree('a')
146
self.build_tree_contents([('a/foo', 'original\n')])
148
a_tree.commit(message='initial commit')
150
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
152
self.build_tree_contents([('a/foo', 'changed\n')])
153
a_tree.commit(message='later change')
155
self.build_tree_contents([('a/foo', 'a third change')])
156
a_tree.commit(message='a third change')
158
rev_history_a = a_tree.branch.revision_history()
159
self.assertEqual(len(rev_history_a), 3)
161
b_tree.merge_from_branch(a_tree.branch)
162
b_tree.commit(message='merge')
164
self.assertEqual(len(b_tree.branch.revision_history()), 2)
167
self.run_bzr('pull --overwrite ../a')
168
rev_history_b = b_tree.branch.revision_history()
169
self.assertEqual(len(rev_history_b), 3)
145
def get_rh(expected_len):
146
rh = self.capture('revision-history')
147
# Make sure we don't have trailing empty revisions
148
rh = rh.strip().split('\n')
149
self.assertEqual(len(rh), expected_len)
155
open('foo', 'wb').write('original\n')
157
bzr('commit', '-m', 'initial commit')
160
bzr('branch', 'a', 'b')
163
open('foo', 'wb').write('changed\n')
164
bzr('commit', '-m', 'later change')
166
open('foo', 'wb').write('another\n')
167
bzr('commit', '-m', 'a third change')
169
rev_history_a = get_rh(3)
173
bzr('commit', '-m', 'merge')
175
rev_history_b = get_rh(2)
177
bzr('pull', '--overwrite', '../a')
178
rev_history_b = get_rh(3)
171
180
self.assertEqual(rev_history_b, rev_history_a)
173
182
def test_overwrite_children(self):
174
183
# Make sure pull --overwrite sets the revision-history
175
184
# to be identical to the pull source, even if we have convergence
176
a_tree = self.make_branch_and_tree('a')
177
self.build_tree_contents([('a/foo', 'original\n')])
179
a_tree.commit(message='initial commit')
181
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
183
self.build_tree_contents([('a/foo', 'changed\n')])
184
a_tree.commit(message='later change')
186
self.build_tree_contents([('a/foo', 'a third change')])
187
a_tree.commit(message='a third change')
189
self.assertEqual(len(a_tree.branch.revision_history()), 3)
191
b_tree.merge_from_branch(a_tree.branch)
192
b_tree.commit(message='merge')
194
self.assertEqual(len(b_tree.branch.revision_history()), 2)
196
self.build_tree_contents([('a/foo', 'a fourth change\n')])
197
a_tree.commit(message='a fourth change')
199
rev_history_a = a_tree.branch.revision_history()
200
self.assertEqual(len(rev_history_a), 4)
187
def get_rh(expected_len):
188
rh = self.capture('revision-history')
189
# Make sure we don't have trailing empty revisions
190
rh = rh.strip().split('\n')
191
self.assertEqual(len(rh), expected_len)
197
open('foo', 'wb').write('original\n')
199
bzr('commit', '-m', 'initial commit')
202
bzr('branch', 'a', 'b')
205
open('foo', 'wb').write('changed\n')
206
bzr('commit', '-m', 'later change')
208
open('foo', 'wb').write('another\n')
209
bzr('commit', '-m', 'a third change')
211
rev_history_a = get_rh(3)
215
bzr('commit', '-m', 'merge')
217
rev_history_b = get_rh(2)
220
open('foo', 'wb').write('a fourth change\n')
221
bzr('commit', '-m', 'a fourth change')
223
rev_history_a = get_rh(4)
202
225
# With convergence, we could just pull over the
203
226
# new change, but with --overwrite, we want to switch our history
205
self.run_bzr('pull --overwrite ../a')
206
rev_history_b = b_tree.branch.revision_history()
207
self.assertEqual(len(rev_history_b), 4)
228
bzr('pull', '--overwrite', '../a')
229
rev_history_b = get_rh(4)
209
231
self.assertEqual(rev_history_b, rev_history_a)
292
315
testament_b.as_text())
294
317
# it is legal to attempt to pull an already-merged bundle
295
out, err = self.run_bzr('pull ../bundle')
318
out, err = self.run_bzr('pull', '../bundle')
296
319
self.assertEqual(err, '')
297
320
self.assertEqual(out, 'No revisions to pull.\n')
299
def test_pull_verbose_no_files(self):
300
"""Pull --verbose should not list modified files"""
301
tree_a = self.make_branch_and_tree('tree_a')
302
self.build_tree(['tree_a/foo'])
305
tree_b = self.make_branch_and_tree('tree_b')
306
out = self.run_bzr('pull --verbose -d tree_b tree_a')[0]
307
self.assertContainsRe(out, 'bar')
308
self.assertNotContainsRe(out, 'added:')
309
self.assertNotContainsRe(out, 'foo')
311
def test_pull_quiet(self):
312
"""Check that bzr pull --quiet does not print anything"""
313
tree_a = self.make_branch_and_tree('tree_a')
314
self.build_tree(['tree_a/foo'])
316
revision_id = tree_a.commit('bar')
317
tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
318
out, err = self.run_bzr('pull --quiet -d tree_b')
319
self.assertEqual(out, '')
320
self.assertEqual(err, '')
321
self.assertEqual(tree_b.last_revision(), revision_id)
322
self.build_tree(['tree_a/moo'])
324
revision_id = tree_a.commit('quack')
325
out, err = self.run_bzr('pull --quiet -d tree_b')
326
self.assertEqual(out, '')
327
self.assertEqual(err, '')
328
self.assertEqual(tree_b.last_revision(), revision_id)
330
def test_pull_from_directory_service(self):
331
source = self.make_branch_and_tree('source')
332
source.commit('commit 1')
333
target = source.bzrdir.sprout('target').open_workingtree()
334
source_last = source.commit('commit 2')
335
class FooService(object):
336
"""A directory service that always returns source"""
338
def look_up(self, name, url):
340
directories.register('foo:', FooService, 'Testing directory service')
341
self.addCleanup(lambda: directories.remove('foo:'))
342
self.run_bzr('pull foo:bar -d target')
343
self.assertEqual(source_last, target.last_revision())
345
def test_pull_verbose_defaults_to_long(self):
346
tree = self.example_branch('source')
347
target = self.make_branch_and_tree('target')
348
out = self.run_bzr('pull -v source -d target')[0]
349
self.assertContainsRe(out,
350
r'revno: 1\ncommitter: .*\nbranch nick: source')
351
self.assertNotContainsRe(out, r'\n {4}1 .*\n {6}setup\n')
353
def test_pull_verbose_uses_default_log(self):
354
tree = self.example_branch('source')
355
target = self.make_branch_and_tree('target')
356
target_config = target.branch.get_config()
357
target_config.set_user_option('log_format', 'short')
358
out = self.run_bzr('pull -v source -d target')[0]
359
self.assertContainsRe(out, r'\n {4}1 .*\n {6}setup\n')
360
self.assertNotContainsRe(
361
out, r'revno: 1\ncommitter: .*\nbranch nick: source')