/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_merge.py

  • Committer: Aaron Bentley
  • Date: 2006-09-19 16:17:31 UTC
  • mto: This revision was merged to the branch mainline in revision 2162.
  • Revision ID: abentley@panoramicfeedback.com-20060919161731-4a099268251f858c
Implement specific file id and dangling id handling

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 Canonical Ltd
 
2
#
 
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.
 
7
#
 
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.
 
12
#
 
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
#
 
17
# Author: Aaron Bentley <aaron.bentley@utoronto.ca>
 
18
 
 
19
"""Black-box tests for bzr merge.
 
20
"""
 
21
 
 
22
import os
 
23
 
 
24
from bzrlib.branch import Branch
 
25
from bzrlib.bzrdir import BzrDir
 
26
from bzrlib.conflicts import ConflictList
 
27
from bzrlib.osutils import abspath
 
28
from bzrlib.tests.blackbox import ExternalBase
 
29
import bzrlib.urlutils as urlutils
 
30
from bzrlib.workingtree import WorkingTree
 
31
 
 
32
 
 
33
class TestMerge(ExternalBase):
 
34
 
 
35
    def example_branch(test):
 
36
        test.runbzr('init')
 
37
        file('hello', 'wt').write('foo')
 
38
        test.runbzr('add hello')
 
39
        test.runbzr('commit -m setup hello')
 
40
        file('goodbye', 'wt').write('baz')
 
41
        test.runbzr('add goodbye')
 
42
        test.runbzr('commit -m setup goodbye')
 
43
 
 
44
    def test_merge_reprocess(self):
 
45
        d = BzrDir.create_standalone_workingtree('.')
 
46
        d.commit('h')
 
47
        self.run_bzr('merge', '.', '--reprocess', '--merge-type', 'weave')
 
48
 
 
49
    def test_merge(self):
 
50
        from bzrlib.branch import Branch
 
51
        
 
52
        os.mkdir('a')
 
53
        os.chdir('a')
 
54
        self.example_branch()
 
55
        ancestor = Branch.open('.').revno()
 
56
        os.chdir('..')
 
57
        self.runbzr('branch a b')
 
58
        os.chdir('b')
 
59
        file('goodbye', 'wt').write('quux')
 
60
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
61
 
 
62
        os.chdir('../a')
 
63
        file('hello', 'wt').write('quuux')
 
64
        # We can't merge when there are in-tree changes
 
65
        self.runbzr('merge ../b', retcode=3)
 
66
        a = WorkingTree.open('.')
 
67
        a_tip = a.commit("Like an epidemic of u's")
 
68
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
 
69
                    retcode=3)
 
70
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
 
71
        self.runbzr('revert --no-backup')
 
72
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
 
73
        self.runbzr('revert --no-backup')
 
74
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
 
75
        self.runbzr('revert --no-backup')
 
76
        self.runbzr('merge ../b -r last:1')
 
77
        self.check_file_contents('goodbye', 'quux')
 
78
        # Merging a branch pulls its revision into the tree
 
79
        b = Branch.open('../b')
 
80
        b_tip = b.last_revision()
 
81
        self.failUnless(a.branch.repository.has_revision(b_tip))
 
82
        self.assertEqual([a_tip, b_tip], a.get_parent_ids())
 
83
        self.runbzr('revert --no-backup')
 
84
        out, err = self.runbzr('merge -r revno:1:./hello', retcode=3)
 
85
        self.assertTrue("Not a branch" in err)
 
86
        self.runbzr('merge -r revno:%d:./..revno:%d:../b'
 
87
                    %(ancestor,b.revno()))
 
88
        self.assertEquals(a.pending_merges(), [b.last_revision()])
 
89
        self.check_file_contents('goodbye', 'quux')
 
90
        self.runbzr('revert --no-backup')
 
91
        self.runbzr('merge -r revno:%d:../b'%b.revno())
 
92
        self.assertEquals(a.pending_merges(),
 
93
                          [b.last_revision()])
 
94
        a_tip = a.commit('merged')
 
95
        self.runbzr('merge ../b -r last:1')
 
96
        self.assertEqual([a_tip], a.get_parent_ids())
 
97
 
 
98
    def test_merge_with_missing_file(self):
 
99
        """Merge handles missing file conflicts"""
 
100
        os.mkdir('a')
 
101
        os.chdir('a')
 
102
        os.mkdir('sub')
 
103
        print >> file('sub/a.txt', 'wb'), "hello"
 
104
        print >> file('b.txt', 'wb'), "hello"
 
105
        print >> file('sub/c.txt', 'wb'), "hello"
 
106
        self.runbzr('init')
 
107
        self.runbzr('add')
 
108
        self.runbzr(('commit', '-m', 'added a'))
 
109
        self.runbzr('branch . ../b')
 
110
        print >> file('sub/a.txt', 'ab'), "there"
 
111
        print >> file('b.txt', 'ab'), "there"
 
112
        print >> file('sub/c.txt', 'ab'), "there"
 
113
        self.runbzr(('commit', '-m', 'Added there'))
 
114
        os.unlink('sub/a.txt')
 
115
        os.unlink('sub/c.txt')
 
116
        os.rmdir('sub')
 
117
        os.unlink('b.txt')
 
118
        self.runbzr(('commit', '-m', 'Removed a.txt'))
 
119
        os.chdir('../b')
 
120
        print >> file('sub/a.txt', 'ab'), "something"
 
121
        print >> file('b.txt', 'ab'), "something"
 
122
        print >> file('sub/c.txt', 'ab'), "something"
 
123
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
124
        self.runbzr('merge ../a/', retcode=1)
 
125
        self.assert_(os.path.exists('sub/a.txt.THIS'))
 
126
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
127
        os.chdir('../a')
 
128
        self.runbzr('merge ../b/', retcode=1)
 
129
        self.assert_(os.path.exists('sub/a.txt.OTHER'))
 
130
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
131
 
 
132
    def test_merge_remember(self):
 
133
        """Merge changes from one branch to another and test parent location."""
 
134
        tree_a = self.make_branch_and_tree('branch_a')
 
135
        branch_a = tree_a.branch
 
136
        self.build_tree(['branch_a/a'])
 
137
        tree_a.add('a')
 
138
        tree_a.commit('commit a')
 
139
        branch_b = branch_a.bzrdir.sprout('branch_b').open_branch()
 
140
        tree_b = branch_b.bzrdir.open_workingtree()
 
141
        branch_c = branch_a.bzrdir.sprout('branch_c').open_branch()
 
142
        tree_c = branch_c.bzrdir.open_workingtree()
 
143
        self.build_tree(['branch_a/b'])
 
144
        tree_a.add('b')
 
145
        tree_a.commit('commit b')
 
146
        self.build_tree(['branch_c/c'])
 
147
        tree_c.add('c')
 
148
        tree_c.commit('commit c')
 
149
        # reset parent
 
150
        parent = branch_b.get_parent()
 
151
        branch_b.set_parent(None)
 
152
        self.assertEqual(None, branch_b.get_parent())
 
153
        # test merge for failure without parent set
 
154
        os.chdir('branch_b')
 
155
        out = self.runbzr('merge', retcode=3)
 
156
        self.assertEquals(out,
 
157
                ('','bzr: ERROR: No location specified or remembered\n'))
 
158
        # test implicit --remember when no parent set, this merge conflicts
 
159
        self.build_tree(['d'])
 
160
        tree_b.add('d')
 
161
        out = self.runbzr('merge ../branch_a', retcode=3)
 
162
        self.assertEquals(out,
 
163
                ('','bzr: ERROR: Working tree has uncommitted changes.\n'))
 
164
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
165
        # test implicit --remember after resolving conflict
 
166
        tree_b.commit('commit d')
 
167
        out, err = self.runbzr('merge')
 
168
        
 
169
        base = urlutils.local_path_from_url(branch_a.base)
 
170
        self.assertEquals(out, 'Merging from remembered location %s\n' % (base,))
 
171
        self.assertEquals(err, 'All changes applied successfully.\n')
 
172
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
173
        # re-open tree as external runbzr modified it
 
174
        tree_b = branch_b.bzrdir.open_workingtree()
 
175
        tree_b.commit('merge branch_a')
 
176
        # test explicit --remember
 
177
        out, err = self.runbzr('merge ../branch_c --remember')
 
178
        self.assertEquals(out, '')
 
179
        self.assertEquals(err, 'All changes applied successfully.\n')
 
180
        self.assertEquals(abspath(branch_b.get_parent()),
 
181
                          abspath(branch_c.bzrdir.root_transport.base))
 
182
        # re-open tree as external runbzr modified it
 
183
        tree_b = branch_b.bzrdir.open_workingtree()
 
184
        tree_b.commit('merge branch_c')
 
185
 
 
186
    def test_merge_bundle(self):
 
187
        from bzrlib.testament import Testament
 
188
        tree_a = self.make_branch_and_tree('branch_a')
 
189
        f = file('branch_a/a', 'wb')
 
190
        f.write('hello')
 
191
        f.close()
 
192
        tree_a.add('a')
 
193
        tree_a.commit('message')
 
194
 
 
195
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
 
196
        f = file('branch_a/a', 'wb')
 
197
        f.write('hey there')
 
198
        f.close()
 
199
        tree_a.commit('message')
 
200
 
 
201
        f = file('branch_b/a', 'wb')
 
202
        f.write('goodbye')
 
203
        f.close()
 
204
        tree_b.commit('message')
 
205
        os.chdir('branch_b')
 
206
        file('../bundle', 'wb').write(self.runbzr('bundle ../branch_a')[0])
 
207
        os.chdir('../branch_a')
 
208
        self.runbzr('merge ../bundle', retcode=1)
 
209
        testament_a = Testament.from_revision(tree_a.branch.repository,
 
210
                                              tree_b.get_parent_ids()[0])
 
211
        testament_b = Testament.from_revision(tree_b.branch.repository,
 
212
                                              tree_b.get_parent_ids()[0])
 
213
        self.assertEqualDiff(testament_a.as_text(),
 
214
                         testament_b.as_text())
 
215
        tree_a.set_conflicts(ConflictList())
 
216
        tree_a.commit('message')
 
217
        # it is legal to attempt to merge an already-merged bundle
 
218
        output = self.runbzr('merge ../bundle')[1]
 
219
        # but it does nothing
 
220
        self.assertFalse(tree_a.changes_from(tree_a.basis_tree()).has_changed())
 
221
        self.assertEqual('Nothing to do.\n', output)
 
222
 
 
223
    def test_merge_uncommitted(self):
 
224
        """Check that merge --uncommitted behaves properly"""
 
225
        tree_a = self.make_branch_and_tree('a')
 
226
        self.build_tree(['a/file_1', 'a/file_2'])
 
227
        tree_a.add(['file_1', 'file_2'])
 
228
        tree_a.commit('commit 1')
 
229
        tree_b = tree_a.bzrdir.sprout('b').open_workingtree()
 
230
        self.failUnlessExists('b/file_1')
 
231
        tree_a.rename_one('file_1', 'file_i')
 
232
        tree_a.commit('commit 2')
 
233
        tree_a.rename_one('file_2', 'file_ii')
 
234
        os.chdir('b')
 
235
        self.run_bzr('merge', '../a', '--uncommitted')
 
236
        self.failUnlessExists('file_1')
 
237
        self.failUnlessExists('file_ii')
 
238
        tree_b.revert([])
 
239
        self.run_bzr_error(('Cannot use --uncommitted and --revision',), 
 
240
                           'merge', '../a', '--uncommitted', '-r1')