25
25
from bzrlib.branch import Branch
26
26
from bzrlib.bzrdir import BzrDir
27
27
from bzrlib.conflicts import ConflictList, ContentsConflict
28
from bzrlib.osutils import abspath, file_kind
28
from bzrlib.osutils import abspath, file_kind, pathjoin
29
29
from bzrlib.tests.blackbox import ExternalBase
30
30
import bzrlib.urlutils as urlutils
31
31
from bzrlib.workingtree import WorkingTree
34
34
class TestMerge(ExternalBase):
36
def example_branch(test):
38
file('hello', 'wt').write('foo')
39
test.run_bzr('add hello')
40
test.run_bzr('commit -m setup hello')
41
file('goodbye', 'wt').write('baz')
42
test.run_bzr('add goodbye')
43
test.run_bzr('commit -m setup goodbye')
36
def example_branch(self, path='.'):
37
tree = self.make_branch_and_tree(path)
38
self.build_tree_contents([
39
(pathjoin(path, 'hello'), 'foo'),
40
(pathjoin(path, 'goodbye'), 'baz')])
42
tree.commit(message='setup')
44
tree.commit(message='setup')
45
47
def test_merge_reprocess(self):
46
48
d = BzrDir.create_standalone_workingtree('.')
50
52
def test_merge(self):
51
53
from bzrlib.branch import Branch
56
ancestor = Branch.open('.').revno()
58
self.run_bzr('branch a b')
60
file('goodbye', 'wt').write('quux')
61
self.run_bzr(['commit', '-m', "more u's are always good"])
64
file('hello', 'wt').write('quuux')
55
a_tree = self.example_branch('a')
56
ancestor = a_tree.branch.revno()
57
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
58
self.build_tree_contents([('b/goodbye', 'quux')])
59
b_tree.commit(message="more u's are always good")
61
self.build_tree_contents([('a/hello', 'quuux')])
65
62
# We can't merge when there are in-tree changes
66
64
self.run_bzr('merge ../b', retcode=3)
67
65
a = WorkingTree.open('.')
68
66
a_tip = a.commit("Like an epidemic of u's")
69
67
self.run_bzr('merge ../b -r last:1..last:1 --merge-type blooof',
71
69
self.run_bzr('merge ../b -r last:1..last:1 --merge-type merge3')
72
self.run_bzr('revert --no-backup')
70
a_tree.revert([], backups=False)
73
71
self.run_bzr('merge ../b -r last:1..last:1 --merge-type weave')
74
self.run_bzr('revert --no-backup')
72
a_tree.revert([], backups=False)
75
73
self.run_bzr_error(['Show-base is not supported for this merge type'],
76
74
'merge ../b -r last:1..last:1 --merge-type weave'
78
self.run_bzr('revert --no-backup')
76
a_tree.revert([], backups=False)
79
77
self.run_bzr('merge ../b -r last:1..last:1 --reprocess')
80
self.run_bzr('revert --no-backup')
78
a_tree.revert([], backups=False)
81
79
self.run_bzr('merge ../b -r last:1')
82
80
self.check_file_contents('goodbye', 'quux')
83
81
# Merging a branch pulls its revision into the tree
85
83
b_tip = b.last_revision()
86
84
self.failUnless(a.branch.repository.has_revision(b_tip))
87
85
self.assertEqual([a_tip, b_tip], a.get_parent_ids())
88
self.run_bzr('revert --no-backup')
86
a_tree.revert([], backups=False)
89
87
out, err = self.run_bzr('merge -r revno:1:./hello', retcode=3)
90
88
self.assertTrue("Not a branch" in err)
91
89
self.run_bzr('merge -r revno:%d:./..revno:%d:../b'
93
91
self.assertEquals(a.get_parent_ids(),
94
92
[a.branch.last_revision(), b.last_revision()])
95
93
self.check_file_contents('goodbye', 'quux')
96
self.run_bzr('revert --no-backup')
94
a_tree.revert([], backups=False)
97
95
self.run_bzr('merge -r revno:%d:../b'%b.revno())
98
96
self.assertEquals(a.get_parent_ids(),
99
97
[a.branch.last_revision(), b.last_revision()])
104
102
def test_merge_with_missing_file(self):
105
103
"""Merge handles missing file conflicts"""
109
print >> file('sub/a.txt', 'wb'), "hello"
110
print >> file('b.txt', 'wb'), "hello"
111
print >> file('sub/c.txt', 'wb'), "hello"
114
self.run_bzr(['commit', '-m', 'added a'])
115
self.run_bzr('branch . ../b')
116
print >> file('sub/a.txt', 'ab'), "there"
117
print >> file('b.txt', 'ab'), "there"
118
print >> file('sub/c.txt', 'ab'), "there"
119
self.run_bzr(['commit', '-m', 'Added there'])
120
os.unlink('sub/a.txt')
121
os.unlink('sub/c.txt')
124
self.run_bzr(['commit', '-m', 'Removed a.txt'])
126
print >> file('sub/a.txt', 'ab'), "something"
127
print >> file('b.txt', 'ab'), "something"
128
print >> file('sub/c.txt', 'ab'), "something"
129
self.run_bzr(['commit', '-m', 'Modified a.txt'])
104
self.build_tree_contents([
107
('a/sub/a.txt', 'hello\n'),
108
('a/b.txt', 'hello\n'),
109
('a/sub/c.txt', 'hello\n')])
110
a_tree = self.make_branch_and_tree('a')
111
a_tree.add(['sub', 'b.txt', 'sub/c.txt', 'sub/a.txt'])
112
a_tree.commit(message='added a')
113
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
114
self.build_tree_contents([
115
('a/sub/a.txt', 'hello\nthere\n'),
116
('a/b.txt', 'hello\nthere\n'),
117
('a/sub/c.txt', 'hello\nthere\n')])
118
a_tree.commit(message='Added there')
119
os.remove('a/sub/a.txt')
120
os.remove('a/sub/c.txt')
123
a_tree.commit(message='Removed a.txt')
124
self.build_tree_contents([
125
('b/sub/a.txt', 'hello\nsomething\n'),
126
('b/b.txt', 'hello\nsomething\n'),
127
('b/sub/c.txt', 'hello\nsomething\n')])
128
b_tree.commit(message='Modified a.txt')
130
130
self.run_bzr('merge ../a/', retcode=1)
131
self.assert_(os.path.exists('sub/a.txt.THIS'))
132
self.assert_(os.path.exists('sub/a.txt.BASE'))
131
self.failUnlessExists('sub/a.txt.THIS')
132
self.failUnlessExists('sub/a.txt.BASE')
134
134
self.run_bzr('merge ../b/', retcode=1)
135
self.assert_(os.path.exists('sub/a.txt.OTHER'))
136
self.assert_(os.path.exists('sub/a.txt.BASE'))
135
self.failUnlessExists('sub/a.txt.OTHER')
136
self.failUnlessExists('sub/a.txt.BASE')
138
138
def test_merge_remember(self):
139
139
"""Merge changes from one branch to another and test parent location."""
192
192
def test_merge_bundle(self):
193
193
from bzrlib.testament import Testament
194
194
tree_a = self.make_branch_and_tree('branch_a')
195
f = file('branch_a/a', 'wb')
195
self.build_tree_contents([('branch_a/a', 'hello')])
199
197
tree_a.commit('message')
201
199
tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
202
f = file('branch_a/a', 'wb')
200
self.build_tree_contents([('branch_a/a', 'hey there')])
205
201
tree_a.commit('message')
207
f = file('branch_b/a', 'wb')
203
self.build_tree_contents([('branch_b/a', 'goodbye')])
210
204
tree_b.commit('message')
211
205
os.chdir('branch_b')
212
206
self.run_bzr('bundle ../branch_a -o ../bundle')
246
240
'merge /a --uncommitted -r1 -d b')
248
242
def pullable_branch(self):
251
self.example_branch()
253
self.run_bzr('branch a b')
255
file('goodbye', 'wt').write('quux')
256
self.run_bzr(['commit', '-m', "mode u's are always good"])
259
def pullable_branch(self):
260
243
tree_a = self.make_branch_and_tree('a')
261
244
self.build_tree(['a/file'])
262
245
tree_a.add(['file'])
263
246
self.id1 = tree_a.commit('commit 1')
265
248
tree_b = self.make_branch_and_tree('b')
266
249
tree_b.pull(tree_a.branch)
267
250
file('b/file', 'wb').write('foo')