~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Ross Lagerwall
  • Date: 2012-08-07 06:32:51 UTC
  • mto: (6437.63.5 2.5)
  • mto: This revision was merged to the branch mainline in revision 6558.
  • Revision ID: rosslagerwall@gmail.com-20120807063251-x9p03ghg2ws8oqjc
Add bzrlib/locale to .bzrignore

bzrlib/locale is generated with ./setup.py build_mo which is in turn called
by ./setup.py build

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
86
86
def _get_branch_location(control_dir, possible_transports=None):
87
87
    """Return location of branch for this control dir."""
88
88
    try:
89
 
        target = control_dir.get_branch_reference()
 
89
        this_branch = control_dir.open_branch(
 
90
            possible_transports=possible_transports)
 
91
        # This may be a heavy checkout, where we want the master branch
 
92
        master_location = this_branch.get_bound_location()
 
93
        if master_location is not None:
 
94
            return master_location
 
95
        # If not, use a local sibling
 
96
        return this_branch.base
90
97
    except errors.NotBranchError:
91
 
        return control_dir.root_transport.base
92
 
    if target is not None:
93
 
        return target
94
 
    this_branch = control_dir.open_branch(
95
 
        possible_transports=possible_transports)
96
 
    # This may be a heavy checkout, where we want the master branch
97
 
    master_location = this_branch.get_bound_location()
98
 
    if master_location is not None:
99
 
        return master_location
100
 
    # If not, use a local sibling
101
 
    return this_branch.base
 
98
        format = control_dir.find_branch_format()
 
99
        if getattr(format, 'get_reference', None) is not None:
 
100
            return format.get_reference(control_dir)
 
101
        else:
 
102
            return control_dir.root_transport.base
102
103
 
103
104
 
104
105
def _is_colocated(control_dir, possible_transports=None):
105
106
    """Check if the branch in control_dir is colocated.
106
107
 
107
108
    :param control_dir: Control directory
108
 
    :return: Tuple with boolean indicating whether the branch is colocated
109
 
        and the full URL to the actual branch
 
109
    :return: Boolean indicating whether 
110
110
    """
111
111
    # This path is meant to be relative to the existing branch
112
112
    this_url = _get_branch_location(control_dir,
132
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
133
133
    """Lookup the location for a new sibling branch.
134
134
 
135
 
    :param control_dir: Control directory to find sibling branches from
 
135
    :param control_dir: Control directory relative to which to look up
 
136
        the name.
136
137
    :param location: Name of the new branch
137
138
    :return: Full location to the new branch
138
139
    """
149
150
 
150
151
 
151
152
def open_sibling_branch(control_dir, location, possible_transports=None):
152
 
    """Open a branch, possibly a sibling of another.
 
153
    """Open a branch, possibly a sibling.
153
154
 
154
155
    :param control_dir: Control directory relative to which to lookup the
155
156
        location.
188
189
        possible_transports=possible_transports)
189
190
 
190
191
 
191
 
def iter_sibling_branches(control_dir, possible_transports=None):
192
 
    """Iterate over the siblings of a branch.
193
 
 
194
 
    :param control_dir: Control directory for which to look up the siblings
195
 
    :return: Iterator over tuples with branch name and branch object
196
 
    """
197
 
    seen_urls = set()
198
 
    try:
199
 
        reference = control_dir.get_branch_reference()
200
 
    except errors.NotBranchError:
201
 
        # There is no active branch, just return the colocated branches.
202
 
        for name, branch in control_dir.get_branches().iteritems():
203
 
            yield name, branch
204
 
        return
205
 
    if reference is not None:
206
 
        ref_branch = Branch.open(reference,
207
 
            possible_transports=possible_transports)
208
 
    else:
209
 
        ref_branch = None
210
 
    if ref_branch is None or ref_branch.name:
211
 
        if ref_branch is not None:
212
 
            control_dir = ref_branch.bzrdir
213
 
        for name, branch in control_dir.get_branches().iteritems():
214
 
            yield name, branch
215
 
    else:
216
 
        repo = ref_branch.bzrdir.find_repository()
217
 
        for branch in repo.find_branches(using=True):
218
 
            name = urlutils.relative_url(repo.user_url,
219
 
                branch.user_url).rstrip("/")
220
 
            yield name, branch
 
192
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
 
193
def tree_files(file_list, default_branch=u'.', canonicalize=True,
 
194
    apply_view=True):
 
195
    return internal_tree_files(file_list, default_branch, canonicalize,
 
196
        apply_view)
221
197
 
222
198
 
223
199
def tree_files_for_add(file_list):
285
261
    return rev_tree
286
262
 
287
263
 
 
264
# XXX: Bad function name; should possibly also be a class method of
 
265
# WorkingTree rather than a function.
 
266
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
 
267
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
 
268
    apply_view=True):
 
269
    """Convert command-line paths to a WorkingTree and relative paths.
 
270
 
 
271
    Deprecated: use WorkingTree.open_containing_paths instead.
 
272
 
 
273
    This is typically used for command-line processors that take one or
 
274
    more filenames, and infer the workingtree that contains them.
 
275
 
 
276
    The filenames given are not required to exist.
 
277
 
 
278
    :param file_list: Filenames to convert.
 
279
 
 
280
    :param default_branch: Fallback tree path to use if file_list is empty or
 
281
        None.
 
282
 
 
283
    :param apply_view: if True and a view is set, apply it or check that
 
284
        specified files are within it
 
285
 
 
286
    :return: workingtree, [relative_paths]
 
287
    """
 
288
    return WorkingTree.open_containing_paths(
 
289
        file_list, default_directory='.',
 
290
        canonicalize=True,
 
291
        apply_view=True)
 
292
 
 
293
 
288
294
def _get_view_info_for_change_reporter(tree):
289
295
    """Get the view information from a tree for change reporting."""
290
296
    view_info = None
368
374
    This will produce the same results as calling 'bzr diff --summarize'.
369
375
    """
370
376
 
371
 
    # TODO: --no-recurse/-N, --recurse options
 
377
    # TODO: --no-recurse, --recurse options
372
378
 
373
379
    takes_args = ['file*']
374
380
    takes_options = ['show-ids', 'revision', 'change', 'verbose',
685
691
            if revision:
686
692
                if len(revision) != 1:
687
693
                    raise errors.BzrCommandError(gettext(
688
 
                        "Revision numbers only make sense for single "
689
 
                        "revisions, not ranges"))
 
694
                        "Tags can only be placed on a single revision, "
 
695
                        "not on a range"))
690
696
                revid = revision[0].as_revision_id(b)
691
697
            else:
692
698
                revid = b.last_revision()
803
809
    takes_args = ['file*']
804
810
    takes_options = [
805
811
        Option('no-recurse',
806
 
               help="Don't recursively add the contents of directories.",
807
 
               short_name='N'),
 
812
               help="Don't recursively add the contents of directories."),
808
813
        Option('dry-run',
809
814
               help="Show what would be done, but don't actually do anything."),
810
815
        'verbose',
950
955
            tree = work_tree
951
956
            extra_trees = []
952
957
 
953
 
        self.add_cleanup(tree.lock_read().unlock)
954
958
        if file_list is not None:
955
959
            file_ids = tree.paths2ids(file_list, trees=extra_trees,
956
960
                                      require_versioned=True)
957
961
            # find_ids_across_trees may include some paths that don't
958
962
            # exist in 'tree'.
959
 
            entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
 
963
            entries = sorted(
 
964
                (tree.id2path(file_id), tree.inventory[file_id])
 
965
                for file_id in file_ids if tree.has_id(file_id))
960
966
        else:
961
 
            entries = tree.iter_entries_by_dir()
 
967
            entries = tree.inventory.entries()
962
968
 
963
 
        for path, entry in sorted(entries):
 
969
        self.cleanup_now()
 
970
        for path, entry in entries:
964
971
            if kind and kind != entry.kind:
965
972
                continue
966
 
            if path == "":
967
 
                continue
968
973
            if show_ids:
969
974
                self.outf.write('%-50s %s\n' % (path, entry.file_id))
970
975
            else:
1042
1047
                and rel_names[0].lower() == rel_names[1].lower()):
1043
1048
                into_existing = False
1044
1049
            else:
 
1050
                inv = tree.inventory
1045
1051
                # 'fix' the case of a potential 'from'
1046
1052
                from_id = tree.path2id(
1047
1053
                            tree.get_canonical_inventory_path(rel_names[0]))
1048
1054
                if (not osutils.lexists(names_list[0]) and
1049
 
                    from_id and tree.stored_kind(from_id) == "directory"):
 
1055
                    from_id and inv.get_file_kind(from_id) == "directory"):
1050
1056
                    into_existing = False
1051
1057
        # move/rename
1052
1058
        if into_existing:
1153
1159
                 "the master branch."
1154
1160
            ),
1155
1161
        Option('show-base',
1156
 
            help="Show base revision text in conflicts."),
1157
 
        Option('overwrite-tags',
1158
 
            help="Overwrite tags only."),
 
1162
            help="Show base revision text in conflicts.")
1159
1163
        ]
1160
1164
    takes_args = ['location?']
1161
1165
    encoding_type = 'replace'
1163
1167
    def run(self, location=None, remember=None, overwrite=False,
1164
1168
            revision=None, verbose=False,
1165
1169
            directory=None, local=False,
1166
 
            show_base=False, overwrite_tags=False):
1167
 
 
1168
 
        if overwrite:
1169
 
            overwrite = ["history", "tags"]
1170
 
        elif overwrite_tags:
1171
 
            overwrite = ["tags"]
1172
 
        else:
1173
 
            overwrite = []
 
1170
            show_base=False):
1174
1171
        # FIXME: too much stuff is in the command class
1175
1172
        revision_id = None
1176
1173
        mergeable = None
1184
1181
            tree_to = None
1185
1182
            branch_to = Branch.open_containing(directory)[0]
1186
1183
            self.add_cleanup(branch_to.lock_write().unlock)
1187
 
            if show_base:
1188
 
                warning(gettext("No working tree, ignoring --show-base"))
 
1184
 
 
1185
        if tree_to is None and show_base:
 
1186
            raise errors.BzrCommandError(gettext("Need working tree for --show-base."))
1189
1187
 
1190
1188
        if local and not branch_to.get_bound_location():
1191
1189
            raise errors.LocalRequiresBoundBranch()
1226
1224
            # Remembers if asked explicitly or no previous location is set
1227
1225
            if (remember
1228
1226
                or (remember is None and branch_to.get_parent() is None)):
1229
 
                # FIXME: This shouldn't be done before the pull
1230
 
                # succeeds... -- vila 2012-01-02
1231
1227
                branch_to.set_parent(branch_from.base)
1232
1228
 
1233
1229
        if revision is not None:
1313
1309
        Option('no-tree',
1314
1310
               help="Don't populate the working tree, even for protocols"
1315
1311
               " that support it."),
1316
 
        Option('overwrite-tags',
1317
 
              help="Overwrite tags only."),
1318
1312
        ]
1319
1313
    takes_args = ['location?']
1320
1314
    encoding_type = 'replace'
1322
1316
    def run(self, location=None, remember=None, overwrite=False,
1323
1317
        create_prefix=False, verbose=False, revision=None,
1324
1318
        use_existing_dir=False, directory=None, stacked_on=None,
1325
 
        stacked=False, strict=None, no_tree=False,
1326
 
        overwrite_tags=False):
 
1319
        stacked=False, strict=None, no_tree=False):
1327
1320
        from bzrlib.push import _show_push_branch
1328
1321
 
1329
 
        if overwrite:
1330
 
            overwrite = ["history", "tags"]
1331
 
        elif overwrite_tags:
1332
 
            overwrite = ["tags"]
1333
 
        else:
1334
 
            overwrite = []
1335
 
 
1336
1322
        if directory is None:
1337
1323
            directory = '.'
1338
1324
        # Get the source branch
1572
1558
                active_branch = dir.open_branch(name="")
1573
1559
            except errors.NotBranchError:
1574
1560
                active_branch = None
 
1561
            branches = dir.get_branches()
1575
1562
            names = {}
1576
 
            for name, branch in iter_sibling_branches(dir):
 
1563
            for name, branch in branches.iteritems():
1577
1564
                if name == "":
1578
1565
                    continue
1579
1566
                active = (active_branch is not None and
1614
1601
    code.)
1615
1602
    """
1616
1603
 
1617
 
    _see_also = ['checkouts', 'branch', 'working-trees', 'remove-tree']
 
1604
    _see_also = ['checkouts', 'branch']
1618
1605
    takes_args = ['branch_location?', 'to_location?']
1619
1606
    takes_options = ['revision',
1620
1607
                     Option('lightweight',
1680
1667
    def run(self, dir=u'.'):
1681
1668
        tree = WorkingTree.open_containing(dir)[0]
1682
1669
        self.add_cleanup(tree.lock_read().unlock)
 
1670
        new_inv = tree.inventory
1683
1671
        old_tree = tree.basis_tree()
1684
1672
        self.add_cleanup(old_tree.lock_read().unlock)
 
1673
        old_inv = old_tree.inventory
1685
1674
        renames = []
1686
1675
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1687
1676
        for f, paths, c, v, p, n, k, e in iterator:
1858
1847
 
1859
1848
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1860
1849
    delete them if they can easily be recovered using revert otherwise they
1861
 
    will be backed up (adding an extension of the form .~#~). If no options or
 
1850
    will be backed up (adding an extention of the form .~#~). If no options or
1862
1851
    parameters are given Bazaar will scan for files that are being tracked by
1863
1852
    Bazaar but missing in your tree and stop tracking them for you.
1864
1853
    """
1870
1859
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1871
1860
            safe='Backup changed files (default).',
1872
1861
            keep='Delete from bzr but leave the working copy.',
1873
 
            no_backup='Don\'t backup changed files.'),
1874
 
        ]
 
1862
            no_backup='Don\'t backup changed files.',
 
1863
            force='Delete all the specified files, even if they can not be '
 
1864
                'recovered and even if they are non-empty directories. '
 
1865
                '(deprecated, use no-backup)')]
1875
1866
    aliases = ['rm', 'del']
1876
1867
    encoding_type = 'replace'
1877
1868
 
1878
1869
    def run(self, file_list, verbose=False, new=False,
1879
1870
        file_deletion_strategy='safe'):
 
1871
        if file_deletion_strategy == 'force':
 
1872
            note(gettext("(The --force option is deprecated, rather use --no-backup "
 
1873
                "in future.)"))
 
1874
            file_deletion_strategy = 'no-backup'
1880
1875
 
1881
1876
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1882
1877
 
2066
2061
         RegistryOption('format',
2067
2062
                help='Specify a format for this branch. '
2068
2063
                'See "help formats".',
2069
 
                lazy_registry=('bzrlib.controldir', 'format_registry'),
 
2064
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
2070
2065
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
2071
2066
                value_switches=True,
2072
2067
                title="Branch format",
2328
2323
            help='Diff format to use.',
2329
2324
            lazy_registry=('bzrlib.diff', 'format_registry'),
2330
2325
            title='Diff format'),
2331
 
        Option('context',
2332
 
            help='How many lines of context to show.',
2333
 
            type=int,
2334
 
            ),
2335
2326
        ]
2336
2327
    aliases = ['di', 'dif']
2337
2328
    encoding_type = 'exact'
2338
2329
 
2339
2330
    @display_command
2340
2331
    def run(self, revision=None, file_list=None, diff_options=None,
2341
 
            prefix=None, old=None, new=None, using=None, format=None, 
2342
 
            context=None):
 
2332
            prefix=None, old=None, new=None, using=None, format=None):
2343
2333
        from bzrlib.diff import (get_trees_and_branches_to_diff_locked,
2344
2334
            show_diff_trees)
2345
2335
 
2378
2368
                               old_label=old_label, new_label=new_label,
2379
2369
                               extra_trees=extra_trees,
2380
2370
                               path_encoding=path_encoding,
2381
 
                               using=using, context=context,
 
2371
                               using=using,
2382
2372
                               format_cls=format)
2383
2373
 
2384
2374
 
2400
2390
        self.add_cleanup(tree.lock_read().unlock)
2401
2391
        old = tree.basis_tree()
2402
2392
        self.add_cleanup(old.lock_read().unlock)
2403
 
        for path, ie in old.iter_entries_by_dir():
 
2393
        for path, ie in old.inventory.iter_entries():
2404
2394
            if not tree.has_id(ie.file_id):
2405
2395
                self.outf.write(path)
2406
2396
                if show_ids:
2444
2434
        self.add_cleanup(wt.lock_read().unlock)
2445
2435
        basis = wt.basis_tree()
2446
2436
        self.add_cleanup(basis.lock_read().unlock)
2447
 
        root_id = wt.get_root_id()
2448
 
        for file_id in wt.all_file_ids():
2449
 
            if basis.has_id(file_id):
2450
 
                continue
2451
 
            if root_id == file_id:
2452
 
                continue
2453
 
            path = wt.id2path(file_id)
 
2437
        basis_inv = basis.inventory
 
2438
        inv = wt.inventory
 
2439
        for file_id in inv:
 
2440
            if basis_inv.has_id(file_id):
 
2441
                continue
 
2442
            if inv.is_root(file_id) and len(basis_inv) == 0:
 
2443
                continue
 
2444
            path = inv.id2path(file_id)
2454
2445
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2455
2446
                continue
2456
2447
            if null:
2818
2809
            self.add_cleanup(b.lock_read().unlock)
2819
2810
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2820
2811
 
2821
 
        if b.get_config_stack().get('validate_signatures_in_log'):
 
2812
        if b.get_config().validate_signatures_in_log():
2822
2813
            signatures = True
2823
2814
 
2824
2815
        if signatures:
3544
3535
            tokens = fixed_bug.split(':')
3545
3536
            if len(tokens) == 1:
3546
3537
                if default_bugtracker is None:
3547
 
                    branch_config = branch.get_config_stack()
3548
 
                    default_bugtracker = branch_config.get(
 
3538
                    branch_config = branch.get_config()
 
3539
                    default_bugtracker = branch_config.get_user_option(
3549
3540
                        "bugtracker")
3550
3541
                if default_bugtracker is None:
3551
3542
                    raise errors.BzrCommandError(gettext(
3890
3881
            if directory is None:
3891
3882
                c = Branch.open_containing(u'.')[0].get_config_stack()
3892
3883
            else:
3893
 
                b = Branch.open(directory)
3894
 
                self.add_cleanup(b.lock_write().unlock)
3895
 
                c = b.get_config_stack()
 
3884
                c = Branch.open(directory).get_config_stack()
3896
3885
        else:
3897
3886
            c = _mod_config.GlobalStack()
3898
3887
        c.set('email', name)
4705
4694
                if tree.kind(file_id) != "directory":
4706
4695
                    continue
4707
4696
 
4708
 
                # FIXME: Support nested trees
4709
 
                for name, ie in tree.root_inventory.iter_entries(file_id):
 
4697
                for name, ie in tree.inventory.iter_entries(file_id):
4710
4698
                    interesting_ids.add(ie.file_id)
4711
4699
            new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4712
4700
        else:
4745
4733
 
4746
4734
 
4747
4735
class cmd_revert(Command):
4748
 
    __doc__ = """\
4749
 
    Set files in the working tree back to the contents of a previous revision.
 
4736
    __doc__ = """Revert files to a previous revision.
4750
4737
 
4751
4738
    Giving a list of files will revert only those files.  Otherwise, all files
4752
4739
    will be reverted.  If the revision is not specified with '--revision', the
4753
 
    working tree basis revision is used. A revert operation affects only the
4754
 
    working tree, not any revision history like the branch and repository or
4755
 
    the working tree basis revision.
 
4740
    last committed revision is used.
4756
4741
 
4757
4742
    To remove only some changes, without reverting to a prior version, use
4758
4743
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
4759
4744
    will remove the changes introduced by the second last commit (-2), without
4760
4745
    affecting the changes introduced by the last commit (-1).  To remove
4761
4746
    certain changes on a hunk-by-hunk basis, see the shelve command.
4762
 
    To update the branch to a specific revision or the latest revision and
4763
 
    update the working tree accordingly while preserving local changes, see the
4764
 
    update command.
4765
4747
 
4766
 
    Uncommitted changes to files that are reverted will be discarded.
4767
 
    Howver, by default, any files that have been manually changed will be
4768
 
    backed up first.  (Files changed only by merge are not backed up.)  Backup
4769
 
    files have '.~#~' appended to their name, where # is a number.
 
4748
    By default, any files that have been manually changed will be backed up
 
4749
    first.  (Files changed only by merge are not backed up.)  Backup files have
 
4750
    '.~#~' appended to their name, where # is a number.
4770
4751
 
4771
4752
    When you provide files, you can use their current pathname or the pathname
4772
4753
    from the target revision.  So you can use revert to "undelete" a file by
5019
5000
                             "You have %d extra revisions:\n", 
5020
5001
                             len(local_extra)) %
5021
5002
                len(local_extra))
5022
 
            rev_tag_dict = {}
5023
 
            if local_branch.supports_tags():
5024
 
                rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5025
5003
            for revision in iter_log_revisions(local_extra,
5026
5004
                                local_branch.repository,
5027
 
                                verbose,
5028
 
                                rev_tag_dict):
 
5005
                                verbose):
5029
5006
                lf.log_revision(revision)
5030
5007
            printed_local = True
5031
5008
            status_code = 1
5039
5016
                             "You are missing %d revisions:\n",
5040
5017
                             len(remote_extra)) %
5041
5018
                len(remote_extra))
5042
 
            if remote_branch.supports_tags():
5043
 
                rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5044
5019
            for revision in iter_log_revisions(remote_extra,
5045
5020
                                remote_branch.repository,
5046
 
                                verbose,
5047
 
                                rev_tag_dict):
 
5021
                                verbose):
5048
5022
                lf.log_revision(revision)
5049
5023
            status_code = 1
5050
5024
 
5140
5114
            Option('strict',
5141
5115
                   help='Produce a strict-format testament.')]
5142
5116
    takes_args = ['branch?']
5143
 
    encoding_type = 'exact'
5144
5117
    @display_command
5145
5118
    def run(self, branch=u'.', revision=None, long=False, strict=False):
5146
5119
        from bzrlib.testament import Testament, StrictTestament
5159
5132
            rev_id = revision[0].as_revision_id(b)
5160
5133
        t = testament_class.from_revision(b.repository, rev_id)
5161
5134
        if long:
5162
 
            self.outf.writelines(t.as_text_lines())
 
5135
            sys.stdout.writelines(t.as_text_lines())
5163
5136
        else:
5164
 
            self.outf.write(t.as_short_text())
 
5137
            sys.stdout.write(t.as_short_text())
5165
5138
 
5166
5139
 
5167
5140
class cmd_annotate(Command):
5308
5281
            else:
5309
5282
                if location is None:
5310
5283
                    if b.get_bound_location() is not None:
5311
 
                        raise errors.BzrCommandError(
5312
 
                            gettext('Branch is already bound'))
 
5284
                        raise errors.BzrCommandError(gettext('Branch is already bound'))
5313
5285
                    else:
5314
 
                        raise errors.BzrCommandError(
5315
 
                            gettext('No location supplied'
5316
 
                                    ' and no previous location known'))
 
5286
                        raise errors.BzrCommandError(gettext('No location supplied '
 
5287
                            'and no previous location known'))
5317
5288
        b_other = Branch.open(location)
5318
5289
        try:
5319
5290
            b.bind(b_other)
5523
5494
               help="Protocol to serve.",
5524
5495
               lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5525
5496
               value_switches=True),
5526
 
        Option('listen',
5527
 
               help='Listen for connections on nominated address.', type=str),
5528
5497
        Option('port',
5529
 
               help='Listen for connections on nominated port.  Passing 0 as '
5530
 
                    'the port number will result in a dynamically allocated '
5531
 
                    'port.  The default port depends on the protocol.',
5532
 
               type=int),
 
5498
               help='Listen for connections on nominated port of the form '
 
5499
                    '[hostname:]portnumber.  Passing 0 as the port number will '
 
5500
                    'result in a dynamically allocated port.  The default port '
 
5501
                    'depends on the protocol.',
 
5502
               type=str),
5533
5503
        custom_help('directory',
5534
5504
               help='Serve contents of this directory.'),
5535
5505
        Option('allow-writes',
5545
5515
               help='Override the default idle client timeout (5min).'),
5546
5516
        ]
5547
5517
 
5548
 
    def run(self, listen=None, port=None, inet=False, directory=None,
5549
 
            allow_writes=False, protocol=None, client_timeout=None):
 
5518
    def get_host_and_port(self, port):
 
5519
        """Return the host and port to run the smart server on.
 
5520
 
 
5521
        If 'port' is None, None will be returned for the host and port.
 
5522
 
 
5523
        If 'port' has a colon in it, the string before the colon will be
 
5524
        interpreted as the host.
 
5525
 
 
5526
        :param port: A string of the port to run the server on.
 
5527
        :return: A tuple of (host, port), where 'host' is a host name or IP,
 
5528
            and port is an integer TCP/IP port.
 
5529
        """
 
5530
        host = None
 
5531
        if port is not None:
 
5532
            if ':' in port:
 
5533
                host, port = port.split(':')
 
5534
            port = int(port)
 
5535
        return host, port
 
5536
 
 
5537
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
 
5538
            protocol=None, client_timeout=None):
5550
5539
        from bzrlib import transport
5551
5540
        if directory is None:
5552
5541
            directory = os.getcwd()
5553
5542
        if protocol is None:
5554
5543
            protocol = transport.transport_server_registry.get()
 
5544
        host, port = self.get_host_and_port(port)
5555
5545
        url = transport.location_to_url(directory)
5556
5546
        if not allow_writes:
5557
5547
            url = 'readonly+' + url
5558
5548
        t = transport.get_transport_from_url(url)
5559
 
        protocol(t, listen, port, inet, client_timeout)
 
5549
        try:
 
5550
            protocol(t, host, port, inet, client_timeout)
 
5551
        except TypeError, e:
 
5552
            # We use symbol_versioning.deprecated_in just so that people
 
5553
            # grepping can find it here.
 
5554
            # symbol_versioning.deprecated_in((2, 5, 0))
 
5555
            symbol_versioning.warn(
 
5556
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
 
5557
                'Most likely it needs to be updated to support a'
 
5558
                ' "timeout" parameter (added in bzr 2.5.0)'
 
5559
                % (e, protocol.__module__, protocol),
 
5560
                DeprecationWarning)
 
5561
            protocol(t, host, port, inet)
5560
5562
 
5561
5563
 
5562
5564
class cmd_join(Command):
5698
5700
        if public_branch is None:
5699
5701
            public_branch = stored_public_branch
5700
5702
        elif stored_public_branch is None:
5701
 
            # FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5702
5703
            branch.set_public_branch(public_branch)
5703
5704
        if not include_bundle and public_branch is None:
5704
5705
            raise errors.BzrCommandError(gettext('No public branch specified or'
6232
6233
                     Option('create-branch', short_name='b',
6233
6234
                        help='Create the target branch from this one before'
6234
6235
                             ' switching to it.'),
6235
 
                     Option('store',
6236
 
                        help='Store and restore uncommitted changes in the'
6237
 
                             ' branch.'),
6238
6236
                    ]
6239
6237
 
6240
6238
    def run(self, to_location=None, force=False, create_branch=False,
6241
 
            revision=None, directory=u'.', store=False):
 
6239
            revision=None, directory=u'.'):
6242
6240
        from bzrlib import switch
6243
6241
        tree_location = directory
6244
6242
        revision = _get_one_revision('switch', revision)
6275
6273
                    possible_transports=possible_transports)
6276
6274
        if revision is not None:
6277
6275
            revision = revision.as_revision_id(to_branch)
6278
 
        switch.switch(control_dir, to_branch, force, revision_id=revision,
6279
 
                      store_uncommitted=store)
 
6276
        switch.switch(control_dir, to_branch, force, revision_id=revision)
6280
6277
        if had_explicit_nick:
6281
6278
            branch = control_dir.open_branch() #get the new branch!
6282
6279
            branch.nick = to_branch.nick
6727
6724
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6728
6725
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6729
6726
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6730
 
        ('cmd_ping', [], 'bzrlib.smart.ping'),
6731
6727
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6732
 
        ('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
 
6728
        ('cmd_verify_signatures', [],
 
6729
                                        'bzrlib.commit_signature_commands'),
6733
6730
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6734
6731
        ]:
6735
6732
        builtin_command_registry.register_lazy(name, aliases, module_name)