~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_conflicts.py

  • Committer: Mark Hammond
  • Date: 2008-12-18 22:15:22 UTC
  • mto: (3932.1.1 prepare-1.11)
  • mto: This revision was merged to the branch mainline in revision 3937.
  • Revision ID: mhammond@skippinet.com.au-20081218221522-yizpnx890yywc2uk
remerge setup changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
18
import os
19
19
 
20
 
from bzrlib import (
21
 
    bzrdir,
22
 
    conflicts,
23
 
    errors,
24
 
    option,
25
 
    tests,
 
20
from bzrlib import bzrdir
 
21
from bzrlib.tests import TestCaseWithTransport, TestCase
 
22
from bzrlib.branch import Branch
 
23
from bzrlib.conflicts import (
 
24
    ConflictList,
 
25
    ContentsConflict,
 
26
    DuplicateID,
 
27
    DuplicateEntry,
 
28
    MissingParent,
 
29
    NonDirectoryParent,
 
30
    ParentLoop,
 
31
    PathConflict,
 
32
    TextConflict,
 
33
    UnversionedParent,
 
34
    resolve,
 
35
    restore,
26
36
    )
27
 
from bzrlib.tests import script
 
37
from bzrlib.errors import NotConflicted
28
38
 
29
39
 
30
40
# TODO: Test commit with some added, and added-but-missing files
34
44
# be a sorted list.
35
45
# u'\xe5' == a with circle
36
46
# '\xc3\xae' == u'\xee' == i with hat
37
 
# So these are u'path' and 'id' only with a circle and a hat. (shappo?)
38
 
example_conflicts = conflicts.ConflictList(
39
 
    [conflicts.MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
40
 
     conflicts.ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'),
41
 
     conflicts.TextConflict(u'p\xe5tha'),
42
 
     conflicts.PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
43
 
     conflicts.DuplicateID('Unversioned existing file',
44
 
                           u'p\xe5thc', u'p\xe5thc2',
45
 
                           '\xc3\xaedc', '\xc3\xaedc'),
46
 
    conflicts.DuplicateEntry('Moved existing file to',
47
 
                             u'p\xe5thdd.moved', u'p\xe5thd',
48
 
                             '\xc3\xaedd', None),
49
 
    conflicts.ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
50
 
                         None, '\xc3\xaed2e'),
51
 
    conflicts.UnversionedParent('Versioned directory',
52
 
                                u'p\xe5thf', '\xc3\xaedf'),
53
 
    conflicts.NonDirectoryParent('Created directory',
54
 
                                 u'p\xe5thg', '\xc3\xaedg'),
 
47
# So these are u'pathg' and 'idg' only with a circle and a hat. (shappo?)
 
48
example_conflicts = ConflictList([ 
 
49
    MissingParent('Not deleting', u'p\xe5thg', '\xc3\xaedg'),
 
50
    ContentsConflict(u'p\xe5tha', None, '\xc3\xaeda'), 
 
51
    TextConflict(u'p\xe5tha'),
 
52
    PathConflict(u'p\xe5thb', u'p\xe5thc', '\xc3\xaedb'),
 
53
    DuplicateID('Unversioned existing file', u'p\xe5thc', u'p\xe5thc2',
 
54
                '\xc3\xaedc', '\xc3\xaedc'),
 
55
    DuplicateEntry('Moved existing file to',  u'p\xe5thdd.moved', u'p\xe5thd',
 
56
                   '\xc3\xaedd', None),
 
57
    ParentLoop('Cancelled move', u'p\xe5the', u'p\xe5th2e',
 
58
               None, '\xc3\xaed2e'),
 
59
    UnversionedParent('Versioned directory', u'p\xe5thf', '\xc3\xaedf'),
 
60
    NonDirectoryParent('Created directory', u'p\xe5thg', '\xc3\xaedg'),
55
61
])
56
62
 
57
63
 
58
 
class TestConflicts(tests.TestCaseWithTransport):
 
64
class TestConflicts(TestCaseWithTransport):
59
65
 
60
66
    def test_conflicts(self):
61
67
        """Conflicts are detected properly"""
62
 
        # Use BzrDirFormat6 so we can fake conflicts
63
 
        tree = self.make_branch_and_tree('.', format=bzrdir.BzrDirFormat6())
64
 
        self.build_tree_contents([('hello', 'hello world4'),
65
 
                                  ('hello.THIS', 'hello world2'),
66
 
                                  ('hello.BASE', 'hello world1'),
67
 
                                  ('hello.OTHER', 'hello world3'),
68
 
                                  ('hello.sploo.BASE', 'yellowworld'),
69
 
                                  ('hello.sploo.OTHER', 'yellowworld2'),
70
 
                                  ])
 
68
        tree = self.make_branch_and_tree('.',
 
69
            format=bzrdir.BzrDirFormat6())
 
70
        b = tree.branch
 
71
        file('hello', 'w').write('hello world4')
 
72
        file('hello.THIS', 'w').write('hello world2')
 
73
        file('hello.BASE', 'w').write('hello world1')
 
74
        file('hello.OTHER', 'w').write('hello world3')
 
75
        file('hello.sploo.BASE', 'w').write('yellow world')
 
76
        file('hello.sploo.OTHER', 'w').write('yellow world2')
71
77
        tree.lock_read()
72
 
        self.assertEqual(6, len(list(tree.list_files())))
 
78
        self.assertEqual(len(list(tree.list_files())), 6)
73
79
        tree.unlock()
74
 
        tree_conflicts = tree.conflicts()
75
 
        self.assertEqual(2, len(tree_conflicts))
76
 
        self.assertTrue('hello' in tree_conflicts[0].path)
77
 
        self.assertTrue('hello.sploo' in tree_conflicts[1].path)
78
 
        conflicts.restore('hello')
79
 
        conflicts.restore('hello.sploo')
80
 
        self.assertEqual(0, len(tree.conflicts()))
 
80
        conflicts = tree.conflicts()
 
81
        self.assertEqual(len(conflicts), 2)
 
82
        self.assert_('hello' in conflicts[0].path)
 
83
        self.assert_('hello.sploo' in conflicts[1].path)
 
84
        restore('hello')
 
85
        restore('hello.sploo')
 
86
        self.assertEqual(len(tree.conflicts()), 0)
81
87
        self.assertFileEqual('hello world2', 'hello')
82
88
        self.assertFalse(os.path.lexists('hello.sploo'))
83
 
        self.assertRaises(errors.NotConflicted, conflicts.restore, 'hello')
84
 
        self.assertRaises(errors.NotConflicted,
85
 
                          conflicts.restore, 'hello.sploo')
 
89
        self.assertRaises(NotConflicted, restore, 'hello')
 
90
        self.assertRaises(NotConflicted, restore, 'hello.sploo')
86
91
 
87
92
    def test_resolve_conflict_dir(self):
88
93
        tree = self.make_branch_and_tree('.')
89
 
        self.build_tree_contents([('hello', 'hello world4'),
90
 
                                  ('hello.THIS', 'hello world2'),
91
 
                                  ('hello.BASE', 'hello world1'),
92
 
                                  ])
 
94
        b = tree.branch
 
95
        file('hello', 'w').write('hello world4')
 
96
        tree.add('hello', 'q')
 
97
        file('hello.THIS', 'w').write('hello world2')
 
98
        file('hello.BASE', 'w').write('hello world1')
93
99
        os.mkdir('hello.OTHER')
94
 
        tree.add('hello', 'q')
95
 
        l = conflicts.ConflictList([conflicts.TextConflict('hello')])
 
100
        l = ConflictList([TextConflict('hello')])
96
101
        l.remove_files(tree)
97
102
 
98
103
    def test_select_conflicts(self):
99
104
        tree = self.make_branch_and_tree('.')
100
 
        clist = conflicts.ConflictList
101
 
 
102
 
        def check_select(not_selected, selected, paths, **kwargs):
103
 
            self.assertEqual(
104
 
                (not_selected, selected),
105
 
                tree_conflicts.select_conflicts(tree, paths, **kwargs))
106
 
 
107
 
        foo = conflicts.ContentsConflict('foo')
108
 
        bar = conflicts.ContentsConflict('bar')
109
 
        tree_conflicts = clist([foo, bar])
110
 
 
111
 
        check_select(clist([bar]), clist([foo]), ['foo'])
112
 
        check_select(clist(), tree_conflicts,
113
 
                     [''], ignore_misses=True, recurse=True)
114
 
 
115
 
        foobaz  = conflicts.ContentsConflict('foo/baz')
116
 
        tree_conflicts = clist([foobaz, bar])
117
 
 
118
 
        check_select(clist([bar]), clist([foobaz]),
119
 
                     ['foo'], ignore_misses=True, recurse=True)
120
 
 
121
 
        qux = conflicts.PathConflict('qux', 'foo/baz')
122
 
        tree_conflicts = clist([qux])
123
 
 
124
 
        check_select(clist(), tree_conflicts,
125
 
                     ['foo'], ignore_misses=True, recurse=True)
126
 
        check_select (tree_conflicts, clist(), ['foo'], ignore_misses=True)
 
105
        tree_conflicts = ConflictList([ContentsConflict('foo'),
 
106
                                       ContentsConflict('bar')])
 
107
        self.assertEqual((ConflictList([ContentsConflict('bar')]),
 
108
                          ConflictList([ContentsConflict('foo')])),
 
109
                         tree_conflicts.select_conflicts(tree, ['foo']))
 
110
        self.assertEqual((ConflictList(), tree_conflicts),
 
111
                         tree_conflicts.select_conflicts(tree, [''],
 
112
                         ignore_misses=True, recurse=True))
 
113
        tree_conflicts = ConflictList([ContentsConflict('foo/baz'),
 
114
                                       ContentsConflict('bar')])
 
115
        self.assertEqual((ConflictList([ContentsConflict('bar')]),
 
116
                          ConflictList([ContentsConflict('foo/baz')])),
 
117
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
118
                                                         recurse=True,
 
119
                                                         ignore_misses=True))
 
120
        tree_conflicts = ConflictList([PathConflict('qux', 'foo/baz')])
 
121
        self.assertEqual((ConflictList(), tree_conflicts),
 
122
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
123
                                                         recurse=True,
 
124
                                                         ignore_misses=True))
 
125
        self.assertEqual((tree_conflicts, ConflictList()),
 
126
                         tree_conflicts.select_conflicts(tree, ['foo'],
 
127
                                                         ignore_misses=True))
127
128
 
128
129
    def test_resolve_conflicts_recursive(self):
129
130
        tree = self.make_branch_and_tree('.')
130
131
        self.build_tree(['dir/', 'dir/hello'])
131
132
        tree.add(['dir', 'dir/hello'])
132
 
 
133
 
        dirhello = conflicts.ConflictList([conflicts.TextConflict('dir/hello')])
134
 
        tree.set_conflicts(dirhello)
135
 
 
136
 
        conflicts.resolve(tree, ['dir'], recursive=False, ignore_misses=True)
137
 
        self.assertEqual(dirhello, tree.conflicts())
138
 
 
139
 
        conflicts.resolve(tree, ['dir'], recursive=True, ignore_misses=True)
140
 
        self.assertEqual(conflicts.ConflictList([]), tree.conflicts())
141
 
 
142
 
 
143
 
class TestConflictStanzas(tests.TestCase):
 
133
        tree.set_conflicts(ConflictList([TextConflict('dir/hello')]))
 
134
        resolve(tree, ['dir'], recursive=False, ignore_misses=True)
 
135
        self.assertEqual(ConflictList([TextConflict('dir/hello')]),
 
136
                         tree.conflicts())
 
137
        resolve(tree, ['dir'], recursive=True, ignore_misses=True)
 
138
        self.assertEqual(ConflictList([]),
 
139
                         tree.conflicts())
 
140
 
 
141
 
 
142
class TestConflictStanzas(TestCase):
144
143
 
145
144
    def test_stanza_roundtrip(self):
146
145
        # write and read our example stanza.
147
146
        stanza_iter = example_conflicts.to_stanzas()
148
 
        processed = conflicts.ConflictList.from_stanzas(stanza_iter)
 
147
        processed = ConflictList.from_stanzas(stanza_iter)
149
148
        for o, p in zip(processed, example_conflicts):
150
149
            self.assertEqual(o, p)
151
150
 
172
171
                self.assertStartsWith(stanza['conflict_path'], u'p\xe5th')
173
172
            if 'conflict_file_id' in stanza:
174
173
                self.assertStartsWith(stanza['conflict_file_id'], u'\xeed')
175
 
 
176
 
 
177
 
# FIXME: The shell-like tests should be converted to real whitebox tests... or
178
 
# moved to a blackbox module -- vila 20100205
179
 
 
180
 
# FIXME: Tests missing for DuplicateID conflict type
181
 
class TestResolveConflicts(script.TestCaseWithTransportAndScript):
182
 
 
183
 
    preamble = None # The setup script set by daughter classes
184
 
 
185
 
    def setUp(self):
186
 
        super(TestResolveConflicts, self).setUp()
187
 
        self.run_script(self.preamble)
188
 
 
189
 
 
190
 
class TestResolveTextConflicts(TestResolveConflicts):
191
 
    # TBC
192
 
    pass
193
 
 
194
 
 
195
 
class TestResolveContentConflicts(TestResolveConflicts):
196
 
 
197
 
    # FIXME: We need to add the reverse case (delete in trunk, modify in
198
 
    # branch) but that could wait until the resolution mechanism is implemented.
199
 
 
200
 
    preamble = """
201
 
$ bzr init trunk
202
 
$ cd trunk
203
 
$ echo 'trunk content' >file
204
 
$ bzr add file
205
 
$ bzr commit -m 'Create trunk'
206
 
 
207
 
$ bzr branch . ../branch
208
 
$ cd ../branch
209
 
$ bzr rm file
210
 
$ bzr commit -m 'Delete file'
211
 
 
212
 
$ cd ../trunk
213
 
$ echo 'more content' >>file
214
 
$ bzr commit -m 'Modify file'
215
 
 
216
 
$ cd ../branch
217
 
$ bzr merge ../trunk
218
 
2>+N  file.OTHER
219
 
2>Contents conflict in file
220
 
2>1 conflicts encountered.
221
 
"""
222
 
 
223
 
    def test_take_this(self):
224
 
        self.run_script("""
225
 
$ bzr rm file.OTHER --force # a simple rm file.OTHER is valid too
226
 
$ bzr resolve file
227
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
228
 
""")
229
 
 
230
 
    def test_take_other(self):
231
 
        self.run_script("""
232
 
$ bzr mv file.OTHER file
233
 
$ bzr resolve file
234
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
235
 
""")
236
 
 
237
 
    def test_resolve_taking_this(self):
238
 
        self.run_script("""
239
 
$ bzr resolve --take-this file
240
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
241
 
""")
242
 
 
243
 
    def test_resolve_taking_other(self):
244
 
        self.run_script("""
245
 
$ bzr resolve --take-other file
246
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
247
 
""")
248
 
 
249
 
 
250
 
class TestResolveDuplicateEntry(TestResolveConflicts):
251
 
 
252
 
    preamble = """
253
 
$ bzr init trunk
254
 
$ cd trunk
255
 
$ echo 'trunk content' >file
256
 
$ bzr add file
257
 
$ bzr commit -m 'Create trunk'
258
 
$ echo 'trunk content too' >file2
259
 
$ bzr add file2
260
 
$ bzr commit -m 'Add file2 in trunk'
261
 
 
262
 
$ bzr branch . -r 1 ../branch
263
 
$ cd ../branch
264
 
$ echo 'branch content' >file2
265
 
$ bzr add file2
266
 
$ bzr commit -m 'Add file2 in branch'
267
 
 
268
 
$ bzr merge ../trunk
269
 
2>+N  file2
270
 
2>R   file2 => file2.moved
271
 
2>Conflict adding file file2.  Moved existing file to file2.moved.
272
 
2>1 conflicts encountered.
273
 
"""
274
 
 
275
 
    def test_keep_this(self):
276
 
        self.run_script("""
277
 
$ bzr rm file2  --force
278
 
$ bzr mv file2.moved file2
279
 
$ bzr resolve file2
280
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
281
 
""")
282
 
 
283
 
    def test_keep_other(self):
284
 
        self.failIfExists('branch/file2.moved')
285
 
        self.run_script("""
286
 
$ bzr rm file2.moved --force
287
 
$ bzr resolve file2
288
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
289
 
""")
290
 
        self.failIfExists('branch/file2.moved')
291
 
 
292
 
    def test_resolve_taking_this(self):
293
 
        self.run_script("""
294
 
$ bzr resolve --take-this file2
295
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
296
 
""")
297
 
 
298
 
    def test_resolve_taking_other(self):
299
 
        self.run_script("""
300
 
$ bzr resolve --take-other file2
301
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
302
 
""")
303
 
 
304
 
 
305
 
class TestResolveUnversionedParent(TestResolveConflicts):
306
 
 
307
 
    # FIXME: Add the reverse tests: dir deleted in trunk, file added in branch
308
 
 
309
 
    # FIXME: While this *creates* UnversionedParent conflicts, this really only
310
 
    # tests MissingParent resolution :-/
311
 
    preamble = """
312
 
$ bzr init trunk
313
 
$ cd trunk
314
 
$ mkdir dir
315
 
$ bzr add dir
316
 
$ bzr commit -m 'Create trunk'
317
 
$ echo 'trunk content' >dir/file
318
 
$ bzr add dir/file
319
 
$ bzr commit -m 'Add dir/file in trunk'
320
 
 
321
 
$ bzr branch . -r 1 ../branch
322
 
$ cd ../branch
323
 
$ bzr rm dir
324
 
$ bzr commit -m 'Remove dir in branch'
325
 
 
326
 
$ bzr merge ../trunk
327
 
2>+N  dir/
328
 
2>+N  dir/file
329
 
2>Conflict adding files to dir.  Created directory.
330
 
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
331
 
2>2 conflicts encountered.
332
 
"""
333
 
 
334
 
    def test_take_this(self):
335
 
        self.run_script("""
336
 
$ bzr rm dir  --force
337
 
$ bzr resolve dir
338
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
339
 
""")
340
 
 
341
 
    def test_take_other(self):
342
 
        self.run_script("""
343
 
$ bzr resolve dir
344
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
345
 
""")
346
 
 
347
 
 
348
 
class TestResolveMissingParent(TestResolveConflicts):
349
 
 
350
 
    preamble = """
351
 
$ bzr init trunk
352
 
$ cd trunk
353
 
$ mkdir dir
354
 
$ echo 'trunk content' >dir/file
355
 
$ bzr add
356
 
$ bzr commit -m 'Create trunk'
357
 
$ echo 'trunk content' >dir/file2
358
 
$ bzr add dir/file2
359
 
$ bzr commit -m 'Add dir/file2 in branch'
360
 
 
361
 
$ bzr branch . -r 1 ../branch
362
 
$ cd ../branch
363
 
$ bzr rm dir/file --force
364
 
$ bzr rm dir
365
 
$ bzr commit -m 'Remove dir/file'
366
 
 
367
 
$ bzr merge ../trunk
368
 
2>+N  dir/
369
 
2>+N  dir/file2
370
 
2>Conflict adding files to dir.  Created directory.
371
 
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
372
 
2>2 conflicts encountered.
373
 
"""
374
 
 
375
 
    def test_keep_them_all(self):
376
 
        self.run_script("""
377
 
$ bzr resolve dir
378
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
379
 
""")
380
 
 
381
 
    def test_adopt_child(self):
382
 
        self.run_script("""
383
 
$ bzr mv dir/file2 file2
384
 
$ bzr rm dir --force
385
 
$ bzr resolve dir
386
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
387
 
""")
388
 
 
389
 
    def test_kill_them_all(self):
390
 
        self.run_script("""
391
 
$ bzr rm dir --force
392
 
$ bzr resolve dir
393
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
394
 
""")
395
 
 
396
 
    def test_resolve_taking_this(self):
397
 
        self.run_script("""
398
 
$ bzr resolve --take-this dir
399
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
400
 
""")
401
 
 
402
 
    def test_resolve_taking_other(self):
403
 
        self.run_script("""
404
 
$ bzr resolve --take-other dir
405
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
406
 
""")
407
 
 
408
 
 
409
 
class TestResolveDeletingParent(TestResolveConflicts):
410
 
 
411
 
    preamble = """
412
 
$ bzr init trunk
413
 
$ cd trunk
414
 
$ mkdir dir
415
 
$ echo 'trunk content' >dir/file
416
 
$ bzr add
417
 
$ bzr commit -m 'Create trunk'
418
 
$ bzr rm dir/file --force
419
 
$ bzr rm dir --force
420
 
$ bzr commit -m 'Remove dir/file'
421
 
 
422
 
$ bzr branch . -r 1 ../branch
423
 
$ cd ../branch
424
 
$ echo 'branch content' >dir/file2
425
 
$ bzr add dir/file2
426
 
$ bzr commit -m 'Add dir/file2 in branch'
427
 
 
428
 
$ bzr merge ../trunk
429
 
2>-D  dir/file
430
 
2>Conflict: can't delete dir because it is not empty.  Not deleting.
431
 
2>Conflict because dir is not versioned, but has versioned children.  Versioned directory.
432
 
2>2 conflicts encountered.
433
 
"""
434
 
 
435
 
    def test_keep_them_all(self):
436
 
        self.run_script("""
437
 
$ bzr resolve dir
438
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
439
 
""")
440
 
 
441
 
    def test_adopt_child(self):
442
 
        self.run_script("""
443
 
$ bzr mv dir/file2 file2
444
 
$ bzr rm dir --force
445
 
$ bzr resolve dir
446
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
447
 
""")
448
 
 
449
 
    def test_kill_them_all(self):
450
 
        self.run_script("""
451
 
$ bzr rm dir --force
452
 
$ bzr resolve dir
453
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
454
 
""")
455
 
 
456
 
    def test_resolve_taking_this(self):
457
 
        self.run_script("""
458
 
$ bzr resolve --take-this dir
459
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
460
 
""")
461
 
 
462
 
    def test_resolve_taking_other(self):
463
 
        self.run_script("""
464
 
$ bzr resolve --take-other dir
465
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
466
 
""")
467
 
 
468
 
 
469
 
class TestResolvePathConflict(TestResolveConflicts):
470
 
 
471
 
    preamble = """
472
 
$ bzr init trunk
473
 
$ cd trunk
474
 
$ echo 'Boo!' >file
475
 
$ bzr add
476
 
$ bzr commit -m 'Create trunk'
477
 
$ bzr mv file file-in-trunk
478
 
$ bzr commit -m 'Renamed to file-in-trunk'
479
 
 
480
 
$ bzr branch . -r 1 ../branch
481
 
$ cd ../branch
482
 
$ bzr mv file file-in-branch
483
 
$ bzr commit -m 'Renamed to file-in-branch'
484
 
 
485
 
$ bzr merge ../trunk
486
 
2>R   file-in-branch => file-in-trunk
487
 
2>Path conflict: file-in-branch / file-in-trunk
488
 
2>1 conflicts encountered.
489
 
"""
490
 
 
491
 
    def test_keep_source(self):
492
 
        self.run_script("""
493
 
$ bzr resolve file-in-trunk
494
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
495
 
""")
496
 
 
497
 
    def test_keep_target(self):
498
 
        self.run_script("""
499
 
$ bzr mv file-in-trunk file-in-branch
500
 
$ bzr resolve file-in-branch
501
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
502
 
""")
503
 
 
504
 
    def test_resolve_taking_this(self):
505
 
        self.run_script("""
506
 
$ bzr resolve --take-this file-in-branch
507
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
508
 
""")
509
 
 
510
 
    def test_resolve_taking_other(self):
511
 
        self.run_script("""
512
 
$ bzr resolve --take-other file-in-branch
513
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
514
 
""")
515
 
 
516
 
 
517
 
class TestResolveParentLoop(TestResolveConflicts):
518
 
 
519
 
    preamble = """
520
 
$ bzr init trunk
521
 
$ cd trunk
522
 
$ bzr mkdir dir1
523
 
$ bzr mkdir dir2
524
 
$ bzr commit -m 'Create trunk'
525
 
$ bzr mv dir2 dir1
526
 
$ bzr commit -m 'Moved dir2 into dir1'
527
 
 
528
 
$ bzr branch . -r 1 ../branch
529
 
$ cd ../branch
530
 
$ bzr mv dir1 dir2
531
 
$ bzr commit -m 'Moved dir1 into dir2'
532
 
 
533
 
$ bzr merge ../trunk
534
 
2>Conflict moving dir2/dir1 into dir2.  Cancelled move.
535
 
2>1 conflicts encountered.
536
 
"""
537
 
 
538
 
    def test_take_this(self):
539
 
        self.run_script("""
540
 
$ bzr resolve dir2
541
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
542
 
""")
543
 
 
544
 
    def test_take_other(self):
545
 
        self.run_script("""
546
 
$ bzr mv dir2/dir1 dir1
547
 
$ bzr mv dir2 dir1
548
 
$ bzr resolve dir2
549
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
550
 
""")
551
 
 
552
 
    def test_resolve_taking_this(self):
553
 
        self.run_script("""
554
 
$ bzr resolve --take-this dir2
555
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
556
 
""")
557
 
        self.failUnlessExists('dir2')
558
 
 
559
 
    def test_resolve_taking_other(self):
560
 
        self.run_script("""
561
 
$ bzr resolve --take-other dir2
562
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
563
 
""")
564
 
        self.failUnlessExists('dir1')
565
 
 
566
 
 
567
 
class TestResolveNonDirectoryParent(TestResolveConflicts):
568
 
 
569
 
    preamble = """
570
 
$ bzr init trunk
571
 
$ cd trunk
572
 
$ bzr mkdir foo
573
 
$ bzr commit -m 'Create trunk'
574
 
$ echo "Boing" >foo/bar
575
 
$ bzr add foo/bar
576
 
$ bzr commit -m 'Add foo/bar'
577
 
 
578
 
$ bzr branch . -r 1 ../branch
579
 
$ cd ../branch
580
 
$ rm -r foo
581
 
$ echo "Boo!" >foo
582
 
$ bzr commit -m 'foo is now a file'
583
 
 
584
 
$ bzr merge ../trunk
585
 
2>+N  foo.new/bar
586
 
2>RK  foo => foo.new/
587
 
# FIXME: The message is misleading, foo.new *is* a directory when the message
588
 
# is displayed -- vila 090916
589
 
2>Conflict: foo.new is not a directory, but has files in it.  Created directory.
590
 
2>1 conflicts encountered.
591
 
"""
592
 
 
593
 
    def test_take_this(self):
594
 
        self.run_script("""
595
 
$ bzr rm foo.new --force
596
 
# FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
597
 
# aside ? -- vila 090916
598
 
$ bzr add foo
599
 
$ bzr resolve foo.new
600
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
601
 
""")
602
 
 
603
 
    def test_take_other(self):
604
 
        self.run_script("""
605
 
$ bzr rm foo --force
606
 
$ bzr mv foo.new foo
607
 
$ bzr resolve foo
608
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
609
 
""")
610
 
 
611
 
    def test_resolve_taking_this(self):
612
 
        self.run_script("""
613
 
$ bzr resolve --take-this foo.new
614
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
615
 
""")
616
 
 
617
 
    def test_resolve_taking_other(self):
618
 
        self.run_script("""
619
 
$ bzr resolve --take-other foo.new
620
 
$ bzr commit --strict -m 'No more conflicts nor unknown files'
621
 
""")
622
 
 
623
 
 
624
 
class TestMalformedTransform(script.TestCaseWithTransportAndScript):
625
 
 
626
 
    def test_bug_430129(self):
627
 
        # This is nearly like TestResolveNonDirectoryParent but with branch and
628
 
        # trunk switched. As such it should certainly produce the same
629
 
        # conflict.
630
 
        self.run_script("""
631
 
$ bzr init trunk
632
 
$ cd trunk
633
 
$ bzr mkdir foo
634
 
$ bzr commit -m 'Create trunk'
635
 
$ rm -r foo
636
 
$ echo "Boo!" >foo
637
 
$ bzr commit -m 'foo is now a file'
638
 
 
639
 
$ bzr branch . -r 1 ../branch
640
 
$ cd ../branch
641
 
$ echo "Boing" >foo/bar
642
 
$ bzr add foo/bar
643
 
$ bzr commit -m 'Add foo/bar'
644
 
 
645
 
$ bzr merge ../trunk
646
 
2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
647
 
""")
648
 
 
649
 
 
650
 
class TestResolveActionOption(tests.TestCase):
651
 
 
652
 
    def setUp(self):
653
 
        super(TestResolveActionOption, self).setUp()
654
 
        self.options = [conflicts.ResolveActionOption()]
655
 
        self.parser = option.get_optparser(dict((o.name, o)
656
 
                                                for o in self.options))
657
 
 
658
 
    def parse(self, args):
659
 
        return self.parser.parse_args(args)
660
 
 
661
 
    def test_unknown_action(self):
662
 
        self.assertRaises(errors.BadOptionValue,
663
 
                          self.parse, ['--action', 'take-me-to-the-moon'])
664
 
 
665
 
    def test_done(self):
666
 
        opts, args = self.parse(['--action', 'done'])
667
 
        self.assertEqual({'action':'done'}, opts)
668
 
 
669
 
    def test_take_this(self):
670
 
        opts, args = self.parse(['--action', 'take-this'])
671
 
        self.assertEqual({'action': 'take_this'}, opts)
672
 
        opts, args = self.parse(['--take-this'])
673
 
        self.assertEqual({'action': 'take_this'}, opts)
674
 
 
675
 
    def test_take_other(self):
676
 
        opts, args = self.parse(['--action', 'take-other'])
677
 
        self.assertEqual({'action': 'take_other'}, opts)
678
 
        opts, args = self.parse(['--take-other'])
679
 
        self.assertEqual({'action': 'take_other'}, opts)