~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/builtins.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-06 05:53:44 UTC
  • mfrom: (2063 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2071.
  • Revision ID: john@arbash-meinel.com-20061006055344-e73b97b7c6ca6e72
[merge] bzr.dev 2063

Show diffs side-by-side

added added

removed removed

Lines of Context:
57
57
from bzrlib.progress import DummyProgress, ProgressPhase
58
58
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
59
59
from bzrlib.transport.local import LocalTransport
 
60
import bzrlib.tree
 
61
from bzrlib.workingtree import WorkingTree
60
62
 
61
63
 
62
64
def tree_files(file_list, default_branch=u'.'):
109
111
        format = bzrdir.BzrDirMetaFormat1()
110
112
        format.repository_format = repository.RepositoryFormatKnit1()
111
113
        return format
 
114
    if typestring == "experimental-knit2":
 
115
        format = bzrdir.BzrDirMetaFormat1()
 
116
        format.repository_format = repository.RepositoryFormatKnit2()
 
117
        return format
112
118
    msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
113
119
          "metaweave and weave" % typestring
114
120
    raise BzrCommandError(msg)
359
365
    """Show inventory of the current working copy or a revision.
360
366
 
361
367
    It is possible to limit the output to a particular entry
362
 
    type using the --kind option.  For example; --kind file.
 
368
    type using the --kind option.  For example: --kind file.
 
369
 
 
370
    It is also possible to restrict the list of files to a specific
 
371
    set. For example: bzr inventory --show-ids this/file
363
372
    """
364
373
 
365
374
    takes_options = ['revision', 'show-ids', 'kind']
366
 
    
 
375
    takes_args = ['file*']
 
376
 
367
377
    @display_command
368
 
    def run(self, revision=None, show_ids=False, kind=None):
 
378
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
369
379
        if kind and kind not in ['file', 'directory', 'symlink']:
370
380
            raise BzrCommandError('invalid kind specified')
371
 
        tree = WorkingTree.open_containing(u'.')[0]
372
 
        if revision is None:
373
 
            inv = tree.read_working_inventory()
374
 
        else:
 
381
 
 
382
        work_tree, file_list = tree_files(file_list)
 
383
 
 
384
        if revision is not None:
375
385
            if len(revision) > 1:
376
386
                raise BzrCommandError('bzr inventory --revision takes'
377
 
                    ' exactly one revision identifier')
378
 
            inv = tree.branch.repository.get_revision_inventory(
379
 
                revision[0].in_history(tree.branch).rev_id)
380
 
 
381
 
        for path, entry in inv.entries():
 
387
                                      ' exactly one revision identifier')
 
388
            revision_id = revision[0].in_history(work_tree.branch).rev_id
 
389
            tree = work_tree.branch.repository.revision_tree(revision_id)
 
390
                        
 
391
            # We include work_tree as well as 'tree' here
 
392
            # So that doing '-r 10 path/foo' will lookup whatever file
 
393
            # exists now at 'path/foo' even if it has been renamed, as
 
394
            # well as whatever files existed in revision 10 at path/foo
 
395
            trees = [tree, work_tree]
 
396
        else:
 
397
            tree = work_tree
 
398
            trees = [tree]
 
399
 
 
400
        if file_list is not None:
 
401
            file_ids = bzrlib.tree.find_ids_across_trees(file_list, trees,
 
402
                                                      require_versioned=True)
 
403
            # find_ids_across_trees may include some paths that don't
 
404
            # exist in 'tree'.
 
405
            entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
 
406
                             for file_id in file_ids if file_id in tree)
 
407
        else:
 
408
            entries = tree.inventory.entries()
 
409
 
 
410
        for path, entry in entries:
382
411
            if kind and kind != entry.kind:
383
412
                continue
384
413
            if show_ids:
762
791
        # if the source and to_location are the same, 
763
792
        # and there is no working tree,
764
793
        # then reconstitute a branch
765
 
        if (osutils.abspath(to_location) == 
 
794
        if (osutils.abspath(to_location) ==
766
795
            osutils.abspath(branch_location)):
767
796
            try:
768
797
                source.bzrdir.open_workingtree()
825
854
        tree = WorkingTree.open_containing(dir)[0]
826
855
        tree.lock_write()
827
856
        try:
828
 
            existing_pending_merges = tree.pending_merges()
 
857
            existing_pending_merges = tree.get_parent_ids()[1:]
829
858
            last_rev = tree.last_revision()
830
859
            if last_rev == tree.branch.last_revision():
831
860
                # may be up to date, check master too.
837
866
            conflicts = tree.update()
838
867
            revno = tree.branch.revision_id_to_revno(tree.last_revision())
839
868
            note('Updated to revision %d.' % (revno,))
840
 
            if tree.pending_merges() != existing_pending_merges:
 
869
            if tree.get_parent_ids()[1:] != existing_pending_merges:
841
870
                note('Your local commits will now show as pending merges with '
842
871
                     "'bzr status', and can be committed with 'bzr commit'.")
843
872
            if conflicts != 0:
1348
1377
        else:
1349
1378
            # local dir only
1350
1379
            # FIXME ? log the current subdir only RBC 20060203 
1351
 
            dir, relpath = bzrdir.BzrDir.open_containing('.')
 
1380
            if revision is not None \
 
1381
                    and len(revision) > 0 and revision[0].get_branch():
 
1382
                location = revision[0].get_branch()
 
1383
            else:
 
1384
                location = '.'
 
1385
            dir, relpath = bzrdir.BzrDir.open_containing(location)
1352
1386
            b = dir.open_branch()
1353
1387
 
1354
1388
        if revision is None:
1357
1391
        elif len(revision) == 1:
1358
1392
            rev1 = rev2 = revision[0].in_history(b).revno
1359
1393
        elif len(revision) == 2:
 
1394
            if revision[1].get_branch() != revision[0].get_branch():
 
1395
                # b is taken from revision[0].get_branch(), and
 
1396
                # show_log will use its revision_history. Having
 
1397
                # different branches will lead to weird behaviors.
 
1398
                raise BzrCommandError(
 
1399
                    "Log doesn't accept two revisions in different branches.")
1360
1400
            if revision[0].spec is None:
1361
1401
                # missing begin-range means first revision
1362
1402
                rev1 = 1
1650
1690
 
1651
1691
        if tree is None:
1652
1692
            b, relpath = Branch.open_containing(filename)
 
1693
        if revision is not None and revision[0].get_branch() is not None:
 
1694
            b = Branch.open(revision[0].get_branch())
1653
1695
        if revision is None:
1654
1696
            revision_id = b.last_revision()
1655
1697
        else:
1870
1912
        # display a warning if an email address isn't included in the given name.
1871
1913
        try:
1872
1914
            config.extract_email_address(name)
1873
 
        except BzrError, e:
 
1915
        except errors.NoEmailInUsername, e:
1874
1916
            warning('"%s" does not seem to contain an email address.  '
1875
1917
                    'This is allowed, but not recommended.', name)
1876
1918
        
1987
2029
                test_suite_factory = benchmarks.test_suite
1988
2030
                if verbose is None:
1989
2031
                    verbose = True
 
2032
                # TODO: should possibly lock the history file...
1990
2033
                benchfile = open(".perf_history", "at")
1991
2034
            else:
1992
2035
                test_suite_factory = None
2134
2177
                else:
2135
2178
                    return 1
2136
2179
 
2137
 
        branch = self._get_remembered_parent(tree, branch, 'Merging from')
 
2180
        if revision is None \
 
2181
                or len(revision) < 1 or revision[0].needs_branch():
 
2182
            branch = self._get_remembered_parent(tree, branch, 'Merging from')
2138
2183
 
2139
2184
        if revision is None or len(revision) < 1:
2140
2185
            if uncommitted:
2148
2193
            if uncommitted:
2149
2194
                raise BzrCommandError('Cannot use --uncommitted and --revision'
2150
2195
                                      ' at the same time.')
 
2196
            branch = revision[0].get_branch() or branch
2151
2197
            if len(revision) == 1:
2152
2198
                base = [None, None]
2153
2199
                other_branch, path = Branch.open_containing(branch)
2157
2203
                assert len(revision) == 2
2158
2204
                if None in revision:
2159
2205
                    raise BzrCommandError(
2160
 
                        "Merge doesn't permit that revision specifier.")
2161
 
                other_branch, path = Branch.open_containing(branch)
 
2206
                        "Merge doesn't permit empty revision specifier.")
 
2207
                base_branch, path = Branch.open_containing(branch)
 
2208
                branch1 = revision[1].get_branch() or branch
 
2209
                other_branch, path1 = Branch.open_containing(branch1)
 
2210
                if revision[0].get_branch() is not None:
 
2211
                    # then path was obtained from it, and is None.
 
2212
                    path = path1
2162
2213
 
2163
 
                base = [branch, revision[0].in_history(other_branch).revno]
2164
 
                other = [branch, revision[1].in_history(other_branch).revno]
 
2214
                base = [branch, revision[0].in_history(base_branch).revno]
 
2215
                other = [branch1, revision[1].in_history(other_branch).revno]
2165
2216
 
2166
2217
        if tree.branch.get_parent() is None or remember:
2167
2218
            tree.branch.set_parent(other_branch.base)
2301
2352
            return 0
2302
2353
 
2303
2354
class cmd_revert(Command):
2304
 
    """Reverse all changes since the last commit.
2305
 
 
2306
 
    Only versioned files are affected.  Specify filenames to revert only 
2307
 
    those files.  By default, any files that are changed will be backed up
2308
 
    first.  Backup files have a '~' appended to their name.
 
2355
    """Revert files to a previous revision.
 
2356
 
 
2357
    Giving a list of files will revert only those files.  Otherwise, all files
 
2358
    will be reverted.  If the revision is not specified with '--revision', the
 
2359
    last committed revision is used.
 
2360
 
 
2361
    To remove only some changes, without reverting to a prior version, use
 
2362
    merge instead.  For example, "merge . --r-2..-3" will remove the changes
 
2363
    introduced by -2, without affecting the changes introduced by -1.  Or
 
2364
    to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
 
2365
    
 
2366
    By default, any files that have been manually changed will be backed up
 
2367
    first.  (Files changed only by merge are not backed up.)  Backup files have
 
2368
    '.~#~' appended to their name, where # is a number.
 
2369
 
 
2370
    When you provide files, you can use their current pathname or the pathname
 
2371
    from the target revision.  So you can use revert to "undelete" a file by
 
2372
    name.  If you name a directory, all the contents of that directory will be
 
2373
    reverted.
2309
2374
    """
2310
2375
    takes_options = ['revision', 'no-backup']
2311
2376
    takes_args = ['file*']
2742
2807
            pass
2743
2808
        
2744
2809
 
 
2810
class cmd_wait_until_signalled(Command):
 
2811
    """Test helper for test_start_and_stop_bzr_subprocess_send_signal.
 
2812
 
 
2813
    This just prints a line to signal when it is ready, then blocks on stdin.
 
2814
    """
 
2815
 
 
2816
    hidden = True
 
2817
 
 
2818
    def run(self):
 
2819
        sys.stdout.write("running\n")
 
2820
        sys.stdout.flush()
 
2821
        sys.stdin.readline()
 
2822
 
 
2823
 
 
2824
class cmd_serve(Command):
 
2825
    """Run the bzr server."""
 
2826
 
 
2827
    aliases = ['server']
 
2828
 
 
2829
    takes_options = [
 
2830
        Option('inet',
 
2831
               help='serve on stdin/out for use from inetd or sshd'),
 
2832
        Option('port',
 
2833
               help='listen for connections on nominated port of the form '
 
2834
                    '[hostname:]portnumber. Passing 0 as the port number will '
 
2835
                    'result in a dynamically allocated port.',
 
2836
               type=str),
 
2837
        Option('directory',
 
2838
               help='serve contents of directory',
 
2839
               type=unicode),
 
2840
        Option('allow-writes',
 
2841
               help='By default the server is a readonly server. Supplying '
 
2842
                    '--allow-writes enables write access to the contents of '
 
2843
                    'the served directory and below. '
 
2844
                ),
 
2845
        ]
 
2846
 
 
2847
    def run(self, port=None, inet=False, directory=None, allow_writes=False):
 
2848
        from bzrlib.transport import smart
 
2849
        from bzrlib.transport import get_transport
 
2850
        if directory is None:
 
2851
            directory = os.getcwd()
 
2852
        url = urlutils.local_path_to_url(directory)
 
2853
        if not allow_writes:
 
2854
            url = 'readonly+' + url
 
2855
        t = get_transport(url)
 
2856
        if inet:
 
2857
            server = smart.SmartStreamServer(sys.stdin, sys.stdout, t)
 
2858
        elif port is not None:
 
2859
            if ':' in port:
 
2860
                host, port = port.split(':')
 
2861
            else:
 
2862
                host = '127.0.0.1'
 
2863
            server = smart.SmartTCPServer(t, host=host, port=int(port))
 
2864
            print 'listening on port: ', server.port
 
2865
            sys.stdout.flush()
 
2866
        else:
 
2867
            raise BzrCommandError("bzr serve requires one of --inet or --port")
 
2868
        server.serve()
 
2869
 
2745
2870
 
2746
2871
# command-line interpretation helper for merge-related commands
2747
2872
def _merge_helper(other_revision, base_revision,
2825
2950
# we do need to load at least some information about them to know of 
2826
2951
# aliases.  ideally we would avoid loading the implementation until the
2827
2952
# details were needed.
 
2953
from bzrlib.cmd_version_info import cmd_version_info
2828
2954
from bzrlib.conflicts import cmd_resolve, cmd_conflicts, restore
2829
2955
from bzrlib.bundle.commands import cmd_bundle_revisions
2830
2956
from bzrlib.sign_my_commits import cmd_sign_my_commits