~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: Martin Pool
  • Date: 2005-08-25 05:58:05 UTC
  • mfrom: (974.1.36)
  • Revision ID: mbp@sourcefrog.net-20050825055805-8c892bc3c2d75131
- merge aaron's merge improvements:

  * When merging, pull in all missing revisions from the source
    branch. 

  * Detect common ancestors by looking at the whole ancestry graph, 
    rather than just mainline history.

  Some changes to reconcile this with parallel updates to the test and
  trace code.

aaron.bentley@utoronto.ca-20050823052551-f3401a8b57d9126f

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
"""Black-box tests for bzr.
20
20
 
21
21
These check that it behaves properly when it's invoked through the regular
22
 
command-line interface. This doesn't actually run a new interpreter but 
23
 
rather starts again from the run_bzr function.
 
22
command-line interface.
 
23
 
 
24
This always reinvokes bzr through a new Python interpreter, which is a
 
25
bit inefficient but arguably tests in a way more representative of how
 
26
it's normally invoked.
24
27
"""
25
28
 
26
 
 
27
 
from cStringIO import StringIO
28
 
import os
29
 
import re
30
 
import shutil
31
29
import sys
32
 
 
33
 
from bzrlib.branch import Branch
34
 
from bzrlib.clone import copy_branch
35
 
from bzrlib.errors import BzrCommandError
36
 
from bzrlib.osutils import has_symlinks
37
 
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
38
 
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
39
 
 
40
 
 
41
 
class ExternalBase(TestCaseInTempDir):
42
 
 
43
 
    def runbzr(self, args, retcode=0, backtick=False):
 
30
from bzrlib.selftest import InTempDir, BzrTestBase
 
31
 
 
32
 
 
33
class ExternalBase(InTempDir):
 
34
 
 
35
    def runbzr(self, args, retcode=0,backtick=False):
 
36
        try:
 
37
            import shutil
 
38
            from subprocess import call
 
39
        except ImportError, e:
 
40
            _need_subprocess()
 
41
            raise
 
42
 
44
43
        if isinstance(args, basestring):
45
44
            args = args.split()
46
45
 
47
46
        if backtick:
48
 
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
47
            return self.backtick(['python', self.BZRPATH,] + args,
 
48
                           retcode=retcode)
49
49
        else:
50
 
            return self.run_bzr_captured(args, retcode=retcode)
51
 
 
 
50
            return self.runcmd(['python', self.BZRPATH,] + args,
 
51
                           retcode=retcode)
52
52
 
53
53
class TestCommands(ExternalBase):
54
54
 
60
60
        self.runbzr('commit -h')
61
61
 
62
62
    def test_init_branch(self):
 
63
        import os
63
64
        self.runbzr(['init'])
64
65
 
65
66
    def test_whoami(self):
76
77
        f = file('.bzr/email', 'wt')
77
78
        f.write('Branch Identity <branch@identi.ty>')
78
79
        f.close()
79
 
        bzr_email = os.environ.get('BZREMAIL')
80
 
        if bzr_email is not None:
81
 
            del os.environ['BZREMAIL']
82
80
        whoami = self.runbzr("whoami",backtick=True)
83
81
        whoami_email = self.runbzr("whoami --email",backtick=True)
84
82
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
85
83
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
86
 
        # Verify that the environment variable overrides the value 
87
 
        # in the file
88
 
        os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
89
 
        whoami = self.runbzr("whoami",backtick=True)
90
 
        whoami_email = self.runbzr("whoami --email",backtick=True)
91
 
        self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
92
 
        self.assertTrue(whoami_email.startswith('other@environ.ment'))
93
 
        if bzr_email is not None:
94
 
            os.environ['BZREMAIL'] = bzr_email
95
84
 
96
85
    def test_invalid_commands(self):
97
86
        self.runbzr("pants", retcode=1)
105
94
        self.runbzr("add hello.txt")
106
95
        self.runbzr("commit -m added")
107
96
 
108
 
    def test_empty_commit_message(self):
109
 
        self.runbzr("init")
110
 
        file('foo.c', 'wt').write('int main() {}')
111
 
        self.runbzr(['add', 'foo.c'])
112
 
        self.runbzr(["commit", "-m", ""] , retcode=1) 
113
 
 
114
 
    def test_other_branch_commit(self):
115
 
        # this branch is to ensure consistent behaviour, whether we're run
116
 
        # inside a branch, or not.
117
 
        os.mkdir('empty_branch')
118
 
        os.chdir('empty_branch')
119
 
        self.runbzr('init')
120
 
        os.mkdir('branch')
121
 
        os.chdir('branch')
122
 
        self.runbzr('init')
123
 
        file('foo.c', 'wt').write('int main() {}')
124
 
        file('bar.c', 'wt').write('int main() {}')
125
 
        os.chdir('..')
126
 
        self.runbzr(['add', 'branch/foo.c'])
127
 
        self.runbzr(['add', 'branch'])
128
 
        # can't commit files in different trees; sane error
129
 
        self.runbzr('commit -m newstuff branch/foo.c .', retcode=1)
130
 
        self.runbzr('commit -m newstuff branch/foo.c')
131
 
        self.runbzr('commit -m newstuff branch')
132
 
        self.runbzr('commit -m newstuff branch', retcode=1)
133
 
 
134
 
 
135
97
    def test_ignore_patterns(self):
136
98
        from bzrlib.branch import Branch
137
99
        
138
 
        b = Branch.initialize('.')
 
100
        b = Branch('.', init=True)
139
101
        self.assertEquals(list(b.unknowns()), [])
140
102
 
141
103
        file('foo.tmp', 'wt').write('tmp files are ignored')
142
104
        self.assertEquals(list(b.unknowns()), [])
143
 
        assert self.capture('unknowns') == ''
 
105
        assert self.backtick('bzr unknowns') == ''
144
106
 
145
107
        file('foo.c', 'wt').write('int main() {}')
146
108
        self.assertEquals(list(b.unknowns()), ['foo.c'])
147
 
        assert self.capture('unknowns') == 'foo.c\n'
 
109
        assert self.backtick('bzr unknowns') == 'foo.c\n'
148
110
 
149
111
        self.runbzr(['add', 'foo.c'])
150
 
        assert self.capture('unknowns') == ''
 
112
        assert self.backtick('bzr unknowns') == ''
151
113
 
152
114
        # 'ignore' works when creating the .bzignore file
153
115
        file('foo.blah', 'wt').write('blah')
154
116
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
155
117
        self.runbzr('ignore *.blah')
156
118
        self.assertEquals(list(b.unknowns()), [])
157
 
        assert file('.bzrignore', 'rU').read() == '*.blah\n'
 
119
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
158
120
 
159
121
        # 'ignore' works when then .bzrignore file already exists
160
122
        file('garh', 'wt').write('garh')
161
123
        self.assertEquals(list(b.unknowns()), ['garh'])
162
 
        assert self.capture('unknowns') == 'garh\n'
 
124
        assert self.backtick('bzr unknowns') == 'garh\n'
163
125
        self.runbzr('ignore garh')
164
126
        self.assertEquals(list(b.unknowns()), [])
165
 
        assert file('.bzrignore', 'rU').read() == '*.blah\ngarh\n'
 
127
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
166
128
 
167
129
    def test_revert(self):
 
130
        import os
 
131
 
168
132
        self.runbzr('init')
169
133
 
170
134
        file('hello', 'wt').write('foo')
174
138
        file('goodbye', 'wt').write('baz')
175
139
        self.runbzr('add goodbye')
176
140
        self.runbzr('commit -m setup goodbye')
177
 
 
 
141
        
178
142
        file('hello', 'wt').write('bar')
179
143
        file('goodbye', 'wt').write('qux')
180
144
        self.runbzr('revert hello')
189
153
        os.rmdir('revertdir')
190
154
        self.runbzr('revert')
191
155
 
192
 
        os.symlink('/unlikely/to/exist', 'symlink')
193
 
        self.runbzr('add symlink')
194
 
        self.runbzr('commit -m f')
195
 
        os.unlink('symlink')
196
 
        self.runbzr('revert')
197
 
        self.failUnlessExists('symlink')
198
 
        os.unlink('symlink')
199
 
        os.symlink('a-different-path', 'symlink')
200
 
        self.runbzr('revert')
201
 
        self.assertEqual('/unlikely/to/exist',
202
 
                         os.readlink('symlink'))
203
 
        
204
 
        file('hello', 'wt').write('xyz')
205
 
        self.runbzr('commit -m xyz hello')
206
 
        self.runbzr('revert -r 1 hello')
207
 
        self.check_file_contents('hello', 'foo')
208
 
        self.runbzr('revert hello')
209
 
        self.check_file_contents('hello', 'xyz')
210
 
        os.chdir('revertdir')
211
 
        self.runbzr('revert')
212
 
        os.chdir('..')
213
 
 
214
 
 
215
 
    def test_mv_modes(self):
 
156
 
 
157
    def skipped_test_mv_modes(self):
216
158
        """Test two modes of operation for mv"""
217
159
        from bzrlib.branch import Branch
218
 
        b = Branch.initialize('.')
 
160
        b = Branch('.', init=True)
219
161
        self.build_tree(['a', 'c', 'subdir/'])
220
 
        self.run_bzr_captured(['add', self.test_dir])
221
 
        self.run_bzr_captured(['mv', 'a', 'b'])
222
 
        self.run_bzr_captured(['mv', 'b', 'subdir'])
223
 
        self.run_bzr_captured(['mv', 'subdir/b', 'a'])
224
 
        self.run_bzr_captured(['mv', 'a', 'c', 'subdir'])
225
 
        self.run_bzr_captured(['mv', 'subdir/a', 'subdir/newa'])
 
162
        self.run_bzr('mv', 'a', 'b')
 
163
        self.run_bzr('mv', 'b', 'subdir')
 
164
        self.run_bzr('mv', 'subdir/b', 'a')
 
165
        self.run_bzr('mv', 'a', 'b', 'subdir')
 
166
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
226
167
 
227
168
    def test_main_version(self):
228
169
        """Check output from version command and master option is reasonable"""
239
180
        self.log(tmp_output)
240
181
        self.assertEquals(output, tmp_output)
241
182
 
242
 
    def example_branch(test):
243
 
        test.runbzr('init')
244
 
        file('hello', 'wt').write('foo')
245
 
        test.runbzr('add hello')
246
 
        test.runbzr('commit -m setup hello')
247
 
        file('goodbye', 'wt').write('baz')
248
 
        test.runbzr('add goodbye')
249
 
        test.runbzr('commit -m setup goodbye')
250
 
 
251
 
    def test_export(self):
252
 
        os.mkdir('branch')
253
 
        os.chdir('branch')
254
 
        self.example_branch()
255
 
        self.runbzr('export ../latest')
256
 
        self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
257
 
        self.runbzr('export ../first -r 1')
258
 
        assert not os.path.exists('../first/goodbye')
259
 
        self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
260
 
        self.runbzr('export ../first.gz -r 1')
261
 
        self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
262
 
        self.runbzr('export ../first.bz2 -r 1')
263
 
        self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
264
 
        self.runbzr('export ../first.tar -r 1')
265
 
        assert os.path.isfile('../first.tar')
266
 
        from tarfile import TarFile
267
 
        tf = TarFile('../first.tar')
268
 
        assert 'first/hello' in tf.getnames(), tf.getnames()
269
 
        self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
270
 
        self.runbzr('export ../first.tar.gz -r 1')
271
 
        assert os.path.isfile('../first.tar.gz')
272
 
        self.runbzr('export ../first.tbz2 -r 1')
273
 
        assert os.path.isfile('../first.tbz2')
274
 
        self.runbzr('export ../first.tar.bz2 -r 1')
275
 
        assert os.path.isfile('../first.tar.bz2')
276
 
        self.runbzr('export ../first.tar.tbz2 -r 1')
277
 
        assert os.path.isfile('../first.tar.tbz2')
278
 
        from bz2 import BZ2File
279
 
        tf = TarFile('../first.tar.tbz2', 
280
 
                     fileobj=BZ2File('../first.tar.tbz2', 'r'))
281
 
        assert 'first.tar/hello' in tf.getnames(), tf.getnames()
282
 
        self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
283
 
        self.runbzr('export ../first2.tar -r 1 --root pizza')
284
 
        tf = TarFile('../first2.tar')
285
 
        assert 'pizza/hello' in tf.getnames(), tf.getnames()
286
 
 
287
 
    def test_diff(self):
288
 
        self.example_branch()
289
 
        file('hello', 'wt').write('hello world!')
290
 
        self.runbzr('commit -m fixing hello')
291
 
        output = self.runbzr('diff -r 2..3', backtick=1, retcode=1)
292
 
        self.assert_('\n+hello world!' in output)
293
 
        output = self.runbzr('diff -r last:3..last:1', backtick=1, retcode=1)
294
 
        self.assert_('\n+baz' in output)
295
 
 
296
 
    def test_diff_branches(self):
297
 
        self.build_tree(['branch1/', 'branch1/file', 'branch2/'])
298
 
        branch = Branch.initialize('branch1')
299
 
        branch.add(['file'])
300
 
        branch.commit('add file')
301
 
        copy_branch(branch, 'branch2')
302
 
        print >> open('branch2/file', 'w'), 'new content'
303
 
        branch2 = Branch.open('branch2')
304
 
        branch2.commit('update file')
305
 
        # should open branch1 and diff against branch2, 
306
 
        output = self.run_bzr_captured(['diff', '-r', 'branch:branch2', 
307
 
                                        'branch1'],
308
 
                                       retcode=1)
309
 
        self.assertEquals(("=== modified file 'file'\n"
310
 
                           "--- file\n"
311
 
                           "+++ file\n"
312
 
                           "@@ -1,1 +1,1 @@\n"
313
 
                           "-new content\n"
314
 
                           "+contents of branch1/file\n"
315
 
                           "\n", ''), output)
316
 
 
317
 
    def test_branch(self):
318
 
        """Branch from one branch to another."""
319
 
        os.mkdir('a')
320
 
        os.chdir('a')
321
 
        self.example_branch()
322
 
        os.chdir('..')
323
 
        self.runbzr('branch a b')
324
 
        self.assertFileEqual('b\n', 'b/.bzr/branch-name')
325
 
        self.runbzr('branch a c -r 1')
326
 
        os.chdir('b')
327
 
        self.runbzr('commit -m foo --unchanged')
328
 
        os.chdir('..')
329
 
        # naughty - abstraction violations RBC 20050928  
330
 
        print "test_branch used to delete the stores, how is this meant to work ?"
331
 
        #shutil.rmtree('a/.bzr/revision-store')
332
 
        #shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
333
 
        #shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
334
 
        self.runbzr('branch a d --basis b')
335
 
 
336
 
    def test_merge(self):
337
 
        from bzrlib.branch import Branch
338
 
        
339
 
        os.mkdir('a')
340
 
        os.chdir('a')
341
 
        self.example_branch()
342
 
        os.chdir('..')
343
 
        self.runbzr('branch a b')
344
 
        os.chdir('b')
345
 
        file('goodbye', 'wt').write('quux')
346
 
        self.runbzr(['commit',  '-m',  "more u's are always good"])
347
 
 
348
 
        os.chdir('../a')
349
 
        file('hello', 'wt').write('quuux')
350
 
        # We can't merge when there are in-tree changes
351
 
        self.runbzr('merge ../b', retcode=1)
352
 
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
353
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
354
 
                    retcode=1)
355
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
356
 
        self.runbzr('revert --no-backup')
357
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
358
 
        self.runbzr('revert --no-backup')
359
 
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
360
 
        self.runbzr('revert --no-backup')
361
 
        self.runbzr('merge ../b -r last:1')
362
 
        self.check_file_contents('goodbye', 'quux')
363
 
        # Merging a branch pulls its revision into the tree
364
 
        a = Branch.open('.')
365
 
        b = Branch.open('../b')
366
 
        a.get_revision_xml(b.last_revision())
367
 
        self.log('pending merges: %s', a.pending_merges())
368
 
        assert a.pending_merges() == [b.last_revision()], "Assertion %s %s" \
369
 
            % (a.pending_merges(), b.last_patch())
370
 
        self.runbzr('commit -m merged')
371
 
        self.runbzr('merge ../b -r last:1')
372
 
        self.assertEqual(Branch.open('.').pending_merges(), [])
373
 
 
374
 
 
375
 
    def test_merge_with_missing_file(self):
376
 
        """Merge handles missing file conflicts"""
377
 
        os.mkdir('a')
378
 
        os.chdir('a')
379
 
        os.mkdir('sub')
380
 
        print >> file('sub/a.txt', 'wb'), "hello"
381
 
        print >> file('b.txt', 'wb'), "hello"
382
 
        print >> file('sub/c.txt', 'wb'), "hello"
383
 
        self.runbzr('init')
384
 
        self.runbzr('add')
385
 
        self.runbzr(('commit', '-m', 'added a'))
386
 
        self.runbzr('branch . ../b')
387
 
        print >> file('sub/a.txt', 'ab'), "there"
388
 
        print >> file('b.txt', 'ab'), "there"
389
 
        print >> file('sub/c.txt', 'ab'), "there"
390
 
        self.runbzr(('commit', '-m', 'Added there'))
391
 
        os.unlink('sub/a.txt')
392
 
        os.unlink('sub/c.txt')
393
 
        os.rmdir('sub')
394
 
        os.unlink('b.txt')
395
 
        self.runbzr(('commit', '-m', 'Removed a.txt'))
396
 
        os.chdir('../b')
397
 
        print >> file('sub/a.txt', 'ab'), "something"
398
 
        print >> file('b.txt', 'ab'), "something"
399
 
        print >> file('sub/c.txt', 'ab'), "something"
400
 
        self.runbzr(('commit', '-m', 'Modified a.txt'))
401
 
        self.runbzr('merge ../a/', retcode=1)
402
 
        assert os.path.exists('sub/a.txt.THIS')
403
 
        assert os.path.exists('sub/a.txt.BASE')
404
 
        os.chdir('../a')
405
 
        self.runbzr('merge ../b/', retcode=1)
406
 
        assert os.path.exists('sub/a.txt.OTHER')
407
 
        assert os.path.exists('sub/a.txt.BASE')
408
 
 
409
 
    def test_pull(self):
410
 
        """Pull changes from one branch to another."""
411
 
        os.mkdir('a')
412
 
        os.chdir('a')
413
 
 
414
 
        self.example_branch()
415
 
        self.runbzr('pull', retcode=1)
416
 
        self.runbzr('missing', retcode=1)
417
 
        self.runbzr('missing .')
418
 
        self.runbzr('missing')
419
 
        self.runbzr('pull')
420
 
        self.runbzr('pull /', retcode=1)
421
 
        self.runbzr('pull')
422
 
 
423
 
        os.chdir('..')
424
 
        self.runbzr('branch a b')
425
 
        os.chdir('b')
426
 
        self.runbzr('pull')
427
 
        os.mkdir('subdir')
428
 
        self.runbzr('add subdir')
429
 
        self.runbzr('commit -m blah --unchanged')
430
 
        os.chdir('../a')
431
 
        a = Branch.open('.')
432
 
        b = Branch.open('../b')
433
 
        assert a.revision_history() == b.revision_history()[:-1]
434
 
        self.runbzr('pull ../b')
435
 
        assert a.revision_history() == b.revision_history()
436
 
        self.runbzr('commit -m blah2 --unchanged')
437
 
        os.chdir('../b')
438
 
        self.runbzr('commit -m blah3 --unchanged')
439
 
        # no overwrite
440
 
        self.runbzr('pull ../a', retcode=1)
441
 
        os.chdir('..')
442
 
        self.runbzr('branch b overwriteme')
443
 
        os.chdir('overwriteme')
444
 
        self.runbzr('pull --overwrite ../a')
445
 
        overwritten = Branch.open('.')
446
 
        self.assertEqual(overwritten.revision_history(),
447
 
                         a.revision_history())
448
 
        os.chdir('../a')
449
 
        self.runbzr('merge ../b')
450
 
        self.runbzr('commit -m blah4 --unchanged')
451
 
        os.chdir('../b/subdir')
452
 
        self.runbzr('pull ../../a')
453
 
        assert a.revision_history()[-1] == b.revision_history()[-1]
454
 
        self.runbzr('commit -m blah5 --unchanged')
455
 
        self.runbzr('commit -m blah6 --unchanged')
456
 
        os.chdir('..')
457
 
        self.runbzr('pull ../a')
458
 
        os.chdir('../a')
459
 
        self.runbzr('commit -m blah7 --unchanged')
460
 
        self.runbzr('merge ../b')
461
 
        self.runbzr('commit -m blah8 --unchanged')
462
 
        self.runbzr('pull ../b')
463
 
        self.runbzr('pull ../b')
464
 
 
465
 
    def test_ls(self):
466
 
        """Test the abilities of 'bzr ls'"""
467
 
        bzr = self.runbzr
468
 
        def bzrout(*args, **kwargs):
469
 
            kwargs['backtick'] = True
470
 
            return self.runbzr(*args, **kwargs)
471
 
 
472
 
        def ls_equals(value, *args):
473
 
            out = self.runbzr(['ls'] + list(args), backtick=True)
474
 
            self.assertEquals(out, value)
475
 
 
476
 
        bzr('init')
477
 
        open('a', 'wb').write('hello\n')
478
 
 
479
 
        # Can't supply both
480
 
        bzr('ls --verbose --null', retcode=1)
481
 
 
482
 
        ls_equals('a\n')
483
 
        ls_equals('?        a\n', '--verbose')
484
 
        ls_equals('a\n', '--unknown')
485
 
        ls_equals('', '--ignored')
486
 
        ls_equals('', '--versioned')
487
 
        ls_equals('a\n', '--unknown', '--ignored', '--versioned')
488
 
        ls_equals('', '--ignored', '--versioned')
489
 
        ls_equals('a\0', '--null')
490
 
 
491
 
        bzr('add a')
492
 
        ls_equals('V        a\n', '--verbose')
493
 
        bzr('commit -m add')
494
 
        
495
 
        os.mkdir('subdir')
496
 
        ls_equals('V        a\n'
497
 
                  '?        subdir/\n'
498
 
                  , '--verbose')
499
 
        open('subdir/b', 'wb').write('b\n')
500
 
        bzr('add')
501
 
        ls_equals('V        a\n'
502
 
                  'V        subdir/\n'
503
 
                  'V        subdir/b\n'
504
 
                  , '--verbose')
505
 
        bzr('commit -m subdir')
506
 
 
507
 
        ls_equals('a\n'
508
 
                  'subdir\n'
509
 
                  , '--non-recursive')
510
 
 
511
 
        ls_equals('V        a\n'
512
 
                  'V        subdir/\n'
513
 
                  , '--verbose', '--non-recursive')
514
 
 
515
 
        # Check what happens in a sub-directory
516
 
        os.chdir('subdir')
517
 
        ls_equals('b\n')
518
 
        ls_equals('b\0'
519
 
                  , '--null')
520
 
        ls_equals('a\n'
521
 
                  'subdir\n'
522
 
                  'subdir/b\n'
523
 
                  , '--from-root')
524
 
        ls_equals('a\0'
525
 
                  'subdir\0'
526
 
                  'subdir/b\0'
527
 
                  , '--from-root', '--null')
528
 
        ls_equals('a\n'
529
 
                  'subdir\n'
530
 
                  , '--from-root', '--non-recursive')
531
 
 
532
 
        os.chdir('..')
533
 
 
534
 
        # Check what happens when we supply a specific revision
535
 
        ls_equals('a\n', '--revision', '1')
536
 
        ls_equals('V        a\n'
537
 
                  , '--verbose', '--revision', '1')
538
 
 
539
 
        os.chdir('subdir')
540
 
        ls_equals('', '--revision', '1')
541
 
 
542
 
        # Now try to do ignored files.
543
 
        os.chdir('..')
544
 
        open('blah.py', 'wb').write('unknown\n')
545
 
        open('blah.pyo', 'wb').write('ignored\n')
546
 
        ls_equals('a\n'
547
 
                  'blah.py\n'
548
 
                  'blah.pyo\n'
549
 
                  'subdir\n'
550
 
                  'subdir/b\n')
551
 
        ls_equals('V        a\n'
552
 
                  '?        blah.py\n'
553
 
                  'I        blah.pyo\n'
554
 
                  'V        subdir/\n'
555
 
                  'V        subdir/b\n'
556
 
                  , '--verbose')
557
 
        ls_equals('blah.pyo\n'
558
 
                  , '--ignored')
559
 
        ls_equals('blah.py\n'
560
 
                  , '--unknown')
561
 
        ls_equals('a\n'
562
 
                  'subdir\n'
563
 
                  'subdir/b\n'
564
 
                  , '--versioned')
565
 
 
566
 
 
567
 
    def test_locations(self):
568
 
        """Using and remembering different locations"""
569
 
        os.mkdir('a')
570
 
        os.chdir('a')
571
 
        self.runbzr('init')
572
 
        self.runbzr('commit -m unchanged --unchanged')
573
 
        self.runbzr('pull', retcode=1)
574
 
        self.runbzr('merge', retcode=1)
575
 
        self.runbzr('branch . ../b')
576
 
        os.chdir('../b')
577
 
        self.runbzr('pull')
578
 
        self.runbzr('branch . ../c')
579
 
        self.runbzr('pull ../c')
580
 
        self.runbzr('merge')
581
 
        os.chdir('../a')
582
 
        self.runbzr('pull ../b')
583
 
        self.runbzr('pull')
584
 
        self.runbzr('pull ../c')
585
 
        self.runbzr('branch ../c ../d')
586
 
        shutil.rmtree('../c')
587
 
        self.runbzr('pull')
588
 
        os.chdir('../b')
589
 
        self.runbzr('pull')
590
 
        os.chdir('../d')
591
 
        self.runbzr('pull', retcode=1)
592
 
        self.runbzr('pull ../a --remember')
593
 
        self.runbzr('pull')
594
 
        
595
 
    def test_add_reports(self):
596
 
        """add command prints the names of added files."""
597
 
        b = Branch.initialize('.')
598
 
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
599
 
        out = self.run_bzr_captured(['add'], retcode = 0)[0]
600
 
        # the ordering is not defined at the moment
601
 
        results = sorted(out.rstrip('\n').split('\n'))
602
 
        self.assertEquals(['added dir',
603
 
                           'added dir'+os.sep+'sub.txt',
604
 
                           'added top.txt',],
605
 
                          results)
606
 
 
607
 
    def test_add_quiet_is(self):
608
 
        """add -q does not print the names of added files."""
609
 
        b = Branch.initialize('.')
610
 
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
611
 
        out = self.run_bzr_captured(['add', '-q'], retcode = 0)[0]
612
 
        # the ordering is not defined at the moment
613
 
        results = sorted(out.rstrip('\n').split('\n'))
614
 
        self.assertEquals([''], results)
615
 
 
616
 
    def test_unknown_command(self):
617
 
        """Handling of unknown command."""
618
 
        out, err = self.run_bzr_captured(['fluffy-badger'],
619
 
                                         retcode=1)
620
 
        self.assertEquals(out, '')
621
 
        err.index('unknown command')
622
 
 
623
 
    def test_conflicts(self):
624
 
        """Handling of merge conflicts"""
625
 
        os.mkdir('base')
626
 
        os.chdir('base')
627
 
        file('hello', 'wb').write("hi world")
628
 
        file('answer', 'wb').write("42")
629
 
        self.runbzr('init')
630
 
        self.runbzr('add')
631
 
        self.runbzr('commit -m base')
632
 
        self.runbzr('branch . ../other')
633
 
        self.runbzr('branch . ../this')
634
 
        os.chdir('../other')
635
 
        file('hello', 'wb').write("Hello.")
636
 
        file('answer', 'wb').write("Is anyone there?")
637
 
        self.runbzr('commit -m other')
638
 
        os.chdir('../this')
639
 
        file('hello', 'wb').write("Hello, world")
640
 
        self.runbzr('mv answer question')
641
 
        file('question', 'wb').write("What do you get when you multiply six"
642
 
                                   "times nine?")
643
 
        self.runbzr('commit -m this')
644
 
        self.runbzr('merge ../other --show-base', retcode=1)
645
 
        conflict_text = file('hello').read()
646
 
        assert '<<<<<<<' in conflict_text
647
 
        assert '>>>>>>>' in conflict_text
648
 
        assert '=======' in conflict_text
649
 
        assert '|||||||' in conflict_text
650
 
        assert 'hi world' in conflict_text
651
 
        self.runbzr('revert')
652
 
        self.runbzr('resolve --all')
653
 
        self.runbzr('merge ../other', retcode=1)
654
 
        conflict_text = file('hello').read()
655
 
        assert '|||||||' not in conflict_text
656
 
        assert 'hi world' not in conflict_text
657
 
        result = self.runbzr('conflicts', backtick=1)
658
 
        self.assertEquals(result, "hello\nquestion\n")
659
 
        result = self.runbzr('status', backtick=1)
660
 
        assert "conflicts:\n  hello\n  question\n" in result, result
661
 
        self.runbzr('resolve hello')
662
 
        result = self.runbzr('conflicts', backtick=1)
663
 
        self.assertEquals(result, "question\n")
664
 
        self.runbzr('commit -m conflicts', retcode=1)
665
 
        self.runbzr('resolve --all')
666
 
        result = self.runbzr('conflicts', backtick=1)
667
 
        self.runbzr('commit -m conflicts')
668
 
        self.assertEquals(result, "")
669
 
 
670
 
    def test_resign(self):
671
 
        """Test re signing of data."""
672
 
        import bzrlib.gpg
673
 
        oldstrategy = bzrlib.gpg.GPGStrategy
674
 
        branch = Branch.initialize('.')
675
 
        branch.commit("base", allow_pointless=True, rev_id='A')
676
 
        try:
677
 
            # monkey patch gpg signing mechanism
678
 
            from bzrlib.testament import Testament
679
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
680
 
            self.runbzr('re-sign -r revid:A')
681
 
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
682
 
                             branch.revision_store.get('A', 'sig').read())
683
 
        finally:
684
 
            bzrlib.gpg.GPGStrategy = oldstrategy
685
 
            
686
 
    def test_resign_range(self):
687
 
        import bzrlib.gpg
688
 
        oldstrategy = bzrlib.gpg.GPGStrategy
689
 
        branch = Branch.initialize('.')
690
 
        branch.commit("base", allow_pointless=True, rev_id='A')
691
 
        branch.commit("base", allow_pointless=True, rev_id='B')
692
 
        branch.commit("base", allow_pointless=True, rev_id='C')
693
 
        try:
694
 
            # monkey patch gpg signing mechanism
695
 
            from bzrlib.testament import Testament
696
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
697
 
            self.runbzr('re-sign -r 1..')
698
 
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
699
 
                             branch.revision_store.get('A', 'sig').read())
700
 
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
701
 
                             branch.revision_store.get('B', 'sig').read())
702
 
            self.assertEqual(Testament.from_revision(branch,'C').as_short_text(),
703
 
                             branch.revision_store.get('C', 'sig').read())
704
 
        finally:
705
 
            bzrlib.gpg.GPGStrategy = oldstrategy
706
 
 
707
 
    def test_push(self):
708
 
        # create a source branch
709
 
        os.mkdir('my-branch')
710
 
        os.chdir('my-branch')
711
 
        self.example_branch()
712
 
 
713
 
        # with no push target, fail
714
 
        self.runbzr('push', retcode=1)
715
 
        # with an explicit target work
716
 
        self.runbzr('push ../output-branch')
717
 
        # with an implicit target work
718
 
        self.runbzr('push')
719
 
        # nothing missing
720
 
        self.runbzr('missing ../output-branch')
721
 
        # advance this branch
722
 
        self.runbzr('commit --unchanged -m unchanged')
723
 
 
724
 
        os.chdir('../output-branch')
725
 
        # should be a diff as we have not pushed the tree
726
 
        self.runbzr('diff', retcode=1)
727
 
        self.runbzr('revert')
728
 
        # but not now.
729
 
        self.runbzr('diff')
730
 
        # diverge the branches
731
 
        self.runbzr('commit --unchanged -m unchanged')
732
 
        os.chdir('../my-branch')
733
 
        # cannot push now
734
 
        self.runbzr('push', retcode=1)
735
 
        # and there are difference
736
 
        self.runbzr('missing ../output-branch', retcode=1)
737
 
        # but we can force a push
738
 
        self.runbzr('push --overwrite')
739
 
        # nothing missing
740
 
        self.runbzr('missing ../output-branch')
741
 
 
742
 
 
743
 
def listdir_sorted(dir):
744
 
    L = os.listdir(dir)
745
 
    L.sort()
746
 
    return L
747
 
 
748
 
 
749
183
class OldTests(ExternalBase):
750
 
    """old tests moved from ./testbzr."""
751
 
 
 
184
    # old tests moved from ./testbzr
752
185
    def test_bzr(self):
753
186
        from os import chdir, mkdir
754
187
        from os.path import exists
 
188
        import os
755
189
 
756
190
        runbzr = self.runbzr
757
 
        capture = self.capture
 
191
        backtick = self.backtick
758
192
        progress = self.log
759
193
 
760
194
        progress("basic branch creation")
762
196
        chdir('branch1')
763
197
        runbzr('init')
764
198
 
765
 
        self.assertEquals(capture('root').rstrip(),
 
199
        self.assertEquals(backtick('bzr root').rstrip(),
766
200
                          os.path.join(self.test_dir, 'branch1'))
767
201
 
768
202
        progress("status of new file")
771
205
        f.write('hello world!\n')
772
206
        f.close()
773
207
 
774
 
        self.assertEquals(capture('unknowns'), 'test.txt\n')
 
208
        out = backtick("bzr unknowns")
 
209
        self.assertEquals(out, 'test.txt\n')
775
210
 
776
 
        out = capture("status")
 
211
        out = backtick("bzr status")
777
212
        assert out == 'unknown:\n  test.txt\n'
778
213
 
779
 
        out = capture("status --all")
 
214
        out = backtick("bzr status --all")
780
215
        assert out == "unknown:\n  test.txt\n"
781
216
 
782
 
        out = capture("status test.txt --all")
 
217
        out = backtick("bzr status test.txt --all")
783
218
        assert out == "unknown:\n  test.txt\n"
784
219
 
785
220
        f = file('test2.txt', 'wt')
786
221
        f.write('goodbye cruel world...\n')
787
222
        f.close()
788
223
 
789
 
        out = capture("status test.txt")
 
224
        out = backtick("bzr status test.txt")
790
225
        assert out == "unknown:\n  test.txt\n"
791
226
 
792
 
        out = capture("status")
 
227
        out = backtick("bzr status")
793
228
        assert out == ("unknown:\n"
794
229
                       "  test.txt\n"
795
230
                       "  test2.txt\n")
797
232
        os.unlink('test2.txt')
798
233
 
799
234
        progress("command aliases")
800
 
        out = capture("st --all")
 
235
        out = backtick("bzr st --all")
801
236
        assert out == ("unknown:\n"
802
237
                       "  test.txt\n")
803
238
 
804
 
        out = capture("stat")
 
239
        out = backtick("bzr stat")
805
240
        assert out == ("unknown:\n"
806
241
                       "  test.txt\n")
807
242
 
811
246
        runbzr("help commands")
812
247
        runbzr("help slartibartfast", 1)
813
248
 
814
 
        out = capture("help ci")
 
249
        out = backtick("bzr help ci")
815
250
        out.index('aliases: ')
816
251
 
817
252
        progress("can't rename unversioned file")
820
255
        progress("adding a file")
821
256
 
822
257
        runbzr("add test.txt")
823
 
        assert capture("unknowns") == ''
824
 
        assert capture("status --all") == ("added:\n"
 
258
        assert backtick("bzr unknowns") == ''
 
259
        assert backtick("bzr status --all") == ("added:\n"
825
260
                                                "  test.txt\n")
826
261
 
827
262
        progress("rename newly-added file")
829
264
        assert os.path.exists("hello.txt")
830
265
        assert not os.path.exists("test.txt")
831
266
 
832
 
        assert capture("revno") == '0\n'
 
267
        assert backtick("bzr revno") == '0\n'
833
268
 
834
269
        progress("add first revision")
835
270
        runbzr(['commit', '-m', 'add first revision'])
843
278
        runbzr("add sub1")
844
279
        runbzr("rename sub1 sub2")
845
280
        runbzr("move hello.txt sub2")
846
 
        self.assertEqual(capture("relpath sub2/hello.txt"),
847
 
                         os.path.join("sub2", "hello.txt\n"))
 
281
        assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
848
282
 
849
283
        assert exists("sub2")
850
284
        assert exists("sub2/hello.txt")
865
299
        runbzr(['commit', '-m', 'rename nested subdirectories'])
866
300
 
867
301
        chdir('sub1/sub2')
868
 
        self.assertEquals(capture('root')[:-1],
 
302
        self.assertEquals(backtick('bzr root')[:-1],
869
303
                          os.path.join(self.test_dir, 'branch1'))
870
304
        runbzr('move ../hello.txt .')
871
305
        assert exists('./hello.txt')
872
 
        self.assertEquals(capture('relpath hello.txt'),
873
 
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
874
 
        assert capture('relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
306
        assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
307
        assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
875
308
        runbzr(['commit', '-m', 'move to parent directory'])
876
309
        chdir('..')
877
 
        assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
310
        assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
878
311
 
879
312
        runbzr('move sub2/hello.txt .')
880
313
        assert exists('hello.txt')
884
317
        f.close()
885
318
 
886
319
        f = file('msg.tmp', 'wt')
887
 
        f.write('this is my new commit\nand it has multiple lines, for fun')
 
320
        f.write('this is my new commit\n')
888
321
        f.close()
889
322
 
890
323
        runbzr('commit -F msg.tmp')
891
324
 
892
 
        assert capture('revno') == '5\n'
 
325
        assert backtick('bzr revno') == '5\n'
893
326
        runbzr('export -r 5 export-5.tmp')
894
327
        runbzr('export export.tmp')
895
328
 
897
330
        runbzr('log -v')
898
331
        runbzr('log -v --forward')
899
332
        runbzr('log -m', retcode=1)
900
 
        log_out = capture('log -m commit')
901
 
        assert "this is my new commit\n  and" in log_out
 
333
        log_out = backtick('bzr log -m commit')
 
334
        assert "this is my new commit" in log_out
902
335
        assert "rename nested" not in log_out
903
336
        assert 'revision-id' not in log_out
904
 
        assert 'revision-id' in capture('log --show-ids -m commit')
905
 
 
906
 
        log_out = capture('log --line')
907
 
        for line in log_out.splitlines():
908
 
            assert len(line) <= 79, len(line)
909
 
        assert "this is my new commit and" in log_out
 
337
        assert 'revision-id' in backtick('bzr log --show-ids -m commit')
910
338
 
911
339
 
912
340
        progress("file with spaces in name")
913
341
        mkdir('sub directory')
914
342
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
915
343
        runbzr('add .')
916
 
        runbzr('diff', retcode=1)
 
344
        runbzr('diff')
917
345
        runbzr('commit -m add-spaces')
918
346
        runbzr('check')
919
347
 
922
350
 
923
351
        runbzr('info')
924
352
 
925
 
        if has_symlinks():
926
 
            progress("symlinks")
927
 
            mkdir('symlinks')
928
 
            chdir('symlinks')
929
 
            runbzr('init')
930
 
            os.symlink("NOWHERE1", "link1")
931
 
            runbzr('add link1')
932
 
            assert self.capture('unknowns') == ''
933
 
            runbzr(['commit', '-m', '1: added symlink link1'])
934
 
    
935
 
            mkdir('d1')
936
 
            runbzr('add d1')
937
 
            assert self.capture('unknowns') == ''
938
 
            os.symlink("NOWHERE2", "d1/link2")
939
 
            assert self.capture('unknowns') == 'd1/link2\n'
940
 
            # is d1/link2 found when adding d1
941
 
            runbzr('add d1')
942
 
            assert self.capture('unknowns') == ''
943
 
            os.symlink("NOWHERE3", "d1/link3")
944
 
            assert self.capture('unknowns') == 'd1/link3\n'
945
 
            runbzr(['commit', '-m', '2: added dir, symlink'])
946
 
    
947
 
            runbzr('rename d1 d2')
948
 
            runbzr('move d2/link2 .')
949
 
            runbzr('move link1 d2')
950
 
            assert os.readlink("./link2") == "NOWHERE2"
951
 
            assert os.readlink("d2/link1") == "NOWHERE1"
952
 
            runbzr('add d2/link3')
953
 
            runbzr('diff', retcode=1)
954
 
            runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
955
 
    
956
 
            os.unlink("link2")
957
 
            os.symlink("TARGET 2", "link2")
958
 
            os.unlink("d2/link1")
959
 
            os.symlink("TARGET 1", "d2/link1")
960
 
            runbzr('diff', retcode=1)
961
 
            assert self.capture("relpath d2/link1") == "d2/link1\n"
962
 
            runbzr(['commit', '-m', '4: retarget of two links'])
963
 
    
964
 
            runbzr('remove d2/link1')
965
 
            assert self.capture('unknowns') == 'd2/link1\n'
966
 
            runbzr(['commit', '-m', '5: remove d2/link1'])
967
 
            # try with the rm alias
968
 
            runbzr('add d2/link1')
969
 
            runbzr(['commit', '-m', '6: add d2/link1'])
970
 
            runbzr('rm d2/link1')
971
 
            assert self.capture('unknowns') == 'd2/link1\n'
972
 
            runbzr(['commit', '-m', '7: remove d2/link1'])
973
 
    
974
 
            os.mkdir("d1")
975
 
            runbzr('add d1')
976
 
            runbzr('rename d2/link3 d1/link3new')
977
 
            assert self.capture('unknowns') == 'd2/link1\n'
978
 
            runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
979
 
            
980
 
            runbzr(['check'])
981
 
            
982
 
            runbzr(['export', '-r', '1', 'exp1.tmp'])
983
 
            chdir("exp1.tmp")
984
 
            assert listdir_sorted(".") == [ "link1" ]
985
 
            assert os.readlink("link1") == "NOWHERE1"
986
 
            chdir("..")
987
 
            
988
 
            runbzr(['export', '-r', '2', 'exp2.tmp'])
989
 
            chdir("exp2.tmp")
990
 
            assert listdir_sorted(".") == [ "d1", "link1" ]
991
 
            chdir("..")
992
 
            
993
 
            runbzr(['export', '-r', '3', 'exp3.tmp'])
994
 
            chdir("exp3.tmp")
995
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
996
 
            assert listdir_sorted("d2") == [ "link1", "link3" ]
997
 
            assert os.readlink("d2/link1") == "NOWHERE1"
998
 
            assert os.readlink("link2")    == "NOWHERE2"
999
 
            chdir("..")
1000
 
            
1001
 
            runbzr(['export', '-r', '4', 'exp4.tmp'])
1002
 
            chdir("exp4.tmp")
1003
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
1004
 
            assert os.readlink("d2/link1") == "TARGET 1"
1005
 
            assert os.readlink("link2")    == "TARGET 2"
1006
 
            assert listdir_sorted("d2") == [ "link1", "link3" ]
1007
 
            chdir("..")
1008
 
            
1009
 
            runbzr(['export', '-r', '5', 'exp5.tmp'])
1010
 
            chdir("exp5.tmp")
1011
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
1012
 
            assert os.path.islink("link2")
1013
 
            assert listdir_sorted("d2")== [ "link3" ]
1014
 
            chdir("..")
1015
 
            
1016
 
            runbzr(['export', '-r', '8', 'exp6.tmp'])
1017
 
            chdir("exp6.tmp")
1018
 
            self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
1019
 
            assert listdir_sorted("d1") == [ "link3new" ]
1020
 
            assert listdir_sorted("d2") == []
1021
 
            assert os.readlink("d1/link3new") == "NOWHERE3"
1022
 
            chdir("..")
1023
 
        else:
1024
 
            progress("skipping symlink tests")
1025
 
 
1026
 
 
1027
 
class HttpTests(TestCaseWithWebserver):
1028
 
    """Test bzr ui commands against remote branches."""
1029
 
 
1030
 
    def test_branch(self):
1031
 
        os.mkdir('from')
1032
 
        branch = Branch.initialize('from')
1033
 
        branch.commit('empty commit for nonsense', allow_pointless=True)
1034
 
        url = self.get_remote_url('from')
1035
 
        self.run_bzr('branch', url, 'to')
1036
 
        branch = Branch.open('to')
1037
 
        self.assertEqual(1, len(branch.revision_history()))
1038
 
 
1039
 
    def test_log(self):
1040
 
        self.build_tree(['branch/', 'branch/file'])
1041
 
        branch = Branch.initialize('branch')
1042
 
        branch.add(['file'])
1043
 
        branch.commit('add file', rev_id='A')
1044
 
        url = self.get_remote_url('branch/file')
1045
 
        output = self.capture('log %s' % url)
1046
 
        self.assertEqual(7, len(output.split('\n')))
1047
 
        
1048
 
 
1049
 
 
 
353
 
 
354
 
 
355
def example_branch(test):
 
356
    test.runbzr('init')
 
357
 
 
358
    file('hello', 'wt').write('foo')
 
359
    test.runbzr('add hello')
 
360
    test.runbzr('commit -m setup hello')
 
361
 
 
362
    file('goodbye', 'wt').write('baz')
 
363
    test.runbzr('add goodbye')
 
364
    test.runbzr('commit -m setup goodbye')
 
365
 
 
366
 
 
367
class RevertCommand(ExternalBase):
 
368
    def runTest(self):
 
369
        example_branch(self)
 
370
        file('hello', 'wt').write('bar')
 
371
        file('goodbye', 'wt').write('qux')
 
372
        self.runbzr('revert hello')
 
373
        self.check_file_contents('hello', 'foo')
 
374
        self.check_file_contents('goodbye', 'qux')
 
375
        self.runbzr('revert')
 
376
        self.check_file_contents('goodbye', 'baz')
 
377
 
 
378
 
 
379
class MergeCommand(ExternalBase):
 
380
    def runTest(self):
 
381
        from bzrlib.branch import Branch
 
382
        import os
 
383
        os.mkdir('a')
 
384
        os.chdir('a')
 
385
        example_branch(self)
 
386
        os.chdir('..')
 
387
        self.runbzr('branch a b')
 
388
        os.chdir('b')
 
389
        file('goodbye', 'wt').write('quux')
 
390
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
391
 
 
392
        os.chdir('../a')
 
393
        file('hello', 'wt').write('quuux')
 
394
        # We can't merge when there are in-tree changes
 
395
        self.runbzr('merge ../b', retcode=1)
 
396
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
397
        self.runbzr('merge ../b')
 
398
        self.check_file_contents('goodbye', 'quux')
 
399
        # Merging a branch pulls its revision into the tree
 
400
        a = Branch('.')
 
401
        b = Branch('../b')
 
402
        a.get_revision_xml(b.last_patch())
 
403
        print "Pending: %s" % a.pending_merges()
 
404
#        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
 
405
#        % (a.pending_merges(), b.last_patch())
1050
406