~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2007-04-28 15:04:17 UTC
  • mfrom: (2466 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2566.
  • Revision ID: john@arbash-meinel.com-20070428150417-trp3pi0pzd411pu4
[merge] bzr.dev 2466

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
import bzrlib
32
32
from bzrlib import (
33
33
    branch,
 
34
    bugtracker,
34
35
    bundle,
35
36
    bzrdir,
36
37
    delta,
59
60
""")
60
61
 
61
62
from bzrlib.commands import Command, display_command
62
 
from bzrlib.option import Option, RegistryOption
 
63
from bzrlib.option import ListOption, Option, RegistryOption
63
64
from bzrlib.progress import DummyProgress, ProgressPhase
64
65
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
65
66
 
189
190
    aliases = ['st', 'stat']
190
191
 
191
192
    encoding_type = 'replace'
 
193
    _see_also = ['diff', 'revert']
192
194
    
193
195
    @display_command
194
196
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
247
249
 
248
250
    To re-create the working tree, use "bzr checkout".
249
251
    """
 
252
    _see_also = ['checkout']
250
253
 
251
254
    takes_args = ['location?']
252
255
 
276
279
    This is equal to the number of revisions on this branch.
277
280
    """
278
281
 
 
282
    _see_also = ['info']
279
283
    takes_args = ['location?']
280
284
 
281
285
    @display_command
352
356
                     Option('file-ids-from', type=unicode,
353
357
                            help='Lookup file ids from here')]
354
358
    encoding_type = 'replace'
 
359
    _see_also = ['remove']
355
360
 
356
361
    def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
357
362
            file_ids_from=None):
436
441
 
437
442
    It is also possible to restrict the list of files to a specific
438
443
    set. For example: bzr inventory --show-ids this/file
439
 
 
440
 
    See also: bzr ls
441
444
    """
442
445
 
443
446
    hidden = True
444
 
 
 
447
    _see_also = ['ls']
445
448
    takes_options = ['revision', 'show-ids', 'kind']
446
 
 
447
449
    takes_args = ['file*']
448
450
 
449
451
    @display_command
560
562
    location can be accessed.
561
563
    """
562
564
 
 
565
    _see_also = ['push', 'update']
563
566
    takes_options = ['remember', 'overwrite', 'revision', 'verbose',
564
567
        Option('directory',
565
568
            help='branch to pull into, '
666
669
    location can be accessed.
667
670
    """
668
671
 
 
672
    _see_also = ['pull', 'update']
669
673
    takes_options = ['remember', 'overwrite', 'verbose',
670
674
        Option('create-prefix',
671
675
               help='Create the path leading up to the branch '
848
852
    To retrieve the branch as of a particular revision, supply the --revision
849
853
    parameter, as in "branch foo/bar -r 5".
850
854
    """
 
855
 
 
856
    _see_also = ['checkout']
851
857
    takes_args = ['from_location', 'to_location?']
852
858
    takes_options = ['revision']
853
859
    aliases = ['get', 'clone']
916
922
    parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
917
923
    out of date [so you cannot commit] but it may be useful (i.e. to examine old
918
924
    code.)
 
925
    """
919
926
 
920
 
    See "help checkouts" for more information on checkouts.
921
 
    """
 
927
    _see_also = ['checkouts', 'branch']
922
928
    takes_args = ['branch_location?', 'to_location?']
923
929
    takes_options = ['revision',
924
930
                     Option('lightweight',
978
984
    # TODO: Option to show renames between two historical versions.
979
985
 
980
986
    # TODO: Only show renames under dir, rather than in the whole branch.
 
987
    _see_also = ['status']
981
988
    takes_args = ['dir?']
982
989
 
983
990
    @display_command
1010
1017
    If you want to discard your local changes, you can just do a 
1011
1018
    'bzr revert' instead of 'bzr commit' after the update.
1012
1019
    """
 
1020
 
 
1021
    _see_also = ['pull']
1013
1022
    takes_args = ['dir?']
1014
1023
    aliases = ['up']
1015
1024
 
1053
1062
 
1054
1063
    Branches and working trees will also report any missing revisions.
1055
1064
    """
 
1065
    _see_also = ['revno']
1056
1066
    takes_args = ['location?']
1057
1067
    takes_options = ['verbose']
1058
1068
 
1064
1074
 
1065
1075
 
1066
1076
class cmd_remove(Command):
1067
 
    """Make a file unversioned.
 
1077
    """Remove files or directories.
1068
1078
 
1069
 
    This makes bzr stop tracking changes to a versioned file.  It does
1070
 
    not delete the working copy.
 
1079
    This makes bzr stop tracking changes to the specified files and
 
1080
    delete them if they can easily be recovered using revert.
1071
1081
 
1072
1082
    You can specify one or more files, and/or --new.  If you specify --new,
1073
1083
    only 'added' files will be removed.  If you specify both, then new files
1075
1085
    also new, they will also be removed.
1076
1086
    """
1077
1087
    takes_args = ['file*']
1078
 
    takes_options = ['verbose', Option('new', help='remove newly-added files')]
 
1088
    takes_options = ['verbose',
 
1089
        Option('new', help='remove newly-added files'),
 
1090
        RegistryOption.from_kwargs('file-deletion-strategy',
 
1091
            'The file deletion mode to be used',
 
1092
            title='Deletion Strategy', value_switches=True, enum_switch=False,
 
1093
            safe='Only delete files if they can be'
 
1094
                 ' safely recovered (default).',
 
1095
            keep="Don't delete any files.",
 
1096
            force='Delete all the specified files, even if they can not be '
 
1097
                'recovered and even if they are non-empty directories.')]
1079
1098
    aliases = ['rm']
1080
1099
    encoding_type = 'replace'
1081
 
    
1082
 
    def run(self, file_list, verbose=False, new=False):
 
1100
 
 
1101
    def run(self, file_list, verbose=False, new=False,
 
1102
        file_deletion_strategy='safe'):
1083
1103
        tree, file_list = tree_files(file_list)
1084
 
        if new is False:
1085
 
            if file_list is None:
1086
 
                raise errors.BzrCommandError('Specify one or more files to'
1087
 
                                             ' remove, or use --new.')
1088
 
        else:
 
1104
 
 
1105
        if file_list is not None:
 
1106
            file_list = [f for f in file_list if f != '']
 
1107
        elif not new:
 
1108
            raise errors.BzrCommandError('Specify one or more files to'
 
1109
            ' remove, or use --new.')
 
1110
 
 
1111
        if new:
1089
1112
            added = tree.changes_from(tree.basis_tree(),
1090
1113
                specific_files=file_list).added
1091
1114
            file_list = sorted([f[0] for f in added], reverse=True)
1092
1115
            if len(file_list) == 0:
1093
1116
                raise errors.BzrCommandError('No matching files.')
1094
 
        tree.remove(file_list, verbose=verbose, to_file=self.outf)
 
1117
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
 
1118
            keep_files=file_deletion_strategy=='keep',
 
1119
            force=file_deletion_strategy=='force')
1095
1120
 
1096
1121
 
1097
1122
class cmd_file_id(Command):
1103
1128
    """
1104
1129
 
1105
1130
    hidden = True
 
1131
    _see_also = ['inventory', 'ls']
1106
1132
    takes_args = ['filename']
1107
1133
 
1108
1134
    @display_command
1155
1181
 
1156
1182
    The branch *MUST* be on a listable system such as local disk or sftp.
1157
1183
    """
 
1184
 
 
1185
    _see_also = ['check']
1158
1186
    takes_args = ['branch?']
1159
1187
 
1160
1188
    def run(self, branch="."):
1165
1193
 
1166
1194
class cmd_revision_history(Command):
1167
1195
    """Display the list of revision ids on a branch."""
 
1196
 
 
1197
    _see_also = ['log']
1168
1198
    takes_args = ['location?']
1169
1199
 
1170
1200
    hidden = True
1179
1209
 
1180
1210
class cmd_ancestry(Command):
1181
1211
    """List all revisions merged into this branch."""
 
1212
 
 
1213
    _see_also = ['log', 'revision-history']
1182
1214
    takes_args = ['location?']
1183
1215
 
1184
1216
    hidden = True
1222
1254
        bzr status
1223
1255
        bzr commit -m 'imported project'
1224
1256
    """
 
1257
 
 
1258
    _see_also = ['init-repo', 'branch', 'checkout']
1225
1259
    takes_args = ['location?']
1226
1260
    takes_options = [
1227
1261
         RegistryOption('format',
1293
1327
        (add files here)
1294
1328
    """
1295
1329
 
 
1330
    _see_also = ['init', 'branch', 'checkout']
1296
1331
    takes_args = ["location"]
1297
1332
    takes_options = [RegistryOption('format',
1298
1333
                            help='Specify a format for this repository. See'
1358
1393
 
1359
1394
    # TODO: This probably handles non-Unix newlines poorly.
1360
1395
 
 
1396
    _see_also = ['status']
1361
1397
    takes_args = ['file*']
1362
1398
    takes_options = ['revision', 'diff-options',
1363
1399
        Option('prefix', type=str,
1443
1479
    # directories with readdir, rather than stating each one.  Same
1444
1480
    # level of effort but possibly much less IO.  (Or possibly not,
1445
1481
    # if the directories are very large...)
 
1482
    _see_also = ['status', 'ls']
1446
1483
    takes_options = ['show-ids']
1447
1484
 
1448
1485
    @display_command
1468
1505
 
1469
1506
class cmd_modified(Command):
1470
1507
    """List files modified in working tree.
1471
 
 
1472
 
    See also: "bzr status".
1473
1508
    """
1474
1509
 
1475
1510
    hidden = True
 
1511
    _see_also = ['status', 'ls']
1476
1512
 
1477
1513
    @display_command
1478
1514
    def run(self):
1484
1520
 
1485
1521
class cmd_added(Command):
1486
1522
    """List files added in working tree.
1487
 
 
1488
 
    See also: "bzr status".
1489
1523
    """
1490
1524
 
1491
1525
    hidden = True
 
1526
    _see_also = ['status', 'ls']
1492
1527
 
1493
1528
    @display_command
1494
1529
    def run(self):
1520
1555
 
1521
1556
    The root is the nearest enclosing directory with a .bzr control
1522
1557
    directory."""
 
1558
 
1523
1559
    takes_args = ['filename?']
1524
1560
    @display_command
1525
1561
    def run(self, filename=None):
1687
1723
    """List files in a tree.
1688
1724
    """
1689
1725
 
 
1726
    _see_also = ['status', 'cat']
1690
1727
    takes_args = ['path?']
1691
1728
    # TODO: Take a revision or remote path and list that tree instead.
1692
1729
    takes_options = ['verbose', 'revision',
1776
1813
 
1777
1814
class cmd_unknowns(Command):
1778
1815
    """List unknown files.
1779
 
 
1780
 
    See also: "bzr ls --unknown".
1781
1816
    """
1782
1817
 
1783
1818
    hidden = True
 
1819
    _see_also = ['ls']
1784
1820
 
1785
1821
    @display_command
1786
1822
    def run(self):
1821
1857
        bzr ignore 'lib/**/*.o'
1822
1858
        bzr ignore 'RE:lib/.*\.o'
1823
1859
    """
 
1860
 
 
1861
    _see_also = ['status', 'ignored']
1824
1862
    takes_args = ['name_pattern*']
1825
1863
    takes_options = [
1826
1864
                     Option('old-default-rules',
1876
1914
 
1877
1915
class cmd_ignored(Command):
1878
1916
    """List ignored files and the patterns that matched them.
 
1917
    """
1879
1918
 
1880
 
    See also: bzr ignore"""
 
1919
    _see_also = ['ignore']
1881
1920
    @display_command
1882
1921
    def run(self):
1883
1922
        tree = WorkingTree.open_containing(u'.')[0]
1972
2011
    binary file. 
1973
2012
    """
1974
2013
 
 
2014
    _see_also = ['ls']
1975
2015
    takes_options = ['revision', 'name-from-revision']
1976
2016
    takes_args = ['filename']
1977
2017
    encoding_type = 'exact'
2063
2103
 
2064
2104
    # XXX: verbose currently does nothing
2065
2105
 
 
2106
    _see_also = ['bugs', 'uncommit']
2066
2107
    takes_args = ['selected*']
2067
2108
    takes_options = ['message', 'verbose', 
2068
2109
                     Option('unchanged',
2074
2115
                     Option('strict',
2075
2116
                            help="refuse to commit if there are unknown "
2076
2117
                            "files in the working tree."),
 
2118
                     ListOption('fixes', type=str,
 
2119
                                help="mark a bug as being fixed by this "
 
2120
                                     "revision."),
2077
2121
                     Option('local',
2078
2122
                            help="perform a local only commit in a bound "
2079
2123
                                 "branch. Such commits are not pushed to "
2083
2127
                     ]
2084
2128
    aliases = ['ci', 'checkin']
2085
2129
 
 
2130
    def _get_bug_fix_properties(self, fixes, branch):
 
2131
        properties = []
 
2132
        # Configure the properties for bug fixing attributes.
 
2133
        for fixed_bug in fixes:
 
2134
            tokens = fixed_bug.split(':')
 
2135
            if len(tokens) != 2:
 
2136
                raise errors.BzrCommandError(
 
2137
                    "Invalid bug %s. Must be in the form of 'tag:id'. "
 
2138
                    "Commit refused." % fixed_bug)
 
2139
            tag, bug_id = tokens
 
2140
            try:
 
2141
                bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
 
2142
            except errors.UnknownBugTrackerAbbreviation:
 
2143
                raise errors.BzrCommandError(
 
2144
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
 
2145
            except errors.MalformedBugIdentifier:
 
2146
                raise errors.BzrCommandError(
 
2147
                    "Invalid bug identifier for %s. Commit refused."
 
2148
                    % fixed_bug)
 
2149
            properties.append('%s fixed' % bug_url)
 
2150
        return '\n'.join(properties)
 
2151
 
2086
2152
    def run(self, message=None, file=None, verbose=True, selected_list=None,
2087
 
            unchanged=False, strict=False, local=False):
 
2153
            unchanged=False, strict=False, local=False, fixes=None):
2088
2154
        from bzrlib.commit import (NullCommitReporter, ReportCommitToLog)
2089
2155
        from bzrlib.errors import (PointlessCommit, ConflictsInTree,
2090
2156
                StrictCommitFailed)
2096
2162
 
2097
2163
        # TODO: do more checks that the commit will succeed before 
2098
2164
        # spending the user's valuable time typing a commit message.
 
2165
 
 
2166
        properties = {}
 
2167
 
2099
2168
        tree, selected_list = tree_files(selected_list)
2100
2169
        if selected_list == ['']:
2101
2170
            # workaround - commit of root of tree should be exactly the same
2103
2172
            # selected-file merge commit is not done yet
2104
2173
            selected_list = []
2105
2174
 
 
2175
        bug_property = self._get_bug_fix_properties(fixes, tree.branch)
 
2176
        if bug_property:
 
2177
            properties['bugs'] = bug_property
 
2178
 
2106
2179
        if local and not tree.branch.get_bound_location():
2107
2180
            raise errors.LocalRequiresBoundBranch()
2108
2181
 
2124
2197
            if my_message == "":
2125
2198
                raise errors.BzrCommandError("empty commit message specified")
2126
2199
            return my_message
2127
 
        
 
2200
 
2128
2201
        if verbose:
2129
2202
            reporter = ReportCommitToLog()
2130
2203
        else:
2134
2207
            tree.commit(message_callback=get_message,
2135
2208
                        specific_files=selected_list,
2136
2209
                        allow_pointless=unchanged, strict=strict, local=local,
2137
 
                        reporter=reporter)
 
2210
                        reporter=reporter, revprops=properties)
2138
2211
        except PointlessCommit:
2139
2212
            # FIXME: This should really happen before the file is read in;
2140
2213
            # perhaps prepare the commit; get the message; then actually commit
2160
2233
    This command checks various invariants about the branch storage to
2161
2234
    detect data corruption or bzr bugs.
2162
2235
    """
 
2236
 
 
2237
    _see_also = ['reconcile']
2163
2238
    takes_args = ['branch?']
2164
2239
    takes_options = ['verbose']
2165
2240
 
2180
2255
    this command. When the default format has changed you may also be warned
2181
2256
    during other operations to upgrade.
2182
2257
    """
 
2258
 
 
2259
    _see_also = ['check']
2183
2260
    takes_args = ['url?']
2184
2261
    takes_options = [
2185
2262
                    RegistryOption('format',
2248
2325
    If unset, the tree root directory name is used as the nickname
2249
2326
    To print the current nickname, execute with no argument.  
2250
2327
    """
 
2328
 
 
2329
    _see_also = ['info']
2251
2330
    takes_args = ['nickname?']
2252
2331
    def run(self, nickname=None):
2253
2332
        branch = Branch.open_containing(u'.')[0]
2264
2343
class cmd_selftest(Command):
2265
2344
    """Run internal test suite.
2266
2345
    
2267
 
    This creates temporary test directories in the working directory, but not
 
2346
    This creates temporary test directories in the working directory, but no
2268
2347
    existing data is affected.  These directories are deleted if the tests
2269
2348
    pass, or left behind to help in debugging if they fail and --keep-output
2270
2349
    is specified.
2277
2356
    all other tests are run.  This is useful if you have been working in a
2278
2357
    particular area, but want to make sure nothing else was broken.
2279
2358
 
 
2359
    If --exclude is given, tests that match that regular expression are
 
2360
    excluded, regardless of whether they match --first or not.
 
2361
 
 
2362
    To help catch accidential dependencies between tests, the --randomize
 
2363
    option is useful. In most cases, the argument used is the word 'now'.
 
2364
    Note that the seed used for the random number generator is displayed
 
2365
    when this option is used. The seed can be explicitly passed as the
 
2366
    argument to this option if required. This enables reproduction of the
 
2367
    actual ordering used if and when an order sensitive problem is encountered.
 
2368
 
 
2369
    If --list-only is given, the tests that would be run are listed. This is
 
2370
    useful when combined with --first, --exclude and/or --randomize to
 
2371
    understand their impact. The test harness reports "Listed nn tests in ..."
 
2372
    instead of "Ran nn tests in ..." when list mode is enabled.
 
2373
 
2280
2374
    If the global option '--no-plugins' is given, plugins are not loaded
2281
2375
    before running the selftests.  This has two effects: features provided or
2282
2376
    modified by plugins will not be tested, and tests provided by plugins will
2295
2389
    of running tests to create such subdirectories. This is default behavior
2296
2390
    on Windows because of path length limitation.
2297
2391
    """
2298
 
    # TODO: --list should give a list of all available tests
2299
 
 
2300
2392
    # NB: this is used from the class without creating an instance, which is
2301
2393
    # why it does not have a self parameter.
2302
2394
    def get_transport_type(typestring):
2317
2409
    hidden = True
2318
2410
    takes_args = ['testspecs*']
2319
2411
    takes_options = ['verbose',
2320
 
                     Option('one', help='stop when one test fails'),
 
2412
                     Option('one',
 
2413
                             help='stop when one test fails',
 
2414
                             short_name='1',
 
2415
                             ),
2321
2416
                     Option('keep-output',
2322
2417
                            help='keep output directories when tests fail'),
2323
2418
                     Option('transport',
2335
2430
                            help='clean temporary tests directories'
2336
2431
                                 ' without running tests'),
2337
2432
                     Option('first',
2338
 
                            help='run all tests, but run specified tests first'
 
2433
                            help='run all tests, but run specified tests first',
 
2434
                            short_name='f',
2339
2435
                            ),
2340
2436
                     Option('numbered-dirs',
2341
2437
                            help='use numbered dirs for TestCaseInTempDir'),
 
2438
                     Option('list-only',
 
2439
                            help='list the tests instead of running them'),
 
2440
                     Option('randomize', type=str, argname="SEED",
 
2441
                            help='randomize the order of tests using the given'
 
2442
                                 ' seed or "now" for the current time'),
 
2443
                     Option('exclude', type=str, argname="PATTERN",
 
2444
                            short_name='x',
 
2445
                            help='exclude tests that match this regular'
 
2446
                                 ' expression'),
2342
2447
                     ]
2343
2448
    encoding_type = 'replace'
2344
2449
 
2345
2450
    def run(self, testspecs_list=None, verbose=None, one=False,
2346
2451
            keep_output=False, transport=None, benchmark=None,
2347
2452
            lsprof_timed=None, cache_dir=None, clean_output=False,
2348
 
            first=False, numbered_dirs=None):
 
2453
            first=False, numbered_dirs=None, list_only=False,
 
2454
            randomize=None, exclude=None):
2349
2455
        import bzrlib.ui
2350
2456
        from bzrlib.tests import selftest
2351
2457
        import bzrlib.benchmarks as benchmarks
2390
2496
                              bench_history=benchfile,
2391
2497
                              matching_tests_first=first,
2392
2498
                              numbered_dirs=numbered_dirs,
 
2499
                              list_only=list_only,
 
2500
                              random_seed=randomize,
 
2501
                              exclude_pattern=exclude
2393
2502
                              )
2394
2503
        finally:
2395
2504
            if benchfile is not None:
2488
2597
    merge refuses to run if there are any uncommitted changes, unless
2489
2598
    --force is given.
2490
2599
    """
 
2600
 
 
2601
    _see_also = ['update', 'remerge']
2491
2602
    takes_args = ['branch?']
2492
2603
    takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
2493
2604
        Option('show-base', help="Show base revision text in "
2753
2864
    name.  If you name a directory, all the contents of that directory will be
2754
2865
    reverted.
2755
2866
    """
 
2867
 
 
2868
    _see_also = ['cat', 'export']
2756
2869
    takes_options = ['revision', 'no-backup']
2757
2870
    takes_args = ['file*']
2758
2871
 
2792
2905
 
2793
2906
class cmd_help(Command):
2794
2907
    """Show help on a command or other topic.
 
2908
    """
2795
2909
 
2796
 
    For a list of all available commands, say 'bzr help commands'.
2797
 
    """
 
2910
    _see_also = ['topics']
2798
2911
    takes_options = [Option('long', 'show help on all commands')]
2799
2912
    takes_args = ['topic?']
2800
2913
    aliases = ['?', '--help', '-?', '-h']
2841
2954
 
2842
2955
    OTHER_BRANCH may be local or remote.
2843
2956
    """
 
2957
 
 
2958
    _see_also = ['merge', 'pull']
2844
2959
    takes_args = ['other_branch?']
2845
2960
    takes_options = [Option('reverse', 'Reverse the order of revisions'),
2846
2961
                     Option('mine-only', 
2943
3058
 
2944
3059
class cmd_testament(Command):
2945
3060
    """Show testament (signing-form) of a revision."""
2946
 
    takes_options = ['revision', 
 
3061
    takes_options = ['revision',
2947
3062
                     Option('long', help='Produce long-format testament'), 
2948
3063
                     Option('strict', help='Produce a strict-format'
2949
3064
                            ' testament')]
3059
3174
 
3060
3175
    Once converted into a checkout, commits must succeed on the master branch
3061
3176
    before they will be applied to the local branch.
3062
 
 
3063
 
    See "help checkouts" for more information on checkouts.
3064
3177
    """
3065
3178
 
 
3179
    _see_also = ['checkouts', 'unbind']
3066
3180
    takes_args = ['location?']
3067
3181
    takes_options = []
3068
3182
 
3091
3205
 
3092
3206
    After unbinding, the local branch is considered independent and subsequent
3093
3207
    commits will be local only.
3094
 
 
3095
 
    See "help checkouts" for more information on checkouts.
3096
3208
    """
3097
3209
 
 
3210
    _see_also = ['checkouts', 'bind']
3098
3211
    takes_args = []
3099
3212
    takes_options = []
3100
3213
 
3119
3232
    # unreferenced information in 'branch-as-repository' branches.
3120
3233
    # TODO: jam 20060108 Add the ability for uncommit to remove unreferenced
3121
3234
    # information in shared branches as well.
 
3235
    _see_also = ['commit']
3122
3236
    takes_options = ['verbose', 'revision',
3123
3237
                    Option('dry-run', help='Don\'t actually make changes'),
3124
3238
                    Option('force', help='Say yes to all questions.')]
3248
3362
        ]
3249
3363
 
3250
3364
    def run(self, port=None, inet=False, directory=None, allow_writes=False):
3251
 
        from bzrlib.smart import server, medium
 
3365
        from bzrlib.smart import medium, server
3252
3366
        from bzrlib.transport import get_transport
3253
 
        from bzrlib.transport.remote import BZR_DEFAULT_PORT
 
3367
        from bzrlib.transport.chroot import ChrootServer
 
3368
        from bzrlib.transport.remote import BZR_DEFAULT_PORT, BZR_DEFAULT_INTERFACE
3254
3369
        if directory is None:
3255
3370
            directory = os.getcwd()
3256
3371
        url = urlutils.local_path_to_url(directory)
3257
3372
        if not allow_writes:
3258
3373
            url = 'readonly+' + url
3259
 
        t = get_transport(url)
 
3374
        chroot_server = ChrootServer(get_transport(url))
 
3375
        chroot_server.setUp()
 
3376
        t = get_transport(chroot_server.get_url())
3260
3377
        if inet:
3261
3378
            smart_server = medium.SmartServerPipeStreamMedium(
3262
3379
                sys.stdin, sys.stdout, t)
3263
3380
        else:
 
3381
            host = BZR_DEFAULT_INTERFACE
3264
3382
            if port is None:
3265
3383
                port = BZR_DEFAULT_PORT
3266
 
                host = '127.0.0.1'
3267
3384
            else:
3268
3385
                if ':' in port:
3269
3386
                    host, port = port.split(':')
3270
 
                else:
3271
 
                    host = '127.0.0.1'
3272
3387
                port = int(port)
3273
3388
            smart_server = server.SmartTCPServer(t, host=host, port=port)
3274
3389
            print 'listening on port: ', smart_server.port
3275
3390
            sys.stdout.flush()
3276
 
        smart_server.serve()
 
3391
        # for the duration of this server, no UI output is permitted.
 
3392
        # note that this may cause problems with blackbox tests. This should
 
3393
        # be changed with care though, as we dont want to use bandwidth sending
 
3394
        # progress over stderr to smart server clients!
 
3395
        old_factory = ui.ui_factory
 
3396
        try:
 
3397
            ui.ui_factory = ui.SilentUIFactory()
 
3398
            smart_server.serve()
 
3399
        finally:
 
3400
            ui.ui_factory = old_factory
 
3401
 
3277
3402
 
3278
3403
class cmd_join(Command):
3279
3404
    """Combine a subtree into its containing tree.
3296
3421
    and merge, will recurse into the subtree.
3297
3422
    """
3298
3423
 
 
3424
    _see_also = ['split']
3299
3425
    takes_args = ['tree']
3300
3426
    takes_options = [Option('reference', 'join by reference')]
3301
3427
    hidden = True
3337
3463
    subdirectory will be converted into an independent tree, with its own
3338
3464
    branch.  Commits in the top-level tree will not apply to the new subtree.
3339
3465
    If you want that behavior, do "bzr join --reference TREE".
3340
 
 
3341
 
    To undo this operation, do "bzr join TREE".
3342
3466
    """
3343
3467
 
 
3468
    _see_also = ['join']
3344
3469
    takes_args = ['tree']
3345
3470
 
3346
3471
    hidden = True
3456
3581
    --force, in which case the tag is moved to point to the new revision.
3457
3582
    """
3458
3583
 
 
3584
    _see_also = ['commit', 'tags']
3459
3585
    takes_args = ['tag_name']
3460
3586
    takes_options = [
3461
3587
        Option('delete',
3507
3633
    This tag shows a table of tag names and the revisions they reference.
3508
3634
    """
3509
3635
 
 
3636
    _see_also = ['tag']
3510
3637
    takes_options = [
3511
3638
        Option('directory',
3512
3639
            help='Branch whose tags should be displayed',