/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/selftest/blackbox.py

[merge] basic_io metaformat (mbp)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
 
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
 
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
 
 
19
"""Black-box tests for bzr.
 
20
 
 
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.
 
24
"""
 
25
 
 
26
 
 
27
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
28
# Note: Please don't add new tests here, it's too big and bulky.  Instead add
 
29
# them into small suites for the particular function that's tested.
 
30
 
 
31
 
 
32
from cStringIO import StringIO
 
33
import os
 
34
import re
 
35
import shutil
 
36
import sys
 
37
 
 
38
from bzrlib.branch import Branch
 
39
from bzrlib.clone import copy_branch
 
40
from bzrlib.errors import BzrCommandError
 
41
from bzrlib.osutils import has_symlinks
 
42
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
 
43
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
 
44
 
 
45
 
 
46
class ExternalBase(TestCaseInTempDir):
 
47
 
 
48
    def runbzr(self, args, retcode=0, backtick=False):
 
49
        if isinstance(args, basestring):
 
50
            args = args.split()
 
51
 
 
52
        if backtick:
 
53
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
54
        else:
 
55
            return self.run_bzr_captured(args, retcode=retcode)
 
56
 
 
57
 
 
58
class TestCommands(ExternalBase):
 
59
 
 
60
    def test_help_commands(self):
 
61
        self.runbzr('--help')
 
62
        self.runbzr('help')
 
63
        self.runbzr('help commands')
 
64
        self.runbzr('help help')
 
65
        self.runbzr('commit -h')
 
66
 
 
67
    def test_init_branch(self):
 
68
        self.runbzr(['init'])
 
69
 
 
70
        # Can it handle subdirectories as well?
 
71
        self.runbzr('init subdir1')
 
72
        self.assert_(os.path.exists('subdir1'))
 
73
        self.assert_(os.path.exists('subdir1/.bzr'))
 
74
 
 
75
        self.runbzr('init subdir2/nothere', retcode=3)
 
76
        
 
77
        os.mkdir('subdir2')
 
78
        self.runbzr('init subdir2')
 
79
        self.runbzr('init subdir2', retcode=3)
 
80
 
 
81
        self.runbzr('init subdir2/subsubdir1')
 
82
        self.assert_(os.path.exists('subdir2/subsubdir1/.bzr'))
 
83
 
 
84
    def test_whoami(self):
 
85
        # this should always identify something, if only "john@localhost"
 
86
        self.runbzr("whoami")
 
87
        self.runbzr("whoami --email")
 
88
 
 
89
        self.assertEquals(self.runbzr("whoami --email",
 
90
                                      backtick=True).count('@'), 1)
 
91
        
 
92
    def test_whoami_branch(self):
 
93
        """branch specific user identity works."""
 
94
        self.runbzr('init')
 
95
        f = file('.bzr/email', 'wt')
 
96
        f.write('Branch Identity <branch@identi.ty>')
 
97
        f.close()
 
98
        bzr_email = os.environ.get('BZREMAIL')
 
99
        if bzr_email is not None:
 
100
            del os.environ['BZREMAIL']
 
101
        whoami = self.runbzr("whoami",backtick=True)
 
102
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
103
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
 
104
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
 
105
        # Verify that the environment variable overrides the value 
 
106
        # in the file
 
107
        os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
 
108
        whoami = self.runbzr("whoami",backtick=True)
 
109
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
110
        self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
 
111
        self.assertTrue(whoami_email.startswith('other@environ.ment'))
 
112
        if bzr_email is not None:
 
113
            os.environ['BZREMAIL'] = bzr_email
 
114
 
 
115
    def test_nick_command(self):
 
116
        """bzr nick for viewing, setting nicknames"""
 
117
        os.mkdir('me.dev')
 
118
        os.chdir('me.dev')
 
119
        self.runbzr('init')
 
120
        nick = self.runbzr("nick",backtick=True)
 
121
        self.assertEqual(nick, 'me.dev\n')
 
122
        nick = self.runbzr("nick moo")
 
123
        nick = self.runbzr("nick",backtick=True)
 
124
        self.assertEqual(nick, 'moo\n')
 
125
 
 
126
 
 
127
    def test_invalid_commands(self):
 
128
        self.runbzr("pants", retcode=3)
 
129
        self.runbzr("--pants off", retcode=3)
 
130
        self.runbzr("diff --message foo", retcode=3)
 
131
 
 
132
    def test_empty_commit(self):
 
133
        self.runbzr("init")
 
134
        self.build_tree(['hello.txt'])
 
135
        self.runbzr("commit -m empty", retcode=3)
 
136
        self.runbzr("add hello.txt")
 
137
        self.runbzr("commit -m added")       
 
138
 
 
139
    def test_empty_commit_message(self):
 
140
        self.runbzr("init")
 
141
        file('foo.c', 'wt').write('int main() {}')
 
142
        self.runbzr(['add', 'foo.c'])
 
143
        self.runbzr(["commit", "-m", ""] , retcode=3) 
 
144
 
 
145
    def test_remove_deleted(self):
 
146
        self.runbzr("init")
 
147
        self.build_tree(['a'])
 
148
        self.runbzr(['add', 'a'])
 
149
        self.runbzr(['commit', '-m', 'added a'])
 
150
        os.unlink('a')
 
151
        self.runbzr(['remove', 'a'])
 
152
 
 
153
    def test_other_branch_commit(self):
 
154
        # this branch is to ensure consistent behaviour, whether we're run
 
155
        # inside a branch, or not.
 
156
        os.mkdir('empty_branch')
 
157
        os.chdir('empty_branch')
 
158
        self.runbzr('init')
 
159
        os.mkdir('branch')
 
160
        os.chdir('branch')
 
161
        self.runbzr('init')
 
162
        file('foo.c', 'wt').write('int main() {}')
 
163
        file('bar.c', 'wt').write('int main() {}')
 
164
        os.chdir('..')
 
165
        self.runbzr(['add', 'branch/foo.c'])
 
166
        self.runbzr(['add', 'branch'])
 
167
        # can't commit files in different trees; sane error
 
168
        self.runbzr('commit -m newstuff branch/foo.c .', retcode=3)
 
169
        self.runbzr('commit -m newstuff branch/foo.c')
 
170
        self.runbzr('commit -m newstuff branch')
 
171
        self.runbzr('commit -m newstuff branch', retcode=3)
 
172
 
 
173
    def test_ignore_patterns(self):
 
174
        from bzrlib.branch import Branch
 
175
        Branch.initialize('.')
 
176
        self.assertEquals(self.capture('unknowns'), '')
 
177
 
 
178
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
179
        self.assertEquals(self.capture('unknowns'), '')
 
180
 
 
181
        file('foo.c', 'wt').write('int main() {}')
 
182
        self.assertEquals(self.capture('unknowns'), 'foo.c\n')
 
183
 
 
184
        self.runbzr(['add', 'foo.c'])
 
185
        self.assertEquals(self.capture('unknowns'), '')
 
186
 
 
187
        # 'ignore' works when creating the .bzignore file
 
188
        file('foo.blah', 'wt').write('blah')
 
189
        self.assertEquals(self.capture('unknowns'), 'foo.blah\n')
 
190
        self.runbzr('ignore *.blah')
 
191
        self.assertEquals(self.capture('unknowns'), '')
 
192
        self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\n')
 
193
 
 
194
        # 'ignore' works when then .bzrignore file already exists
 
195
        file('garh', 'wt').write('garh')
 
196
        self.assertEquals(self.capture('unknowns'), 'garh\n')
 
197
        self.runbzr('ignore garh')
 
198
        self.assertEquals(self.capture('unknowns'), '')
 
199
        self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\ngarh\n')
 
200
 
 
201
    def test_revert(self):
 
202
        self.runbzr('init')
 
203
 
 
204
        file('hello', 'wt').write('foo')
 
205
        self.runbzr('add hello')
 
206
        self.runbzr('commit -m setup hello')
 
207
 
 
208
        file('goodbye', 'wt').write('baz')
 
209
        self.runbzr('add goodbye')
 
210
        self.runbzr('commit -m setup goodbye')
 
211
 
 
212
        file('hello', 'wt').write('bar')
 
213
        file('goodbye', 'wt').write('qux')
 
214
        self.runbzr('revert hello')
 
215
        self.check_file_contents('hello', 'foo')
 
216
        self.check_file_contents('goodbye', 'qux')
 
217
        self.runbzr('revert')
 
218
        self.check_file_contents('goodbye', 'baz')
 
219
 
 
220
        os.mkdir('revertdir')
 
221
        self.runbzr('add revertdir')
 
222
        self.runbzr('commit -m f')
 
223
        os.rmdir('revertdir')
 
224
        self.runbzr('revert')
 
225
 
 
226
        os.symlink('/unlikely/to/exist', 'symlink')
 
227
        self.runbzr('add symlink')
 
228
        self.runbzr('commit -m f')
 
229
        os.unlink('symlink')
 
230
        self.runbzr('revert')
 
231
        self.failUnlessExists('symlink')
 
232
        os.unlink('symlink')
 
233
        os.symlink('a-different-path', 'symlink')
 
234
        self.runbzr('revert')
 
235
        self.assertEqual('/unlikely/to/exist',
 
236
                         os.readlink('symlink'))
 
237
        
 
238
        file('hello', 'wt').write('xyz')
 
239
        self.runbzr('commit -m xyz hello')
 
240
        self.runbzr('revert -r 1 hello')
 
241
        self.check_file_contents('hello', 'foo')
 
242
        self.runbzr('revert hello')
 
243
        self.check_file_contents('hello', 'xyz')
 
244
        os.chdir('revertdir')
 
245
        self.runbzr('revert')
 
246
        os.chdir('..')
 
247
 
 
248
    def test_status(self):
 
249
        self.runbzr("init")
 
250
        self.build_tree(['hello.txt'])
 
251
        result = self.runbzr("status")
 
252
        self.assert_("unknown:\n  hello.txt\n" in result, result)
 
253
        self.runbzr("add hello.txt")
 
254
        result = self.runbzr("status")
 
255
        self.assert_("added:\n  hello.txt\n" in result, result)
 
256
        self.runbzr("commit -m added")
 
257
        result = self.runbzr("status -r 0..1")
 
258
        self.assert_("added:\n  hello.txt\n" in result, result)
 
259
        self.build_tree(['world.txt'])
 
260
        result = self.runbzr("status -r 0")
 
261
        self.assert_("added:\n  hello.txt\n" \
 
262
                     "unknown:\n  world.txt\n" in result, result)
 
263
 
 
264
    def test_mv_modes(self):
 
265
        """Test two modes of operation for mv"""
 
266
        from bzrlib.branch import Branch
 
267
        b = Branch.initialize('.')
 
268
        self.build_tree(['a', 'c', 'subdir/'])
 
269
        self.run_bzr_captured(['add', self.test_dir])
 
270
        self.run_bzr_captured(['mv', 'a', 'b'])
 
271
        self.run_bzr_captured(['mv', 'b', 'subdir'])
 
272
        self.run_bzr_captured(['mv', 'subdir/b', 'a'])
 
273
        self.run_bzr_captured(['mv', 'a', 'c', 'subdir'])
 
274
        self.run_bzr_captured(['mv', 'subdir/a', 'subdir/newa'])
 
275
 
 
276
    def test_main_version(self):
 
277
        """Check output from version command and master option is reasonable"""
 
278
        # output is intentionally passed through to stdout so that we
 
279
        # can see the version being tested
 
280
        output = self.runbzr('version', backtick=1)
 
281
        self.log('bzr version output:')
 
282
        self.log(output)
 
283
        self.assert_(output.startswith('bzr (bazaar-ng) '))
 
284
        self.assertNotEqual(output.index('Canonical'), -1)
 
285
        # make sure --version is consistent
 
286
        tmp_output = self.runbzr('--version', backtick=1)
 
287
        self.log('bzr --version output:')
 
288
        self.log(tmp_output)
 
289
        self.assertEquals(output, tmp_output)
 
290
 
 
291
    def example_branch(test):
 
292
        test.runbzr('init')
 
293
        file('hello', 'wt').write('foo')
 
294
        test.runbzr('add hello')
 
295
        test.runbzr('commit -m setup hello')
 
296
        file('goodbye', 'wt').write('baz')
 
297
        test.runbzr('add goodbye')
 
298
        test.runbzr('commit -m setup goodbye')
 
299
 
 
300
    def test_export(self):
 
301
        os.mkdir('branch')
 
302
        os.chdir('branch')
 
303
        self.example_branch()
 
304
        self.runbzr('export ../latest')
 
305
        self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
 
306
        self.runbzr('export ../first -r 1')
 
307
        self.assert_(not os.path.exists('../first/goodbye'))
 
308
        self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
 
309
        self.runbzr('export ../first.gz -r 1')
 
310
        self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
 
311
        self.runbzr('export ../first.bz2 -r 1')
 
312
        self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
 
313
        self.runbzr('export ../first.tar -r 1')
 
314
        self.assert_(os.path.isfile('../first.tar'))
 
315
        from tarfile import TarFile
 
316
        tf = TarFile('../first.tar')
 
317
        self.assert_('first/hello' in tf.getnames(), tf.getnames())
 
318
        self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
 
319
        self.runbzr('export ../first.tar.gz -r 1')
 
320
        self.assert_(os.path.isfile('../first.tar.gz'))
 
321
        self.runbzr('export ../first.tbz2 -r 1')
 
322
        self.assert_(os.path.isfile('../first.tbz2'))
 
323
        self.runbzr('export ../first.tar.bz2 -r 1')
 
324
        self.assert_(os.path.isfile('../first.tar.bz2'))
 
325
        self.runbzr('export ../first.tar.tbz2 -r 1')
 
326
        self.assert_(os.path.isfile('../first.tar.tbz2'))
 
327
        from bz2 import BZ2File
 
328
        tf = TarFile('../first.tar.tbz2', 
 
329
                     fileobj=BZ2File('../first.tar.tbz2', 'r'))
 
330
        self.assert_('first.tar/hello' in tf.getnames(), tf.getnames())
 
331
        self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
 
332
        self.runbzr('export ../first2.tar -r 1 --root pizza')
 
333
        tf = TarFile('../first2.tar')
 
334
        self.assert_('pizza/hello' in tf.getnames(), tf.getnames())
 
335
 
 
336
    def test_diff(self):
 
337
        self.example_branch()
 
338
        file('hello', 'wt').write('hello world!')
 
339
        self.runbzr('commit -m fixing hello')
 
340
        output = self.runbzr('diff -r 2..3', backtick=1, retcode=1)
 
341
        self.assert_('\n+hello world!' in output)
 
342
        output = self.runbzr('diff -r last:3..last:1', backtick=1, retcode=1)
 
343
        self.assert_('\n+baz' in output)
 
344
        file('moo', 'wb').write('moo')
 
345
        self.runbzr('add moo')
 
346
        os.unlink('moo')
 
347
        self.runbzr('diff')
 
348
 
 
349
    def test_diff_branches(self):
 
350
        self.build_tree(['branch1/', 'branch1/file', 'branch2/'], line_endings='binary')
 
351
        branch = Branch.initialize('branch1')
 
352
        branch.working_tree().add(['file'])
 
353
        branch.working_tree().commit('add file')
 
354
        copy_branch(branch, 'branch2')
 
355
        print >> open('branch2/file', 'wb'), 'new content'
 
356
        branch2 = Branch.open('branch2')
 
357
        branch2.working_tree().commit('update file')
 
358
        # should open branch1 and diff against branch2, 
 
359
        output = self.run_bzr_captured(['diff', '-r', 'branch:branch2', 
 
360
                                        'branch1'],
 
361
                                       retcode=1)
 
362
        self.assertEquals(("=== modified file 'file'\n"
 
363
                           "--- file\t\n"
 
364
                           "+++ file\t\n"
 
365
                           "@@ -1,1 +1,1 @@\n"
 
366
                           "-new content\n"
 
367
                           "+contents of branch1/file\n"
 
368
                           "\n", ''), output)
 
369
        output = self.run_bzr_captured(['diff', 'branch2', 'branch1'],
 
370
                                       retcode=1)
 
371
        self.assertEqualDiff(("=== modified file 'file'\n"
 
372
                              "--- file\t\n"
 
373
                              "+++ file\t\n"
 
374
                              "@@ -1,1 +1,1 @@\n"
 
375
                              "-new content\n"
 
376
                              "+contents of branch1/file\n"
 
377
                              "\n", ''), output)
 
378
 
 
379
 
 
380
    def test_branch(self):
 
381
        """Branch from one branch to another."""
 
382
        os.mkdir('a')
 
383
        os.chdir('a')
 
384
        self.example_branch()
 
385
        os.chdir('..')
 
386
        self.runbzr('branch a b')
 
387
        self.assertFileEqual('b\n', 'b/.bzr/branch-name')
 
388
        self.runbzr('branch a c -r 1')
 
389
        os.chdir('b')
 
390
        self.runbzr('commit -m foo --unchanged')
 
391
        os.chdir('..')
 
392
        # naughty - abstraction violations RBC 20050928  
 
393
        print "test_branch used to delete the stores, how is this meant to work ?"
 
394
        #shutil.rmtree('a/.bzr/revision-store')
 
395
        #shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
 
396
        #shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
 
397
        self.runbzr('branch a d --basis b')
 
398
 
 
399
    def test_merge(self):
 
400
        from bzrlib.branch import Branch
 
401
        
 
402
        os.mkdir('a')
 
403
        os.chdir('a')
 
404
        self.example_branch()
 
405
        os.chdir('..')
 
406
        self.runbzr('branch a b')
 
407
        os.chdir('b')
 
408
        file('goodbye', 'wt').write('quux')
 
409
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
410
 
 
411
        os.chdir('../a')
 
412
        file('hello', 'wt').write('quuux')
 
413
        # We can't merge when there are in-tree changes
 
414
        self.runbzr('merge ../b', retcode=3)
 
415
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
416
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
 
417
                    retcode=3)
 
418
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
 
419
        self.runbzr('revert --no-backup')
 
420
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
 
421
        self.runbzr('revert --no-backup')
 
422
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
 
423
        self.runbzr('revert --no-backup')
 
424
        self.runbzr('merge ../b -r last:1')
 
425
        self.check_file_contents('goodbye', 'quux')
 
426
        # Merging a branch pulls its revision into the tree
 
427
        a = Branch.open('.')
 
428
        b = Branch.open('../b')
 
429
        a.get_revision_xml(b.last_revision())
 
430
        self.log('pending merges: %s', a.working_tree().pending_merges())
 
431
        self.assertEquals(a.working_tree().pending_merges(),
 
432
                          [b.last_revision()])
 
433
        self.runbzr('commit -m merged')
 
434
        self.runbzr('merge ../b -r last:1')
 
435
        self.assertEqual(Branch.open('.').working_tree().pending_merges(), [])
 
436
 
 
437
    def test_merge_with_missing_file(self):
 
438
        """Merge handles missing file conflicts"""
 
439
        os.mkdir('a')
 
440
        os.chdir('a')
 
441
        os.mkdir('sub')
 
442
        print >> file('sub/a.txt', 'wb'), "hello"
 
443
        print >> file('b.txt', 'wb'), "hello"
 
444
        print >> file('sub/c.txt', 'wb'), "hello"
 
445
        self.runbzr('init')
 
446
        self.runbzr('add')
 
447
        self.runbzr(('commit', '-m', 'added a'))
 
448
        self.runbzr('branch . ../b')
 
449
        print >> file('sub/a.txt', 'ab'), "there"
 
450
        print >> file('b.txt', 'ab'), "there"
 
451
        print >> file('sub/c.txt', 'ab'), "there"
 
452
        self.runbzr(('commit', '-m', 'Added there'))
 
453
        os.unlink('sub/a.txt')
 
454
        os.unlink('sub/c.txt')
 
455
        os.rmdir('sub')
 
456
        os.unlink('b.txt')
 
457
        self.runbzr(('commit', '-m', 'Removed a.txt'))
 
458
        os.chdir('../b')
 
459
        print >> file('sub/a.txt', 'ab'), "something"
 
460
        print >> file('b.txt', 'ab'), "something"
 
461
        print >> file('sub/c.txt', 'ab'), "something"
 
462
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
463
        self.runbzr('merge ../a/', retcode=1)
 
464
        self.assert_(os.path.exists('sub/a.txt.THIS'))
 
465
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
466
        os.chdir('../a')
 
467
        self.runbzr('merge ../b/', retcode=1)
 
468
        self.assert_(os.path.exists('sub/a.txt.OTHER'))
 
469
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
470
 
 
471
    def test_pull(self):
 
472
        """Pull changes from one branch to another."""
 
473
        os.mkdir('a')
 
474
        os.chdir('a')
 
475
 
 
476
        self.example_branch()
 
477
        self.runbzr('pull', retcode=3)
 
478
        self.runbzr('missing', retcode=3)
 
479
        self.runbzr('missing .')
 
480
        self.runbzr('missing')
 
481
        self.runbzr('pull')
 
482
        self.runbzr('pull /', retcode=3)
 
483
        self.runbzr('pull')
 
484
 
 
485
        os.chdir('..')
 
486
        self.runbzr('branch a b')
 
487
        os.chdir('b')
 
488
        self.runbzr('pull')
 
489
        os.mkdir('subdir')
 
490
        self.runbzr('add subdir')
 
491
        self.runbzr('commit -m blah --unchanged')
 
492
        os.chdir('../a')
 
493
        a = Branch.open('.')
 
494
        b = Branch.open('../b')
 
495
        self.assertEquals(a.revision_history(), b.revision_history()[:-1])
 
496
        self.runbzr('pull ../b')
 
497
        self.assertEquals(a.revision_history(), b.revision_history())
 
498
        self.runbzr('commit -m blah2 --unchanged')
 
499
        os.chdir('../b')
 
500
        self.runbzr('commit -m blah3 --unchanged')
 
501
        # no overwrite
 
502
        self.runbzr('pull ../a', retcode=3)
 
503
        os.chdir('..')
 
504
        self.runbzr('branch b overwriteme')
 
505
        os.chdir('overwriteme')
 
506
        self.runbzr('pull --overwrite ../a')
 
507
        overwritten = Branch.open('.')
 
508
        self.assertEqual(overwritten.revision_history(),
 
509
                         a.revision_history())
 
510
        os.chdir('../a')
 
511
        self.runbzr('merge ../b')
 
512
        self.runbzr('commit -m blah4 --unchanged')
 
513
        os.chdir('../b/subdir')
 
514
        self.runbzr('pull ../../a')
 
515
        self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
 
516
        self.runbzr('commit -m blah5 --unchanged')
 
517
        self.runbzr('commit -m blah6 --unchanged')
 
518
        os.chdir('..')
 
519
        self.runbzr('pull ../a')
 
520
        os.chdir('../a')
 
521
        self.runbzr('commit -m blah7 --unchanged')
 
522
        self.runbzr('merge ../b')
 
523
        self.runbzr('commit -m blah8 --unchanged')
 
524
        self.runbzr('pull ../b')
 
525
        self.runbzr('pull ../b')
 
526
 
 
527
    def test_inventory(self):
 
528
        bzr = self.runbzr
 
529
        def output_equals(value, *args):
 
530
            out = self.runbzr(['inventory'] + list(args), backtick=True)
 
531
            self.assertEquals(out, value)
 
532
 
 
533
        bzr('init')
 
534
        open('a', 'wb').write('hello\n')
 
535
        os.mkdir('b')
 
536
 
 
537
        bzr('add a b')
 
538
        bzr('commit -m add')
 
539
 
 
540
        output_equals('a\n', '--kind', 'file')
 
541
        output_equals('b\n', '--kind', 'directory')        
 
542
 
 
543
    def test_ls(self):
 
544
        """Test the abilities of 'bzr ls'"""
 
545
        bzr = self.runbzr
 
546
        def bzrout(*args, **kwargs):
 
547
            kwargs['backtick'] = True
 
548
            return self.runbzr(*args, **kwargs)
 
549
 
 
550
        def ls_equals(value, *args):
 
551
            out = self.runbzr(['ls'] + list(args), backtick=True)
 
552
            self.assertEquals(out, value)
 
553
 
 
554
        bzr('init')
 
555
        open('a', 'wb').write('hello\n')
 
556
 
 
557
        # Can't supply both
 
558
        bzr('ls --verbose --null', retcode=3)
 
559
 
 
560
        ls_equals('a\n')
 
561
        ls_equals('?        a\n', '--verbose')
 
562
        ls_equals('a\n', '--unknown')
 
563
        ls_equals('', '--ignored')
 
564
        ls_equals('', '--versioned')
 
565
        ls_equals('a\n', '--unknown', '--ignored', '--versioned')
 
566
        ls_equals('', '--ignored', '--versioned')
 
567
        ls_equals('a\0', '--null')
 
568
 
 
569
        bzr('add a')
 
570
        ls_equals('V        a\n', '--verbose')
 
571
        bzr('commit -m add')
 
572
        
 
573
        os.mkdir('subdir')
 
574
        ls_equals('V        a\n'
 
575
                  '?        subdir/\n'
 
576
                  , '--verbose')
 
577
        open('subdir/b', 'wb').write('b\n')
 
578
        bzr('add')
 
579
        ls_equals('V        a\n'
 
580
                  'V        subdir/\n'
 
581
                  'V        subdir/b\n'
 
582
                  , '--verbose')
 
583
        bzr('commit -m subdir')
 
584
 
 
585
        ls_equals('a\n'
 
586
                  'subdir\n'
 
587
                  , '--non-recursive')
 
588
 
 
589
        ls_equals('V        a\n'
 
590
                  'V        subdir/\n'
 
591
                  , '--verbose', '--non-recursive')
 
592
 
 
593
        # Check what happens in a sub-directory
 
594
        os.chdir('subdir')
 
595
        ls_equals('b\n')
 
596
        ls_equals('b\0'
 
597
                  , '--null')
 
598
        ls_equals('a\n'
 
599
                  'subdir\n'
 
600
                  'subdir/b\n'
 
601
                  , '--from-root')
 
602
        ls_equals('a\0'
 
603
                  'subdir\0'
 
604
                  'subdir/b\0'
 
605
                  , '--from-root', '--null')
 
606
        ls_equals('a\n'
 
607
                  'subdir\n'
 
608
                  , '--from-root', '--non-recursive')
 
609
 
 
610
        os.chdir('..')
 
611
 
 
612
        # Check what happens when we supply a specific revision
 
613
        ls_equals('a\n', '--revision', '1')
 
614
        ls_equals('V        a\n'
 
615
                  , '--verbose', '--revision', '1')
 
616
 
 
617
        os.chdir('subdir')
 
618
        ls_equals('', '--revision', '1')
 
619
 
 
620
        # Now try to do ignored files.
 
621
        os.chdir('..')
 
622
        open('blah.py', 'wb').write('unknown\n')
 
623
        open('blah.pyo', 'wb').write('ignored\n')
 
624
        ls_equals('a\n'
 
625
                  'blah.py\n'
 
626
                  'blah.pyo\n'
 
627
                  'subdir\n'
 
628
                  'subdir/b\n')
 
629
        ls_equals('V        a\n'
 
630
                  '?        blah.py\n'
 
631
                  'I        blah.pyo\n'
 
632
                  'V        subdir/\n'
 
633
                  'V        subdir/b\n'
 
634
                  , '--verbose')
 
635
        ls_equals('blah.pyo\n'
 
636
                  , '--ignored')
 
637
        ls_equals('blah.py\n'
 
638
                  , '--unknown')
 
639
        ls_equals('a\n'
 
640
                  'subdir\n'
 
641
                  'subdir/b\n'
 
642
                  , '--versioned')
 
643
 
 
644
    def test_pull_verbose(self):
 
645
        """Pull changes from one branch to another and watch the output."""
 
646
 
 
647
        os.mkdir('a')
 
648
        os.chdir('a')
 
649
 
 
650
        bzr = self.runbzr
 
651
        self.example_branch()
 
652
 
 
653
        os.chdir('..')
 
654
        bzr('branch a b')
 
655
        os.chdir('b')
 
656
        open('b', 'wb').write('else\n')
 
657
        bzr('add b')
 
658
        bzr(['commit', '-m', 'added b'])
 
659
 
 
660
        os.chdir('../a')
 
661
        out = bzr('pull --verbose ../b', backtick=True)
 
662
        self.failIfEqual(out.find('Added Revisions:'), -1)
 
663
        self.failIfEqual(out.find('message:\n  added b'), -1)
 
664
        self.failIfEqual(out.find('added b'), -1)
 
665
 
 
666
        # Check that --overwrite --verbose prints out the removed entries
 
667
        bzr('commit -m foo --unchanged')
 
668
        os.chdir('../b')
 
669
        bzr('commit -m baz --unchanged')
 
670
        bzr('pull ../a', retcode=3)
 
671
        out = bzr('pull --overwrite --verbose ../a', backtick=1)
 
672
 
 
673
        remove_loc = out.find('Removed Revisions:')
 
674
        self.failIfEqual(remove_loc, -1)
 
675
        added_loc = out.find('Added Revisions:')
 
676
        self.failIfEqual(added_loc, -1)
 
677
 
 
678
        removed_message = out.find('message:\n  baz')
 
679
        self.failIfEqual(removed_message, -1)
 
680
        self.failUnless(remove_loc < removed_message < added_loc)
 
681
 
 
682
        added_message = out.find('message:\n  foo')
 
683
        self.failIfEqual(added_message, -1)
 
684
        self.failUnless(added_loc < added_message)
 
685
        
 
686
    def test_locations(self):
 
687
        """Using and remembering different locations"""
 
688
        os.mkdir('a')
 
689
        os.chdir('a')
 
690
        self.runbzr('init')
 
691
        self.runbzr('commit -m unchanged --unchanged')
 
692
        self.runbzr('pull', retcode=3)
 
693
        self.runbzr('merge', retcode=3)
 
694
        self.runbzr('branch . ../b')
 
695
        os.chdir('../b')
 
696
        self.runbzr('pull')
 
697
        self.runbzr('branch . ../c')
 
698
        self.runbzr('pull ../c')
 
699
        self.runbzr('merge')
 
700
        os.chdir('../a')
 
701
        self.runbzr('pull ../b')
 
702
        self.runbzr('pull')
 
703
        self.runbzr('pull ../c')
 
704
        self.runbzr('branch ../c ../d')
 
705
        shutil.rmtree('../c')
 
706
        self.runbzr('pull')
 
707
        os.chdir('../b')
 
708
        self.runbzr('pull')
 
709
        os.chdir('../d')
 
710
        self.runbzr('pull', retcode=3)
 
711
        self.runbzr('pull ../a --remember')
 
712
        self.runbzr('pull')
 
713
        
 
714
    def test_add_reports(self):
 
715
        """add command prints the names of added files."""
 
716
        b = Branch.initialize('.')
 
717
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
718
        out = self.run_bzr_captured(['add'], retcode=0)[0]
 
719
        # the ordering is not defined at the moment
 
720
        results = sorted(out.rstrip('\n').split('\n'))
 
721
        self.assertEquals(['added dir',
 
722
                           'added dir'+os.sep+'sub.txt',
 
723
                           'added top.txt',],
 
724
                          results)
 
725
 
 
726
    def test_add_quiet_is(self):
 
727
        """add -q does not print the names of added files."""
 
728
        b = Branch.initialize('.')
 
729
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
730
        out = self.run_bzr_captured(['add', '-q'], retcode=0)[0]
 
731
        # the ordering is not defined at the moment
 
732
        results = sorted(out.rstrip('\n').split('\n'))
 
733
        self.assertEquals([''], results)
 
734
 
 
735
    def test_add_in_unversioned(self):
 
736
        """Try to add a file in an unversioned directory.
 
737
 
 
738
        "bzr add" should add the parent(s) as necessary.
 
739
        """
 
740
        from bzrlib.branch import Branch
 
741
        Branch.initialize('.')
 
742
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
 
743
        self.assertEquals(self.capture('unknowns'), 'inertiatic\n')
 
744
        self.run_bzr('add', 'inertiatic/esp')
 
745
        self.assertEquals(self.capture('unknowns'), '')
 
746
 
 
747
        # Multiple unversioned parents
 
748
        self.build_tree(['veil/', 'veil/cerpin/', 'veil/cerpin/taxt'])
 
749
        self.assertEquals(self.capture('unknowns'), 'veil\n')
 
750
        self.run_bzr('add', 'veil/cerpin/taxt')
 
751
        self.assertEquals(self.capture('unknowns'), '')
 
752
 
 
753
        # Check whacky paths work
 
754
        self.build_tree(['cicatriz/', 'cicatriz/esp'])
 
755
        self.assertEquals(self.capture('unknowns'), 'cicatriz\n')
 
756
        self.run_bzr('add', 'inertiatic/../cicatriz/esp')
 
757
        self.assertEquals(self.capture('unknowns'), '')
 
758
 
 
759
    def test_add_in_versioned(self):
 
760
        """Try to add a file in a versioned directory.
 
761
 
 
762
        "bzr add" should do this happily.
 
763
        """
 
764
        from bzrlib.branch import Branch
 
765
        Branch.initialize('.')
 
766
        self.build_tree(['inertiatic/', 'inertiatic/esp'])
 
767
        self.assertEquals(self.capture('unknowns'), 'inertiatic\n')
 
768
        self.run_bzr('add', '--no-recurse', 'inertiatic')
 
769
        self.assertEquals(self.capture('unknowns'), 'inertiatic'+os.sep+'esp\n')
 
770
        self.run_bzr('add', 'inertiatic/esp')
 
771
        self.assertEquals(self.capture('unknowns'), '')
 
772
 
 
773
    def test_subdir_add(self):
 
774
        """Add in subdirectory should add only things from there down"""
 
775
        from bzrlib.branch import Branch
 
776
        
 
777
        eq = self.assertEqual
 
778
        ass = self.assert_
 
779
        chdir = os.chdir
 
780
        
 
781
        b = Branch.initialize('.')
 
782
        t = b.working_tree()
 
783
        self.build_tree(['src/', 'README'])
 
784
        
 
785
        eq(sorted(t.unknowns()),
 
786
           ['README', 'src'])
 
787
        
 
788
        self.run_bzr('add', 'src')
 
789
        
 
790
        self.build_tree(['src/foo.c'])
 
791
        
 
792
        chdir('src')
 
793
        self.run_bzr('add')
 
794
        
 
795
        self.assertEquals(self.capture('unknowns'), 'README\n')
 
796
        eq(len(t.read_working_inventory()), 3)
 
797
                
 
798
        chdir('..')
 
799
        self.run_bzr('add')
 
800
        self.assertEquals(self.capture('unknowns'), '')
 
801
        self.run_bzr('check')
 
802
 
 
803
    def test_unknown_command(self):
 
804
        """Handling of unknown command."""
 
805
        out, err = self.run_bzr_captured(['fluffy-badger'],
 
806
                                         retcode=3)
 
807
        self.assertEquals(out, '')
 
808
        err.index('unknown command')
 
809
 
 
810
    def create_conflicts(self):
 
811
        """Create a conflicted tree"""
 
812
        os.mkdir('base')
 
813
        os.chdir('base')
 
814
        file('hello', 'wb').write("hi world")
 
815
        file('answer', 'wb').write("42")
 
816
        self.runbzr('init')
 
817
        self.runbzr('add')
 
818
        self.runbzr('commit -m base')
 
819
        self.runbzr('branch . ../other')
 
820
        self.runbzr('branch . ../this')
 
821
        os.chdir('../other')
 
822
        file('hello', 'wb').write("Hello.")
 
823
        file('answer', 'wb').write("Is anyone there?")
 
824
        self.runbzr('commit -m other')
 
825
        os.chdir('../this')
 
826
        file('hello', 'wb').write("Hello, world")
 
827
        self.runbzr('mv answer question')
 
828
        file('question', 'wb').write("What do you get when you multiply six"
 
829
                                   "times nine?")
 
830
        self.runbzr('commit -m this')
 
831
 
 
832
    def test_remerge(self):
 
833
        """Remerge command works as expected"""
 
834
        self.create_conflicts()
 
835
        self.runbzr('merge ../other --show-base', retcode=1)
 
836
        conflict_text = file('hello').read()
 
837
        assert '|||||||' in conflict_text
 
838
        assert 'hi world' in conflict_text
 
839
        self.runbzr('remerge', retcode=1)
 
840
        conflict_text = file('hello').read()
 
841
        assert '|||||||' not in conflict_text
 
842
        assert 'hi world' not in conflict_text
 
843
        os.unlink('hello.OTHER')
 
844
        self.runbzr('remerge hello --merge-type weave', retcode=1)
 
845
        assert os.path.exists('hello.OTHER')
 
846
        file_id = self.runbzr('file-id hello')
 
847
        file_id = self.runbzr('file-id hello.THIS', retcode=3)
 
848
        self.runbzr('remerge --merge-type weave', retcode=1)
 
849
        assert os.path.exists('hello.OTHER')
 
850
        assert not os.path.exists('hello.BASE')
 
851
        assert '|||||||' not in conflict_text
 
852
        assert 'hi world' not in conflict_text
 
853
        self.runbzr('remerge . --merge-type weave --show-base', retcode=3)
 
854
        self.runbzr('remerge . --merge-type weave --reprocess', retcode=3)
 
855
        self.runbzr('remerge . --show-base --reprocess', retcode=3)
 
856
        self.runbzr('remerge hello --show-base', retcode=1)
 
857
        self.runbzr('remerge hello --reprocess', retcode=1)
 
858
        self.runbzr('resolve --all')
 
859
        self.runbzr('commit -m done',)
 
860
        self.runbzr('remerge', retcode=3)
 
861
 
 
862
 
 
863
    def test_conflicts(self):
 
864
        """Handling of merge conflicts"""
 
865
        self.create_conflicts()
 
866
        self.runbzr('merge ../other --show-base', retcode=1)
 
867
        conflict_text = file('hello').read()
 
868
        self.assert_('<<<<<<<' in conflict_text)
 
869
        self.assert_('>>>>>>>' in conflict_text)
 
870
        self.assert_('=======' in conflict_text)
 
871
        self.assert_('|||||||' in conflict_text)
 
872
        self.assert_('hi world' in conflict_text)
 
873
        self.runbzr('revert')
 
874
        self.runbzr('resolve --all')
 
875
        self.runbzr('merge ../other', retcode=1)
 
876
        conflict_text = file('hello').read()
 
877
        self.assert_('|||||||' not in conflict_text)
 
878
        self.assert_('hi world' not in conflict_text)
 
879
        result = self.runbzr('conflicts', backtick=1)
 
880
        self.assertEquals(result, "hello\nquestion\n")
 
881
        result = self.runbzr('status', backtick=1)
 
882
        self.assert_("conflicts:\n  hello\n  question\n" in result, result)
 
883
        self.runbzr('resolve hello')
 
884
        result = self.runbzr('conflicts', backtick=1)
 
885
        self.assertEquals(result, "question\n")
 
886
        self.runbzr('commit -m conflicts', retcode=3)
 
887
        self.runbzr('resolve --all')
 
888
        result = self.runbzr('conflicts', backtick=1)
 
889
        self.runbzr('commit -m conflicts')
 
890
        self.assertEquals(result, "")
 
891
 
 
892
    def test_resign(self):
 
893
        """Test re signing of data."""
 
894
        import bzrlib.gpg
 
895
        oldstrategy = bzrlib.gpg.GPGStrategy
 
896
        branch = Branch.initialize('.')
 
897
        branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
 
898
        try:
 
899
            # monkey patch gpg signing mechanism
 
900
            from bzrlib.testament import Testament
 
901
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
 
902
            self.runbzr('re-sign -r revid:A')
 
903
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
 
904
                             branch.revision_store.get('A', 'sig').read())
 
905
        finally:
 
906
            bzrlib.gpg.GPGStrategy = oldstrategy
 
907
            
 
908
    def test_resign_range(self):
 
909
        import bzrlib.gpg
 
910
        oldstrategy = bzrlib.gpg.GPGStrategy
 
911
        branch = Branch.initialize('.')
 
912
        branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
 
913
        branch.working_tree().commit("base", allow_pointless=True, rev_id='B')
 
914
        branch.working_tree().commit("base", allow_pointless=True, rev_id='C')
 
915
        try:
 
916
            # monkey patch gpg signing mechanism
 
917
            from bzrlib.testament import Testament
 
918
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
 
919
            self.runbzr('re-sign -r 1..')
 
920
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
 
921
                             branch.revision_store.get('A', 'sig').read())
 
922
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
 
923
                             branch.revision_store.get('B', 'sig').read())
 
924
            self.assertEqual(Testament.from_revision(branch,'C').as_short_text(),
 
925
                             branch.revision_store.get('C', 'sig').read())
 
926
        finally:
 
927
            bzrlib.gpg.GPGStrategy = oldstrategy
 
928
 
 
929
    def test_push(self):
 
930
        # create a source branch
 
931
        os.mkdir('my-branch')
 
932
        os.chdir('my-branch')
 
933
        self.example_branch()
 
934
 
 
935
        # with no push target, fail
 
936
        self.runbzr('push', retcode=3)
 
937
        # with an explicit target work
 
938
        self.runbzr('push ../output-branch')
 
939
        # with an implicit target work
 
940
        self.runbzr('push')
 
941
        # nothing missing
 
942
        self.runbzr('missing ../output-branch')
 
943
        # advance this branch
 
944
        self.runbzr('commit --unchanged -m unchanged')
 
945
 
 
946
        os.chdir('../output-branch')
 
947
        # should be a diff as we have not pushed the tree
 
948
        self.runbzr('diff', retcode=1)
 
949
        self.runbzr('revert')
 
950
        # but not now.
 
951
        self.runbzr('diff')
 
952
        # diverge the branches
 
953
        self.runbzr('commit --unchanged -m unchanged')
 
954
        os.chdir('../my-branch')
 
955
        # cannot push now
 
956
        self.runbzr('push', retcode=3)
 
957
        # and there are difference
 
958
        self.runbzr('missing ../output-branch', retcode=1)
 
959
        self.runbzr('missing --verbose ../output-branch', retcode=1)
 
960
        # but we can force a push
 
961
        self.runbzr('push --overwrite')
 
962
        # nothing missing
 
963
        self.runbzr('missing ../output-branch')
 
964
        
 
965
        # pushing to a new dir with no parent should fail
 
966
        self.runbzr('push ../missing/new-branch', retcode=3)
 
967
        # unless we provide --create-prefix
 
968
        self.runbzr('push --create-prefix ../missing/new-branch')
 
969
        # nothing missing
 
970
        self.runbzr('missing ../missing/new-branch')
 
971
 
 
972
    def test_external_command(self):
 
973
        """test that external commands can be run by setting the path"""
 
974
        cmd_name = 'test-command'
 
975
        output = 'Hello from test-command'
 
976
        if sys.platform == 'win32':
 
977
            cmd_name += '.bat'
 
978
            output += '\r\n'
 
979
        else:
 
980
            output += '\n'
 
981
 
 
982
        oldpath = os.environ.get('BZRPATH', None)
 
983
 
 
984
        bzr = self.capture
 
985
 
 
986
        try:
 
987
            if os.environ.has_key('BZRPATH'):
 
988
                del os.environ['BZRPATH']
 
989
 
 
990
            f = file(cmd_name, 'wb')
 
991
            if sys.platform == 'win32':
 
992
                f.write('@echo off\n')
 
993
            else:
 
994
                f.write('#!/bin/sh\n')
 
995
            f.write('echo Hello from test-command')
 
996
            f.close()
 
997
            os.chmod(cmd_name, 0755)
 
998
 
 
999
            # It should not find the command in the local 
 
1000
            # directory by default, since it is not in my path
 
1001
            bzr(cmd_name, retcode=3)
 
1002
 
 
1003
            # Now put it into my path
 
1004
            os.environ['BZRPATH'] = '.'
 
1005
 
 
1006
            bzr(cmd_name)
 
1007
            # The test suite does not capture stdout for external commands
 
1008
            # this is because you have to have a real file object
 
1009
            # to pass to Popen(stdout=FOO), and StringIO is not one of those.
 
1010
            # (just replacing sys.stdout does not change a spawned objects stdout)
 
1011
            #self.assertEquals(bzr(cmd_name), output)
 
1012
 
 
1013
            # Make sure empty path elements are ignored
 
1014
            os.environ['BZRPATH'] = os.pathsep
 
1015
 
 
1016
            bzr(cmd_name, retcode=3)
 
1017
 
 
1018
        finally:
 
1019
            if oldpath:
 
1020
                os.environ['BZRPATH'] = oldpath
 
1021
 
 
1022
 
 
1023
def listdir_sorted(dir):
 
1024
    L = os.listdir(dir)
 
1025
    L.sort()
 
1026
    return L
 
1027
 
 
1028
 
 
1029
class OldTests(ExternalBase):
 
1030
    """old tests moved from ./testbzr."""
 
1031
 
 
1032
    def test_bzr(self):
 
1033
        from os import chdir, mkdir
 
1034
        from os.path import exists
 
1035
 
 
1036
        runbzr = self.runbzr
 
1037
        capture = self.capture
 
1038
        progress = self.log
 
1039
 
 
1040
        progress("basic branch creation")
 
1041
        mkdir('branch1')
 
1042
        chdir('branch1')
 
1043
        runbzr('init')
 
1044
 
 
1045
        self.assertEquals(capture('root').rstrip(),
 
1046
                          os.path.join(self.test_dir, 'branch1'))
 
1047
 
 
1048
        progress("status of new file")
 
1049
 
 
1050
        f = file('test.txt', 'wt')
 
1051
        f.write('hello world!\n')
 
1052
        f.close()
 
1053
 
 
1054
        self.assertEquals(capture('unknowns'), 'test.txt\n')
 
1055
 
 
1056
        out = capture("status")
 
1057
        self.assertEquals(out, 'unknown:\n  test.txt\n')
 
1058
 
 
1059
        out = capture("status --all")
 
1060
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
1061
 
 
1062
        out = capture("status test.txt --all")
 
1063
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
1064
 
 
1065
        f = file('test2.txt', 'wt')
 
1066
        f.write('goodbye cruel world...\n')
 
1067
        f.close()
 
1068
 
 
1069
        out = capture("status test.txt")
 
1070
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
1071
 
 
1072
        out = capture("status")
 
1073
        self.assertEquals(out, ("unknown:\n" "  test.txt\n" "  test2.txt\n"))
 
1074
 
 
1075
        os.unlink('test2.txt')
 
1076
 
 
1077
        progress("command aliases")
 
1078
        out = capture("st --all")
 
1079
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
1080
 
 
1081
        out = capture("stat")
 
1082
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
 
1083
 
 
1084
        progress("command help")
 
1085
        runbzr("help st")
 
1086
        runbzr("help")
 
1087
        runbzr("help commands")
 
1088
        runbzr("help slartibartfast", 3)
 
1089
 
 
1090
        out = capture("help ci")
 
1091
        out.index('aliases: ')
 
1092
 
 
1093
        progress("can't rename unversioned file")
 
1094
        runbzr("rename test.txt new-test.txt", 3)
 
1095
 
 
1096
        progress("adding a file")
 
1097
 
 
1098
        runbzr("add test.txt")
 
1099
        self.assertEquals(capture("unknowns"), '')
 
1100
        self.assertEquals(capture("status --all"), ("added:\n" "  test.txt\n"))
 
1101
 
 
1102
        progress("rename newly-added file")
 
1103
        runbzr("rename test.txt hello.txt")
 
1104
        self.assert_(os.path.exists("hello.txt"))
 
1105
        self.assert_(not os.path.exists("test.txt"))
 
1106
 
 
1107
        self.assertEquals(capture("revno"), '0\n')
 
1108
 
 
1109
        progress("add first revision")
 
1110
        runbzr(['commit', '-m', 'add first revision'])
 
1111
 
 
1112
        progress("more complex renames")
 
1113
        os.mkdir("sub1")
 
1114
        runbzr("rename hello.txt sub1", 3)
 
1115
        runbzr("rename hello.txt sub1/hello.txt", 3)
 
1116
        runbzr("move hello.txt sub1", 3)
 
1117
 
 
1118
        runbzr("add sub1")
 
1119
        runbzr("rename sub1 sub2")
 
1120
        runbzr("move hello.txt sub2")
 
1121
        self.assertEqual(capture("relpath sub2/hello.txt"),
 
1122
                         os.path.join("sub2", "hello.txt\n"))
 
1123
 
 
1124
        self.assert_(exists("sub2"))
 
1125
        self.assert_(exists("sub2/hello.txt"))
 
1126
        self.assert_(not exists("sub1"))
 
1127
        self.assert_(not exists("hello.txt"))
 
1128
 
 
1129
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
 
1130
 
 
1131
        mkdir("sub1")
 
1132
        runbzr('add sub1')
 
1133
        runbzr('move sub2/hello.txt sub1')
 
1134
        self.assert_(not exists('sub2/hello.txt'))
 
1135
        self.assert_(exists('sub1/hello.txt'))
 
1136
        runbzr('move sub2 sub1')
 
1137
        self.assert_(not exists('sub2'))
 
1138
        self.assert_(exists('sub1/sub2'))
 
1139
 
 
1140
        runbzr(['commit', '-m', 'rename nested subdirectories'])
 
1141
 
 
1142
        chdir('sub1/sub2')
 
1143
        self.assertEquals(capture('root')[:-1],
 
1144
                          os.path.join(self.test_dir, 'branch1'))
 
1145
        runbzr('move ../hello.txt .')
 
1146
        self.assert_(exists('./hello.txt'))
 
1147
        self.assertEquals(capture('relpath hello.txt'),
 
1148
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
 
1149
        self.assertEquals(capture('relpath ../../sub1/sub2/hello.txt'), os.path.join('sub1', 'sub2', 'hello.txt\n'))
 
1150
        runbzr(['commit', '-m', 'move to parent directory'])
 
1151
        chdir('..')
 
1152
        self.assertEquals(capture('relpath sub2/hello.txt'), os.path.join('sub1', 'sub2', 'hello.txt\n'))
 
1153
 
 
1154
        runbzr('move sub2/hello.txt .')
 
1155
        self.assert_(exists('hello.txt'))
 
1156
 
 
1157
        f = file('hello.txt', 'wt')
 
1158
        f.write('some nice new content\n')
 
1159
        f.close()
 
1160
 
 
1161
        f = file('msg.tmp', 'wt')
 
1162
        f.write('this is my new commit\nand it has multiple lines, for fun')
 
1163
        f.close()
 
1164
 
 
1165
        runbzr('commit -F msg.tmp')
 
1166
 
 
1167
        self.assertEquals(capture('revno'), '5\n')
 
1168
        runbzr('export -r 5 export-5.tmp')
 
1169
        runbzr('export export.tmp')
 
1170
 
 
1171
        runbzr('log')
 
1172
        runbzr('log -v')
 
1173
        runbzr('log -v --forward')
 
1174
        runbzr('log -m', retcode=3)
 
1175
        log_out = capture('log -m commit')
 
1176
        self.assert_("this is my new commit\n  and" in log_out)
 
1177
        self.assert_("rename nested" not in log_out)
 
1178
        self.assert_('revision-id' not in log_out)
 
1179
        self.assert_('revision-id' in capture('log --show-ids -m commit'))
 
1180
 
 
1181
        log_out = capture('log --line')
 
1182
        for line in log_out.splitlines():
 
1183
            self.assert_(len(line) <= 79, len(line))
 
1184
        self.assert_("this is my new commit and" in log_out)
 
1185
 
 
1186
 
 
1187
        progress("file with spaces in name")
 
1188
        mkdir('sub directory')
 
1189
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
 
1190
        runbzr('add .')
 
1191
        runbzr('diff', retcode=1)
 
1192
        runbzr('commit -m add-spaces')
 
1193
        runbzr('check')
 
1194
 
 
1195
        runbzr('log')
 
1196
        runbzr('log --forward')
 
1197
 
 
1198
        runbzr('info')
 
1199
 
 
1200
        if has_symlinks():
 
1201
            progress("symlinks")
 
1202
            mkdir('symlinks')
 
1203
            chdir('symlinks')
 
1204
            runbzr('init')
 
1205
            os.symlink("NOWHERE1", "link1")
 
1206
            runbzr('add link1')
 
1207
            self.assertEquals(self.capture('unknowns'), '')
 
1208
            runbzr(['commit', '-m', '1: added symlink link1'])
 
1209
    
 
1210
            mkdir('d1')
 
1211
            runbzr('add d1')
 
1212
            self.assertEquals(self.capture('unknowns'), '')
 
1213
            os.symlink("NOWHERE2", "d1/link2")
 
1214
            self.assertEquals(self.capture('unknowns'), 'd1/link2\n')
 
1215
            # is d1/link2 found when adding d1
 
1216
            runbzr('add d1')
 
1217
            self.assertEquals(self.capture('unknowns'), '')
 
1218
            os.symlink("NOWHERE3", "d1/link3")
 
1219
            self.assertEquals(self.capture('unknowns'), 'd1/link3\n')
 
1220
            runbzr(['commit', '-m', '2: added dir, symlink'])
 
1221
    
 
1222
            runbzr('rename d1 d2')
 
1223
            runbzr('move d2/link2 .')
 
1224
            runbzr('move link1 d2')
 
1225
            self.assertEquals(os.readlink("./link2"), "NOWHERE2")
 
1226
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
 
1227
            runbzr('add d2/link3')
 
1228
            runbzr('diff', retcode=1)
 
1229
            runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
 
1230
    
 
1231
            os.unlink("link2")
 
1232
            os.symlink("TARGET 2", "link2")
 
1233
            os.unlink("d2/link1")
 
1234
            os.symlink("TARGET 1", "d2/link1")
 
1235
            runbzr('diff', retcode=1)
 
1236
            self.assertEquals(self.capture("relpath d2/link1"), "d2/link1\n")
 
1237
            runbzr(['commit', '-m', '4: retarget of two links'])
 
1238
    
 
1239
            runbzr('remove d2/link1')
 
1240
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
 
1241
            runbzr(['commit', '-m', '5: remove d2/link1'])
 
1242
            # try with the rm alias
 
1243
            runbzr('add d2/link1')
 
1244
            runbzr(['commit', '-m', '6: add d2/link1'])
 
1245
            runbzr('rm d2/link1')
 
1246
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
 
1247
            runbzr(['commit', '-m', '7: remove d2/link1'])
 
1248
    
 
1249
            os.mkdir("d1")
 
1250
            runbzr('add d1')
 
1251
            runbzr('rename d2/link3 d1/link3new')
 
1252
            self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
 
1253
            runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
 
1254
            
 
1255
            runbzr(['check'])
 
1256
            
 
1257
            runbzr(['export', '-r', '1', 'exp1.tmp'])
 
1258
            chdir("exp1.tmp")
 
1259
            self.assertEquals(listdir_sorted("."), [ "link1" ])
 
1260
            self.assertEquals(os.readlink("link1"), "NOWHERE1")
 
1261
            chdir("..")
 
1262
            
 
1263
            runbzr(['export', '-r', '2', 'exp2.tmp'])
 
1264
            chdir("exp2.tmp")
 
1265
            self.assertEquals(listdir_sorted("."), [ "d1", "link1" ])
 
1266
            chdir("..")
 
1267
            
 
1268
            runbzr(['export', '-r', '3', 'exp3.tmp'])
 
1269
            chdir("exp3.tmp")
 
1270
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
 
1271
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
 
1272
            self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
 
1273
            self.assertEquals(os.readlink("link2")   , "NOWHERE2")
 
1274
            chdir("..")
 
1275
            
 
1276
            runbzr(['export', '-r', '4', 'exp4.tmp'])
 
1277
            chdir("exp4.tmp")
 
1278
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
 
1279
            self.assertEquals(os.readlink("d2/link1"), "TARGET 1")
 
1280
            self.assertEquals(os.readlink("link2")   , "TARGET 2")
 
1281
            self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
 
1282
            chdir("..")
 
1283
            
 
1284
            runbzr(['export', '-r', '5', 'exp5.tmp'])
 
1285
            chdir("exp5.tmp")
 
1286
            self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
 
1287
            self.assert_(os.path.islink("link2"))
 
1288
            self.assert_(listdir_sorted("d2")== [ "link3" ])
 
1289
            chdir("..")
 
1290
            
 
1291
            runbzr(['export', '-r', '8', 'exp6.tmp'])
 
1292
            chdir("exp6.tmp")
 
1293
            self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
 
1294
            self.assertEquals(listdir_sorted("d1"), [ "link3new" ])
 
1295
            self.assertEquals(listdir_sorted("d2"), [])
 
1296
            self.assertEquals(os.readlink("d1/link3new"), "NOWHERE3")
 
1297
            chdir("..")
 
1298
        else:
 
1299
            progress("skipping symlink tests")
 
1300
 
 
1301
 
 
1302
class HttpTests(TestCaseWithWebserver):
 
1303
    """Test bzr ui commands against remote branches."""
 
1304
 
 
1305
    def test_branch(self):
 
1306
        os.mkdir('from')
 
1307
        branch = Branch.initialize('from')
 
1308
        branch.working_tree().commit('empty commit for nonsense', allow_pointless=True)
 
1309
        url = self.get_remote_url('from')
 
1310
        self.run_bzr('branch', url, 'to')
 
1311
        branch = Branch.open('to')
 
1312
        self.assertEqual(1, len(branch.revision_history()))
 
1313
 
 
1314
    def test_log(self):
 
1315
        self.build_tree(['branch/', 'branch/file'])
 
1316
        branch = Branch.initialize('branch')
 
1317
        branch.working_tree().add(['file'])
 
1318
        branch.working_tree().commit('add file', rev_id='A')
 
1319
        url = self.get_remote_url('branch/file')
 
1320
        output = self.capture('log %s' % url)
 
1321
        self.assertEqual(8, len(output.split('\n')))