~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Vincent Ladeuil
  • Date: 2012-02-14 17:22:37 UTC
  • mfrom: (6466 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120214172237-7dv7er3n4uy8d5m4
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
    )
84
84
 
85
85
 
 
86
def _get_branch_location(control_dir, possible_transports=None):
 
87
    """Return location of branch for this control dir."""
 
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
 
97
    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
 
103
 
 
104
 
 
105
def _is_colocated(control_dir, possible_transports=None):
 
106
    """Check if the branch in control_dir is colocated.
 
107
 
 
108
    :param control_dir: Control directory
 
109
    :return: Boolean indicating whether 
 
110
    """
 
111
    # This path is meant to be relative to the existing branch
 
112
    this_url = _get_branch_location(control_dir,
 
113
        possible_transports=possible_transports)
 
114
    # Perhaps the target control dir supports colocated branches?
 
115
    try:
 
116
        root = controldir.ControlDir.open(this_url,
 
117
            possible_transports=possible_transports)
 
118
    except errors.NotBranchError:
 
119
        return (False, this_url)
 
120
    else:
 
121
        try:
 
122
            wt = control_dir.open_workingtree()
 
123
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
124
            return (False, this_url)
 
125
        else:
 
126
            return (
 
127
                root._format.colocated_branches and
 
128
                control_dir.control_url == root.control_url,
 
129
                this_url)
 
130
 
 
131
 
 
132
def lookup_new_sibling_branch(control_dir, location, possible_transports=None):
 
133
    """Lookup the location for a new sibling branch.
 
134
 
 
135
    :param control_dir: Control directory relative to which to look up
 
136
        the name.
 
137
    :param location: Name of the new branch
 
138
    :return: Full location to the new branch
 
139
    """
 
140
    location = directory_service.directories.dereference(location)
 
141
    if '/' not in location and '\\' not in location:
 
142
        (colocated, this_url) = _is_colocated(control_dir, possible_transports)
 
143
 
 
144
        if colocated:
 
145
            return urlutils.join_segment_parameters(this_url,
 
146
                {"branch": urlutils.escape(location)})
 
147
        else:
 
148
            return urlutils.join(this_url, '..', urlutils.escape(location))
 
149
    return location
 
150
 
 
151
 
 
152
def lookup_sibling_branch(control_dir, location, possible_transports=None):
 
153
    """Lookup sibling branch.
 
154
    
 
155
    :param control_dir: Control directory relative to which to lookup the
 
156
        location.
 
157
    :param location: Location to look up
 
158
    :return: branch to open
 
159
    """
 
160
    try:
 
161
        # Perhaps it's a colocated branch?
 
162
        return control_dir.open_branch(location, 
 
163
            possible_transports=possible_transports)
 
164
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
 
165
        try:
 
166
            return Branch.open(location)
 
167
        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
 
86
174
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
87
175
def tree_files(file_list, default_branch=u'.', canonicalize=True,
88
176
    apply_view=True):
849
937
            tree = work_tree
850
938
            extra_trees = []
851
939
 
 
940
        self.add_cleanup(tree.lock_read().unlock)
852
941
        if file_list is not None:
853
942
            file_ids = tree.paths2ids(file_list, trees=extra_trees,
854
943
                                      require_versioned=True)
855
944
            # find_ids_across_trees may include some paths that don't
856
945
            # exist in 'tree'.
857
 
            entries = sorted(
858
 
                (tree.id2path(file_id), tree.inventory[file_id])
859
 
                for file_id in file_ids if tree.has_id(file_id))
 
946
            entries = tree.iter_entries_by_dir(specific_file_ids=file_ids)
860
947
        else:
861
 
            entries = tree.inventory.entries()
 
948
            entries = tree.iter_entries_by_dir()
862
949
 
863
 
        self.cleanup_now()
864
 
        for path, entry in entries:
 
950
        for path, entry in sorted(entries):
865
951
            if kind and kind != entry.kind:
866
952
                continue
 
953
            if path == "":
 
954
                continue
867
955
            if show_ids:
868
956
                self.outf.write('%-50s %s\n' % (path, entry.file_id))
869
957
            else:
941
1029
                and rel_names[0].lower() == rel_names[1].lower()):
942
1030
                into_existing = False
943
1031
            else:
944
 
                inv = tree.inventory
945
1032
                # 'fix' the case of a potential 'from'
946
1033
                from_id = tree.path2id(
947
1034
                            tree.get_canonical_inventory_path(rel_names[0]))
948
1035
                if (not osutils.lexists(names_list[0]) and
949
 
                    from_id and inv.get_file_kind(from_id) == "directory"):
 
1036
                    from_id and tree.stored_kind(from_id) == "directory"):
950
1037
                    into_existing = False
951
1038
        # move/rename
952
1039
        if into_existing:
1350
1437
            revision_id = br_from.last_revision()
1351
1438
        if to_location is None:
1352
1439
            to_location = getattr(br_from, "name", None)
1353
 
            if to_location is None:
 
1440
            if not to_location:
1354
1441
                to_location = urlutils.derive_to_location(from_location)
1355
1442
        to_transport = transport.get_transport(to_location)
1356
1443
        try:
1396
1483
                    from_location, revision)
1397
1484
                raise errors.BzrCommandError(msg)
1398
1485
        else:
 
1486
            try:
 
1487
                to_repo = to_dir.open_repository()
 
1488
            except errors.NoRepositoryPresent:
 
1489
                to_repo = to_dir.create_repository()
 
1490
            to_repo.fetch(br_from.repository, revision_id=revision_id)
1399
1491
            branch = br_from.sprout(to_dir, revision_id=revision_id)
1400
1492
        _merge_tags_if_possible(br_from, branch)
1401
1493
        # If the source branch is stacked, the new branch may
1446
1538
        else:
1447
1539
            dir = controldir.ControlDir.open_containing(location)[0]
1448
1540
            try:
1449
 
                active_branch = dir.open_branch(name=None)
 
1541
                active_branch = dir.open_branch(name="")
1450
1542
            except errors.NotBranchError:
1451
1543
                active_branch = None
1452
1544
            branches = dir.get_branches()
1453
1545
            names = {}
1454
1546
            for name, branch in branches.iteritems():
1455
 
                if name is None:
 
1547
                if name == "":
1456
1548
                    continue
1457
1549
                active = (active_branch is not None and
1458
1550
                          active_branch.base == branch.base)
1558
1650
    def run(self, dir=u'.'):
1559
1651
        tree = WorkingTree.open_containing(dir)[0]
1560
1652
        self.add_cleanup(tree.lock_read().unlock)
1561
 
        new_inv = tree.inventory
 
1653
        new_inv = tree.root_inventory
1562
1654
        old_tree = tree.basis_tree()
1563
1655
        self.add_cleanup(old_tree.lock_read().unlock)
1564
 
        old_inv = old_tree.inventory
 
1656
        old_inv = old_tree.root_inventory
1565
1657
        renames = []
1566
1658
        iterator = tree.iter_changes(old_tree, include_unchanged=True)
1567
1659
        for f, paths, c, v, p, n, k, e in iterator:
2281
2373
        self.add_cleanup(tree.lock_read().unlock)
2282
2374
        old = tree.basis_tree()
2283
2375
        self.add_cleanup(old.lock_read().unlock)
2284
 
        for path, ie in old.inventory.iter_entries():
 
2376
        for path, ie in old.iter_entries_by_dir():
2285
2377
            if not tree.has_id(ie.file_id):
2286
2378
                self.outf.write(path)
2287
2379
                if show_ids:
2325
2417
        self.add_cleanup(wt.lock_read().unlock)
2326
2418
        basis = wt.basis_tree()
2327
2419
        self.add_cleanup(basis.lock_read().unlock)
2328
 
        basis_inv = basis.inventory
2329
 
        inv = wt.inventory
2330
 
        for file_id in inv:
2331
 
            if basis_inv.has_id(file_id):
2332
 
                continue
2333
 
            if inv.is_root(file_id) and len(basis_inv) == 0:
2334
 
                continue
2335
 
            path = inv.id2path(file_id)
 
2420
        root_id = wt.get_root_id()
 
2421
        for file_id in wt.all_file_ids():
 
2422
            if basis.has_id(file_id):
 
2423
                continue
 
2424
            if root_id == file_id:
 
2425
                continue
 
2426
            path = wt.id2path(file_id)
2336
2427
            if not os.access(osutils.pathjoin(wt.basedir, path), os.F_OK):
2337
2428
                continue
2338
2429
            if null:
2700
2791
            self.add_cleanup(b.lock_read().unlock)
2701
2792
            rev1, rev2 = _get_revision_range(revision, b, self.name())
2702
2793
 
2703
 
        if b.get_config().validate_signatures_in_log():
 
2794
        if b.get_config_stack().get('validate_signatures_in_log'):
2704
2795
            signatures = True
2705
2796
 
2706
2797
        if signatures:
3426
3517
            tokens = fixed_bug.split(':')
3427
3518
            if len(tokens) == 1:
3428
3519
                if default_bugtracker is None:
3429
 
                    branch_config = branch.get_config()
3430
 
                    default_bugtracker = branch_config.get_user_option(
 
3520
                    branch_config = branch.get_config_stack()
 
3521
                    default_bugtracker = branch_config.get(
3431
3522
                        "bugtracker")
3432
3523
                if default_bugtracker is None:
3433
3524
                    raise errors.BzrCommandError(gettext(
4172
4263
    Merge will do its best to combine the changes in two branches, but there
4173
4264
    are some kinds of problems only a human can fix.  When it encounters those,
4174
4265
    it will mark a conflict.  A conflict means that you need to fix something,
4175
 
    before you should commit.
 
4266
    before you can commit.
4176
4267
 
4177
4268
    Use bzr resolve when you have fixed a problem.  See also bzr conflicts.
4178
4269
 
4586
4677
                if tree.kind(file_id) != "directory":
4587
4678
                    continue
4588
4679
 
4589
 
                for name, ie in tree.inventory.iter_entries(file_id):
 
4680
                # FIXME: Support nested trees
 
4681
                for name, ie in tree.root_inventory.iter_entries(file_id):
4590
4682
                    interesting_ids.add(ie.file_id)
4591
4683
            new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4592
4684
        else:
6135
6227
        from bzrlib import switch
6136
6228
        tree_location = directory
6137
6229
        revision = _get_one_revision('switch', revision)
6138
 
        control_dir = controldir.ControlDir.open_containing(tree_location)[0]
 
6230
        possible_transports = []
 
6231
        control_dir = controldir.ControlDir.open_containing(tree_location,
 
6232
            possible_transports=possible_transports)[0]
6139
6233
        if to_location is None:
6140
6234
            if revision is None:
6141
6235
                raise errors.BzrCommandError(gettext('You must supply either a'
6142
6236
                                             ' revision or a location'))
6143
6237
            to_location = tree_location
6144
6238
        try:
6145
 
            branch = control_dir.open_branch()
 
6239
            branch = control_dir.open_branch(
 
6240
                possible_transports=possible_transports)
6146
6241
            had_explicit_nick = branch.get_config().has_explicit_nickname()
6147
6242
        except errors.NotBranchError:
6148
6243
            branch = None
6149
6244
            had_explicit_nick = False
6150
6245
        if create_branch:
6151
6246
            if branch is None:
6152
 
                raise errors.BzrCommandError(gettext('cannot create branch without'
6153
 
                                             ' source branch'))
6154
 
            to_location = directory_service.directories.dereference(
6155
 
                              to_location)
6156
 
            if '/' not in to_location and '\\' not in to_location:
6157
 
                # This path is meant to be relative to the existing branch
6158
 
                this_url = self._get_branch_location(control_dir)
6159
 
                # Perhaps the target control dir supports colocated branches?
6160
 
                try:
6161
 
                    root = controldir.ControlDir.open(this_url,
6162
 
                        possible_transports=[control_dir.user_transport])
6163
 
                except errors.NotBranchError:
6164
 
                    colocated = False
6165
 
                else:
6166
 
                    colocated = root._format.colocated_branches
6167
 
                if colocated:
6168
 
                    to_location = urlutils.join_segment_parameters(this_url,
6169
 
                        {"branch": urlutils.escape(to_location)})
6170
 
                else:
6171
 
                    to_location = urlutils.join(
6172
 
                        this_url, '..', urlutils.escape(to_location))
 
6247
                raise errors.BzrCommandError(
 
6248
                    gettext('cannot create branch without source branch'))
 
6249
            to_location = lookup_new_sibling_branch(control_dir, to_location,
 
6250
                 possible_transports=possible_transports)
6173
6251
            to_branch = branch.bzrdir.sprout(to_location,
6174
 
                                 possible_transports=[branch.bzrdir.root_transport],
6175
 
                                 source_branch=branch).open_branch()
 
6252
                 possible_transports=possible_transports,
 
6253
                 source_branch=branch).open_branch()
6176
6254
        else:
6177
 
            # Perhaps it's a colocated branch?
6178
 
            try:
6179
 
                to_branch = control_dir.open_branch(to_location)
6180
 
            except (errors.NotBranchError, errors.NoColocatedBranchSupport):
6181
 
                try:
6182
 
                    to_branch = Branch.open(to_location)
6183
 
                except errors.NotBranchError:
6184
 
                    this_url = self._get_branch_location(control_dir)
6185
 
                    to_branch = Branch.open(
6186
 
                        urlutils.join(
6187
 
                            this_url, '..', urlutils.escape(to_location)))
 
6255
            to_branch = lookup_sibling_branch(control_dir, to_location)
6188
6256
        if revision is not None:
6189
6257
            revision = revision.as_revision_id(to_branch)
6190
6258
        switch.switch(control_dir, to_branch, force, revision_id=revision)
6194
6262
        note(gettext('Switched to branch: %s'),
6195
6263
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6196
6264
 
6197
 
    def _get_branch_location(self, control_dir):
6198
 
        """Return location of branch for this control dir."""
6199
 
        try:
6200
 
            this_branch = control_dir.open_branch()
6201
 
            # This may be a heavy checkout, where we want the master branch
6202
 
            master_location = this_branch.get_bound_location()
6203
 
            if master_location is not None:
6204
 
                return master_location
6205
 
            # If not, use a local sibling
6206
 
            return this_branch.base
6207
 
        except errors.NotBranchError:
6208
 
            format = control_dir.find_branch_format()
6209
 
            if getattr(format, 'get_reference', None) is not None:
6210
 
                return format.get_reference(control_dir)
6211
 
            else:
6212
 
                return control_dir.root_transport.base
6213
6265
 
6214
6266
 
6215
6267
class cmd_view(Command):
6408
6460
    def run(self, location=None):
6409
6461
        if location is None:
6410
6462
            location = "."
6411
 
        branch = Branch.open_containing(location)[0]
6412
 
        branch.bzrdir.destroy_branch()
 
6463
        cdir = controldir.ControlDir.open_containing(location)[0]
 
6464
        cdir.destroy_branch()
6413
6465
 
6414
6466
 
6415
6467
class cmd_shelve(Command):