~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-03-06 06:48:25 UTC
  • mfrom: (4070.8.6 debug-config)
  • Revision ID: pqm@pqm.ubuntu.com-20090306064825-kbpwggw21dygeix6
(mbp) debug_flags configuration option

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""builtin bzr commands"""
18
18
 
35
35
    config,
36
36
    errors,
37
37
    globbing,
38
 
    hooks,
39
38
    log,
40
39
    merge as _mod_merge,
41
40
    merge_directive,
42
41
    osutils,
43
42
    reconfigure,
44
 
    rename_map,
45
43
    revision as _mod_revision,
46
44
    symbol_versioning,
47
45
    transport,
84
82
        tree = WorkingTree.open_containing(file_list[0])[0]
85
83
        if tree.supports_views():
86
84
            view_files = tree.views.lookup_view()
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)
 
85
            for filename in file_list:
 
86
                if not osutils.is_inside_any(view_files, filename):
 
87
                    raise errors.FileOutsideView(filename, view_files)
91
88
    else:
92
89
        tree = WorkingTree.open_containing(u'.')[0]
93
90
        if tree.supports_views():
95
92
            if view_files:
96
93
                file_list = view_files
97
94
                view_str = views.view_display_str(view_files)
98
 
                note("Ignoring files outside view. View is %s" % view_str)
 
95
                note("ignoring files outside view: %s" % view_str)
99
96
    return tree, file_list
100
97
 
101
98
 
151
148
            if view_files:
152
149
                file_list = view_files
153
150
                view_str = views.view_display_str(view_files)
154
 
                note("Ignoring files outside view. View is %s" % view_str)
 
151
                note("ignoring files outside view: %s" % view_str)
155
152
        return tree, file_list
156
153
    tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
157
154
    return tree, safe_relpath_files(tree, file_list, canonicalize,
722
719
    takes_args = ['names*']
723
720
    takes_options = [Option("after", help="Move only the bzr identifier"
724
721
        " 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.'),
727
722
        ]
728
723
    aliases = ['move', 'rename']
729
724
    encoding_type = 'replace'
730
725
 
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.')
 
726
    def run(self, names_list, after=False):
736
727
        if names_list is None:
737
728
            names_list = []
 
729
 
738
730
        if len(names_list) < 2:
739
731
            raise errors.BzrCommandError("missing file argument")
740
732
        tree, rel_names = tree_files(names_list, canonicalize=False)
744
736
        finally:
745
737
            tree.unlock()
746
738
 
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
 
 
761
739
    def _run(self, tree, names_list, rel_names, after):
762
740
        into_existing = osutils.isdir(names_list[-1])
763
741
        if into_existing and len(names_list) == 2:
861
839
    with bzr send.
862
840
    """
863
841
 
864
 
    _see_also = ['push', 'update', 'status-flags', 'send']
 
842
    _see_also = ['push', 'update', 'status-flags']
865
843
    takes_options = ['remember', 'overwrite', 'revision',
866
844
        custom_help('verbose',
867
845
            help='Show logs of pulled revisions.'),
1320
1298
      basic statistics (like the number of files in the working tree and
1321
1299
      number of revisions in the branch and repository):
1322
1300
 
1323
 
        bzr info -v
 
1301
        bzr -v info
1324
1302
 
1325
1303
      Display the above together with number of committers to the branch:
1326
1304
 
1327
 
        bzr info -vv
 
1305
        bzr -vv info
1328
1306
    """
1329
1307
    _see_also = ['revno', 'working-trees', 'repositories']
1330
1308
    takes_args = ['location?']
1952
1930
        --show-ids  display revision-ids (and file-ids), not just revnos
1953
1931
 
1954
1932
      Note that the default number of levels to display is a function of the
1955
 
      log format. If the -n option is not used, the standard log formats show
1956
 
      just the top level (mainline).
 
1933
      log format. If the -n option is not used, ``short`` and ``line`` show
 
1934
      just the top level (mainline) while ``long`` shows all levels of merged
 
1935
      revisions.
1957
1936
 
1958
1937
      Status summaries are shown using status flags like A, M, etc. To see
1959
1938
      the changes explained using words like ``added`` and ``modified``
1995
1974
 
1996
1975
    :Path filtering:
1997
1976
 
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.
 
1977
      If a parameter is given and it's not a branch, the log will be filtered
 
1978
      to show only those revisions that changed the nominated file or
 
1979
      directory.
2001
1980
 
2002
1981
      Filenames are interpreted within their historical context. To log a
2003
1982
      deleted file, specify a revision range so that the file existed at
2026
2005
      explicitly ask for this (and no way to stop logging a file back
2027
2006
      until it was last renamed).
2028
2007
 
 
2008
      Note: If the path is a directory, only revisions that directly changed
 
2009
      that directory object are currently shown. This is considered a bug.
 
2010
      (Support for filtering against multiple files and for files within a
 
2011
      directory is under development.)
 
2012
 
2029
2013
    :Other filtering:
2030
2014
 
2031
2015
      The --message option can be used for finding revisions that match a
2045
2029
      You may find it useful to add the aliases below to ``bazaar.conf``::
2046
2030
 
2047
2031
        [ALIASES]
2048
 
        tip = log -r-1
2049
 
        top = log -l10 --line
2050
 
        show = log -v -p
 
2032
        tip = log -r-1 -n1
 
2033
        top = log -r-10.. --short --forward
 
2034
        show = log -v -p -n1 --long
2051
2035
 
2052
2036
      ``bzr tip`` will then show the latest revision while ``bzr top``
2053
2037
      will show the last 10 mainline revisions. To see the details of a
2054
2038
      particular revision X,  ``bzr show -rX``.
2055
2039
 
2056
 
      If you are interested in looking deeper into a particular merge X,
2057
 
      use ``bzr log -n0 -rX``.
 
2040
      As many GUI tools and Web interfaces do, you may prefer viewing
 
2041
      history collapsed initially. If you are interested in looking deeper
 
2042
      into a particular merge X, use ``bzr log -n0 -rX``. If you like
 
2043
      working this way, you may wish to either:
 
2044
 
 
2045
      * change your default log format to short (or line)
 
2046
      * add this alias: log = log -n1
2058
2047
 
2059
2048
      ``bzr log -v`` on a branch with lots of history is currently
2060
2049
      very slow. A fix for this issue is currently under development.
2071
2060
      the revnocache plugin. This plugin buffers historical information
2072
2061
      trading disk space for faster speed.
2073
2062
    """
2074
 
    takes_args = ['file*']
 
2063
    takes_args = ['location?']
2075
2064
    _see_also = ['log-formats', 'revisionspec']
2076
2065
    takes_options = [
2077
2066
            Option('forward',
2109
2098
    encoding_type = 'replace'
2110
2099
 
2111
2100
    @display_command
2112
 
    def run(self, file_list=None, timezone='original',
 
2101
    def run(self, location=None, timezone='original',
2113
2102
            verbose=False,
2114
2103
            show_ids=False,
2115
2104
            forward=False,
2120
2109
            message=None,
2121
2110
            limit=None,
2122
2111
            show_diff=False):
2123
 
        from bzrlib.log import (
2124
 
            Logger,
2125
 
            make_log_request_dict,
2126
 
            _get_info_for_log_files,
2127
 
            )
 
2112
        from bzrlib.log import show_log, _get_fileid_to_log
2128
2113
        direction = (forward and 'forward') or 'reverse'
2129
2114
 
2130
2115
        if change is not None:
2136
2121
            else:
2137
2122
                revision = change
2138
2123
 
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:
 
2124
        # log everything
 
2125
        file_id = None
 
2126
        if location:
 
2127
            # find the file id to log:
 
2128
 
 
2129
            tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
 
2130
                location)
 
2131
            if fp != '':
 
2132
                file_id = _get_fileid_to_log(revision, tree, b, fp)
2146
2133
                if file_id is None:
2147
2134
                    raise errors.BzrCommandError(
2148
2135
                        "Path unknown at end or start of revision range: %s" %
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'])
 
2136
                        location)
2158
2137
        else:
2159
 
            # log everything
 
2138
            # local dir only
2160
2139
            # FIXME ? log the current subdir only RBC 20060203
2161
2140
            if revision is not None \
2162
2141
                    and len(revision) > 0 and revision[0].get_branch():
2165
2144
                location = '.'
2166
2145
            dir, relpath = bzrdir.BzrDir.open_containing(location)
2167
2146
            b = dir.open_branch()
 
2147
 
 
2148
        b.lock_read()
 
2149
        try:
2168
2150
            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
2186
2151
            if log_format is None:
2187
2152
                log_format = log.log_formatter_registry.get_default(b)
 
2153
 
2188
2154
            lf = log_format(show_ids=show_ids, to_file=self.outf,
2189
2155
                            show_timezone=timezone,
2190
2156
                            delta_format=get_verbosity_level(),
2191
2157
                            levels=levels)
2192
2158
 
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)
 
2159
            show_log(b,
 
2160
                     lf,
 
2161
                     file_id,
 
2162
                     verbose=verbose,
 
2163
                     direction=direction,
 
2164
                     start_revision=rev1,
 
2165
                     end_revision=rev2,
 
2166
                     search=message,
 
2167
                     limit=limit,
 
2168
                     show_diff=show_diff)
2218
2169
        finally:
2219
2170
            b.unlock()
2220
2171
 
2223
2174
    """Take the input of a revision option and turn it into a revision range.
2224
2175
 
2225
2176
    It returns RevisionInfo objects which can be used to obtain the rev_id's
2226
 
    of the desired revisions. It does some user input validations.
 
2177
    of the desired revisons. It does some user input validations.
2227
2178
    """
2228
2179
    if revisionspec_list is None:
2229
2180
        rev1 = None
2357
2308
            if view_files:
2358
2309
                apply_view = True
2359
2310
                view_str = views.view_display_str(view_files)
2360
 
                note("Ignoring files outside view. View is %s" % view_str)
 
2311
                note("ignoring files outside view: %s" % view_str)
2361
2312
 
2362
2313
        tree.lock_read()
2363
2314
        try:
2488
2439
        tree.unlock()
2489
2440
        if len(matches) > 0:
2490
2441
            print "Warning: the following files are version controlled and" \
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),)
 
2442
                  " match your ignore pattern:\n%s" % ("\n".join(matches),)
2494
2443
 
2495
2444
 
2496
2445
class cmd_ignored(Command):
2575
2524
               help="Type of file to export to.",
2576
2525
               type=unicode),
2577
2526
        'revision',
2578
 
        Option('filters', help='Apply content filters to export the '
2579
 
                'convenient form.'),
2580
2527
        Option('root',
2581
2528
               type=str,
2582
2529
               help="Name of the root directory inside the exported file."),
2583
2530
        ]
2584
2531
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
2585
 
        root=None, filters=False):
 
2532
        root=None):
2586
2533
        from bzrlib.export import export
2587
2534
 
2588
2535
        if branch_or_subdir is None:
2595
2542
 
2596
2543
        rev_tree = _get_one_revision_tree('export', revision, branch=b, tree=tree)
2597
2544
        try:
2598
 
            export(rev_tree, dest, format, root, subdir, filtered=filters)
 
2545
            export(rev_tree, dest, format, root, subdir)
2599
2546
        except errors.NoSuchExportFormat, e:
2600
2547
            raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
2601
2548
 
2612
2559
    _see_also = ['ls']
2613
2560
    takes_options = [
2614
2561
        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.'),
2617
2562
        'revision',
2618
2563
        ]
2619
2564
    takes_args = ['filename']
2620
2565
    encoding_type = 'exact'
2621
2566
 
2622
2567
    @display_command
2623
 
    def run(self, filename, revision=None, name_from_revision=False,
2624
 
            filters=False):
 
2568
    def run(self, filename, revision=None, name_from_revision=False):
2625
2569
        if revision is not None and len(revision) != 1:
2626
2570
            raise errors.BzrCommandError("bzr cat --revision takes exactly"
2627
2571
                                         " one revision specifier")
2630
2574
        branch.lock_read()
2631
2575
        try:
2632
2576
            return self._run(tree, branch, relpath, filename, revision,
2633
 
                             name_from_revision, filters)
 
2577
                             name_from_revision)
2634
2578
        finally:
2635
2579
            branch.unlock()
2636
2580
 
2637
 
    def _run(self, tree, b, relpath, filename, revision, name_from_revision,
2638
 
        filtered):
 
2581
    def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2639
2582
        if tree is None:
2640
2583
            tree = b.basis_tree()
2641
2584
        rev_tree = _get_one_revision_tree('cat', revision, branch=b)
2642
2585
 
 
2586
        cur_file_id = tree.path2id(relpath)
2643
2587
        old_file_id = rev_tree.path2id(relpath)
2644
2588
 
2645
2589
        if name_from_revision:
2646
 
            # Try in revision if requested
2647
2590
            if old_file_id is None:
2648
2591
                raise errors.BzrCommandError(
2649
2592
                    "%r is not present in revision %s" % (
2650
2593
                        filename, rev_tree.get_revision_id()))
2651
2594
            else:
2652
2595
                content = rev_tree.get_file_text(old_file_id)
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)
 
2596
        elif cur_file_id is not None:
 
2597
            content = rev_tree.get_file_text(cur_file_id)
 
2598
        elif old_file_id is not None:
 
2599
            content = rev_tree.get_file_text(old_file_id)
 
2600
        else:
 
2601
            raise errors.BzrCommandError(
 
2602
                "%r is not present in revision %s" % (
 
2603
                    filename, rev_tree.get_revision_id()))
 
2604
        self.outf.write(content)
2685
2605
 
2686
2606
 
2687
2607
class cmd_local_time_offset(Command):
2761
2681
                    help="Refuse to commit if there are unknown "
2762
2682
                    "files in the working tree."),
2763
2683
             ListOption('fixes', type=str,
2764
 
                    help="Mark a bug as being fixed by this revision "
2765
 
                         "(see \"bzr help bugs\")."),
 
2684
                    help="Mark a bug as being fixed by this revision."),
2766
2685
             ListOption('author', type=unicode,
2767
2686
                    help="Set the author's name, if it's different "
2768
2687
                         "from the committer."),
2778
2697
             ]
2779
2698
    aliases = ['ci', 'checkin']
2780
2699
 
2781
 
    def _iter_bug_fix_urls(self, fixes, branch):
 
2700
    def _get_bug_fix_properties(self, fixes, branch):
 
2701
        properties = []
2782
2702
        # Configure the properties for bug fixing attributes.
2783
2703
        for fixed_bug in fixes:
2784
2704
            tokens = fixed_bug.split(':')
2785
2705
            if len(tokens) != 2:
2786
2706
                raise errors.BzrCommandError(
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)
 
2707
                    "Invalid bug %s. Must be in the form of 'tag:id'. "
 
2708
                    "Commit refused." % fixed_bug)
2790
2709
            tag, bug_id = tokens
2791
2710
            try:
2792
 
                yield bugtracker.get_bug_url(tag, branch, bug_id)
 
2711
                bug_url = bugtracker.get_bug_url(tag, branch, bug_id)
2793
2712
            except errors.UnknownBugTrackerAbbreviation:
2794
2713
                raise errors.BzrCommandError(
2795
2714
                    'Unrecognized bug %s. Commit refused.' % fixed_bug)
2796
 
            except errors.MalformedBugIdentifier, e:
 
2715
            except errors.MalformedBugIdentifier:
2797
2716
                raise errors.BzrCommandError(
2798
 
                    "%s\nCommit refused." % (str(e),))
 
2717
                    "Invalid bug identifier for %s. Commit refused."
 
2718
                    % fixed_bug)
 
2719
            properties.append('%s fixed' % bug_url)
 
2720
        return '\n'.join(properties)
2799
2721
 
2800
2722
    def run(self, message=None, file=None, verbose=False, selected_list=None,
2801
2723
            unchanged=False, strict=False, local=False, fixes=None,
2828
2750
 
2829
2751
        if fixes is None:
2830
2752
            fixes = []
2831
 
        bug_property = bugtracker.encode_fixes_bug_urls(
2832
 
            self._iter_bug_fix_urls(fixes, tree.branch))
 
2753
        bug_property = self._get_bug_fix_properties(fixes, tree.branch)
2833
2754
        if bug_property:
2834
2755
            properties['bugs'] = bug_property
2835
2756
 
2967
2888
 
2968
2889
    def run(self, url='.', format=None):
2969
2890
        from bzrlib.upgrade import upgrade
 
2891
        if format is None:
 
2892
            format = bzrdir.format_registry.make_bzrdir('default')
2970
2893
        upgrade(url, format)
2971
2894
 
2972
2895
 
3199
3122
                            ),
3200
3123
                     Option('list-only',
3201
3124
                            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
 
                        ),
3207
3125
                     Option('randomize', type=str, argname="SEED",
3208
3126
                            help='Randomize the order of tests using the given'
3209
3127
                                 ' seed or "now" for the current time.'),
3211
3129
                            short_name='x',
3212
3130
                            help='Exclude tests that match this regular'
3213
3131
                                 ' expression.'),
3214
 
                     Option('subunit',
3215
 
                        help='Output test progress via subunit.'),
3216
3132
                     Option('strict', help='Fail on missing dependencies or '
3217
3133
                            'known failures.'),
3218
3134
                     Option('load-list', type=str, argname='TESTLISTFILE',
3235
3151
            lsprof_timed=None, cache_dir=None,
3236
3152
            first=False, list_only=False,
3237
3153
            randomize=None, exclude=None, strict=False,
3238
 
            load_list=None, debugflag=None, starting_with=None, subunit=False,
3239
 
            parallel=None):
 
3154
            load_list=None, debugflag=None, starting_with=None):
3240
3155
        from bzrlib.tests import selftest
3241
3156
        import bzrlib.benchmarks as benchmarks
3242
3157
        from bzrlib.benchmarks import tree_creator
3258
3173
            pattern = '|'.join(testspecs_list)
3259
3174
        else:
3260
3175
            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)
3271
3176
        if benchmark:
3272
3177
            test_suite_factory = benchmarks.test_suite
3273
3178
            # Unless user explicitly asks for quiet, be verbose in benchmarks
3414
3319
 
3415
3320
            bzr merge -r 81..82 ../bzr.dev
3416
3321
 
3417
 
        To apply a merge directive contained in /tmp/merge:
 
3322
        To apply a merge directive contained in in /tmp/merge:
3418
3323
 
3419
3324
            bzr merge /tmp/merge
3420
3325
    """
3421
3326
 
3422
3327
    encoding_type = 'exact'
3423
 
    _see_also = ['update', 'remerge', 'status-flags', 'send']
 
3328
    _see_also = ['update', 'remerge', 'status-flags']
3424
3329
    takes_args = ['location?']
3425
3330
    takes_options = [
3426
3331
        'change',
3462
3367
        allow_pending = True
3463
3368
        verified = 'inapplicable'
3464
3369
        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
 
 
3476
3370
        view_info = _get_view_info_for_change_reporter(tree)
3477
3371
        change_reporter = delta._ChangeReporter(
3478
3372
            unversioned_filter=tree.is_ignored, view_info=view_info)
3531
3425
                                       merger.other_rev_id)
3532
3426
                    result.report(self.outf)
3533
3427
                    return 0
3534
 
            merger.check_basis(False)
 
3428
            merger.check_basis(not force)
3535
3429
            if preview:
3536
3430
                return self._do_preview(merger)
3537
3431
            else:
3890
3784
 
3891
3785
    OTHER_BRANCH may be local or remote.
3892
3786
 
3893
 
    To filter on a range of revisions, you can use the command -r begin..end
 
3787
    To filter on a range of revirions, you can use the command -r begin..end
3894
3788
    -r revision requests a specific revision, -r ..end or -r begin.. are
3895
3789
    also valid.
3896
3790
 
3936
3830
            type=_parse_revision_str,
3937
3831
            help='Filter on local branch revisions (inclusive). '
3938
3832
                'See "help revisionspec" for details.'),
3939
 
        Option('include-merges',
3940
 
               'Show all revisions in addition to the mainline ones.'),
 
3833
        Option('include-merges', 'Show merged revisions.'),
3941
3834
        ]
3942
3835
    encoding_type = 'replace'
3943
3836
 
4809
4702
    default.  "0.9" uses revision bundle format 0.9 and merge directive
4810
4703
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
4811
4704
 
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.
 
4705
    Merge directives are applied using the merge command or the pull command.
4814
4706
    """
4815
4707
 
4816
4708
    encoding_type = 'exact'
4839
4731
               type=unicode),
4840
4732
        'revision',
4841
4733
        'message',
4842
 
        Option('body', help='Body for the email.', type=unicode),
4843
4734
        RegistryOption.from_kwargs('format',
4844
4735
        'Use the specified output format.',
4845
4736
        **{'4': 'Bundle format 4, Merge Directive 2 (default)',
4848
4739
 
4849
4740
    def run(self, submit_branch=None, public_branch=None, no_bundle=False,
4850
4741
            no_patch=False, revision=None, remember=False, output=None,
4851
 
            format='4', mail_to=None, message=None, body=None, **kwargs):
 
4742
            format='4', mail_to=None, message=None, **kwargs):
4852
4743
        return self._run(submit_branch, revision, public_branch, remember,
4853
4744
                         format, no_bundle, no_patch, output,
4854
 
                         kwargs.get('from', '.'), mail_to, message, body)
 
4745
                         kwargs.get('from', '.'), mail_to, message)
4855
4746
 
4856
4747
    def _run(self, submit_branch, revision, public_branch, remember, format,
4857
 
             no_bundle, no_patch, output, from_, mail_to, message, body):
 
4748
             no_bundle, no_patch, output, from_, mail_to, message):
4858
4749
        from bzrlib.revision import NULL_REVISION
4859
4750
        branch = Branch.open_containing(from_)[0]
4860
4751
        if output is None:
4872
4763
                if mail_to is None:
4873
4764
                    mail_to = config.get_user_option('submit_to')
4874
4765
                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__)
4880
4766
            if remember and submit_branch is None:
4881
4767
                raise errors.BzrCommandError(
4882
4768
                    '--remember requires a branch to be specified.')
4959
4845
                    subject += revision.get_summary()
4960
4846
                basename = directive.get_disk_name(branch)
4961
4847
                mail_client.compose_merge_request(mail_to, subject,
4962
 
                                                  outfile.getvalue(),
4963
 
                                                  basename, body)
 
4848
                                                  outfile.getvalue(), basename)
4964
4849
        finally:
4965
4850
            if output != '-':
4966
4851
                outfile.close()
5034
4919
            output = '-'
5035
4920
        return self._run(submit_branch, revision, public_branch, remember,
5036
4921
                         format, no_bundle, no_patch, output,
5037
 
                         kwargs.get('from', '.'), None, None, None)
 
4922
                         kwargs.get('from', '.'), None, None)
5038
4923
 
5039
4924
 
5040
4925
class cmd_tag(Command):
5443
5328
 
5444
5329
 
5445
5330
class cmd_hooks(Command):
5446
 
    """Show hooks."""
 
5331
    """Show a branch's currently registered hooks.
 
5332
    """
5447
5333
 
5448
5334
    hidden = True
 
5335
    takes_args = ['path?']
5449
5336
 
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")
 
5337
    def run(self, path=None):
 
5338
        if path is None:
 
5339
            path = '.'
 
5340
        branch_hooks = Branch.open(path).hooks
 
5341
        for hook_type in branch_hooks:
 
5342
            hooks = branch_hooks[hook_type]
 
5343
            self.outf.write("%s:\n" % (hook_type,))
 
5344
            if hooks:
 
5345
                for hook in hooks:
 
5346
                    self.outf.write("  %s\n" %
 
5347
                                    (branch_hooks.get_hook_name(hook),))
 
5348
            else:
 
5349
                self.outf.write("  <no hooks installed>\n")
5463
5350
 
5464
5351
 
5465
5352
class cmd_shelve(Command):
5498
5385
                       value_switches=True, enum_switch=False),
5499
5386
 
5500
5387
        Option('list', help='List shelved changes.'),
5501
 
        Option('destroy',
5502
 
               help='Destroy removed changes instead of shelving them.'),
5503
5388
    ]
5504
5389
    _see_also = ['unshelve']
5505
5390
 
5506
5391
    def run(self, revision=None, all=False, file_list=None, message=None,
5507
 
            writer=None, list=False, destroy=False):
 
5392
            writer=None, list=False):
5508
5393
        if list:
5509
5394
            return self.run_for_list()
5510
5395
        from bzrlib.shelf_ui import Shelver
5512
5397
            writer = bzrlib.option.diff_writer_registry.get()
5513
5398
        try:
5514
5399
            Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5515
 
                              message, destroy=destroy).run()
 
5400
                              message).run()
5516
5401
        except errors.UserAbort:
5517
5402
            return 0
5518
5403
 
5560
5445
        Unshelver.from_args(shelf_id, action).run()
5561
5446
 
5562
5447
 
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
 
 
5597
5448
def _create_prefix(cur_transport):
5598
5449
    needed = [cur_transport]
5599
5450
    # Recurse upwards until we can create a directory successfully