~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Matt Nordhoff
  • Date: 2009-04-04 02:50:01 UTC
  • mfrom: (4253 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4256.
  • Revision ID: mnordhoff@mattnordhoff.com-20090404025001-z1403k0tatmc8l91
Merge bzr.dev, fixing conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
35
35
    config,
36
36
    errors,
37
37
    globbing,
 
38
    hooks,
38
39
    log,
39
40
    merge as _mod_merge,
40
41
    merge_directive,
41
42
    osutils,
42
43
    reconfigure,
 
44
    rename_map,
43
45
    revision as _mod_revision,
44
46
    symbol_versioning,
45
47
    transport,
82
84
        tree = WorkingTree.open_containing(file_list[0])[0]
83
85
        if tree.supports_views():
84
86
            view_files = tree.views.lookup_view()
85
 
            for filename in file_list:
86
 
                if not osutils.is_inside_any(view_files, filename):
87
 
                    raise errors.FileOutsideView(filename, view_files)
 
87
            if view_files:
 
88
                for filename in file_list:
 
89
                    if not osutils.is_inside_any(view_files, filename):
 
90
                        raise errors.FileOutsideView(filename, view_files)
88
91
    else:
89
92
        tree = WorkingTree.open_containing(u'.')[0]
90
93
        if tree.supports_views():
92
95
            if view_files:
93
96
                file_list = view_files
94
97
                view_str = views.view_display_str(view_files)
95
 
                note("ignoring files outside view: %s" % view_str)
 
98
                note("Ignoring files outside view. View is %s" % view_str)
96
99
    return tree, file_list
97
100
 
98
101
 
131
134
 
132
135
    The filenames given are not required to exist.
133
136
 
134
 
    :param file_list: Filenames to convert.  
 
137
    :param file_list: Filenames to convert.
135
138
 
136
139
    :param default_branch: Fallback tree path to use if file_list is empty or
137
140
        None.
148
151
            if view_files:
149
152
                file_list = view_files
150
153
                view_str = views.view_display_str(view_files)
151
 
                note("ignoring files outside view: %s" % view_str)
 
154
                note("Ignoring files outside view. View is %s" % view_str)
152
155
        return tree, file_list
153
156
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
154
157
    return tree, safe_relpath_files(tree, file_list, canonicalize,
237
240
 
238
241
    To see ignored files use 'bzr ignored'.  For details on the
239
242
    changes to file texts, use 'bzr diff'.
240
 
    
 
243
 
241
244
    Note that --short or -S gives status flags for each item, similar
242
245
    to Subversion's status command. To get output similar to svn -q,
243
246
    use bzr status -SV.
255
258
    If a revision argument is given, the status is calculated against
256
259
    that revision, or between two revisions if two are provided.
257
260
    """
258
 
    
 
261
 
259
262
    # TODO: --no-recurse, --recurse options
260
 
    
 
263
 
261
264
    takes_args = ['file*']
262
265
    takes_options = ['show-ids', 'revision', 'change', 'verbose',
263
266
                     Option('short', help='Use short status indicators.',
271
274
 
272
275
    encoding_type = 'replace'
273
276
    _see_also = ['diff', 'revert', 'status-flags']
274
 
    
 
277
 
275
278
    @display_command
276
279
    def run(self, show_ids=False, file_list=None, revision=None, short=False,
277
280
            versioned=False, no_pending=False, verbose=False):
299
302
 
300
303
class cmd_cat_revision(Command):
301
304
    """Write out metadata for a revision.
302
 
    
 
305
 
303
306
    The revision to print can either be specified by a specific
304
307
    revision identifier, or you can use --revision.
305
308
    """
309
312
    takes_options = ['revision']
310
313
    # cat-revision is more for frontends so should be exact
311
314
    encoding = 'strict'
312
 
    
 
315
 
313
316
    @display_command
314
317
    def run(self, revision_id=None, revision=None):
315
318
        if revision_id is not None and revision is not None:
430
433
 
431
434
    def run(self, location='.', force=False):
432
435
        d = bzrdir.BzrDir.open(location)
433
 
        
 
436
 
434
437
        try:
435
438
            working = d.open_workingtree()
436
439
        except errors.NoWorkingTree:
448
451
        if working_path != branch_path:
449
452
            raise errors.BzrCommandError("You cannot remove the working tree from "
450
453
                                         "a lightweight checkout")
451
 
        
 
454
 
452
455
        d.destroy_workingtree()
453
 
        
 
456
 
454
457
 
455
458
class cmd_revno(Command):
456
459
    """Show current revision number.
506
509
                revno = '.'.join(str(i) for i in dotted_map[revision_id])
507
510
            print '%s %s' % (revno, revision_id)
508
511
 
509
 
    
 
512
 
510
513
class cmd_add(Command):
511
514
    """Add specified files or directories.
512
515
 
530
533
    you should never need to explicitly add a directory, they'll just
531
534
    get added when you add a file in the directory.
532
535
 
533
 
    --dry-run will show which files would be added, but not actually 
 
536
    --dry-run will show which files would be added, but not actually
534
537
    add them.
535
538
 
536
539
    --file-ids-from will try to use the file ids from the supplied path.
585
588
        finally:
586
589
            if base_tree is not None:
587
590
                base_tree.unlock()
588
 
        if not is_quiet() and len(added) > 0:
589
 
            self.outf.write('add completed\n')
590
591
        if len(ignored) > 0:
591
592
            if verbose:
592
593
                for glob in sorted(ignored.keys()):
593
594
                    for path in ignored[glob]:
594
 
                        self.outf.write("ignored %s matching \"%s\"\n" 
 
595
                        self.outf.write("ignored %s matching \"%s\"\n"
595
596
                                        % (path, glob))
596
597
            else:
597
598
                match_len = 0
624
625
 
625
626
    takes_args = ['filename']
626
627
    hidden = True
627
 
    
 
628
 
628
629
    @display_command
629
630
    def run(self, filename):
630
631
        # TODO: jam 20050106 Can relpath return a munged path if
721
722
    takes_args = ['names*']
722
723
    takes_options = [Option("after", help="Move only the bzr identifier"
723
724
        " of the file, because the file has already been moved."),
 
725
        Option('auto', help='Automatically guess renames.'),
 
726
        Option('dry-run', help='Avoid making changes when guessing renames.'),
724
727
        ]
725
728
    aliases = ['move', 'rename']
726
729
    encoding_type = 'replace'
727
730
 
728
 
    def run(self, names_list, after=False):
 
731
    def run(self, names_list, after=False, auto=False, dry_run=False):
 
732
        if auto:
 
733
            return self.run_auto(names_list, after, dry_run)
 
734
        elif dry_run:
 
735
            raise errors.BzrCommandError('--dry-run requires --auto.')
729
736
        if names_list is None:
730
737
            names_list = []
731
 
 
732
738
        if len(names_list) < 2:
733
739
            raise errors.BzrCommandError("missing file argument")
734
740
        tree, rel_names = tree_files(names_list, canonicalize=False)
738
744
        finally:
739
745
            tree.unlock()
740
746
 
 
747
    def run_auto(self, names_list, after, dry_run):
 
748
        if names_list is not None and len(names_list) > 1:
 
749
            raise errors.BzrCommandError('Only one path may be specified to'
 
750
                                         ' --auto.')
 
751
        if after:
 
752
            raise errors.BzrCommandError('--after cannot be specified with'
 
753
                                         ' --auto.')
 
754
        work_tree, file_list = tree_files(names_list, default_branch='.')
 
755
        work_tree.lock_write()
 
756
        try:
 
757
            rename_map.RenameMap.guess_renames(work_tree, dry_run)
 
758
        finally:
 
759
            work_tree.unlock()
 
760
 
741
761
    def _run(self, tree, names_list, rel_names, after):
742
762
        into_existing = osutils.isdir(names_list[-1])
743
763
        if into_existing and len(names_list) == 2:
801
821
                        # pathjoin with an empty tail adds a slash, which breaks
802
822
                        # relpath :(
803
823
                        dest_parent_fq = tree.basedir
804
 
    
 
824
 
805
825
                    dest_tail = osutils.canonical_relpath(
806
826
                                    dest_parent_fq,
807
827
                                    osutils.pathjoin(dest_parent_fq, spec_tail))
841
861
    with bzr send.
842
862
    """
843
863
 
844
 
    _see_also = ['push', 'update', 'status-flags']
 
864
    _see_also = ['push', 'update', 'status-flags', 'send']
845
865
    takes_options = ['remember', 'overwrite', 'revision',
846
866
        custom_help('verbose',
847
867
            help='Show logs of pulled revisions.'),
931
951
 
932
952
class cmd_push(Command):
933
953
    """Update a mirror of this branch.
934
 
    
 
954
 
935
955
    The target branch will not have its working tree populated because this
936
956
    is both expensive, and is not supported on remote file systems.
937
 
    
 
957
 
938
958
    Some smart servers or protocols *may* put the working tree in place in
939
959
    the future.
940
960
 
944
964
 
945
965
    If branches have diverged, you can use 'bzr push --overwrite' to replace
946
966
    the other branch completely, discarding its unmerged changes.
947
 
    
 
967
 
948
968
    If you want to ensure you have the different changes in the other branch,
949
969
    do a merge (see bzr help merge) from the other branch, and commit that.
950
970
    After that you will be able to do a push without '--overwrite'.
1127
1147
    the branch found in '.'. This is useful if you have removed the working tree
1128
1148
    or if it was never created - i.e. if you pushed the branch to its current
1129
1149
    location using SFTP.
1130
 
    
 
1150
 
1131
1151
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
1132
1152
    be used.  In other words, "checkout ../foo/bar" will attempt to create ./bar.
1133
1153
    If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1175
1195
            revision_id = None
1176
1196
        if to_location is None:
1177
1197
            to_location = urlutils.derive_to_location(branch_location)
1178
 
        # if the source and to_location are the same, 
 
1198
        # if the source and to_location are the same,
1179
1199
        # and there is no working tree,
1180
1200
        # then reconstitute a branch
1181
1201
        if (osutils.abspath(to_location) ==
1227
1247
 
1228
1248
class cmd_update(Command):
1229
1249
    """Update a tree to have the latest code committed to its branch.
1230
 
    
 
1250
 
1231
1251
    This will perform a merge into the working tree, and may generate
1232
 
    conflicts. If you have any local changes, you will still 
 
1252
    conflicts. If you have any local changes, you will still
1233
1253
    need to commit them after the update for the update to be complete.
1234
 
    
1235
 
    If you want to discard your local changes, you can just do a 
 
1254
 
 
1255
    If you want to discard your local changes, you can just do a
1236
1256
    'bzr revert' instead of 'bzr commit' after the update.
1237
1257
    """
1238
1258
 
1282
1302
    """Show information about a working tree, branch or repository.
1283
1303
 
1284
1304
    This command will show all known locations and formats associated to the
1285
 
    tree, branch or repository.  Statistical information is included with
1286
 
    each report.
 
1305
    tree, branch or repository.
 
1306
 
 
1307
    In verbose mode, statistical information is included with each report.
 
1308
    To see extended statistic information, use a verbosity level of 2 or
 
1309
    higher by specifying the verbose option multiple times, e.g. -vv.
1287
1310
 
1288
1311
    Branches and working trees will also report any missing revisions.
 
1312
 
 
1313
    :Examples:
 
1314
 
 
1315
      Display information on the format and related locations:
 
1316
 
 
1317
        bzr info
 
1318
 
 
1319
      Display the above together with extended format information and
 
1320
      basic statistics (like the number of files in the working tree and
 
1321
      number of revisions in the branch and repository):
 
1322
 
 
1323
        bzr info -v
 
1324
 
 
1325
      Display the above together with number of committers to the branch:
 
1326
 
 
1327
        bzr info -vv
1289
1328
    """
1290
1329
    _see_also = ['revno', 'working-trees', 'repositories']
1291
1330
    takes_args = ['location?']
1295
1334
    @display_command
1296
1335
    def run(self, location=None, verbose=False):
1297
1336
        if verbose:
1298
 
            noise_level = 2
 
1337
            noise_level = get_verbosity_level()
1299
1338
        else:
1300
1339
            noise_level = 0
1301
1340
        from bzrlib.info import show_bzrdir_info
1408
1447
 
1409
1448
    This can correct data mismatches that may have been caused by
1410
1449
    previous ghost operations or bzr upgrades. You should only
1411
 
    need to run this command if 'bzr check' or a bzr developer 
 
1450
    need to run this command if 'bzr check' or a bzr developer
1412
1451
    advises you to run it.
1413
1452
 
1414
1453
    If a second branch is provided, cross-branch reconciliation is
1416
1455
    id which was not present in very early bzr versions is represented
1417
1456
    correctly in both branches.
1418
1457
 
1419
 
    At the same time it is run it may recompress data resulting in 
 
1458
    At the same time it is run it may recompress data resulting in
1420
1459
    a potential saving in disk space or performance gain.
1421
1460
 
1422
1461
    The branch *MUST* be on a listable system such as local disk or sftp.
1478
1517
    Use this to create an empty branch, or before importing an
1479
1518
    existing project.
1480
1519
 
1481
 
    If there is a repository in a parent directory of the location, then 
 
1520
    If there is a repository in a parent directory of the location, then
1482
1521
    the history of the branch will be stored in the repository.  Otherwise
1483
1522
    init creates a standalone branch which carries its own history
1484
1523
    in the .bzr directory.
1637
1676
 
1638
1677
class cmd_diff(Command):
1639
1678
    """Show differences in the working tree, between revisions or branches.
1640
 
    
 
1679
 
1641
1680
    If no arguments are given, all changes for the current tree are listed.
1642
1681
    If files are given, only the changes in those files are listed.
1643
1682
    Remote and multiple branches can be compared by using the --old and
1744
1783
        old_tree, new_tree, specific_files, extra_trees = \
1745
1784
                _get_trees_to_diff(file_list, revision, old, new,
1746
1785
                apply_view=True)
1747
 
        return show_diff_trees(old_tree, new_tree, sys.stdout, 
 
1786
        return show_diff_trees(old_tree, new_tree, sys.stdout,
1748
1787
                               specific_files=specific_files,
1749
1788
                               external_diff_options=diff_options,
1750
1789
                               old_label=old_label, new_label=new_label,
1897
1936
    were merged.
1898
1937
 
1899
1938
    :Output control:
1900
 
 
 
1939
 
1901
1940
      The log format controls how information about each revision is
1902
1941
      displayed. The standard log formats are called ``long``, ``short``
1903
1942
      and ``line``. The default is long. See ``bzr help log-formats``
1905
1944
 
1906
1945
      The following options can be used to control what information is
1907
1946
      displayed::
1908
 
  
 
1947
 
1909
1948
        -l N        display a maximum of N revisions
1910
1949
        -n N        display N levels of revisions (0 for all, 1 for collapsed)
1911
1950
        -v          display a status summary (delta) for each revision
1912
1951
        -p          display a diff (patch) for each revision
1913
1952
        --show-ids  display revision-ids (and file-ids), not just revnos
1914
 
  
 
1953
 
1915
1954
      Note that the default number of levels to display is a function of the
1916
 
      log format. If the -n option is not used, ``short`` and ``line`` show
1917
 
      just the top level (mainline) while ``long`` shows all levels of merged
1918
 
      revisions.
1919
 
  
 
1955
      log format. If the -n option is not used, the standard log formats show
 
1956
      just the top level (mainline).
 
1957
 
1920
1958
      Status summaries are shown using status flags like A, M, etc. To see
1921
1959
      the changes explained using words like ``added`` and ``modified``
1922
1960
      instead, use the -vv option.
1923
 
  
 
1961
 
1924
1962
    :Ordering control:
1925
 
  
 
1963
 
1926
1964
      To display revisions from oldest to newest, use the --forward option.
1927
1965
      In most cases, using this option will have little impact on the total
1928
1966
      time taken to produce a log, though --forward does not incrementally
1929
1967
      display revisions like --reverse does when it can.
1930
 
  
 
1968
 
1931
1969
    :Revision filtering:
1932
 
  
 
1970
 
1933
1971
      The -r option can be used to specify what revision or range of revisions
1934
1972
      to filter against. The various forms are shown below::
1935
 
  
 
1973
 
1936
1974
        -rX      display revision X
1937
1975
        -rX..    display revision X and later
1938
1976
        -r..Y    display up to and including revision Y
1939
1977
        -rX..Y   display from X to Y inclusive
1940
 
  
 
1978
 
1941
1979
      See ``bzr help revisionspec`` for details on how to specify X and Y.
1942
1980
      Some common examples are given below::
1943
 
  
 
1981
 
1944
1982
        -r-1                show just the tip
1945
1983
        -r-10..             show the last 10 mainline revisions
1946
1984
        -rsubmit:..         show what's new on this branch
1947
1985
        -rancestor:path..   show changes since the common ancestor of this
1948
1986
                            branch and the one at location path
1949
1987
        -rdate:yesterday..  show changes since yesterday
1950
 
  
 
1988
 
1951
1989
      When logging a range of revisions using -rX..Y, log starts at
1952
1990
      revision Y and searches back in history through the primary
1953
1991
      ("left-hand") parents until it finds X. When logging just the
1956
1994
      a nested merge revision and the log will be truncated accordingly.
1957
1995
 
1958
1996
    :Path filtering:
1959
 
  
1960
 
      If a parameter is given and it's not a branch, the log will be filtered
1961
 
      to show only those revisions that changed the nominated file or
1962
 
      directory.
1963
 
  
 
1997
 
 
1998
      If parameters are given and the first one is not a branch, the log
 
1999
      will be filtered to show only those revisions that changed the
 
2000
      nominated files or directories.
 
2001
 
1964
2002
      Filenames are interpreted within their historical context. To log a
1965
2003
      deleted file, specify a revision range so that the file existed at
1966
2004
      the end or start of the range.
1967
 
  
 
2005
 
1968
2006
      Historical context is also important when interpreting pathnames of
1969
2007
      renamed files/directories. Consider the following example:
1970
 
  
 
2008
 
1971
2009
      * revision 1: add tutorial.txt
1972
2010
      * revision 2: modify tutorial.txt
1973
2011
      * revision 3: rename tutorial.txt to guide.txt; add tutorial.txt
1974
 
  
 
2012
 
1975
2013
      In this case:
1976
 
  
 
2014
 
1977
2015
      * ``bzr log guide.txt`` will log the file added in revision 1
1978
 
  
 
2016
 
1979
2017
      * ``bzr log tutorial.txt`` will log the new file added in revision 3
1980
 
  
 
2018
 
1981
2019
      * ``bzr log -r2 -p tutorial.txt`` will show the changes made to
1982
2020
        the original file in revision 2.
1983
 
  
 
2021
 
1984
2022
      * ``bzr log -r2 -p guide.txt`` will display an error message as there
1985
2023
        was no file called guide.txt in revision 2.
1986
 
  
 
2024
 
1987
2025
      Renames are always followed by log. By design, there is no need to
1988
2026
      explicitly ask for this (and no way to stop logging a file back
1989
2027
      until it was last renamed).
1990
 
  
1991
 
      Note: If the path is a directory, only revisions that directly changed
1992
 
      that directory object are currently shown. This is considered a bug.
1993
 
      (Support for filtering against multiple files and for files within a
1994
 
      directory is under development.)
1995
 
  
 
2028
 
1996
2029
    :Other filtering:
1997
 
  
 
2030
 
1998
2031
      The --message option can be used for finding revisions that match a
1999
2032
      regular expression in a commit message.
2000
 
  
 
2033
 
2001
2034
    :Tips & tricks:
2002
 
  
 
2035
 
2003
2036
      GUI tools and IDEs are often better at exploring history than command
2004
2037
      line tools. You may prefer qlog or glog from the QBzr and Bzr-Gtk packages
2005
2038
      respectively for example. (TortoiseBzr uses qlog for displaying logs.) See
2006
2039
      http://bazaar-vcs.org/BzrPlugins and http://bazaar-vcs.org/IDEIntegration.
2007
 
  
 
2040
 
2008
2041
      Web interfaces are often better at exploring history than command line
2009
2042
      tools, particularly for branches on servers. You may prefer Loggerhead
2010
2043
      or one of its alternatives. See http://bazaar-vcs.org/WebInterface.
2011
 
  
 
2044
 
2012
2045
      You may find it useful to add the aliases below to ``bazaar.conf``::
2013
 
  
 
2046
 
2014
2047
        [ALIASES]
2015
 
        tip = log -r-1 -n1
2016
 
        top = log -r-10.. --short --forward
2017
 
        show = log -v -p -n1 --long
2018
 
  
 
2048
        tip = log -r-1
 
2049
        top = log -l10 --line
 
2050
        show = log -v -p
 
2051
 
2019
2052
      ``bzr tip`` will then show the latest revision while ``bzr top``
2020
2053
      will show the last 10 mainline revisions. To see the details of a
2021
2054
      particular revision X,  ``bzr show -rX``.
2022
 
  
2023
 
      As many GUI tools and Web interfaces do, you may prefer viewing
2024
 
      history collapsed initially. If you are interested in looking deeper
2025
 
      into a particular merge X, use ``bzr log -n0 -rX``. If you like
2026
 
      working this way, you may wish to either:
2027
 
  
2028
 
      * change your default log format to short (or line)
2029
 
      * add this alias: log = log -n1
2030
 
  
 
2055
 
 
2056
      If you are interested in looking deeper into a particular merge X,
 
2057
      use ``bzr log -n0 -rX``.
 
2058
 
2031
2059
      ``bzr log -v`` on a branch with lots of history is currently
2032
2060
      very slow. A fix for this issue is currently under development.
2033
2061
      With or without that fix, it is recommended that a revision range
2034
2062
      be given when using the -v option.
2035
 
  
 
2063
 
2036
2064
      bzr has a generic full-text matching plugin, bzr-search, that can be
2037
2065
      used to find revisions matching user names, commit messages, etc.
2038
2066
      Among other features, this plugin can find all revisions containing
2039
2067
      a list of words but not others.
2040
 
  
 
2068
 
2041
2069
      When exploring non-mainline history on large projects with deep
2042
2070
      history, the performance of log can be greatly improved by installing
2043
2071
      the revnocache plugin. This plugin buffers historical information
2044
2072
      trading disk space for faster speed.
2045
2073
    """
2046
 
    takes_args = ['location?']
 
2074
    takes_args = ['file*']
2047
2075
    _see_also = ['log-formats', 'revisionspec']
2048
2076
    takes_options = [
2049
2077
            Option('forward',
2081
2109
    encoding_type = 'replace'
2082
2110
 
2083
2111
    @display_command
2084
 
    def run(self, location=None, timezone='original',
 
2112
    def run(self, file_list=None, timezone='original',
2085
2113
            verbose=False,
2086
2114
            show_ids=False,
2087
2115
            forward=False,
2092
2120
            message=None,
2093
2121
            limit=None,
2094
2122
            show_diff=False):
2095
 
        from bzrlib.log import show_log, _get_fileid_to_log
 
2123
        from bzrlib.log import (
 
2124
            Logger,
 
2125
            make_log_request_dict,
 
2126
            _get_info_for_log_files,
 
2127
            )
2096
2128
        direction = (forward and 'forward') or 'reverse'
2097
2129
 
2098
2130
        if change is not None:
2104
2136
            else:
2105
2137
                revision = change
2106
2138
 
2107
 
        # log everything
2108
 
        file_id = None
2109
 
        if location:
2110
 
            # find the file id to log:
2111
 
 
2112
 
            tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
2113
 
                location)
2114
 
            if fp != '':
2115
 
                file_id = _get_fileid_to_log(revision, tree, b, fp)
 
2139
        file_ids = []
 
2140
        filter_by_dir = False
 
2141
        if file_list:
 
2142
            # find the file ids to log and check for directory filtering
 
2143
            b, file_info_list, rev1, rev2 = _get_info_for_log_files(revision,
 
2144
                file_list)
 
2145
            for relpath, file_id, kind in file_info_list:
2116
2146
                if file_id is None:
2117
2147
                    raise errors.BzrCommandError(
2118
2148
                        "Path unknown at end or start of revision range: %s" %
2119
 
                        location)
 
2149
                        relpath)
 
2150
                # If the relpath is the top of the tree, we log everything
 
2151
                if relpath == '':
 
2152
                    file_ids = []
 
2153
                    break
 
2154
                else:
 
2155
                    file_ids.append(file_id)
 
2156
                filter_by_dir = filter_by_dir or (
 
2157
                    kind in ['directory', 'tree-reference'])
2120
2158
        else:
2121
 
            # local dir only
2122
 
            # FIXME ? log the current subdir only RBC 20060203 
 
2159
            # log everything
 
2160
            # FIXME ? log the current subdir only RBC 20060203
2123
2161
            if revision is not None \
2124
2162
                    and len(revision) > 0 and revision[0].get_branch():
2125
2163
                location = revision[0].get_branch()
2127
2165
                location = '.'
2128
2166
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2129
2167
            b = dir.open_branch()
2130
 
 
2131
 
        b.lock_read()
2132
 
        try:
2133
2168
            rev1, rev2 = _get_revision_range(revision, b, self.name())
 
2169
 
 
2170
        # Decide on the type of delta & diff filtering to use
 
2171
        # TODO: add an --all-files option to make this configurable & consistent
 
2172
        if not verbose:
 
2173
            delta_type = None
 
2174
        else:
 
2175
            delta_type = 'full'
 
2176
        if not show_diff:
 
2177
            diff_type = None
 
2178
        elif file_ids:
 
2179
            diff_type = 'partial'
 
2180
        else:
 
2181
            diff_type = 'full'
 
2182
 
 
2183
        b.lock_read()
 
2184
        try:
 
2185
            # Build the log formatter
2134
2186
            if log_format is None:
2135
2187
                log_format = log.log_formatter_registry.get_default(b)
2136
 
 
2137
2188
            lf = log_format(show_ids=show_ids, to_file=self.outf,
2138
2189
                            show_timezone=timezone,
2139
2190
                            delta_format=get_verbosity_level(),
2140
2191
                            levels=levels)
2141
2192
 
2142
 
            show_log(b,
2143
 
                     lf,
2144
 
                     file_id,
2145
 
                     verbose=verbose,
2146
 
                     direction=direction,
2147
 
                     start_revision=rev1,
2148
 
                     end_revision=rev2,
2149
 
                     search=message,
2150
 
                     limit=limit,
2151
 
                     show_diff=show_diff)
 
2193
            # Choose the algorithm for doing the logging. It's annoying
 
2194
            # having multiple code paths like this but necessary until
 
2195
            # the underlying repository format is faster at generating
 
2196
            # deltas or can provide everything we need from the indices.
 
2197
            # The default algorithm - match-using-deltas - works for
 
2198
            # multiple files and directories and is faster for small
 
2199
            # amounts of history (200 revisions say). However, it's too
 
2200
            # slow for logging a single file in a repository with deep
 
2201
            # history, i.e. > 10K revisions. In the spirit of "do no
 
2202
            # evil when adding features", we continue to use the
 
2203
            # original algorithm - per-file-graph - for the "single
 
2204
            # file that isn't a directory without showing a delta" case.
 
2205
            partial_history = revision and b.repository._format.supports_chks
 
2206
            match_using_deltas = (len(file_ids) != 1 or filter_by_dir
 
2207
                or delta_type or partial_history)
 
2208
 
 
2209
            # Build the LogRequest and execute it
 
2210
            if len(file_ids) == 0:
 
2211
                file_ids = None
 
2212
            rqst = make_log_request_dict(
 
2213
                direction=direction, specific_fileids=file_ids,
 
2214
                start_revision=rev1, end_revision=rev2, limit=limit,
 
2215
                message_search=message, delta_type=delta_type,
 
2216
                diff_type=diff_type, _match_using_deltas=match_using_deltas)
 
2217
            Logger(b, rqst).show(lf)
2152
2218
        finally:
2153
2219
            b.unlock()
2154
2220
 
2157
2223
    """Take the input of a revision option and turn it into a revision range.
2158
2224
 
2159
2225
    It returns RevisionInfo objects which can be used to obtain the rev_id's
2160
 
    of the desired revisons. It does some user input validations.
 
2226
    of the desired revisions. It does some user input validations.
2161
2227
    """
2162
2228
    if revisionspec_list is None:
2163
2229
        rev1 = None
2285
2351
        if revision is not None or tree is None:
2286
2352
            tree = _get_one_revision_tree('ls', revision, branch=branch)
2287
2353
 
 
2354
        apply_view = False
 
2355
        if isinstance(tree, WorkingTree) and tree.supports_views():
 
2356
            view_files = tree.views.lookup_view()
 
2357
            if view_files:
 
2358
                apply_view = True
 
2359
                view_str = views.view_display_str(view_files)
 
2360
                note("Ignoring files outside view. View is %s" % view_str)
 
2361
 
2288
2362
        tree.lock_read()
2289
2363
        try:
2290
2364
            for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2296
2370
                        continue
2297
2371
                    if kind is not None and fkind != kind:
2298
2372
                        continue
 
2373
                    if apply_view:
 
2374
                        try:
 
2375
                            views.check_path_in_view(tree, fp)
 
2376
                        except errors.FileOutsideView:
 
2377
                            continue
2299
2378
                    kindch = entry.kind_character()
2300
2379
                    outstring = fp + kindch
2301
2380
                    if verbose:
2346
2425
    using this command or directly by using an editor, be sure to commit
2347
2426
    it.
2348
2427
 
2349
 
    Note: ignore patterns containing shell wildcards must be quoted from 
 
2428
    Note: ignore patterns containing shell wildcards must be quoted from
2350
2429
    the shell on Unix.
2351
2430
 
2352
2431
    :Examples:
2377
2456
        Option('old-default-rules',
2378
2457
               help='Write out the ignore rules bzr < 0.9 always used.')
2379
2458
        ]
2380
 
    
 
2459
 
2381
2460
    def run(self, name_pattern_list=None, old_default_rules=None):
2382
2461
        from bzrlib import ignores
2383
2462
        if old_default_rules is not None:
2388
2467
        if not name_pattern_list:
2389
2468
            raise errors.BzrCommandError("ignore requires at least one "
2390
2469
                                  "NAME_PATTERN or --old-default-rules")
2391
 
        name_pattern_list = [globbing.normalize_pattern(p) 
 
2470
        name_pattern_list = [globbing.normalize_pattern(p)
2392
2471
                             for p in name_pattern_list]
2393
2472
        for name_pattern in name_pattern_list:
2394
 
            if (name_pattern[0] == '/' or 
 
2473
            if (name_pattern[0] == '/' or
2395
2474
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
2396
2475
                raise errors.BzrCommandError(
2397
2476
                    "NAME_PATTERN should not be an absolute path")
2409
2488
        tree.unlock()
2410
2489
        if len(matches) > 0:
2411
2490
            print "Warning: the following files are version controlled and" \
2412
 
                  " match your ignore pattern:\n%s" % ("\n".join(matches),)
 
2491
                  " match your ignore pattern:\n%s" \
 
2492
                  "\nThese files will continue to be version controlled" \
 
2493
                  " unless you 'bzr remove' them." % ("\n".join(matches),)
2413
2494
 
2414
2495
 
2415
2496
class cmd_ignored(Command):
2449
2530
    """
2450
2531
    hidden = True
2451
2532
    takes_args = ['revno']
2452
 
    
 
2533
 
2453
2534
    @display_command
2454
2535
    def run(self, revno):
2455
2536
        try:
2494
2575
               help="Type of file to export to.",
2495
2576
               type=unicode),
2496
2577
        'revision',
 
2578
        Option('filters', help='Apply content filters to export the '
 
2579
                'convenient form.'),
2497
2580
        Option('root',
2498
2581
               type=str,
2499
2582
               help="Name of the root directory inside the exported file."),
2500
2583
        ]
2501
2584
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2502
 
        root=None):
 
2585
        root=None, filters=False):
2503
2586
        from bzrlib.export import export
2504
2587
 
2505
2588
        if branch_or_subdir is None:
2512
2595
 
2513
2596
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2514
2597
        try:
2515
 
            export(rev_tree, dest, format, root, subdir)
 
2598
            export(rev_tree, dest, format, root, subdir, filtered=filters)
2516
2599
        except errors.NoSuchExportFormat, e:
2517
2600
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2518
2601
 
2523
2606
    If no revision is nominated, the last revision is used.
2524
2607
 
2525
2608
    Note: Take care to redirect standard output when using this command on a
2526
 
    binary file. 
 
2609
    binary file.
2527
2610
    """
2528
2611
 
2529
2612
    _see_also = ['ls']
2530
2613
    takes_options = [
2531
2614
        Option('name-from-revision', help='The path name in the old tree.'),
 
2615
        Option('filters', help='Apply content filters to display the '
 
2616
                'convenience form.'),
2532
2617
        'revision',
2533
2618
        ]
2534
2619
    takes_args = ['filename']
2535
2620
    encoding_type = 'exact'
2536
2621
 
2537
2622
    @display_command
2538
 
    def run(self, filename, revision=None, name_from_revision=False):
 
2623
    def run(self, filename, revision=None, name_from_revision=False,
 
2624
            filters=False):
2539
2625
        if revision is not None and len(revision) != 1:
2540
2626
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2541
2627
                                         " one revision specifier")
2544
2630
        branch.lock_read()
2545
2631
        try:
2546
2632
            return self._run(tree, branch, relpath, filename, revision,
2547
 
                             name_from_revision)
 
2633
                             name_from_revision, filters)
2548
2634
        finally:
2549
2635
            branch.unlock()
2550
2636
 
2551
 
    def _run(self, tree, b, relpath, filename, revision, name_from_revision):
 
2637
    def _run(self, tree, b, relpath, filename, revision, name_from_revision,
 
2638
        filtered):
2552
2639
        if tree is None:
2553
2640
            tree = b.basis_tree()
2554
2641
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2555
2642
 
2556
 
        cur_file_id = tree.path2id(relpath)
2557
2643
        old_file_id = rev_tree.path2id(relpath)
2558
2644
 
2559
2645
        if name_from_revision:
 
2646
            # Try in revision if requested
2560
2647
            if old_file_id is None:
2561
2648
                raise errors.BzrCommandError(
2562
2649
                    "%r is not present in revision %s" % (
2563
2650
                        filename, rev_tree.get_revision_id()))
2564
2651
            else:
2565
2652
                content = rev_tree.get_file_text(old_file_id)
2566
 
        elif cur_file_id is not None:
2567
 
            content = rev_tree.get_file_text(cur_file_id)
2568
 
        elif old_file_id is not None:
2569
 
            content = rev_tree.get_file_text(old_file_id)
2570
 
        else:
2571
 
            raise errors.BzrCommandError(
2572
 
                "%r is not present in revision %s" % (
2573
 
                    filename, rev_tree.get_revision_id()))
2574
 
        self.outf.write(content)
 
2653
        else:
 
2654
            cur_file_id = tree.path2id(relpath)
 
2655
            found = False
 
2656
            if cur_file_id is not None:
 
2657
                # Then try with the actual file id
 
2658
                try:
 
2659
                    content = rev_tree.get_file_text(cur_file_id)
 
2660
                    found = True
 
2661
                except errors.NoSuchId:
 
2662
                    # The actual file id didn't exist at that time
 
2663
                    pass
 
2664
            if not found and old_file_id is not None:
 
2665
                # Finally try with the old file id
 
2666
                content = rev_tree.get_file_text(old_file_id)
 
2667
                found = True
 
2668
            if not found:
 
2669
                # Can't be found anywhere
 
2670
                raise errors.BzrCommandError(
 
2671
                    "%r is not present in revision %s" % (
 
2672
                        filename, rev_tree.get_revision_id()))
 
2673
        if filtered:
 
2674
            from bzrlib.filters import (
 
2675
                ContentFilterContext,
 
2676
                filtered_output_bytes,
 
2677
                )
 
2678
            filters = rev_tree._content_filter_stack(relpath)
 
2679
            chunks = content.splitlines(True)
 
2680
            content = filtered_output_bytes(chunks, filters,
 
2681
                ContentFilterContext(relpath, rev_tree))
 
2682
            self.outf.writelines(content)
 
2683
        else:
 
2684
            self.outf.write(content)
2575
2685
 
2576
2686
 
2577
2687
class cmd_local_time_offset(Command):
2578
2688
    """Show the offset in seconds from GMT to local time."""
2579
 
    hidden = True    
 
2689
    hidden = True
2580
2690
    @display_command
2581
2691
    def run(self):
2582
2692
        print osutils.local_time_offset()
2585
2695
 
2586
2696
class cmd_commit(Command):
2587
2697
    """Commit changes into a new revision.
2588
 
    
 
2698
 
2589
2699
    If no arguments are given, the entire tree is committed.
2590
2700
 
2591
2701
    If selected files are specified, only changes to those files are
2592
 
    committed.  If a directory is specified then the directory and everything 
 
2702
    committed.  If a directory is specified then the directory and everything
2593
2703
    within it is committed.
2594
2704
 
2595
2705
    When excludes are given, they take precedence over selected files.
2601
2711
    If author of the change is not the same person as the committer, you can
2602
2712
    specify the author's name using the --author option. The name should be
2603
2713
    in the same format as a committer-id, e.g. "John Doe <jdoe@example.com>".
 
2714
    If there is more than one author of the change you can specify the option
 
2715
    multiple times, once for each author.
2604
2716
 
2605
2717
    A selected-file commit may fail in some cases where the committed
2606
2718
    tree would be invalid. Consider::
2649
2761
                    help="Refuse to commit if there are unknown "
2650
2762
                    "files in the working tree."),
2651
2763
             ListOption('fixes', type=str,
2652
 
                    help="Mark a bug as being fixed by this revision."),
2653
 
             Option('author', type=unicode,
 
2764
                    help="Mark a bug as being fixed by this revision "
 
2765
                         "(see \"bzr help bugs\")."),
 
2766
             ListOption('author', type=unicode,
2654
2767
                    help="Set the author's name, if it's different "
2655
2768
                         "from the committer."),
2656
2769
             Option('local',
2665
2778
             ]
2666
2779
    aliases = ['ci', 'checkin']
2667
2780
 
2668
 
    def _get_bug_fix_properties(self, fixes, branch):
2669
 
        properties = []
 
2781
    def _iter_bug_fix_urls(self, fixes, branch):
2670
2782
        # Configure the properties for bug fixing attributes.
2671
2783
        for fixed_bug in fixes:
2672
2784
            tokens = fixed_bug.split(':')
2673
2785
            if len(tokens) != 2:
2674
2786
                raise errors.BzrCommandError(
2675
 
                    "Invalid bug %s. Must be in the form of 'tag:id'. "
2676
 
                    "Commit refused." % fixed_bug)
 
2787
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
 
2788
                    "See \"bzr help bugs\" for more information on this "
 
2789
                    "feature.\nCommit refused." % fixed_bug)
2677
2790
            tag, bug_id = tokens
2678
2791
            try:
2679
 
                bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
 
2792
                yield bugtracker.get_bug_url(tag, branch, bug_id)
2680
2793
            except errors.UnknownBugTrackerAbbreviation:
2681
2794
                raise errors.BzrCommandError(
2682
2795
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
2683
 
            except errors.MalformedBugIdentifier:
 
2796
            except errors.MalformedBugIdentifier, e:
2684
2797
                raise errors.BzrCommandError(
2685
 
                    "Invalid bug identifier for %s. Commit refused."
2686
 
                    % fixed_bug)
2687
 
            properties.append('%s fixed' % bug_url)
2688
 
        return '\n'.join(properties)
 
2798
                    "%s\nCommit refused." % (str(e),))
2689
2799
 
2690
2800
    def run(self, message=None, file=None, verbose=False, selected_list=None,
2691
2801
            unchanged=False, strict=False, local=False, fixes=None,
2704
2814
        # TODO: Need a blackbox test for invoking the external editor; may be
2705
2815
        # slightly problematic to run this cross-platform.
2706
2816
 
2707
 
        # TODO: do more checks that the commit will succeed before 
 
2817
        # TODO: do more checks that the commit will succeed before
2708
2818
        # spending the user's valuable time typing a commit message.
2709
2819
 
2710
2820
        properties = {}
2718
2828
 
2719
2829
        if fixes is None:
2720
2830
            fixes = []
2721
 
        bug_property = self._get_bug_fix_properties(fixes, tree.branch)
 
2831
        bug_property = bugtracker.encode_fixes_bug_urls(
 
2832
            self._iter_bug_fix_urls(fixes, tree.branch))
2722
2833
        if bug_property:
2723
2834
            properties['bugs'] = bug_property
2724
2835
 
2733
2844
                        selected_list, diff=show_diff,
2734
2845
                        output_encoding=osutils.get_user_encoding())
2735
2846
                start_message = generate_commit_message_template(commit_obj)
2736
 
                my_message = edit_commit_message_encoded(t, 
 
2847
                my_message = edit_commit_message_encoded(t,
2737
2848
                    start_message=start_message)
2738
2849
                if my_message is None:
2739
2850
                    raise errors.BzrCommandError("please specify a commit"
2753
2864
                        specific_files=selected_list,
2754
2865
                        allow_pointless=unchanged, strict=strict, local=local,
2755
2866
                        reporter=None, verbose=verbose, revprops=properties,
2756
 
                        author=author,
 
2867
                        authors=author,
2757
2868
                        exclude=safe_relpath_files(tree, exclude))
2758
2869
        except PointlessCommit:
2759
2870
            # FIXME: This should really happen before the file is read in;
2856
2967
 
2857
2968
    def run(self, url='.', format=None):
2858
2969
        from bzrlib.upgrade import upgrade
2859
 
        if format is None:
2860
 
            format = bzrdir.format_registry.make_bzrdir('default')
2861
2970
        upgrade(url, format)
2862
2971
 
2863
2972
 
2864
2973
class cmd_whoami(Command):
2865
2974
    """Show or set bzr user id.
2866
 
    
 
2975
 
2867
2976
    :Examples:
2868
2977
        Show the email of the current user::
2869
2978
 
2881
2990
                    ]
2882
2991
    takes_args = ['name?']
2883
2992
    encoding_type = 'replace'
2884
 
    
 
2993
 
2885
2994
    @display_command
2886
2995
    def run(self, email=False, branch=False, name=None):
2887
2996
        if name is None:
2902
3011
        except errors.NoEmailInUsername, e:
2903
3012
            warning('"%s" does not seem to contain an email address.  '
2904
3013
                    'This is allowed, but not recommended.', name)
2905
 
        
 
3014
 
2906
3015
        # use global config unless --branch given
2907
3016
        if branch:
2908
3017
            c = Branch.open_containing('.')[0].get_config()
3007
3116
 
3008
3117
class cmd_selftest(Command):
3009
3118
    """Run internal test suite.
3010
 
    
 
3119
 
3011
3120
    If arguments are given, they are regular expressions that say which tests
3012
3121
    should run.  Tests matching any expression are run, and other tests are
3013
3122
    not run.
3036
3145
    modified by plugins will not be tested, and tests provided by plugins will
3037
3146
    not be run.
3038
3147
 
3039
 
    Tests that need working space on disk use a common temporary directory, 
 
3148
    Tests that need working space on disk use a common temporary directory,
3040
3149
    typically inside $TMPDIR or /tmp.
3041
3150
 
3042
3151
    :Examples:
3090
3199
                            ),
3091
3200
                     Option('list-only',
3092
3201
                            help='List the tests instead of running them.'),
 
3202
                     RegistryOption('parallel',
 
3203
                        help="Run the test suite in parallel.",
 
3204
                        lazy_registry=('bzrlib.tests', 'parallel_registry'),
 
3205
                        value_switches=False,
 
3206
                        ),
3093
3207
                     Option('randomize', type=str, argname="SEED",
3094
3208
                            help='Randomize the order of tests using the given'
3095
3209
                                 ' seed or "now" for the current time.'),
3097
3211
                            short_name='x',
3098
3212
                            help='Exclude tests that match this regular'
3099
3213
                                 ' expression.'),
 
3214
                     Option('subunit',
 
3215
                        help='Output test progress via subunit.'),
3100
3216
                     Option('strict', help='Fail on missing dependencies or '
3101
3217
                            'known failures.'),
3102
3218
                     Option('load-list', type=str, argname='TESTLISTFILE',
3119
3235
            lsprof_timed=None, cache_dir=None,
3120
3236
            first=False, list_only=False,
3121
3237
            randomize=None, exclude=None, strict=False,
3122
 
            load_list=None, debugflag=None, starting_with=None):
 
3238
            load_list=None, debugflag=None, starting_with=None, subunit=False,
 
3239
            parallel=None):
3123
3240
        from bzrlib.tests import selftest
3124
3241
        import bzrlib.benchmarks as benchmarks
3125
3242
        from bzrlib.benchmarks import tree_creator
3141
3258
            pattern = '|'.join(testspecs_list)
3142
3259
        else:
3143
3260
            pattern = ".*"
 
3261
        if subunit:
 
3262
            try:
 
3263
                from bzrlib.tests import SubUnitBzrRunner
 
3264
            except ImportError:
 
3265
                raise errors.BzrCommandError("subunit not available. subunit "
 
3266
                    "needs to be installed to use --subunit.")
 
3267
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunner
 
3268
        if parallel:
 
3269
            self.additional_selftest_args.setdefault(
 
3270
                'suite_decorators', []).append(parallel)
3144
3271
        if benchmark:
3145
3272
            test_suite_factory = benchmarks.test_suite
3146
3273
            # Unless user explicitly asks for quiet, be verbose in benchmarks
3212
3339
    #       merging only part of the history.
3213
3340
    takes_args = ['branch', 'other']
3214
3341
    hidden = True
3215
 
    
 
3342
 
3216
3343
    @display_command
3217
3344
    def run(self, branch, other):
3218
3345
        from bzrlib.revision import ensure_null
3219
 
        
 
3346
 
3220
3347
        branch1 = Branch.open_containing(branch)[0]
3221
3348
        branch2 = Branch.open_containing(other)[0]
3222
3349
        branch1.lock_read()
3238
3365
 
3239
3366
class cmd_merge(Command):
3240
3367
    """Perform a three-way merge.
3241
 
    
 
3368
 
3242
3369
    The source of the merge can be specified either in the form of a branch,
3243
3370
    or in the form of a path to a file containing a merge directive generated
3244
3371
    with bzr send. If neither is specified, the default is the upstream branch
3254
3381
    By default, bzr will try to merge in all new work from the other
3255
3382
    branch, automatically determining an appropriate base.  If this
3256
3383
    fails, you may need to give an explicit base.
3257
 
    
 
3384
 
3258
3385
    Merge will do its best to combine the changes in two branches, but there
3259
3386
    are some kinds of problems only a human can fix.  When it encounters those,
3260
3387
    it will mark a conflict.  A conflict means that you need to fix something,
3270
3397
    The results of the merge are placed into the destination working
3271
3398
    directory, where they can be reviewed (with bzr diff), tested, and then
3272
3399
    committed to record the result of the merge.
3273
 
    
 
3400
 
3274
3401
    merge refuses to run if there are any uncommitted changes, unless
3275
3402
    --force is given.
3276
3403
 
3293
3420
    """
3294
3421
 
3295
3422
    encoding_type = 'exact'
3296
 
    _see_also = ['update', 'remerge', 'status-flags']
 
3423
    _see_also = ['update', 'remerge', 'status-flags', 'send']
3297
3424
    takes_args = ['location?']
3298
3425
    takes_options = [
3299
3426
        'change',
3335
3462
        allow_pending = True
3336
3463
        verified = 'inapplicable'
3337
3464
        tree = WorkingTree.open_containing(directory)[0]
 
3465
 
 
3466
        # die as quickly as possible if there are uncommitted changes
 
3467
        try:
 
3468
            basis_tree = tree.revision_tree(tree.last_revision())
 
3469
        except errors.NoSuchRevision:
 
3470
            basis_tree = tree.basis_tree()
 
3471
        if not force:
 
3472
            changes = tree.changes_from(basis_tree)
 
3473
            if changes.has_changed():
 
3474
                raise errors.UncommittedChanges(tree)
 
3475
 
3338
3476
        view_info = _get_view_info_for_change_reporter(tree)
3339
3477
        change_reporter = delta._ChangeReporter(
3340
3478
            unversioned_filter=tree.is_ignored, view_info=view_info)
3393
3531
                                       merger.other_rev_id)
3394
3532
                    result.report(self.outf)
3395
3533
                    return 0
3396
 
            merger.check_basis(not force)
 
3534
            merger.check_basis(False)
3397
3535
            if preview:
3398
3536
                return self._do_preview(merger)
3399
3537
            else:
3542
3680
    """Redo a merge.
3543
3681
 
3544
3682
    Use this if you want to try a different merge technique while resolving
3545
 
    conflicts.  Some merge techniques are better than others, and remerge 
 
3683
    conflicts.  Some merge techniques are better than others, and remerge
3546
3684
    lets you try different ones on different files.
3547
3685
 
3548
3686
    The options for remerge have the same meaning and defaults as the ones for
3552
3690
    :Examples:
3553
3691
        Re-do the merge of all conflicted files, and show the base text in
3554
3692
        conflict regions, in addition to the usual THIS and OTHER texts::
3555
 
      
 
3693
 
3556
3694
            bzr remerge --show-base
3557
3695
 
3558
3696
        Re-do the merge of "foobar", using the weave merge algorithm, with
3559
3697
        additional processing to reduce the size of conflict regions::
3560
 
      
 
3698
 
3561
3699
            bzr remerge --merge-type weave --reprocess foobar
3562
3700
    """
3563
3701
    takes_args = ['file*']
3593
3731
                    interesting_ids.add(file_id)
3594
3732
                    if tree.kind(file_id) != "directory":
3595
3733
                        continue
3596
 
                    
 
3734
 
3597
3735
                    for name, ie in tree.inventory.iter_entries(file_id):
3598
3736
                        interesting_ids.add(ie.file_id)
3599
3737
                new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3648
3786
    merge instead.  For example, "merge . --revision -2..-3" will remove the
3649
3787
    changes introduced by -2, without affecting the changes introduced by -1.
3650
3788
    Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3651
 
    
 
3789
 
3652
3790
    By default, any files that have been manually changed will be backed up
3653
3791
    first.  (Files changed only by merge are not backed up.)  Backup files have
3654
3792
    '.~#~' appended to their name, where # is a number.
3723
3861
            ]
3724
3862
    takes_args = ['topic?']
3725
3863
    aliases = ['?', '--help', '-?', '-h']
3726
 
    
 
3864
 
3727
3865
    @display_command
3728
3866
    def run(self, topic=None, long=False):
3729
3867
        import bzrlib.help
3740
3878
    takes_args = ['context?']
3741
3879
    aliases = ['s-c']
3742
3880
    hidden = True
3743
 
    
 
3881
 
3744
3882
    @display_command
3745
3883
    def run(self, context=None):
3746
3884
        import shellcomplete
3752
3890
 
3753
3891
    OTHER_BRANCH may be local or remote.
3754
3892
 
3755
 
    To filter on a range of revirions, you can use the command -r begin..end
 
3893
    To filter on a range of revisions, you can use the command -r begin..end
3756
3894
    -r revision requests a specific revision, -r ..end or -r begin.. are
3757
3895
    also valid.
3758
3896
 
3798
3936
            type=_parse_revision_str,
3799
3937
            help='Filter on local branch revisions (inclusive). '
3800
3938
                'See "help revisionspec" for details.'),
3801
 
        Option('include-merges', 'Show merged revisions.'),
 
3939
        Option('include-merges',
 
3940
               'Show all revisions in addition to the mainline ones.'),
3802
3941
        ]
3803
3942
    encoding_type = 'replace'
3804
3943
 
3936
4075
 
3937
4076
class cmd_plugins(Command):
3938
4077
    """List the installed plugins.
3939
 
    
 
4078
 
3940
4079
    This command displays the list of installed plugins including
3941
4080
    version of plugin and a short description of each.
3942
4081
 
4019
4158
    This prints out the given file with an annotation on the left side
4020
4159
    indicating which revision, author and date introduced the change.
4021
4160
 
4022
 
    If the origin is the same for a run of consecutive lines, it is 
 
4161
    If the origin is the same for a run of consecutive lines, it is
4023
4162
    shown only at the top, unless the --all option is given.
4024
4163
    """
4025
4164
    # TODO: annotate directories; showing when each file was last changed
4026
 
    # TODO: if the working copy is modified, show annotations on that 
 
4165
    # TODO: if the working copy is modified, show annotations on that
4027
4166
    #       with new uncommitted lines marked
4028
4167
    aliases = ['ann', 'blame', 'praise']
4029
4168
    takes_args = ['filename']
4075
4214
    hidden = True # is this right ?
4076
4215
    takes_args = ['revision_id*']
4077
4216
    takes_options = ['revision']
4078
 
    
 
4217
 
4079
4218
    def run(self, revision_id_list=None, revision=None):
4080
4219
        if revision_id_list is not None and revision is not None:
4081
4220
            raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
4311
4450
    holding the lock has been stopped.
4312
4451
 
4313
4452
    You can get information on what locks are open via the 'bzr info' command.
4314
 
    
 
4453
 
4315
4454
    :Examples:
4316
4455
        bzr break-lock
4317
4456
    """
4325
4464
            control.break_lock()
4326
4465
        except NotImplementedError:
4327
4466
            pass
4328
 
        
 
4467
 
4329
4468
 
4330
4469
class cmd_wait_until_signalled(Command):
4331
4470
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
4445
4584
 
4446
4585
class cmd_join(Command):
4447
4586
    """Combine a subtree into its containing tree.
4448
 
    
 
4587
 
4449
4588
    This command is for experimental use only.  It requires the target tree
4450
4589
    to be in dirstate-with-subtree format, which cannot be converted into
4451
4590
    earlier formats.
4493
4632
            try:
4494
4633
                containing_tree.subsume(sub_tree)
4495
4634
            except errors.BadSubsumeSource, e:
4496
 
                raise errors.BzrCommandError("Cannot join %s.  %s" % 
 
4635
                raise errors.BzrCommandError("Cannot join %s.  %s" %
4497
4636
                                             (tree, e.reason))
4498
4637
 
4499
4638
 
4652
4791
    Mail is sent using your preferred mail program.  This should be transparent
4653
4792
    on Windows (it uses MAPI).  On Linux, it requires the xdg-email utility.
4654
4793
    If the preferred client can't be found (or used), your editor will be used.
4655
 
    
 
4794
 
4656
4795
    To use a specific mail program, set the mail_client configuration option.
4657
4796
    (For Thunderbird 1.5, this works around some bugs.)  Supported values for
4658
4797
    specific clients are "claws", "evolution", "kmail", "mutt", and
4661
4800
 
4662
4801
    If mail is being sent, a to address is required.  This can be supplied
4663
4802
    either on the commandline, by setting the submit_to configuration
4664
 
    option in the branch itself or the child_submit_to configuration option 
 
4803
    option in the branch itself or the child_submit_to configuration option
4665
4804
    in the submit branch.
4666
4805
 
4667
4806
    Two formats are currently supported: "4" uses revision bundle format 4 and
4669
4808
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
4670
4809
    default.  "0.9" uses revision bundle format 0.9 and merge directive
4671
4810
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
4672
 
    
4673
 
    Merge directives are applied using the merge command or the pull command.
 
4811
 
 
4812
    The merge directives created by bzr send may be applied using bzr merge or
 
4813
    bzr pull by specifying a file containing a merge directive as the location.
4674
4814
    """
4675
4815
 
4676
4816
    encoding_type = 'exact'
4699
4839
               type=unicode),
4700
4840
        'revision',
4701
4841
        'message',
 
4842
        Option('body', help='Body for the email.', type=unicode),
4702
4843
        RegistryOption.from_kwargs('format',
4703
4844
        'Use the specified output format.',
4704
4845
        **{'4': 'Bundle format 4, Merge Directive 2 (default)',
4707
4848
 
4708
4849
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4709
4850
            no_patch=False, revision=None, remember=False, output=None,
4710
 
            format='4', mail_to=None, message=None, **kwargs):
 
4851
            format='4', mail_to=None, message=None, body=None, **kwargs):
4711
4852
        return self._run(submit_branch, revision, public_branch, remember,
4712
4853
                         format, no_bundle, no_patch, output,
4713
 
                         kwargs.get('from', '.'), mail_to, message)
 
4854
                         kwargs.get('from', '.'), mail_to, message, body)
4714
4855
 
4715
4856
    def _run(self, submit_branch, revision, public_branch, remember, format,
4716
 
             no_bundle, no_patch, output, from_, mail_to, message):
 
4857
             no_bundle, no_patch, output, from_, mail_to, message, body):
4717
4858
        from bzrlib.revision import NULL_REVISION
4718
4859
        branch = Branch.open_containing(from_)[0]
4719
4860
        if output is None:
4731
4872
                if mail_to is None:
4732
4873
                    mail_to = config.get_user_option('submit_to')
4733
4874
                mail_client = config.get_mail_client()
 
4875
                if (not getattr(mail_client, 'supports_body', False)
 
4876
                    and body is not None):
 
4877
                    raise errors.BzrCommandError(
 
4878
                        'Mail client "%s" does not support specifying body' %
 
4879
                        mail_client.__class__.__name__)
4734
4880
            if remember and submit_branch is None:
4735
4881
                raise errors.BzrCommandError(
4736
4882
                    '--remember requires a branch to be specified.')
4813
4959
                    subject += revision.get_summary()
4814
4960
                basename = directive.get_disk_name(branch)
4815
4961
                mail_client.compose_merge_request(mail_to, subject,
4816
 
                                                  outfile.getvalue(), basename)
 
4962
                                                  outfile.getvalue(),
 
4963
                                                  basename, body)
4817
4964
        finally:
4818
4965
            if output != '-':
4819
4966
                outfile.close()
4887
5034
            output = '-'
4888
5035
        return self._run(submit_branch, revision, public_branch, remember,
4889
5036
                         format, no_bundle, no_patch, output,
4890
 
                         kwargs.get('from', '.'), None, None)
 
5037
                         kwargs.get('from', '.'), None, None, None)
4891
5038
 
4892
5039
 
4893
5040
class cmd_tag(Command):
4894
5041
    """Create, remove or modify a tag naming a revision.
4895
 
    
 
5042
 
4896
5043
    Tags give human-meaningful names to revisions.  Commands that take a -r
4897
5044
    (--revision) option can be given -rtag:X, where X is any previously
4898
5045
    created tag.
4900
5047
    Tags are stored in the branch.  Tags are copied from one branch to another
4901
5048
    along when you branch, push, pull or merge.
4902
5049
 
4903
 
    It is an error to give a tag name that already exists unless you pass 
 
5050
    It is an error to give a tag name that already exists unless you pass
4904
5051
    --force, in which case the tag is moved to point to the new revision.
4905
5052
 
4906
5053
    To rename a tag (change the name but keep it on the same revsion), run ``bzr
5091
5238
 
5092
5239
class cmd_switch(Command):
5093
5240
    """Set the branch of a checkout and update.
5094
 
    
 
5241
 
5095
5242
    For lightweight checkouts, this changes the branch being referenced.
5096
5243
    For heavyweight checkouts, this checks that there are no local commits
5097
5244
    versus the current bound branch, then it makes the local branch a mirror
5296
5443
 
5297
5444
 
5298
5445
class cmd_hooks(Command):
5299
 
    """Show a branch's currently registered hooks.
5300
 
    """
 
5446
    """Show hooks."""
5301
5447
 
5302
5448
    hidden = True
5303
 
    takes_args = ['path?']
5304
5449
 
5305
 
    def run(self, path=None):
5306
 
        if path is None:
5307
 
            path = '.'
5308
 
        branch_hooks = Branch.open(path).hooks
5309
 
        for hook_type in branch_hooks:
5310
 
            hooks = branch_hooks[hook_type]
5311
 
            self.outf.write("%s:\n" % (hook_type,))
5312
 
            if hooks:
5313
 
                for hook in hooks:
5314
 
                    self.outf.write("  %s\n" %
5315
 
                                    (branch_hooks.get_hook_name(hook),))
5316
 
            else:
5317
 
                self.outf.write("  <no hooks installed>\n")
 
5450
    def run(self):
 
5451
        for hook_key in sorted(hooks.known_hooks.keys()):
 
5452
            some_hooks = hooks.known_hooks_key_to_object(hook_key)
 
5453
            self.outf.write("%s:\n" % type(some_hooks).__name__)
 
5454
            for hook_name, hook_point in sorted(some_hooks.items()):
 
5455
                self.outf.write("  %s:\n" % (hook_name,))
 
5456
                found_hooks = list(hook_point)
 
5457
                if found_hooks:
 
5458
                    for hook in found_hooks:
 
5459
                        self.outf.write("    %s\n" %
 
5460
                                        (some_hooks.get_hook_name(hook),))
 
5461
                else:
 
5462
                    self.outf.write("    <no hooks installed>\n")
5318
5463
 
5319
5464
 
5320
5465
class cmd_shelve(Command):
5353
5498
                       value_switches=True, enum_switch=False),
5354
5499
 
5355
5500
        Option('list', help='List shelved changes.'),
 
5501
        Option('destroy',
 
5502
               help='Destroy removed changes instead of shelving them.'),
5356
5503
    ]
5357
5504
    _see_also = ['unshelve']
5358
5505
 
5359
5506
    def run(self, revision=None, all=False, file_list=None, message=None,
5360
 
            writer=None, list=False):
 
5507
            writer=None, list=False, destroy=False):
5361
5508
        if list:
5362
5509
            return self.run_for_list()
5363
5510
        from bzrlib.shelf_ui import Shelver
5365
5512
            writer = bzrlib.option.diff_writer_registry.get()
5366
5513
        try:
5367
5514
            Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5368
 
                              message).run()
 
5515
                              message, destroy=destroy).run()
5369
5516
        except errors.UserAbort:
5370
5517
            return 0
5371
5518
 
5413
5560
        Unshelver.from_args(shelf_id, action).run()
5414
5561
 
5415
5562
 
 
5563
class cmd_clean_tree(Command):
 
5564
    """Remove unwanted files from working tree.
 
5565
 
 
5566
    By default, only unknown files, not ignored files, are deleted.  Versioned
 
5567
    files are never deleted.
 
5568
 
 
5569
    Another class is 'detritus', which includes files emitted by bzr during
 
5570
    normal operations and selftests.  (The value of these files decreases with
 
5571
    time.)
 
5572
 
 
5573
    If no options are specified, unknown files are deleted.  Otherwise, option
 
5574
    flags are respected, and may be combined.
 
5575
 
 
5576
    To check what clean-tree will do, use --dry-run.
 
5577
    """
 
5578
    takes_options = [Option('ignored', help='Delete all ignored files.'),
 
5579
                     Option('detritus', help='Delete conflict files, merge'
 
5580
                            ' backups, and failed selftest dirs.'),
 
5581
                     Option('unknown',
 
5582
                            help='Delete files unknown to bzr (default).'),
 
5583
                     Option('dry-run', help='Show files to delete instead of'
 
5584
                            ' deleting them.'),
 
5585
                     Option('force', help='Do not prompt before deleting.')]
 
5586
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
 
5587
            force=False):
 
5588
        from bzrlib.clean_tree import clean_tree
 
5589
        if not (unknown or ignored or detritus):
 
5590
            unknown = True
 
5591
        if dry_run:
 
5592
            force = True
 
5593
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
 
5594
                   dry_run=dry_run, no_prompt=force)
 
5595
 
 
5596
 
5416
5597
def _create_prefix(cur_transport):
5417
5598
    needed = [cur_transport]
5418
5599
    # Recurse upwards until we can create a directory successfully
5437
5618
 
5438
5619
# these get imported and then picked up by the scan for cmd_*
5439
5620
# TODO: Some more consistent way to split command definitions across files;
5440
 
# we do need to load at least some information about them to know of 
 
5621
# we do need to load at least some information about them to know of
5441
5622
# aliases.  ideally we would avoid loading the implementation until the
5442
5623
# details were needed.
5443
5624
from bzrlib.cmd_version_info import cmd_version_info