~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
from bzrlib.revisionspec import RevisionSpec
55
55
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
56
56
from bzrlib.transport.local import LocalTransport
 
57
import bzrlib.tree
57
58
from bzrlib.workingtree import WorkingTree
58
59
 
59
60
 
107
108
        format = bzrdir.BzrDirMetaFormat1()
108
109
        format.repository_format = repository.RepositoryFormatKnit1()
109
110
        return format
 
111
    if typestring == "experimental-knit2":
 
112
        format = bzrdir.BzrDirMetaFormat1()
 
113
        format.repository_format = repository.RepositoryFormatKnit2()
 
114
        return format
110
115
    msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
111
116
          "metaweave and weave" % typestring
112
117
    raise BzrCommandError(msg)
357
362
    """Show inventory of the current working copy or a revision.
358
363
 
359
364
    It is possible to limit the output to a particular entry
360
 
    type using the --kind option.  For example; --kind file.
 
365
    type using the --kind option.  For example: --kind file.
 
366
 
 
367
    It is also possible to restrict the list of files to a specific
 
368
    set. For example: bzr inventory --show-ids this/file
361
369
    """
362
370
 
363
371
    takes_options = ['revision', 'show-ids', 'kind']
364
 
    
 
372
    takes_args = ['file*']
 
373
 
365
374
    @display_command
366
 
    def run(self, revision=None, show_ids=False, kind=None):
 
375
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
367
376
        if kind and kind not in ['file', 'directory', 'symlink']:
368
377
            raise BzrCommandError('invalid kind specified')
369
 
        tree = WorkingTree.open_containing(u'.')[0]
370
 
        if revision is None:
371
 
            inv = tree.read_working_inventory()
372
 
        else:
 
378
 
 
379
        work_tree, file_list = tree_files(file_list)
 
380
 
 
381
        if revision is not None:
373
382
            if len(revision) > 1:
374
383
                raise BzrCommandError('bzr inventory --revision takes'
375
 
                    ' exactly one revision identifier')
376
 
            inv = tree.branch.repository.get_revision_inventory(
377
 
                revision[0].in_history(tree.branch).rev_id)
378
 
 
379
 
        for path, entry in inv.entries():
 
384
                                      ' exactly one revision identifier')
 
385
            revision_id = revision[0].in_history(work_tree.branch).rev_id
 
386
            tree = work_tree.branch.repository.revision_tree(revision_id)
 
387
                        
 
388
            # We include work_tree as well as 'tree' here
 
389
            # So that doing '-r 10 path/foo' will lookup whatever file
 
390
            # exists now at 'path/foo' even if it has been renamed, as
 
391
            # well as whatever files existed in revision 10 at path/foo
 
392
            trees = [tree, work_tree]
 
393
        else:
 
394
            tree = work_tree
 
395
            trees = [tree]
 
396
 
 
397
        if file_list is not None:
 
398
            file_ids = bzrlib.tree.find_ids_across_trees(file_list, trees,
 
399
                                                      require_versioned=True)
 
400
            # find_ids_across_trees may include some paths that don't
 
401
            # exist in 'tree'.
 
402
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
 
403
                             for file_id in file_ids if file_id in tree)
 
404
        else:
 
405
            entries = tree.inventory.entries()
 
406
 
 
407
        for path, entry in entries:
380
408
            if kind and kind != entry.kind:
381
409
                continue
382
410
            if show_ids:
760
788
        # if the source and to_location are the same, 
761
789
        # and there is no working tree,
762
790
        # then reconstitute a branch
763
 
        if (osutils.abspath(to_location) == 
 
791
        if (osutils.abspath(to_location) ==
764
792
            osutils.abspath(branch_location)):
765
793
            try:
766
794
                source.bzrdir.open_workingtree()
823
851
        tree = WorkingTree.open_containing(dir)[0]
824
852
        tree.lock_write()
825
853
        try:
826
 
            existing_pending_merges = tree.pending_merges()
 
854
            existing_pending_merges = tree.get_parent_ids()[1:]
827
855
            last_rev = tree.last_revision()
828
856
            if last_rev == tree.branch.last_revision():
829
857
                # may be up to date, check master too.
835
863
            conflicts = tree.update()
836
864
            revno = tree.branch.revision_id_to_revno(tree.last_revision())
837
865
            note('Updated to revision %d.' % (revno,))
838
 
            if tree.pending_merges() != existing_pending_merges:
 
866
            if tree.get_parent_ids()[1:] != existing_pending_merges:
839
867
                note('Your local commits will now show as pending merges with '
840
868
                     "'bzr status', and can be committed with 'bzr commit'.")
841
869
            if conflicts != 0:
911
939
    def run(self, filename):
912
940
        tree, relpath = WorkingTree.open_containing(filename)
913
941
        i = tree.inventory.path2id(relpath)
914
 
        if i == None:
 
942
        if i is None:
915
943
            raise BzrError("%r is not a versioned file" % filename)
916
944
        else:
917
945
            self.outf.write(i + '\n')
932
960
        tree, relpath = WorkingTree.open_containing(filename)
933
961
        inv = tree.inventory
934
962
        fid = inv.path2id(relpath)
935
 
        if fid == None:
 
963
        if fid is None:
936
964
            raise BzrError("%r is not a versioned file" % filename)
937
965
        for fip in inv.get_idpath(fid):
938
966
            self.outf.write(fip + '\n')
996
1024
            last_revision = wt.last_revision()
997
1025
 
998
1026
        revision_ids = b.repository.get_ancestry(last_revision)
999
 
        assert revision_ids[0] == None
 
1027
        assert revision_ids[0] is None
1000
1028
        revision_ids.pop(0)
1001
1029
        for revision_id in revision_ids:
1002
1030
            self.outf.write(revision_id + '\n')
1346
1374
        else:
1347
1375
            # local dir only
1348
1376
            # FIXME ? log the current subdir only RBC 20060203 
1349
 
            dir, relpath = bzrdir.BzrDir.open_containing('.')
 
1377
            if revision is not None \
 
1378
                    and len(revision) > 0 and revision[0].get_branch():
 
1379
                location = revision[0].get_branch()
 
1380
            else:
 
1381
                location = '.'
 
1382
            dir, relpath = bzrdir.BzrDir.open_containing(location)
1350
1383
            b = dir.open_branch()
1351
1384
 
1352
1385
        if revision is None:
1355
1388
        elif len(revision) == 1:
1356
1389
            rev1 = rev2 = revision[0].in_history(b).revno
1357
1390
        elif len(revision) == 2:
 
1391
            if revision[1].get_branch() != revision[0].get_branch():
 
1392
                # b is taken from revision[0].get_branch(), and
 
1393
                # show_log will use its revision_history. Having
 
1394
                # different branches will lead to weird behaviors.
 
1395
                raise BzrCommandError(
 
1396
                    "Log doesn't accept two revisions in different branches.")
1358
1397
            if revision[0].spec is None:
1359
1398
                # missing begin-range means first revision
1360
1399
                rev1 = 1
1375
1414
        if rev1 > rev2:
1376
1415
            (rev2, rev1) = (rev1, rev2)
1377
1416
 
1378
 
        if (log_format == None):
 
1417
        if (log_format is None):
1379
1418
            default = b.get_config().log_format()
1380
1419
            log_format = get_log_format(long=long, short=short, line=line, 
1381
1420
                                        default=default)
1648
1687
 
1649
1688
        if tree is None:
1650
1689
            b, relpath = Branch.open_containing(filename)
 
1690
        if revision is not None and revision[0].get_branch() is not None:
 
1691
            b = Branch.open(revision[0].get_branch())
1651
1692
        if revision is None:
1652
1693
            revision_id = b.last_revision()
1653
1694
        else:
1985
2026
                test_suite_factory = benchmarks.test_suite
1986
2027
                if verbose is None:
1987
2028
                    verbose = True
 
2029
                # TODO: should possibly lock the history file...
1988
2030
                benchfile = open(".perf_history", "at")
1989
2031
            else:
1990
2032
                test_suite_factory = None
2133
2175
                else:
2134
2176
                    return 1
2135
2177
 
2136
 
        branch = self._get_remembered_parent(tree, branch, 'Merging from')
 
2178
        if revision is None \
 
2179
                or len(revision) < 1 or revision[0].needs_branch():
 
2180
            branch = self._get_remembered_parent(tree, branch, 'Merging from')
2137
2181
 
2138
2182
        if revision is None or len(revision) < 1:
2139
2183
            if uncommitted:
2147
2191
            if uncommitted:
2148
2192
                raise BzrCommandError('Cannot use --uncommitted and --revision'
2149
2193
                                      ' at the same time.')
 
2194
            branch = revision[0].get_branch() or branch
2150
2195
            if len(revision) == 1:
2151
2196
                base = [None, None]
2152
2197
                other_branch, path = Branch.open_containing(branch)
2156
2201
                assert len(revision) == 2
2157
2202
                if None in revision:
2158
2203
                    raise BzrCommandError(
2159
 
                        "Merge doesn't permit that revision specifier.")
2160
 
                other_branch, path = Branch.open_containing(branch)
 
2204
                        "Merge doesn't permit empty revision specifier.")
 
2205
                base_branch, path = Branch.open_containing(branch)
 
2206
                branch1 = revision[1].get_branch() or branch
 
2207
                other_branch, path1 = Branch.open_containing(branch1)
 
2208
                if revision[0].get_branch() is not None:
 
2209
                    # then path was obtained from it, and is None.
 
2210
                    path = path1
2161
2211
 
2162
 
                base = [branch, revision[0].in_history(other_branch).revno]
2163
 
                other = [branch, revision[1].in_history(other_branch).revno]
 
2212
                base = [branch, revision[0].in_history(base_branch).revno]
 
2213
                other = [branch1, revision[1].in_history(other_branch).revno]
2164
2214
 
2165
2215
        if tree.branch.get_parent() is None or remember:
2166
2216
            tree.branch.set_parent(other_branch.base)
2300
2350
            return 0
2301
2351
 
2302
2352
class cmd_revert(Command):
2303
 
    """Reverse all changes since the last commit.
2304
 
 
2305
 
    Only versioned files are affected.  Specify filenames to revert only 
2306
 
    those files.  By default, any files that are changed will be backed up
2307
 
    first.  Backup files have a '~' appended to their name.
 
2353
    """Revert files to a previous revision.
 
2354
 
 
2355
    Giving a list of files will revert only those files.  Otherwise, all files
 
2356
    will be reverted.  If the revision is not specified with '--revision', the
 
2357
    last committed revision is used.
 
2358
 
 
2359
    To remove only some changes, without reverting to a prior version, use
 
2360
    merge instead.  For example, "merge . --r-2..-3" will remove the changes
 
2361
    introduced by -2, without affecting the changes introduced by -1.  Or
 
2362
    to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
 
2363
    
 
2364
    By default, any files that have been manually changed will be backed up
 
2365
    first.  (Files changed only by merge are not backed up.)  Backup files have
 
2366
    '.~#~' appended to their name, where # is a number.
 
2367
 
 
2368
    When you provide files, you can use their current pathname or the pathname
 
2369
    from the target revision.  So you can use revert to "undelete" a file by
 
2370
    name.  If you name a directory, all the contents of that directory will be
 
2371
    reverted.
2308
2372
    """
2309
2373
    takes_options = ['revision', 'no-backup']
2310
2374
    takes_args = ['file*']
2425
2489
            remote_branch.lock_read()
2426
2490
            try:
2427
2491
                local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
2428
 
                if (log_format == None):
 
2492
                if (log_format is None):
2429
2493
                    default = local_branch.get_config().log_format()
2430
2494
                    log_format = get_log_format(long=long, short=short, 
2431
2495
                                                line=line, default=default)
2479
2543
        import bzrlib.plugin
2480
2544
        from inspect import getdoc
2481
2545
        for name, plugin in bzrlib.plugin.all_plugins().items():
2482
 
            if hasattr(plugin, '__path__'):
 
2546
            if getattr(plugin, '__path__', None) is not None:
2483
2547
                print plugin.__path__[0]
2484
 
            elif hasattr(plugin, '__file__'):
 
2548
            elif getattr(plugin, '__file__', None) is not None:
2485
2549
                print plugin.__file__
2486
2550
            else:
2487
 
                print `plugin`
 
2551
                print repr(plugin)
2488
2552
                
2489
2553
            d = getdoc(plugin)
2490
2554
            if d:
2742
2806
            pass
2743
2807
        
2744
2808
 
 
2809
class cmd_wait_until_signalled(Command):
 
2810
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
 
2811
 
 
2812
    This just prints a line to signal when it is ready, then blocks on stdin.
 
2813
    """
 
2814
 
 
2815
    hidden = True
 
2816
 
 
2817
    def run(self):
 
2818
        sys.stdout.write("running\n")
 
2819
        sys.stdout.flush()
 
2820
        sys.stdin.readline()
 
2821
 
 
2822
 
 
2823
class cmd_serve(Command):
 
2824
    """Run the bzr server."""
 
2825
 
 
2826
    aliases = ['server']
 
2827
 
 
2828
    takes_options = [
 
2829
        Option('inet',
 
2830
               help='serve on stdin/out for use from inetd or sshd'),
 
2831
        Option('port',
 
2832
               help='listen for connections on nominated port of the form '
 
2833
                    '[hostname:]portnumber. Passing 0 as the port number will '
 
2834
                    'result in a dynamically allocated port.',
 
2835
               type=str),
 
2836
        Option('directory',
 
2837
               help='serve contents of directory',
 
2838
               type=unicode),
 
2839
        Option('allow-writes',
 
2840
               help='By default the server is a readonly server. Supplying '
 
2841
                    '--allow-writes enables write access to the contents of '
 
2842
                    'the served directory and below. '
 
2843
                ),
 
2844
        ]
 
2845
 
 
2846
    def run(self, port=None, inet=False, directory=None, allow_writes=False):
 
2847
        from bzrlib.transport import smart
 
2848
        from bzrlib.transport import get_transport
 
2849
        if directory is None:
 
2850
            directory = os.getcwd()
 
2851
        url = urlutils.local_path_to_url(directory)
 
2852
        if not allow_writes:
 
2853
            url = 'readonly+' + url
 
2854
        t = get_transport(url)
 
2855
        if inet:
 
2856
            server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
 
2857
        elif port is not None:
 
2858
            if ':' in port:
 
2859
                host, port = port.split(':')
 
2860
            else:
 
2861
                host = '127.0.0.1'
 
2862
            server = smart.SmartTCPServer(t, host=host, port=int(port))
 
2863
            print 'listening on port: ', server.port
 
2864
            sys.stdout.flush()
 
2865
        else:
 
2866
            raise BzrCommandError("bzr serve requires one of --inet or --port")
 
2867
        server.serve()
 
2868
 
2745
2869
 
2746
2870
# command-line interpretation helper for merge-related commands
2747
2871
def merge(other_revision, base_revision,
2817
2941
# we do need to load at least some information about them to know of 
2818
2942
# aliases.  ideally we would avoid loading the implementation until the
2819
2943
# details were needed.
 
2944
from bzrlib.cmd_version_info import cmd_version_info
2820
2945
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2821
2946
from bzrlib.bundle.commands import cmd_bundle_revisions
2822
2947
from bzrlib.sign_my_commits import cmd_sign_my_commits