~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Vincent Ladeuil
  • Date: 2010-06-17 16:54:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5306.
  • Revision ID: v.ladeuil+lp@free.fr-20100617165426-741tbmgwi62a9zub
Pass BZR_PLUGINS_AT and BZR_DISABLE_PLINGS to the subprocess fpr test_import_tariff

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
from bzrlib.lazy_import import lazy_import
22
22
lazy_import(globals(), """
 
23
import codecs
23
24
import cStringIO
24
 
import itertools
25
 
import re
26
25
import sys
27
26
import time
28
27
 
34
33
    bzrdir,
35
34
    directory_service,
36
35
    delta,
37
 
    config as _mod_config,
 
36
    config,
38
37
    errors,
39
38
    globbing,
40
39
    hooks,
76
75
from bzrlib.trace import mutter, note, warning, is_quiet, get_verbosity_level
77
76
 
78
77
 
79
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
80
78
def tree_files(file_list, default_branch=u'.', canonicalize=True,
81
79
    apply_view=True):
82
 
    return internal_tree_files(file_list, default_branch, canonicalize,
83
 
        apply_view)
 
80
    try:
 
81
        return internal_tree_files(file_list, default_branch, canonicalize,
 
82
            apply_view)
 
83
    except errors.FileInWrongBranch, e:
 
84
        raise errors.BzrCommandError("%s is not in the same branch as %s" %
 
85
                                     (e.path, file_list[0]))
84
86
 
85
87
 
86
88
def tree_files_for_add(file_list):
150
152
 
151
153
# XXX: Bad function name; should possibly also be a class method of
152
154
# WorkingTree rather than a function.
153
 
@symbol_versioning.deprecated_function(symbol_versioning.deprecated_in((2, 3, 0)))
154
155
def internal_tree_files(file_list, default_branch=u'.', canonicalize=True,
155
156
    apply_view=True):
156
157
    """Convert command-line paths to a WorkingTree and relative paths.
157
158
 
158
 
    Deprecated: use WorkingTree.open_containing_paths instead.
159
 
 
160
159
    This is typically used for command-line processors that take one or
161
160
    more filenames, and infer the workingtree that contains them.
162
161
 
172
171
 
173
172
    :return: workingtree, [relative_paths]
174
173
    """
175
 
    return WorkingTree.open_containing_paths(
176
 
        file_list, default_directory='.',
177
 
        canonicalize=True,
178
 
        apply_view=True)
 
174
    if file_list is None or len(file_list) == 0:
 
175
        tree = WorkingTree.open_containing(default_branch)[0]
 
176
        if tree.supports_views() and apply_view:
 
177
            view_files = tree.views.lookup_view()
 
178
            if view_files:
 
179
                file_list = view_files
 
180
                view_str = views.view_display_str(view_files)
 
181
                note("Ignoring files outside view. View is %s" % view_str)
 
182
        return tree, file_list
 
183
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
 
184
    return tree, safe_relpath_files(tree, file_list, canonicalize,
 
185
        apply_view=apply_view)
 
186
 
 
187
 
 
188
def safe_relpath_files(tree, file_list, canonicalize=True, apply_view=True):
 
189
    """Convert file_list into a list of relpaths in tree.
 
190
 
 
191
    :param tree: A tree to operate on.
 
192
    :param file_list: A list of user provided paths or None.
 
193
    :param apply_view: if True and a view is set, apply it or check that
 
194
        specified files are within it
 
195
    :return: A list of relative paths.
 
196
    :raises errors.PathNotChild: When a provided path is in a different tree
 
197
        than tree.
 
198
    """
 
199
    if file_list is None:
 
200
        return None
 
201
    if tree.supports_views() and apply_view:
 
202
        view_files = tree.views.lookup_view()
 
203
    else:
 
204
        view_files = []
 
205
    new_list = []
 
206
    # tree.relpath exists as a "thunk" to osutils, but canonical_relpath
 
207
    # doesn't - fix that up here before we enter the loop.
 
208
    if canonicalize:
 
209
        fixer = lambda p: osutils.canonical_relpath(tree.basedir, p)
 
210
    else:
 
211
        fixer = tree.relpath
 
212
    for filename in file_list:
 
213
        try:
 
214
            relpath = fixer(osutils.dereference_path(filename))
 
215
            if  view_files and not osutils.is_inside_any(view_files, relpath):
 
216
                raise errors.FileOutsideView(filename, view_files)
 
217
            new_list.append(relpath)
 
218
        except errors.PathNotChild:
 
219
            raise errors.FileInWrongBranch(tree.branch, filename)
 
220
    return new_list
179
221
 
180
222
 
181
223
def _get_view_info_for_change_reporter(tree):
252
294
    To skip the display of pending merge information altogether, use
253
295
    the no-pending option or specify a file/directory.
254
296
 
255
 
    To compare the working directory to a specific revision, pass a
256
 
    single revision to the revision argument.
257
 
 
258
 
    To see which files have changed in a specific revision, or between
259
 
    two revisions, pass a revision range to the revision argument.
260
 
    This will produce the same results as calling 'bzr diff --summarize'.
 
297
    If a revision argument is given, the status is calculated against
 
298
    that revision, or between two revisions if two are provided.
261
299
    """
262
300
 
263
301
    # TODO: --no-recurse, --recurse options
285
323
            raise errors.BzrCommandError('bzr status --revision takes exactly'
286
324
                                         ' one or two revision specifiers')
287
325
 
288
 
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
 
326
        tree, relfile_list = tree_files(file_list)
289
327
        # Avoid asking for specific files when that is not needed.
290
328
        if relfile_list == ['']:
291
329
            relfile_list = None
723
761
            raise errors.BzrCommandError('invalid kind %r specified' % (kind,))
724
762
 
725
763
        revision = _get_one_revision('inventory', revision)
726
 
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
 
764
        work_tree, file_list = tree_files(file_list)
727
765
        self.add_cleanup(work_tree.lock_read().unlock)
728
766
        if revision is not None:
729
767
            tree = revision.as_tree(work_tree.branch)
794
832
            names_list = []
795
833
        if len(names_list) < 2:
796
834
            raise errors.BzrCommandError("missing file argument")
797
 
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
835
        tree, rel_names = tree_files(names_list, canonicalize=False)
798
836
        self.add_cleanup(tree.lock_tree_write().unlock)
799
837
        self._run(tree, names_list, rel_names, after)
800
838
 
805
843
        if after:
806
844
            raise errors.BzrCommandError('--after cannot be specified with'
807
845
                                         ' --auto.')
808
 
        work_tree, file_list = WorkingTree.open_containing_paths(
809
 
            names_list, default_directory='.')
 
846
        work_tree, file_list = tree_files(names_list, default_branch='.')
810
847
        self.add_cleanup(work_tree.lock_tree_write().unlock)
811
848
        rename_map.RenameMap.guess_renames(work_tree, dry_run)
812
849
 
929
966
                 "branch.  Local pulls are not applied to "
930
967
                 "the master branch."
931
968
            ),
932
 
        Option('show-base',
933
 
            help="Show base revision text in conflicts.")
934
969
        ]
935
970
    takes_args = ['location?']
936
971
    encoding_type = 'replace'
937
972
 
938
973
    def run(self, location=None, remember=False, overwrite=False,
939
974
            revision=None, verbose=False,
940
 
            directory=None, local=False,
941
 
            show_base=False):
 
975
            directory=None, local=False):
942
976
        # FIXME: too much stuff is in the command class
943
977
        revision_id = None
944
978
        mergeable = None
953
987
            branch_to = Branch.open_containing(directory)[0]
954
988
            self.add_cleanup(branch_to.lock_write().unlock)
955
989
 
956
 
        if tree_to is None and show_base:
957
 
            raise errors.BzrCommandError("Need working tree for --show-base.")
958
 
 
959
990
        if local and not branch_to.get_bound_location():
960
991
            raise errors.LocalRequiresBoundBranch()
961
992
 
1006
1037
                view_info=view_info)
1007
1038
            result = tree_to.pull(
1008
1039
                branch_from, overwrite, revision_id, change_reporter,
1009
 
                possible_transports=possible_transports, local=local,
1010
 
                show_base=show_base)
 
1040
                possible_transports=possible_transports, local=local)
1011
1041
        else:
1012
1042
            result = branch_to.pull(
1013
1043
                branch_from, overwrite, revision_id, local=local)
1069
1099
        Option('strict',
1070
1100
               help='Refuse to push if there are uncommitted changes in'
1071
1101
               ' the working tree, --no-strict disables the check.'),
1072
 
        Option('no-tree',
1073
 
               help="Don't populate the working tree, even for protocols"
1074
 
               " that support it."),
1075
1102
        ]
1076
1103
    takes_args = ['location?']
1077
1104
    encoding_type = 'replace'
1079
1106
    def run(self, location=None, remember=False, overwrite=False,
1080
1107
        create_prefix=False, verbose=False, revision=None,
1081
1108
        use_existing_dir=False, directory=None, stacked_on=None,
1082
 
        stacked=False, strict=None, no_tree=False):
 
1109
        stacked=False, strict=None):
1083
1110
        from bzrlib.push import _show_push_branch
1084
1111
 
1085
1112
        if directory is None:
1131
1158
        _show_push_branch(br_from, revision_id, location, self.outf,
1132
1159
            verbose=verbose, overwrite=overwrite, remember=remember,
1133
1160
            stacked_on=stacked_on, create_prefix=create_prefix,
1134
 
            use_existing_dir=use_existing_dir, no_tree=no_tree)
 
1161
            use_existing_dir=use_existing_dir)
1135
1162
 
1136
1163
 
1137
1164
class cmd_branch(Command):
1150
1177
 
1151
1178
    _see_also = ['checkout']
1152
1179
    takes_args = ['from_location', 'to_location?']
1153
 
    takes_options = ['revision',
1154
 
        Option('hardlink', help='Hard-link working tree files where possible.'),
1155
 
        Option('files-from', type=str,
1156
 
               help="Get file contents from this tree."),
 
1180
    takes_options = ['revision', Option('hardlink',
 
1181
        help='Hard-link working tree files where possible.'),
1157
1182
        Option('no-tree',
1158
1183
            help="Create a branch without a working-tree."),
1159
1184
        Option('switch',
1177
1202
 
1178
1203
    def run(self, from_location, to_location=None, revision=None,
1179
1204
            hardlink=False, stacked=False, standalone=False, no_tree=False,
1180
 
            use_existing_dir=False, switch=False, bind=False,
1181
 
            files_from=None):
 
1205
            use_existing_dir=False, switch=False, bind=False):
1182
1206
        from bzrlib import switch as _mod_switch
1183
1207
        from bzrlib.tag import _merge_tags_if_possible
1184
1208
        accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1185
1209
            from_location)
1186
 
        if not (hardlink or files_from):
1187
 
            # accelerator_tree is usually slower because you have to read N
1188
 
            # files (no readahead, lots of seeks, etc), but allow the user to
1189
 
            # explicitly request it
1190
 
            accelerator_tree = None
1191
 
        if files_from is not None and files_from != from_location:
1192
 
            accelerator_tree = WorkingTree.open(files_from)
1193
1210
        revision = _get_one_revision('branch', revision)
1194
1211
        self.add_cleanup(br_from.lock_read().unlock)
1195
1212
        if revision is not None:
1302
1319
            to_location = branch_location
1303
1320
        accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch(
1304
1321
            branch_location)
1305
 
        if not (hardlink or files_from):
1306
 
            # accelerator_tree is usually slower because you have to read N
1307
 
            # files (no readahead, lots of seeks, etc), but allow the user to
1308
 
            # explicitly request it
1309
 
            accelerator_tree = None
1310
1322
        revision = _get_one_revision('checkout', revision)
1311
 
        if files_from is not None and files_from != branch_location:
 
1323
        if files_from is not None:
1312
1324
            accelerator_tree = WorkingTree.open(files_from)
1313
1325
        if revision is not None:
1314
1326
            revision_id = revision.as_revision_id(source)
1370
1382
    If you want to discard your local changes, you can just do a
1371
1383
    'bzr revert' instead of 'bzr commit' after the update.
1372
1384
 
1373
 
    If you want to restore a file that has been removed locally, use
1374
 
    'bzr revert' instead of 'bzr update'.
1375
 
 
1376
1385
    If the tree's branch is bound to a master branch, it will also update
1377
1386
    the branch from the master.
1378
1387
    """
1379
1388
 
1380
1389
    _see_also = ['pull', 'working-trees', 'status-flags']
1381
1390
    takes_args = ['dir?']
1382
 
    takes_options = ['revision',
1383
 
                     Option('show-base',
1384
 
                            help="Show base revision text in conflicts."),
1385
 
                     ]
 
1391
    takes_options = ['revision']
1386
1392
    aliases = ['up']
1387
1393
 
1388
 
    def run(self, dir='.', revision=None, show_base=None):
 
1394
    def run(self, dir='.', revision=None):
1389
1395
        if revision is not None and len(revision) != 1:
1390
1396
            raise errors.BzrCommandError(
1391
1397
                        "bzr update --revision takes exactly one revision")
1431
1437
                change_reporter,
1432
1438
                possible_transports=possible_transports,
1433
1439
                revision=revision_id,
1434
 
                old_tip=old_tip,
1435
 
                show_base=show_base)
 
1440
                old_tip=old_tip)
1436
1441
        except errors.NoSuchRevision, e:
1437
1442
            raise errors.BzrCommandError(
1438
1443
                                  "branch has no revision %s\n"
1500
1505
class cmd_remove(Command):
1501
1506
    __doc__ = """Remove files or directories.
1502
1507
 
1503
 
    This makes Bazaar stop tracking changes to the specified files. Bazaar will
1504
 
    delete them if they can easily be recovered using revert otherwise they
1505
 
    will be backed up (adding an extention of the form .~#~). If no options or
1506
 
    parameters are given Bazaar will scan for files that are being tracked by
1507
 
    Bazaar but missing in your tree and stop tracking them for you.
 
1508
    This makes bzr stop tracking changes to the specified files. bzr will delete
 
1509
    them if they can easily be recovered using revert. If no options or
 
1510
    parameters are given bzr will scan for files that are being tracked by bzr
 
1511
    but missing in your tree and stop tracking them for you.
1508
1512
    """
1509
1513
    takes_args = ['file*']
1510
1514
    takes_options = ['verbose',
1512
1516
        RegistryOption.from_kwargs('file-deletion-strategy',
1513
1517
            'The file deletion mode to be used.',
1514
1518
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1515
 
            safe='Backup changed files (default).',
 
1519
            safe='Only delete files if they can be'
 
1520
                 ' safely recovered (default).',
1516
1521
            keep='Delete from bzr but leave the working copy.',
1517
 
            no_backup='Don\'t backup changed files.',
1518
1522
            force='Delete all the specified files, even if they can not be '
1519
 
                'recovered and even if they are non-empty directories. '
1520
 
                '(deprecated, use no-backup)')]
 
1523
                'recovered and even if they are non-empty directories.')]
1521
1524
    aliases = ['rm', 'del']
1522
1525
    encoding_type = 'replace'
1523
1526
 
1524
1527
    def run(self, file_list, verbose=False, new=False,
1525
1528
        file_deletion_strategy='safe'):
1526
 
        if file_deletion_strategy == 'force':
1527
 
            note("(The --force option is deprecated, rather use --no-backup "
1528
 
                "in future.)")
1529
 
            file_deletion_strategy = 'no-backup'
1530
 
 
1531
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
 
1529
        tree, file_list = tree_files(file_list)
1532
1530
 
1533
1531
        if file_list is not None:
1534
1532
            file_list = [f for f in file_list]
1554
1552
            file_deletion_strategy = 'keep'
1555
1553
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
1556
1554
            keep_files=file_deletion_strategy=='keep',
1557
 
            force=(file_deletion_strategy=='no-backup'))
 
1555
            force=file_deletion_strategy=='force')
1558
1556
 
1559
1557
 
1560
1558
class cmd_file_id(Command):
1622
1620
 
1623
1621
    _see_also = ['check']
1624
1622
    takes_args = ['branch?']
1625
 
    takes_options = [
1626
 
        Option('canonicalize-chks',
1627
 
               help='Make sure CHKs are in canonical form (repairs '
1628
 
                    'bug 522637).',
1629
 
               hidden=True),
1630
 
        ]
1631
1623
 
1632
 
    def run(self, branch=".", canonicalize_chks=False):
 
1624
    def run(self, branch="."):
1633
1625
        from bzrlib.reconcile import reconcile
1634
1626
        dir = bzrdir.BzrDir.open(branch)
1635
 
        reconcile(dir, canonicalize_chks=canonicalize_chks)
 
1627
        reconcile(dir)
1636
1628
 
1637
1629
 
1638
1630
class cmd_revision_history(Command):
1715
1707
                ),
1716
1708
         Option('append-revisions-only',
1717
1709
                help='Never change revnos or the existing log.'
1718
 
                '  Append revisions to it only.'),
1719
 
         Option('no-tree',
1720
 
                'Create a branch without a working tree.')
 
1710
                '  Append revisions to it only.')
1721
1711
         ]
1722
1712
    def run(self, location=None, format=None, append_revisions_only=False,
1723
 
            create_prefix=False, no_tree=False):
 
1713
            create_prefix=False):
1724
1714
        if format is None:
1725
1715
            format = bzrdir.format_registry.make_bzrdir('default')
1726
1716
        if location is None:
1749
1739
        except errors.NotBranchError:
1750
1740
            # really a NotBzrDir error...
1751
1741
            create_branch = bzrdir.BzrDir.create_branch_convenience
1752
 
            if no_tree:
1753
 
                force_new_tree = False
1754
 
            else:
1755
 
                force_new_tree = None
1756
1742
            branch = create_branch(to_transport.base, format=format,
1757
 
                                   possible_transports=[to_transport],
1758
 
                                   force_new_tree=force_new_tree)
 
1743
                                   possible_transports=[to_transport])
1759
1744
            a_bzrdir = branch.bzrdir
1760
1745
        else:
1761
1746
            from bzrlib.transport.local import LocalTransport
1765
1750
                        raise errors.BranchExistsWithoutWorkingTree(location)
1766
1751
                raise errors.AlreadyBranchError(location)
1767
1752
            branch = a_bzrdir.create_branch()
1768
 
            if not no_tree:
1769
 
                a_bzrdir.create_workingtree()
 
1753
            a_bzrdir.create_workingtree()
1770
1754
        if append_revisions_only:
1771
1755
            try:
1772
1756
                branch.set_append_revisions_only(True)
1866
1850
    "bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1867
1851
    produces patches suitable for "patch -p1".
1868
1852
 
1869
 
    Note that when using the -r argument with a range of revisions, the
1870
 
    differences are computed between the two specified revisions.  That
1871
 
    is, the command does not show the changes introduced by the first 
1872
 
    revision in the range.  This differs from the interpretation of 
1873
 
    revision ranges used by "bzr log" which includes the first revision
1874
 
    in the range.
1875
 
 
1876
1853
    :Exit values:
1877
1854
        1 - changed
1878
1855
        2 - unrepresentable changes
1896
1873
 
1897
1874
            bzr diff -r1..3 xxx
1898
1875
 
1899
 
        The changes introduced by revision 2 (equivalent to -r1..2)::
1900
 
 
1901
 
            bzr diff -c2
1902
 
 
1903
 
        To see the changes introduced by revision X::
 
1876
        To see the changes introduced in revision X::
1904
1877
        
1905
1878
            bzr diff -cX
1906
1879
 
1910
1883
 
1911
1884
            bzr diff -r<chosen_parent>..X
1912
1885
 
1913
 
        The changes between the current revision and the previous revision
1914
 
        (equivalent to -c-1 and -r-2..-1)
 
1886
        The changes introduced by revision 2 (equivalent to -r1..2)::
1915
1887
 
1916
 
            bzr diff -r-2..
 
1888
            bzr diff -c2
1917
1889
 
1918
1890
        Show just the differences for file NEWS::
1919
1891
 
1934
1906
        Same as 'bzr diff' but prefix paths with old/ and new/::
1935
1907
 
1936
1908
            bzr diff --prefix old/:new/
1937
 
            
1938
 
        Show the differences using a custom diff program with options::
1939
 
        
1940
 
            bzr diff --using /usr/bin/diff --diff-options -wu
1941
1909
    """
1942
1910
    _see_also = ['status']
1943
1911
    takes_args = ['file*']
2002
1970
         old_branch, new_branch,
2003
1971
         specific_files, extra_trees) = get_trees_and_branches_to_diff_locked(
2004
1972
            file_list, revision, old, new, self.add_cleanup, apply_view=True)
2005
 
        # GNU diff on Windows uses ANSI encoding for filenames
2006
 
        path_encoding = osutils.get_diff_header_encoding()
2007
1973
        return show_diff_trees(old_tree, new_tree, sys.stdout,
2008
1974
                               specific_files=specific_files,
2009
1975
                               external_diff_options=diff_options,
2010
1976
                               old_label=old_label, new_label=new_label,
2011
 
                               extra_trees=extra_trees,
2012
 
                               path_encoding=path_encoding,
2013
 
                               using=using,
 
1977
                               extra_trees=extra_trees, using=using,
2014
1978
                               format_cls=format)
2015
1979
 
2016
1980
 
2688
2652
    Patterns prefixed with '!!' act as regular ignore patterns, but have
2689
2653
    precedence over the '!' exception patterns.
2690
2654
 
2691
 
    :Notes: 
2692
 
        
2693
 
    * Ignore patterns containing shell wildcards must be quoted from
2694
 
      the shell on Unix.
2695
 
 
2696
 
    * Ignore patterns starting with "#" act as comments in the ignore file.
2697
 
      To ignore patterns that begin with that character, use the "RE:" prefix.
 
2655
    Note: ignore patterns containing shell wildcards must be quoted from
 
2656
    the shell on Unix.
2698
2657
 
2699
2658
    :Examples:
2700
2659
        Ignore the top level Makefile::
2709
2668
 
2710
2669
            bzr ignore "!special.class"
2711
2670
 
2712
 
        Ignore files whose name begins with the "#" character::
2713
 
 
2714
 
            bzr ignore "RE:^#"
2715
 
 
2716
2671
        Ignore .o files under the lib directory::
2717
2672
 
2718
2673
            bzr ignore "lib/**/*.o"
2753
2708
                "NAME_PATTERN or --default-rules.")
2754
2709
        name_pattern_list = [globbing.normalize_pattern(p)
2755
2710
                             for p in name_pattern_list]
2756
 
        bad_patterns = ''
2757
 
        for p in name_pattern_list:
2758
 
            if not globbing.Globster.is_pattern_valid(p):
2759
 
                bad_patterns += ('\n  %s' % p)
2760
 
        if bad_patterns:
2761
 
            msg = ('Invalid ignore pattern(s) found. %s' % bad_patterns)
2762
 
            ui.ui_factory.show_error(msg)
2763
 
            raise errors.InvalidPattern('')
2764
2711
        for name_pattern in name_pattern_list:
2765
2712
            if (name_pattern[0] == '/' or
2766
2713
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2770
2717
        ignores.tree_ignores_add_patterns(tree, name_pattern_list)
2771
2718
        ignored = globbing.Globster(name_pattern_list)
2772
2719
        matches = []
2773
 
        self.add_cleanup(tree.lock_read().unlock)
 
2720
        tree.lock_read()
2774
2721
        for entry in tree.list_files():
2775
2722
            id = entry[3]
2776
2723
            if id is not None:
2777
2724
                filename = entry[0]
2778
2725
                if ignored.match(filename):
2779
2726
                    matches.append(filename)
 
2727
        tree.unlock()
2780
2728
        if len(matches) > 0:
2781
2729
            self.outf.write("Warning: the following files are version controlled and"
2782
2730
                  " match your ignore pattern:\n%s"
3158
3106
 
3159
3107
        properties = {}
3160
3108
 
3161
 
        tree, selected_list = WorkingTree.open_containing_paths(selected_list)
 
3109
        tree, selected_list = tree_files(selected_list)
3162
3110
        if selected_list == ['']:
3163
3111
            # workaround - commit of root of tree should be exactly the same
3164
3112
            # as just default commit in that tree, and succeed even though
3199
3147
        def get_message(commit_obj):
3200
3148
            """Callback to get commit message"""
3201
3149
            if file:
3202
 
                f = open(file)
 
3150
                f = codecs.open(file, 'rt', osutils.get_user_encoding())
3203
3151
                try:
3204
 
                    my_message = f.read().decode(osutils.get_user_encoding())
 
3152
                    my_message = f.read()
3205
3153
                finally:
3206
3154
                    f.close()
3207
3155
            elif message is not None:
3238
3186
                        reporter=None, verbose=verbose, revprops=properties,
3239
3187
                        authors=author, timestamp=commit_stamp,
3240
3188
                        timezone=offset,
3241
 
                        exclude=tree.safe_relpath_files(exclude))
 
3189
                        exclude=safe_relpath_files(tree, exclude))
3242
3190
        except PointlessCommit:
3243
3191
            raise errors.BzrCommandError("No changes to commit."
3244
3192
                              " Use --unchanged to commit anyhow.")
3381
3329
                try:
3382
3330
                    c = Branch.open_containing(u'.')[0].get_config()
3383
3331
                except errors.NotBranchError:
3384
 
                    c = _mod_config.GlobalConfig()
 
3332
                    c = config.GlobalConfig()
3385
3333
            else:
3386
3334
                c = Branch.open(directory).get_config()
3387
3335
            if email:
3392
3340
 
3393
3341
        # display a warning if an email address isn't included in the given name.
3394
3342
        try:
3395
 
            _mod_config.extract_email_address(name)
 
3343
            config.extract_email_address(name)
3396
3344
        except errors.NoEmailInUsername, e:
3397
3345
            warning('"%s" does not seem to contain an email address.  '
3398
3346
                    'This is allowed, but not recommended.', name)
3404
3352
            else:
3405
3353
                c = Branch.open(directory).get_config()
3406
3354
        else:
3407
 
            c = _mod_config.GlobalConfig()
 
3355
            c = config.GlobalConfig()
3408
3356
        c.set_user_option('email', name)
3409
3357
 
3410
3358
 
3477
3425
                'bzr alias --remove expects an alias to remove.')
3478
3426
        # If alias is not found, print something like:
3479
3427
        # unalias: foo: not found
3480
 
        c = _mod_config.GlobalConfig()
 
3428
        c = config.GlobalConfig()
3481
3429
        c.unset_alias(alias_name)
3482
3430
 
3483
3431
    @display_command
3484
3432
    def print_aliases(self):
3485
3433
        """Print out the defined aliases in a similar format to bash."""
3486
 
        aliases = _mod_config.GlobalConfig().get_aliases()
 
3434
        aliases = config.GlobalConfig().get_aliases()
3487
3435
        for key, value in sorted(aliases.iteritems()):
3488
3436
            self.outf.write('bzr alias %s="%s"\n' % (key, value))
3489
3437
 
3499
3447
 
3500
3448
    def set_alias(self, alias_name, alias_command):
3501
3449
        """Save the alias in the global config."""
3502
 
        c = _mod_config.GlobalConfig()
 
3450
        c = config.GlobalConfig()
3503
3451
        c.set_alias(alias_name, alias_command)
3504
3452
 
3505
3453
 
3540
3488
    If you set BZR_TEST_PDB=1 when running selftest, failing tests will drop
3541
3489
    into a pdb postmortem session.
3542
3490
 
3543
 
    The --coverage=DIRNAME global option produces a report with covered code
3544
 
    indicated.
3545
 
 
3546
3491
    :Examples:
3547
3492
        Run only tests relating to 'ignore'::
3548
3493
 
3581
3526
                                 'throughout the test suite.',
3582
3527
                            type=get_transport_type),
3583
3528
                     Option('benchmark',
3584
 
                            help='Run the benchmarks rather than selftests.',
3585
 
                            hidden=True),
 
3529
                            help='Run the benchmarks rather than selftests.'),
3586
3530
                     Option('lsprof-timed',
3587
3531
                            help='Generate lsprof output for benchmarked'
3588
3532
                                 ' sections of code.'),
3589
3533
                     Option('lsprof-tests',
3590
3534
                            help='Generate lsprof output for each test.'),
 
3535
                     Option('cache-dir', type=str,
 
3536
                            help='Cache intermediate benchmark output in this '
 
3537
                                 'directory.'),
3591
3538
                     Option('first',
3592
3539
                            help='Run all tests, but run specified tests first.',
3593
3540
                            short_name='f',
3627
3574
 
3628
3575
    def run(self, testspecs_list=None, verbose=False, one=False,
3629
3576
            transport=None, benchmark=None,
3630
 
            lsprof_timed=None,
 
3577
            lsprof_timed=None, cache_dir=None,
3631
3578
            first=False, list_only=False,
3632
3579
            randomize=None, exclude=None, strict=False,
3633
3580
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3634
3581
            parallel=None, lsprof_tests=False):
3635
 
        from bzrlib import tests
3636
 
 
 
3582
        from bzrlib.tests import selftest
 
3583
        import bzrlib.benchmarks as benchmarks
 
3584
        from bzrlib.benchmarks import tree_creator
 
3585
 
 
3586
        # Make deprecation warnings visible, unless -Werror is set
 
3587
        symbol_versioning.activate_deprecation_warnings(override=False)
 
3588
 
 
3589
        if cache_dir is not None:
 
3590
            tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
3637
3591
        if testspecs_list is not None:
3638
3592
            pattern = '|'.join(testspecs_list)
3639
3593
        else:
3658
3612
            self.additional_selftest_args.setdefault(
3659
3613
                'suite_decorators', []).append(parallel)
3660
3614
        if benchmark:
3661
 
            raise errors.BzrCommandError(
3662
 
                "--benchmark is no longer supported from bzr 2.2; "
3663
 
                "use bzr-usertest instead")
3664
 
        test_suite_factory = None
 
3615
            test_suite_factory = benchmarks.test_suite
 
3616
            # Unless user explicitly asks for quiet, be verbose in benchmarks
 
3617
            verbose = not is_quiet()
 
3618
            # TODO: should possibly lock the history file...
 
3619
            benchfile = open(".perf_history", "at", buffering=1)
 
3620
            self.add_cleanup(benchfile.close)
 
3621
        else:
 
3622
            test_suite_factory = None
 
3623
            benchfile = None
3665
3624
        selftest_kwargs = {"verbose": verbose,
3666
3625
                          "pattern": pattern,
3667
3626
                          "stop_on_failure": one,
3669
3628
                          "test_suite_factory": test_suite_factory,
3670
3629
                          "lsprof_timed": lsprof_timed,
3671
3630
                          "lsprof_tests": lsprof_tests,
 
3631
                          "bench_history": benchfile,
3672
3632
                          "matching_tests_first": first,
3673
3633
                          "list_only": list_only,
3674
3634
                          "random_seed": randomize,
3679
3639
                          "starting_with": starting_with
3680
3640
                          }
3681
3641
        selftest_kwargs.update(self.additional_selftest_args)
3682
 
 
3683
 
        # Make deprecation warnings visible, unless -Werror is set
3684
 
        cleanup = symbol_versioning.activate_deprecation_warnings(
3685
 
            override=False)
3686
 
        try:
3687
 
            result = tests.selftest(**selftest_kwargs)
3688
 
        finally:
3689
 
            cleanup()
 
3642
        result = selftest(**selftest_kwargs)
3690
3643
        return int(not result)
3691
3644
 
3692
3645
 
3939
3892
    def _do_preview(self, merger):
3940
3893
        from bzrlib.diff import show_diff_trees
3941
3894
        result_tree = self._get_preview(merger)
3942
 
        path_encoding = osutils.get_diff_header_encoding()
3943
3895
        show_diff_trees(merger.this_tree, result_tree, self.outf,
3944
 
                        old_label='', new_label='',
3945
 
                        path_encoding=path_encoding)
 
3896
                        old_label='', new_label='')
3946
3897
 
3947
3898
    def _do_merge(self, merger, change_reporter, allow_pending, verified):
3948
3899
        merger.change_reporter = change_reporter
4135
4086
        from bzrlib.conflicts import restore
4136
4087
        if merge_type is None:
4137
4088
            merge_type = _mod_merge.Merge3Merger
4138
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
 
4089
        tree, file_list = tree_files(file_list)
4139
4090
        self.add_cleanup(tree.lock_write().unlock)
4140
4091
        parents = tree.get_parent_ids()
4141
4092
        if len(parents) != 2:
4251
4202
 
4252
4203
    def run(self, revision=None, no_backup=False, file_list=None,
4253
4204
            forget_merges=None):
4254
 
        tree, file_list = WorkingTree.open_containing_paths(file_list)
 
4205
        tree, file_list = tree_files(file_list)
4255
4206
        self.add_cleanup(tree.lock_tree_write().unlock)
4256
4207
        if forget_merges:
4257
4208
            tree.set_parent_ids(tree.get_parent_ids()[:1])
4860
4811
            self.outf.write('The above revision(s) will be removed.\n')
4861
4812
 
4862
4813
        if not force:
4863
 
            if not ui.ui_factory.confirm_action(
4864
 
                    'Uncommit these revisions',
4865
 
                    'bzrlib.builtins.uncommit',
4866
 
                    {}):
4867
 
                self.outf.write('Canceled\n')
 
4814
            if not ui.ui_factory.get_boolean('Are you sure'):
 
4815
                self.outf.write('Canceled')
4868
4816
                return 0
4869
4817
 
4870
4818
        mutter('Uncommitting from {%s} to {%s}',
4876
4824
 
4877
4825
 
4878
4826
class cmd_break_lock(Command):
4879
 
    __doc__ = """Break a dead lock.
4880
 
 
4881
 
    This command breaks a lock on a repository, branch, working directory or
4882
 
    config file.
 
4827
    __doc__ = """Break a dead lock on a repository, branch or working directory.
4883
4828
 
4884
4829
    CAUTION: Locks should only be broken when you are sure that the process
4885
4830
    holding the lock has been stopped.
4890
4835
    :Examples:
4891
4836
        bzr break-lock
4892
4837
        bzr break-lock bzr+ssh://example.com/bzr/foo
4893
 
        bzr break-lock --conf ~/.bazaar
4894
4838
    """
4895
 
 
4896
4839
    takes_args = ['location?']
4897
 
    takes_options = [
4898
 
        Option('config',
4899
 
               help='LOCATION is the directory where the config lock is.'),
4900
 
        Option('force',
4901
 
            help='Do not ask for confirmation before breaking the lock.'),
4902
 
        ]
4903
4840
 
4904
 
    def run(self, location=None, config=False, force=False):
 
4841
    def run(self, location=None, show=False):
4905
4842
        if location is None:
4906
4843
            location = u'.'
4907
 
        if force:
4908
 
            ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
4909
 
                None,
4910
 
                {'bzrlib.lockdir.break': True})
4911
 
        if config:
4912
 
            conf = _mod_config.LockableConfig(file_name=location)
4913
 
            conf.break_lock()
4914
 
        else:
4915
 
            control, relpath = bzrdir.BzrDir.open_containing(location)
4916
 
            try:
4917
 
                control.break_lock()
4918
 
            except NotImplementedError:
4919
 
                pass
 
4844
        control, relpath = bzrdir.BzrDir.open_containing(location)
 
4845
        try:
 
4846
            control.break_lock()
 
4847
        except NotImplementedError:
 
4848
            pass
4920
4849
 
4921
4850
 
4922
4851
class cmd_wait_until_signalled(Command):
4985
4914
 
4986
4915
    def run(self, port=None, inet=False, directory=None, allow_writes=False,
4987
4916
            protocol=None):
4988
 
        from bzrlib import transport
 
4917
        from bzrlib.transport import get_transport, transport_server_registry
4989
4918
        if directory is None:
4990
4919
            directory = os.getcwd()
4991
4920
        if protocol is None:
4992
 
            protocol = transport.transport_server_registry.get()
 
4921
            protocol = transport_server_registry.get()
4993
4922
        host, port = self.get_host_and_port(port)
4994
4923
        url = urlutils.local_path_to_url(directory)
4995
4924
        if not allow_writes:
4996
4925
            url = 'readonly+' + url
4997
 
        t = transport.get_transport(url)
4998
 
        protocol(t, host, port, inet)
 
4926
        transport = get_transport(url)
 
4927
        protocol(transport, host, port, inet)
4999
4928
 
5000
4929
 
5001
4930
class cmd_join(Command):
5007
4936
    not part of it.  (Such trees can be produced by "bzr split", but also by
5008
4937
    running "bzr branch" with the target inside a tree.)
5009
4938
 
5010
 
    The result is a combined tree, with the subtree no longer an independent
 
4939
    The result is a combined tree, with the subtree no longer an independant
5011
4940
    part.  This is marked as a merge of the subtree into the containing tree,
5012
4941
    and all history is preserved.
5013
4942
    """
5409
5338
            if tag_name is None:
5410
5339
                raise errors.BzrCommandError("No tag specified to delete.")
5411
5340
            branch.tags.delete_tag(tag_name)
5412
 
            note('Deleted tag %s.' % tag_name)
 
5341
            self.outf.write('Deleted tag %s.\n' % tag_name)
5413
5342
        else:
5414
5343
            if revision:
5415
5344
                if len(revision) != 1:
5427
5356
            if (not force) and branch.tags.has_tag(tag_name):
5428
5357
                raise errors.TagAlreadyExists(tag_name)
5429
5358
            branch.tags.set_tag(tag_name, revision_id)
5430
 
            note('Created tag %s.' % tag_name)
 
5359
            self.outf.write('Created tag %s.\n' % tag_name)
5431
5360
 
5432
5361
 
5433
5362
class cmd_tags(Command):
5442
5371
            help='Branch whose tags should be displayed.'),
5443
5372
        RegistryOption.from_kwargs('sort',
5444
5373
            'Sort tags by different criteria.', title='Sorting',
5445
 
            natural='Sort numeric substrings as numbers:'
5446
 
                    ' suitable for version numbers. (default)',
5447
 
            alpha='Sort tags lexicographically.',
 
5374
            alpha='Sort tags lexicographically (default).',
5448
5375
            time='Sort tags chronologically.',
5449
5376
            ),
5450
5377
        'show-ids',
5454
5381
    @display_command
5455
5382
    def run(self,
5456
5383
            directory='.',
5457
 
            sort='natural',
 
5384
            sort='alpha',
5458
5385
            show_ids=False,
5459
5386
            revision=None,
5460
5387
            ):
5472
5399
            # only show revisions between revid1 and revid2 (inclusive)
5473
5400
            tags = [(tag, revid) for tag, revid in tags if
5474
5401
                graph.is_between(revid, revid1, revid2)]
5475
 
        if sort == 'natural':
5476
 
            def natural_sort_key(tag):
5477
 
                return [f(s) for f,s in 
5478
 
                        zip(itertools.cycle((unicode.lower,int)),
5479
 
                                            re.split('([0-9]+)', tag[0]))]
5480
 
            tags.sort(key=natural_sort_key)
5481
 
        elif sort == 'alpha':
 
5402
        if sort == 'alpha':
5482
5403
            tags.sort()
5483
5404
        elif sort == 'time':
5484
5405
            timestamps = {}
5783
5704
            name=None,
5784
5705
            switch=None,
5785
5706
            ):
5786
 
        tree, file_list = WorkingTree.open_containing_paths(file_list,
5787
 
            apply_view=False)
 
5707
        tree, file_list = tree_files(file_list, apply_view=False)
5788
5708
        current_view, view_dict = tree.views.get_view_info()
5789
5709
        if name is None:
5790
5710
            name = current_view
5919
5839
 
5920
5840
    You can put multiple items on the shelf, and by default, 'unshelve' will
5921
5841
    restore the most recently shelved changes.
5922
 
 
5923
 
    For complicated changes, it is possible to edit the changes in a separate
5924
 
    editor program to decide what the file remaining in the working copy
5925
 
    should look like.  To do this, add the configuration option
5926
 
 
5927
 
        change_editor = PROGRAM @new_path @old_path
5928
 
 
5929
 
    where @new_path is replaced with the path of the new version of the 
5930
 
    file and @old_path is replaced with the path of the old version of 
5931
 
    the file.  The PROGRAM should save the new file with the desired 
5932
 
    contents of the file in the working tree.
5933
 
        
5934
5842
    """
5935
5843
 
5936
5844
    takes_args = ['file*']
5948
5856
        Option('destroy',
5949
5857
               help='Destroy removed changes instead of shelving them.'),
5950
5858
    ]
5951
 
    _see_also = ['unshelve', 'configuration']
 
5859
    _see_also = ['unshelve']
5952
5860
 
5953
5861
    def run(self, revision=None, all=False, file_list=None, message=None,
5954
5862
            writer=None, list=False, destroy=False, directory=u'.'):
6103
6011
    # be only called once.
6104
6012
    for (name, aliases, module_name) in [
6105
6013
        ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6106
 
        ('cmd_config', [], 'bzrlib.config'),
6107
6014
        ('cmd_dpush', [], 'bzrlib.foreign'),
6108
6015
        ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6109
6016
        ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6110
6017
        ('cmd_conflicts', [], 'bzrlib.conflicts'),
6111
6018
        ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6112
 
        ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6113
6019
        ]:
6114
6020
        builtin_command_registry.register_lazy(name, aliases, module_name)