~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Jelmer Vernooij
  • Date: 2012-04-02 01:44:26 UTC
  • mfrom: (6518 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6519.
  • Revision ID: jelmer@samba.org-20120402014426-0o5qtysohyl006b2
merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
        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
 
89
        target = control_dir.get_branch_reference()
97
90
    except errors.NotBranchError:
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
 
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
103
102
 
104
103
 
105
104
def _is_colocated(control_dir, possible_transports=None):
106
105
    """Check if the branch in control_dir is colocated.
107
106
 
108
107
    :param control_dir: Control directory
109
 
    :return: Boolean indicating whether 
 
108
    :return: Tuple with boolean indicating whether the branch is colocated
 
109
        and the full URL to the actual branch
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 relative to which to look up
136
 
        the name.
 
135
    :param control_dir: Control directory to find sibling branches from
137
136
    :param location: Name of the new branch
138
137
    :return: Full location to the new branch
139
138
    """
149
148
    return location
150
149
 
151
150
 
152
 
def lookup_sibling_branch(control_dir, location, possible_transports=None):
153
 
    """Lookup sibling branch.
154
 
    
 
151
def open_sibling_branch(control_dir, location, possible_transports=None):
 
152
    """Open a branch, possibly a sibling of another.
 
153
 
155
154
    :param control_dir: Control directory relative to which to lookup the
156
155
        location.
157
156
    :param location: Location to look up
162
161
        return control_dir.open_branch(location, 
163
162
            possible_transports=possible_transports)
164
163
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
164
        this_url = _get_branch_location(control_dir)
 
165
        return Branch.open(
 
166
            urlutils.join(
 
167
                this_url, '..', urlutils.escape(location)))
 
168
 
 
169
 
 
170
def open_nearby_branch(near=None, location=None, possible_transports=None):
 
171
    """Open a nearby branch.
 
172
 
 
173
    :param near: Optional location of container from which to open branch
 
174
    :param location: Location of the branch
 
175
    :return: Branch instance
 
176
    """
 
177
    if near is None:
 
178
        if location is None:
 
179
            location = "."
165
180
        try:
166
 
            return Branch.open(location)
 
181
            return Branch.open(location,
 
182
                possible_transports=possible_transports)
167
183
        except errors.NotBranchError:
168
 
            this_url = _get_branch_location(control_dir)
169
 
            return Branch.open(
170
 
                urlutils.join(
171
 
                    this_url, '..', urlutils.escape(location)))
172
 
 
173
 
 
174
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
175
 
def tree_files(file_list, default_branch=u'.', canonicalize=True,
176
 
    apply_view=True):
177
 
    return internal_tree_files(file_list, default_branch, canonicalize,
178
 
        apply_view)
 
184
            near = "."
 
185
    cdir = controldir.ControlDir.open(near,
 
186
        possible_transports=possible_transports)
 
187
    return open_sibling_branch(cdir, location,
 
188
        possible_transports=possible_transports)
 
189
 
 
190
 
 
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
179
221
 
180
222
 
181
223
def tree_files_for_add(file_list):
243
285
    return rev_tree
244
286
 
245
287
 
246
 
# XXX: Bad function name; should possibly also be a class method of
247
 
# WorkingTree rather than a function.
248
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
249
 
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
250
 
    apply_view=True):
251
 
    """Convert command-line paths to a WorkingTree and relative paths.
252
 
 
253
 
    Deprecated: use WorkingTree.open_containing_paths instead.
254
 
 
255
 
    This is typically used for command-line processors that take one or
256
 
    more filenames, and infer the workingtree that contains them.
257
 
 
258
 
    The filenames given are not required to exist.
259
 
 
260
 
    :param file_list: Filenames to convert.
261
 
 
262
 
    :param default_branch: Fallback tree path to use if file_list is empty or
263
 
        None.
264
 
 
265
 
    :param apply_view: if True and a view is set, apply it or check that
266
 
        specified files are within it
267
 
 
268
 
    :return: workingtree, [relative_paths]
269
 
    """
270
 
    return WorkingTree.open_containing_paths(
271
 
        file_list, default_directory='.',
272
 
        canonicalize=True,
273
 
        apply_view=True)
274
 
 
275
 
 
276
288
def _get_view_info_for_change_reporter(tree):
277
289
    """Get the view information from a tree for change reporting."""
278
290
    view_info = None
356
368
    This will produce the same results as calling 'bzr diff --summarize'.
357
369
    """
358
370
 
359
 
    # TODO: --no-recurse, --recurse options
 
371
    # TODO: --no-recurse/-N, --recurse options
360
372
 
361
373
    takes_args = ['file*']
362
374
    takes_options = ['show-ids', 'revision', 'change', 'verbose',
791
803
    takes_args = ['file*']
792
804
    takes_options = [
793
805
        Option('no-recurse',
794
 
               help="Don't recursively add the contents of directories."),
 
806
               help="Don't recursively add the contents of directories.",
 
807
               short_name='N'),
795
808
        Option('dry-run',
796
809
               help="Show what would be done, but don't actually do anything."),
797
810
        'verbose',
1541
1554
                active_branch = dir.open_branch(name="")
1542
1555
            except errors.NotBranchError:
1543
1556
                active_branch = None
1544
 
            branches = dir.get_branches()
1545
1557
            names = {}
1546
 
            for name, branch in branches.iteritems():
 
1558
            for name, branch in iter_sibling_branches(dir):
1547
1559
                if name == "":
1548
1560
                    continue
1549
1561
                active = (active_branch is not None and
1828
1840
 
1829
1841
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1830
1842
    delete them if they can easily be recovered using revert otherwise they
1831
 
    will be backed up (adding an extention of the form .~#~). If no options or
 
1843
    will be backed up (adding an extension of the form .~#~). If no options or
1832
1844
    parameters are given Bazaar will scan for files that are being tracked by
1833
1845
    Bazaar but missing in your tree and stop tracking them for you.
1834
1846
    """
2042
2054
         RegistryOption('format',
2043
2055
                help='Specify a format for this branch. '
2044
2056
                'See "help formats".',
2045
 
                lazy_registry=('bzrlib.bzrdir', 'format_registry'),
 
2057
                lazy_registry=('bzrlib.controldir', 'format_registry'),
2046
2058
                converter=lambda name: controldir.format_registry.make_bzrdir(name),
2047
2059
                value_switches=True,
2048
2060
                title="Branch format",
4716
4728
 
4717
4729
 
4718
4730
class cmd_revert(Command):
4719
 
    __doc__ = """Revert files to a previous revision.
 
4731
    __doc__ = """\
 
4732
    Set files in the working tree back to the contents of a previous revision.
4720
4733
 
4721
4734
    Giving a list of files will revert only those files.  Otherwise, all files
4722
4735
    will be reverted.  If the revision is not specified with '--revision', the
4723
 
    last committed revision is used.
 
4736
    working tree basis revision is used. A revert operation affects only the
 
4737
    working tree, not any revision history like the branch and repository or
 
4738
    the working tree basis revision.
4724
4739
 
4725
4740
    To remove only some changes, without reverting to a prior version, use
4726
4741
    merge instead.  For example, "merge . -r -2..-3" (don't forget the ".")
4727
4742
    will remove the changes introduced by the second last commit (-2), without
4728
4743
    affecting the changes introduced by the last commit (-1).  To remove
4729
4744
    certain changes on a hunk-by-hunk basis, see the shelve command.
 
4745
    To update the branch to a specific revision or the latest revision and
 
4746
    update the working tree accordingly while preserving local changes, see the
 
4747
    update command.
4730
4748
 
4731
 
    By default, any files that have been manually changed will be backed up
4732
 
    first.  (Files changed only by merge are not backed up.)  Backup files have
4733
 
    '.~#~' appended to their name, where # is a number.
 
4749
    Uncommitted changes to files that are reverted will be discarded.
 
4750
    Howver, by default, any files that have been manually changed will be
 
4751
    backed up first.  (Files changed only by merge are not backed up.)  Backup
 
4752
    files have '.~#~' appended to their name, where # is a number.
4734
4753
 
4735
4754
    When you provide files, you can use their current pathname or the pathname
4736
4755
    from the target revision.  So you can use revert to "undelete" a file by
5479
5498
               help="Protocol to serve.",
5480
5499
               lazy_registry=('bzrlib.transport', 'transport_server_registry'),
5481
5500
               value_switches=True),
 
5501
        Option('listen',
 
5502
               help='Listen for connections on nominated address.', type=str),
5482
5503
        Option('port',
5483
 
               help='Listen for connections on nominated port of the form '
5484
 
                    '[hostname:]portnumber.  Passing 0 as the port number will '
5485
 
                    'result in a dynamically allocated port.  The default port '
5486
 
                    'depends on the protocol.',
5487
 
               type=str),
 
5504
               help='Listen for connections on nominated port.  Passing 0 as '
 
5505
                    'the port number will result in a dynamically allocated '
 
5506
                    'port.  The default port depends on the protocol.',
 
5507
               type=int),
5488
5508
        custom_help('directory',
5489
5509
               help='Serve contents of this directory.'),
5490
5510
        Option('allow-writes',
5500
5520
               help='Override the default idle client timeout (5min).'),
5501
5521
        ]
5502
5522
 
5503
 
    def get_host_and_port(self, port):
5504
 
        """Return the host and port to run the smart server on.
5505
 
 
5506
 
        If 'port' is None, None will be returned for the host and port.
5507
 
 
5508
 
        If 'port' has a colon in it, the string before the colon will be
5509
 
        interpreted as the host.
5510
 
 
5511
 
        :param port: A string of the port to run the server on.
5512
 
        :return: A tuple of (host, port), where 'host' is a host name or IP,
5513
 
            and port is an integer TCP/IP port.
5514
 
        """
5515
 
        host = None
5516
 
        if port is not None:
5517
 
            if ':' in port:
5518
 
                host, port = port.split(':')
5519
 
            port = int(port)
5520
 
        return host, port
5521
 
 
5522
 
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
5523
 
            protocol=None, client_timeout=None):
 
5523
    def run(self, listen=None, port=None, inet=False, directory=None,
 
5524
            allow_writes=False, protocol=None, client_timeout=None):
5524
5525
        from bzrlib import transport
5525
5526
        if directory is None:
5526
5527
            directory = os.getcwd()
5527
5528
        if protocol is None:
5528
5529
            protocol = transport.transport_server_registry.get()
5529
 
        host, port = self.get_host_and_port(port)
5530
5530
        url = transport.location_to_url(directory)
5531
5531
        if not allow_writes:
5532
5532
            url = 'readonly+' + url
5533
5533
        t = transport.get_transport_from_url(url)
5534
 
        try:
5535
 
            protocol(t, host, port, inet, client_timeout)
5536
 
        except TypeError, e:
5537
 
            # We use symbol_versioning.deprecated_in just so that people
5538
 
            # grepping can find it here.
5539
 
            # symbol_versioning.deprecated_in((2, 5, 0))
5540
 
            symbol_versioning.warn(
5541
 
                'Got TypeError(%s)\ntrying to call protocol: %s.%s\n'
5542
 
                'Most likely it needs to be updated to support a'
5543
 
                ' "timeout" parameter (added in bzr 2.5.0)'
5544
 
                % (e, protocol.__module__, protocol),
5545
 
                DeprecationWarning)
5546
 
            protocol(t, host, port, inet)
 
5534
        protocol(t, listen, port, inet, client_timeout)
5547
5535
 
5548
5536
 
5549
5537
class cmd_join(Command):
6251
6239
                 possible_transports=possible_transports,
6252
6240
                 source_branch=branch).open_branch()
6253
6241
        else:
6254
 
            to_branch = lookup_sibling_branch(control_dir, to_location)
 
6242
            try:
 
6243
                to_branch = Branch.open(to_location,
 
6244
                    possible_transports=possible_transports)
 
6245
            except errors.NotBranchError:
 
6246
                to_branch = open_sibling_branch(control_dir, to_location,
 
6247
                    possible_transports=possible_transports)
6255
6248
        if revision is not None:
6256
6249
            revision = revision.as_revision_id(to_branch)
6257
6250
        switch.switch(control_dir, to_branch, force, revision_id=revision)
6454
6447
 
6455
6448
    takes_args = ["location?"]
6456
6449
 
 
6450
    takes_options = ['directory',
 
6451
        Option('force', help='Remove branch even if it is the active branch.')]
 
6452
 
6457
6453
    aliases = ["rmbranch"]
6458
6454
 
6459
 
    def run(self, location=None):
6460
 
        if location is None:
6461
 
            location = "."
6462
 
        cdir = controldir.ControlDir.open_containing(location)[0]
6463
 
        cdir.destroy_branch()
 
6455
    def run(self, directory=None, location=None, force=False):
 
6456
        br = open_nearby_branch(near=directory, location=location)
 
6457
        if not force and br.bzrdir.has_workingtree():
 
6458
            try:
 
6459
                active_branch = br.bzrdir.open_branch(name="")
 
6460
            except errors.NotBranchError:
 
6461
                active_branch = None
 
6462
            if (active_branch is not None and
 
6463
                br.control_url == active_branch.control_url):
 
6464
                raise errors.BzrCommandError(
 
6465
                    gettext("Branch is active. Use --force to remove it."))
 
6466
        br.bzrdir.destroy_branch(br.name)
6464
6467
 
6465
6468
 
6466
6469
class cmd_shelve(Command):
6696
6699
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6697
6700
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6698
6701
        ('cmd_sign_my_commits', [], 'bzrlib.commit_signature_commands'),
6699
 
        ('cmd_verify_signatures', [],
6700
 
                                        'bzrlib.commit_signature_commands'),
 
6702
        ('cmd_verify_signatures', [], 'bzrlib.commit_signature_commands'),
6701
6703
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6702
6704
        ]:
6703
6705
        builtin_command_registry.register_lazy(name, aliases, module_name)