/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/builtins.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-16 19:47:19 UTC
  • mfrom: (7178 work)
  • mto: This revision was merged to the branch mainline in revision 7179.
  • Revision ID: jelmer@jelmer.uk-20181116194719-m5ut2wfuze5x9s1p
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
    symbol_versioning,
55
55
    timestamp,
56
56
    transport,
57
 
    tree as _mod_tree,
58
57
    ui,
59
58
    urlutils,
60
59
    views,
84
83
    RevisionInfo,
85
84
    )
86
85
from .sixish import (
87
 
    BytesIO,
88
86
    PY3,
89
87
    text_type,
90
88
    viewitems,
119
117
        and the full URL to the actual branch
120
118
    """
121
119
    # This path is meant to be relative to the existing branch
122
 
    this_url = _get_branch_location(control_dir,
123
 
        possible_transports=possible_transports)
 
120
    this_url = _get_branch_location(
 
121
        control_dir, possible_transports=possible_transports)
124
122
    # Perhaps the target control dir supports colocated branches?
125
123
    try:
126
 
        root = controldir.ControlDir.open(this_url,
127
 
            possible_transports=possible_transports)
 
124
        root = controldir.ControlDir.open(
 
125
            this_url, possible_transports=possible_transports)
128
126
    except errors.NotBranchError:
129
127
        return (False, this_url)
130
128
    else:
131
129
        try:
132
 
            wt = control_dir.open_workingtree()
 
130
            control_dir.open_workingtree()
133
131
        except (errors.NoWorkingTree, errors.NotLocalUrl):
134
132
            return (False, this_url)
135
133
        else:
151
149
        (colocated, this_url) = _is_colocated(control_dir, possible_transports)
152
150
 
153
151
        if colocated:
154
 
            return urlutils.join_segment_parameters(this_url,
155
 
                {"branch": urlutils.escape(location)})
 
152
            return urlutils.join_segment_parameters(
 
153
                this_url, {"branch": urlutils.escape(location)})
156
154
        else:
157
155
            return urlutils.join(this_url, '..', urlutils.escape(location))
158
156
    return location
168
166
    """
169
167
    try:
170
168
        # Perhaps it's a colocated branch?
171
 
        return control_dir.open_branch(location, 
172
 
            possible_transports=possible_transports)
 
169
        return control_dir.open_branch(
 
170
            location, possible_transports=possible_transports)
173
171
    except (errors.NotBranchError, errors.NoColocatedBranchSupport):
174
172
        this_url = _get_branch_location(control_dir)
175
173
        return Branch.open(
188
186
        if location is None:
189
187
            location = "."
190
188
        try:
191
 
            return Branch.open(location,
192
 
                possible_transports=possible_transports)
 
189
            return Branch.open(
 
190
                location, possible_transports=possible_transports)
193
191
        except errors.NotBranchError:
194
192
            near = "."
195
 
    cdir = controldir.ControlDir.open(near,
196
 
        possible_transports=possible_transports)
197
 
    return open_sibling_branch(cdir, location,
198
 
        possible_transports=possible_transports)
 
193
    cdir = controldir.ControlDir.open(
 
194
        near, possible_transports=possible_transports)
 
195
    return open_sibling_branch(
 
196
        cdir, location, possible_transports=possible_transports)
199
197
 
200
198
 
201
199
def iter_sibling_branches(control_dir, possible_transports=None):
204
202
    :param control_dir: Control directory for which to look up the siblings
205
203
    :return: Iterator over tuples with branch name and branch object
206
204
    """
207
 
    seen_urls = set()
208
205
    try:
209
206
        reference = control_dir.get_branch_reference()
210
207
    except errors.NotBranchError:
213
210
            yield name, branch
214
211
        return
215
212
    if reference is not None:
216
 
        ref_branch = Branch.open(reference,
217
 
            possible_transports=possible_transports)
 
213
        ref_branch = Branch.open(
 
214
            reference, possible_transports=possible_transports)
218
215
    else:
219
216
        ref_branch = None
220
217
    if ref_branch is None or ref_branch.name:
225
222
    else:
226
223
        repo = ref_branch.controldir.find_repository()
227
224
        for branch in repo.find_branches(using=True):
228
 
            name = urlutils.relative_url(repo.user_url,
229
 
                branch.user_url).rstrip("/")
 
225
            name = urlutils.relative_url(
 
226
                repo.user_url, branch.user_url).rstrip("/")
230
227
            yield name, branch
231
228
 
232
229
 
258
255
            if view_files:
259
256
                file_list = view_files
260
257
                view_str = views.view_display_str(view_files)
261
 
                note(gettext("Ignoring files outside view. View is %s") % view_str)
 
258
                note(gettext("Ignoring files outside view. View is %s"),
 
259
                     view_str)
262
260
    return tree, file_list
263
261
 
264
262
 
274
272
 
275
273
def _get_one_revision_tree(command_name, revisions, branch=None, tree=None):
276
274
    """Get a revision tree. Not suitable for commands that change the tree.
277
 
    
 
275
 
278
276
    Specifically, the basis tree in dirstate trees is coupled to the dirstate
279
277
    and doing a commit/uncommit/pull will at best fail due to changing the
280
278
    basis revision data.
386
384
                            short_name='S'),
387
385
                     Option('versioned', help='Only show versioned files.',
388
386
                            short_name='V'),
389
 
                     Option('no-pending', help='Don\'t show pending merges.',
390
 
                           ),
 
387
                     Option('no-pending', help='Don\'t show pending merges.'),
391
388
                     Option('no-classify',
392
 
                            help='Do not mark object type using indicator.',
393
 
                           ),
 
389
                            help='Do not mark object type using indicator.'),
394
390
                     ]
395
391
    aliases = ['st', 'stat']
396
392
 
404
400
        from .status import show_tree_status
405
401
 
406
402
        if revision and len(revision) > 2:
407
 
            raise errors.BzrCommandError(gettext('brz status --revision takes exactly'
408
 
                                         ' one or two revision specifiers'))
 
403
            raise errors.BzrCommandError(
 
404
                gettext('brz status --revision takes exactly'
 
405
                        ' one or two revision specifiers'))
409
406
 
410
407
        tree, relfile_list = WorkingTree.open_containing_paths(file_list)
411
408
        # Avoid asking for specific files when that is not needed.
449
446
    def run(self, revision_id=None, revision=None, directory=u'.'):
450
447
        if revision_id is not None and revision is not None:
451
448
            raise errors.BzrCommandError(gettext('You can only supply one of'
452
 
                                         ' revision_id or --revision'))
 
449
                                                 ' revision_id or --revision'))
453
450
        if revision_id is None and revision is None:
454
 
            raise errors.BzrCommandError(gettext('You must supply either'
455
 
                                         ' --revision or a revision_id'))
 
451
            raise errors.BzrCommandError(
 
452
                gettext('You must supply either --revision or a revision_id'))
456
453
 
457
454
        b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1]
458
455
 
459
456
        revisions = b.repository.revisions
460
457
        if revisions is None:
461
 
            raise errors.BzrCommandError(gettext('Repository %r does not support '
462
 
                'access to raw revision texts'))
 
458
            raise errors.BzrCommandError(
 
459
                gettext('Repository %r does not support '
 
460
                        'access to raw revision texts'))
463
461
 
464
462
        with b.repository.lock_read():
465
463
            # TODO: jam 20060112 should cat-revision always output utf-8?
468
466
                try:
469
467
                    self.print_revision(revisions, revision_id)
470
468
                except errors.NoSuchRevision:
471
 
                    msg = gettext("The repository {0} contains no revision {1}.").format(
472
 
                        b.repository.base, revision_id.decode('utf-8'))
 
469
                    msg = gettext(
 
470
                        "The repository {0} contains no revision {1}.").format(
 
471
                            b.repository.base, revision_id.decode('utf-8'))
473
472
                    raise errors.BzrCommandError(msg)
474
473
            elif revision is not None:
475
474
                for rev in revision:
498
497
 
499
498
    def run(self, location_list, force=False):
500
499
        if not location_list:
501
 
            location_list=['.']
 
500
            location_list = ['.']
502
501
 
503
502
        for location in location_list:
504
503
            d = controldir.ControlDir.open(location)
506
505
            try:
507
506
                working = d.open_workingtree()
508
507
            except errors.NoWorkingTree:
509
 
                raise errors.BzrCommandError(gettext("No working tree to remove"))
 
508
                raise errors.BzrCommandError(
 
509
                    gettext("No working tree to remove"))
510
510
            except errors.NotLocalUrl:
511
 
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
512
 
                                             " of a remote path"))
 
511
                raise errors.BzrCommandError(
 
512
                    gettext("You cannot remove the working tree"
 
513
                            " of a remote path"))
513
514
            if not force:
514
515
                if (working.has_changes()):
515
516
                    raise errors.UncommittedChanges(working)
517
518
                    raise errors.ShelvedChanges(working)
518
519
 
519
520
            if working.user_url != working.branch.user_url:
520
 
                raise errors.BzrCommandError(gettext("You cannot remove the working tree"
521
 
                                             " from a lightweight checkout"))
 
521
                raise errors.BzrCommandError(
 
522
                    gettext("You cannot remove the working tree"
 
523
                            " from a lightweight checkout"))
522
524
 
523
525
            d.destroy_workingtree()
524
526
 
539
541
    that, you can supply --revision to force the state of the tree.
540
542
    """
541
543
 
542
 
    takes_options = ['revision', 'directory',
 
544
    takes_options = [
 
545
        'revision', 'directory',
543
546
        Option('force',
544
547
               help='Reset the tree even if it doesn\'t appear to be'
545
548
                    ' corrupted.'),
553
556
            try:
554
557
                tree.check_state()
555
558
            except errors.BzrError:
556
 
                pass # There seems to be a real error here, so we'll reset
 
559
                pass  # There seems to be a real error here, so we'll reset
557
560
            else:
558
561
                # Refuse
559
562
                raise errors.BzrCommandError(gettext(
566
569
            revision_ids = [r.as_revision_id(tree.branch) for r in revision]
567
570
        try:
568
571
            tree.reset_state(revision_ids)
569
 
        except errors.BzrError as e:
 
572
        except errors.BzrError:
570
573
            if revision_ids is None:
571
 
                extra = (gettext(', the header appears corrupt, try passing -r -1'
572
 
                         ' to set the state to the last commit'))
 
574
                extra = gettext(', the header appears corrupt, try passing '
 
575
                                '-r -1 to set the state to the last commit')
573
576
            else:
574
577
                extra = ''
575
 
            raise errors.BzrCommandError(gettext('failed to reset the tree state{0}').format(extra))
 
578
            raise errors.BzrCommandError(
 
579
                gettext('failed to reset the tree state{0}').format(extra))
576
580
 
577
581
 
578
582
class cmd_revno(Command):
591
595
    @display_command
592
596
    def run(self, tree=False, location=u'.', revision=None):
593
597
        if revision is not None and tree:
594
 
            raise errors.BzrCommandError(gettext("--tree and --revision can "
595
 
                "not be used together"))
 
598
            raise errors.BzrCommandError(
 
599
                gettext("--tree and --revision can not be used together"))
596
600
 
597
601
        if tree:
598
602
            try:
615
619
                revid = b.last_revision()
616
620
        try:
617
621
            revno_t = b.revision_id_to_dotted_revno(revid)
618
 
        except errors.NoSuchRevision:
 
622
        except (errors.NoSuchRevision, errors.GhostRevisionsHaveNoRevno):
619
623
            revno_t = ('???',)
620
624
        revno = ".".join(str(n) for n in revno_t)
621
625
        self.cleanup_now()
629
633
    takes_args = ['revision_info*']
630
634
    takes_options = [
631
635
        'revision',
632
 
        custom_help('directory',
633
 
            help='Branch to examine, '
634
 
                 'rather than the one containing the working directory.'),
 
636
        custom_help('directory', help='Branch to examine, '
 
637
                    'rather than the one containing the working directory.'),
635
638
        Option('tree', help='Show revno of working tree.'),
636
639
        ]
637
640
 
676
679
 
677
680
        self.cleanup_now()
678
681
        for revno, revid in revinfos:
679
 
            self.outf.write('%*s %s\n' % (maxlen, revno, revid.decode('utf-8')))
 
682
            self.outf.write(
 
683
                '%*s %s\n' % (maxlen, revno, revid.decode('utf-8')))
680
684
 
681
685
 
682
686
class cmd_add(Command):
715
719
    branches that will be merged later (without showing the two different
716
720
    adds as a conflict). It is also useful when merging another project
717
721
    into a subdirectory of this one.
718
 
    
 
722
 
719
723
    Any files matching patterns in the ignore list will not be added
720
724
    unless they are explicitly mentioned.
721
 
    
722
 
    In recursive mode, files larger than the configuration option 
 
725
 
 
726
    In recursive mode, files larger than the configuration option
723
727
    add.maximum_file_size will be skipped. Named items are never skipped due
724
728
    to file size.
725
729
    """
729
733
               help="Don't recursively add the contents of directories.",
730
734
               short_name='N'),
731
735
        Option('dry-run',
732
 
               help="Show what would be done, but don't actually do anything."),
 
736
               help="Show what would be done, but don't actually do "
 
737
                    "anything."),
733
738
        'verbose',
734
739
        Option('file-ids-from',
735
740
               type=text_type,
746
751
        if file_ids_from is not None:
747
752
            try:
748
753
                base_tree, base_path = WorkingTree.open_containing(
749
 
                                            file_ids_from)
 
754
                    file_ids_from)
750
755
            except errors.NoWorkingTree:
751
756
                base_branch, base_path = Branch.open_containing(
752
 
                                            file_ids_from)
 
757
                    file_ids_from)
753
758
                base_tree = base_branch.basis_tree()
754
759
 
755
 
            action = breezy.add.AddFromBaseAction(base_tree, base_path,
756
 
                          to_file=self.outf, should_print=(not is_quiet()))
757
 
        else:
758
 
            action = breezy.add.AddWithSkipLargeAction(to_file=self.outf,
 
760
            action = breezy.add.AddFromBaseAction(
 
761
                base_tree, base_path, to_file=self.outf,
759
762
                should_print=(not is_quiet()))
 
763
        else:
 
764
            action = breezy.add.AddWithSkipLargeAction(
 
765
                to_file=self.outf, should_print=(not is_quiet()))
760
766
 
761
767
        if base_tree:
762
768
            self.add_cleanup(base_tree.lock_read().unlock)
763
769
        tree, file_list = tree_files_for_add(file_list)
764
 
        added, ignored = tree.smart_add(file_list, not
765
 
            no_recurse, action=action, save=not dry_run)
 
770
        added, ignored = tree.smart_add(
 
771
            file_list, not no_recurse, action=action, save=not dry_run)
766
772
        self.cleanup_now()
767
773
        if len(ignored) > 0:
768
774
            if verbose:
769
775
                for glob in sorted(ignored):
770
776
                    for path in ignored[glob]:
771
777
                        self.outf.write(
772
 
                         gettext("ignored {0} matching \"{1}\"\n").format(
773
 
                         path, glob))
 
778
                            gettext("ignored {0} matching \"{1}\"\n").format(
 
779
                                path, glob))
774
780
 
775
781
 
776
782
class cmd_mkdir(Command):
851
857
        'revision',
852
858
        'show-ids',
853
859
        Option('kind',
854
 
               help='List entries of a particular kind: file, directory, symlink.',
 
860
               help='List entries of a particular kind: file, directory, '
 
861
                    'symlink.',
855
862
               type=text_type),
856
863
        ]
857
864
    takes_args = ['file*']
859
866
    @display_command
860
867
    def run(self, revision=None, show_ids=False, kind=None, file_list=None):
861
868
        if kind and kind not in ['file', 'directory', 'symlink']:
862
 
            raise errors.BzrCommandError(gettext('invalid kind %r specified') % (kind,))
 
869
            raise errors.BzrCommandError(
 
870
                gettext('invalid kind %r specified') % (kind,))
863
871
 
864
872
        revision = _get_one_revision('inventory', revision)
865
873
        work_tree, file_list = WorkingTree.open_containing_paths(file_list)
876
884
        self.add_cleanup(tree.lock_read().unlock)
877
885
        if file_list is not None:
878
886
            paths = tree.find_related_paths_across_trees(
879
 
                    file_list, extra_trees, require_versioned=True)
 
887
                file_list, extra_trees, require_versioned=True)
880
888
            # find_ids_across_trees may include some paths that don't
881
889
            # exist in 'tree'.
882
890
            entries = tree.iter_entries_by_dir(specific_files=paths)
889
897
            if path == "":
890
898
                continue
891
899
            if show_ids:
892
 
                self.outf.write('%-50s %s\n' % (path, entry.file_id.decode('utf-8')))
 
900
                self.outf.write('%-50s %s\n' % (
 
901
                    path, entry.file_id.decode('utf-8')))
893
902
            else:
894
903
                self.outf.write(path)
895
904
                self.outf.write('\n')
917
926
    encoding_type = 'replace'
918
927
 
919
928
    def run(self, names_list):
920
 
        import shutil
921
929
        if names_list is None:
922
930
            names_list = []
923
931
        if len(names_list) < 2:
924
932
            raise errors.BzrCommandError(gettext("missing file argument"))
925
 
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
933
        tree, rel_names = WorkingTree.open_containing_paths(
 
934
            names_list, canonicalize=False)
926
935
        for file_name in rel_names[0:-1]:
927
936
            if file_name == '':
928
 
                raise errors.BzrCommandError(gettext("can not copy root of branch"))
 
937
                raise errors.BzrCommandError(
 
938
                    gettext("can not copy root of branch"))
929
939
        self.add_cleanup(tree.lock_tree_write().unlock)
930
940
        into_existing = osutils.isdir(names_list[-1])
931
941
        if not into_existing:
932
942
            try:
933
943
                (src, dst) = rel_names
934
944
            except IndexError:
935
 
                raise errors.BzrCommandError(gettext('to copy multiple files the'
936
 
                                                     ' destination must be a versioned'
937
 
                                                     ' directory'))
 
945
                raise errors.BzrCommandError(
 
946
                    gettext('to copy multiple files the'
 
947
                            ' destination must be a versioned'
 
948
                            ' directory'))
938
949
            pairs = [(src, dst)]
939
950
        else:
940
 
            pairs = [(n, osutils.joinpath([rel_names[-1], osutils.basename(n)]))
941
 
                     for n in rel_names[:-1]]
 
951
            pairs = [
 
952
                (n, osutils.joinpath([rel_names[-1], osutils.basename(n)]))
 
953
                for n in rel_names[:-1]]
942
954
 
943
955
        for src, dst in pairs:
944
956
            try:
945
957
                src_kind = tree.stored_kind(src)
946
958
            except errors.NoSuchFile:
947
959
                raise errors.BzrCommandError(
948
 
                        gettext('Could not copy %s => %s: %s is not versioned.')
949
 
                        % (src, dst, src))
 
960
                    gettext('Could not copy %s => %s: %s is not versioned.')
 
961
                    % (src, dst, src))
950
962
            if src_kind is None:
951
963
                raise errors.BzrCommandError(
952
964
                    gettext('Could not copy %s => %s . %s is not versioned\\.'
953
 
                        % (src, dst, src)))
 
965
                            % (src, dst, src)))
954
966
            if src_kind == 'directory':
955
967
                raise errors.BzrCommandError(
956
968
                    gettext('Could not copy %s => %s . %s is a directory.'
957
 
                        % (src, dst, src)))
 
969
                            % (src, dst, src)))
958
970
            dst_parent = osutils.split(dst)[0]
959
971
            if dst_parent != '':
960
972
                try:
961
973
                    dst_parent_kind = tree.stored_kind(dst_parent)
962
974
                except errors.NoSuchFile:
963
975
                    raise errors.BzrCommandError(
964
 
                            gettext('Could not copy %s => %s: %s is not versioned.')
965
 
                            % (src, dst, dst_parent))
 
976
                        gettext('Could not copy %s => %s: %s is not versioned.')
 
977
                        % (src, dst, dst_parent))
966
978
                if dst_parent_kind != 'directory':
967
979
                    raise errors.BzrCommandError(
968
 
                            gettext('Could not copy to %s: %s is not a directory.')
969
 
                            % (dst_parent, dst_parent))
 
980
                        gettext('Could not copy to %s: %s is not a directory.')
 
981
                        % (dst_parent, dst_parent))
970
982
 
971
983
            tree.copy_one(src, dst)
972
984
 
994
1006
 
995
1007
    takes_args = ['names*']
996
1008
    takes_options = [Option("after", help="Move only the brz identifier"
997
 
        " of the file, because the file has already been moved."),
998
 
        Option('auto', help='Automatically guess renames.'),
999
 
        Option('dry-run', help='Avoid making changes when guessing renames.'),
1000
 
        ]
 
1009
                            " of the file, because the file has already been moved."),
 
1010
                     Option('auto', help='Automatically guess renames.'),
 
1011
                     Option(
 
1012
                         'dry-run', help='Avoid making changes when guessing renames.'),
 
1013
                     ]
1001
1014
    aliases = ['move', 'rename']
1002
1015
    encoding_type = 'replace'
1003
1016
 
1010
1023
            names_list = []
1011
1024
        if len(names_list) < 2:
1012
1025
            raise errors.BzrCommandError(gettext("missing file argument"))
1013
 
        tree, rel_names = WorkingTree.open_containing_paths(names_list, canonicalize=False)
 
1026
        tree, rel_names = WorkingTree.open_containing_paths(
 
1027
            names_list, canonicalize=False)
1014
1028
        for file_name in rel_names[0:-1]:
1015
1029
            if file_name == '':
1016
 
                raise errors.BzrCommandError(gettext("can not move root of branch"))
 
1030
                raise errors.BzrCommandError(
 
1031
                    gettext("can not move root of branch"))
1017
1032
        self.add_cleanup(tree.lock_tree_write().unlock)
1018
1033
        self._run(tree, names_list, rel_names, after)
1019
1034
 
1020
1035
    def run_auto(self, names_list, after, dry_run):
1021
1036
        if names_list is not None and len(names_list) > 1:
1022
 
            raise errors.BzrCommandError(gettext('Only one path may be specified to'
1023
 
                                         ' --auto.'))
 
1037
            raise errors.BzrCommandError(
 
1038
                gettext('Only one path may be specified to --auto.'))
1024
1039
        if after:
1025
 
            raise errors.BzrCommandError(gettext('--after cannot be specified with'
1026
 
                                         ' --auto.'))
 
1040
            raise errors.BzrCommandError(
 
1041
                gettext('--after cannot be specified with --auto.'))
1027
1042
        work_tree, file_list = WorkingTree.open_containing_paths(
1028
1043
            names_list, default_directory='.')
1029
1044
        self.add_cleanup(work_tree.lock_tree_write().unlock)
1030
1045
        rename_map.RenameMap.guess_renames(
1031
 
                work_tree.basis_tree(), work_tree, dry_run)
 
1046
            work_tree.basis_tree(), work_tree, dry_run)
1032
1047
 
1033
1048
    def _run(self, tree, names_list, rel_names, after):
1034
1049
        into_existing = osutils.isdir(names_list[-1])
1039
1054
            #    a directory, but now doesn't exist in the working tree
1040
1055
            #    and the target is an existing directory, just rename it)
1041
1056
            if (not tree.case_sensitive
1042
 
                and rel_names[0].lower() == rel_names[1].lower()):
 
1057
                    and rel_names[0].lower() == rel_names[1].lower()):
1043
1058
                into_existing = False
1044
1059
            else:
1045
1060
                # 'fix' the case of a potential 'from'
1046
1061
                from_path = tree.get_canonical_path(rel_names[0])
1047
1062
                if (not osutils.lexists(names_list[0]) and
1048
1063
                    tree.is_versioned(from_path) and
1049
 
                    tree.stored_kind(from_path) == "directory"):
 
1064
                        tree.stored_kind(from_path) == "directory"):
1050
1065
                    into_existing = False
1051
1066
        # move/rename
1052
1067
        if into_existing:
1060
1075
        else:
1061
1076
            if len(names_list) != 2:
1062
1077
                raise errors.BzrCommandError(gettext('to mv multiple files the'
1063
 
                                             ' destination must be a versioned'
1064
 
                                             ' directory'))
 
1078
                                                     ' destination must be a versioned'
 
1079
                                                     ' directory'))
1065
1080
 
1066
1081
            # for cicp file-systems: the src references an existing inventory
1067
1082
            # item:
1088
1103
                if after:
1089
1104
                    # If 'after' is specified, the tail must refer to a file on disk.
1090
1105
                    if dest_parent:
1091
 
                        dest_parent_fq = osutils.pathjoin(tree.basedir, dest_parent)
 
1106
                        dest_parent_fq = osutils.pathjoin(
 
1107
                            tree.basedir, dest_parent)
1092
1108
                    else:
1093
1109
                        # pathjoin with an empty tail adds a slash, which breaks
1094
1110
                        # relpath :(
1095
1111
                        dest_parent_fq = tree.basedir
1096
1112
 
1097
1113
                    dest_tail = osutils.canonical_relpath(
1098
 
                                    dest_parent_fq,
1099
 
                                    osutils.pathjoin(dest_parent_fq, spec_tail))
 
1114
                        dest_parent_fq,
 
1115
                        osutils.pathjoin(dest_parent_fq, spec_tail))
1100
1116
                else:
1101
1117
                    # not 'after', so case as specified is used
1102
1118
                    dest_tail = spec_tail
1114
1130
    __doc__ = """Turn this branch into a mirror of another branch.
1115
1131
 
1116
1132
    By default, this command only works on branches that have not diverged.
1117
 
    Branches are considered diverged if the destination branch's most recent 
1118
 
    commit is one that has not been merged (directly or indirectly) into the 
 
1133
    Branches are considered diverged if the destination branch's most recent
 
1134
    commit is one that has not been merged (directly or indirectly) into the
1119
1135
    parent.
1120
1136
 
1121
1137
    If branches have diverged, you can use 'brz merge' to integrate the changes
1142
1158
 
1143
1159
    _see_also = ['push', 'update', 'status-flags', 'send']
1144
1160
    takes_options = ['remember', 'overwrite', 'revision',
1145
 
        custom_help('verbose',
1146
 
            help='Show logs of pulled revisions.'),
1147
 
        custom_help('directory',
1148
 
            help='Branch to pull into, '
1149
 
                 'rather than the one containing the working directory.'),
1150
 
        Option('local',
1151
 
            help="Perform a local pull in a bound "
1152
 
                 "branch.  Local pulls are not applied to "
1153
 
                 "the master branch."
1154
 
            ),
1155
 
        Option('show-base',
1156
 
            help="Show base revision text in conflicts."),
1157
 
        Option('overwrite-tags',
1158
 
            help="Overwrite tags only."),
1159
 
        ]
 
1161
                     custom_help('verbose',
 
1162
                                 help='Show logs of pulled revisions.'),
 
1163
                     custom_help('directory',
 
1164
                                 help='Branch to pull into, '
 
1165
                                 'rather than the one containing the working directory.'),
 
1166
                     Option('local',
 
1167
                            help="Perform a local pull in a bound "
 
1168
                            "branch.  Local pulls are not applied to "
 
1169
                            "the master branch."
 
1170
                            ),
 
1171
                     Option('show-base',
 
1172
                            help="Show base revision text in conflicts."),
 
1173
                     Option('overwrite-tags',
 
1174
                            help="Overwrite tags only."),
 
1175
                     ]
1160
1176
    takes_args = ['location?']
1161
1177
    encoding_type = 'replace'
1162
1178
 
1194
1210
        if location is not None:
1195
1211
            try:
1196
1212
                mergeable = bundle.read_mergeable_from_url(location,
1197
 
                    possible_transports=possible_transports)
 
1213
                                                           possible_transports=possible_transports)
1198
1214
            except errors.NotABundle:
1199
1215
                mergeable = None
1200
1216
 
1202
1218
        if location is None:
1203
1219
            if stored_loc is None:
1204
1220
                raise errors.BzrCommandError(gettext("No pull location known or"
1205
 
                                             " specified."))
 
1221
                                                     " specified."))
1206
1222
            else:
1207
1223
                display_url = urlutils.unescape_for_display(stored_loc,
1208
 
                        self.outf.encoding)
 
1224
                                                            self.outf.encoding)
1209
1225
                if not is_quiet():
1210
 
                    self.outf.write(gettext("Using saved parent location: %s\n") % display_url)
 
1226
                    self.outf.write(
 
1227
                        gettext("Using saved parent location: %s\n") % display_url)
1211
1228
                location = stored_loc
1212
1229
 
1213
1230
        revision = _get_one_revision('pull', revision)
1221
1238
            branch_from = branch_to
1222
1239
        else:
1223
1240
            branch_from = Branch.open(location,
1224
 
                possible_transports=possible_transports)
 
1241
                                      possible_transports=possible_transports)
1225
1242
            self.add_cleanup(branch_from.lock_read().unlock)
1226
1243
            # Remembers if asked explicitly or no previous location is set
1227
1244
            if (remember
1228
 
                or (remember is None and branch_to.get_parent() is None)):
 
1245
                    or (remember is None and branch_to.get_parent() is None)):
1229
1246
                # FIXME: This shouldn't be done before the pull
1230
1247
                # succeeds... -- vila 2012-01-02
1231
1248
                branch_to.set_parent(branch_from.base)
1288
1305
 
1289
1306
    _see_also = ['pull', 'update', 'working-trees']
1290
1307
    takes_options = ['remember', 'overwrite', 'verbose', 'revision',
1291
 
        Option('create-prefix',
1292
 
               help='Create the path leading up to the branch '
1293
 
                    'if it does not already exist.'),
1294
 
        custom_help('directory',
1295
 
            help='Branch to push from, '
1296
 
                 'rather than the one containing the working directory.'),
1297
 
        Option('use-existing-dir',
1298
 
               help='By default push will fail if the target'
1299
 
                    ' directory exists, but does not already'
1300
 
                    ' have a control directory.  This flag will'
1301
 
                    ' allow push to proceed.'),
1302
 
        Option('stacked',
1303
 
            help='Create a stacked branch that references the public location '
1304
 
                'of the parent branch.'),
1305
 
        Option('stacked-on',
1306
 
            help='Create a stacked branch that refers to another branch '
1307
 
                'for the commit history. Only the work not present in the '
1308
 
                'referenced branch is included in the branch created.',
1309
 
            type=text_type),
1310
 
        Option('strict',
1311
 
               help='Refuse to push if there are uncommitted changes in'
1312
 
               ' the working tree, --no-strict disables the check.'),
1313
 
        Option('no-tree',
1314
 
               help="Don't populate the working tree, even for protocols"
1315
 
               " that support it."),
1316
 
        Option('overwrite-tags',
1317
 
              help="Overwrite tags only."),
1318
 
        Option('lossy', help="Allow lossy push, i.e. dropping metadata "
1319
 
                             "that can't be represented in the target.")
1320
 
        ]
 
1308
                     Option('create-prefix',
 
1309
                            help='Create the path leading up to the branch '
 
1310
                            'if it does not already exist.'),
 
1311
                     custom_help('directory',
 
1312
                                 help='Branch to push from, '
 
1313
                                 'rather than the one containing the working directory.'),
 
1314
                     Option('use-existing-dir',
 
1315
                            help='By default push will fail if the target'
 
1316
                            ' directory exists, but does not already'
 
1317
                            ' have a control directory.  This flag will'
 
1318
                            ' allow push to proceed.'),
 
1319
                     Option('stacked',
 
1320
                            help='Create a stacked branch that references the public location '
 
1321
                            'of the parent branch.'),
 
1322
                     Option('stacked-on',
 
1323
                            help='Create a stacked branch that refers to another branch '
 
1324
                            'for the commit history. Only the work not present in the '
 
1325
                            'referenced branch is included in the branch created.',
 
1326
                            type=text_type),
 
1327
                     Option('strict',
 
1328
                            help='Refuse to push if there are uncommitted changes in'
 
1329
                            ' the working tree, --no-strict disables the check.'),
 
1330
                     Option('no-tree',
 
1331
                            help="Don't populate the working tree, even for protocols"
 
1332
                            " that support it."),
 
1333
                     Option('overwrite-tags',
 
1334
                            help="Overwrite tags only."),
 
1335
                     Option('lossy', help="Allow lossy push, i.e. dropping metadata "
 
1336
                            "that can't be represented in the target.")
 
1337
                     ]
1321
1338
    takes_args = ['location?']
1322
1339
    encoding_type = 'replace'
1323
1340
 
1324
1341
    def run(self, location=None, remember=None, overwrite=False,
1325
 
        create_prefix=False, verbose=False, revision=None,
1326
 
        use_existing_dir=False, directory=None, stacked_on=None,
1327
 
        stacked=False, strict=None, no_tree=False,
1328
 
        overwrite_tags=False, lossy=False):
 
1342
            create_prefix=False, verbose=False, revision=None,
 
1343
            use_existing_dir=False, directory=None, stacked_on=None,
 
1344
            stacked=False, strict=None, no_tree=False,
 
1345
            overwrite_tags=False, lossy=False):
1329
1346
        from .push import _show_push_branch
1330
1347
 
1331
1348
        if overwrite:
1379
1396
                        "No push location known or specified. To push to the "
1380
1397
                        "parent branch (at %s), use 'brz push :parent'." %
1381
1398
                        urlutils.unescape_for_display(parent_loc,
1382
 
                            self.outf.encoding)))
 
1399
                                                      self.outf.encoding)))
1383
1400
                else:
1384
1401
                    raise errors.BzrCommandError(gettext(
1385
1402
                        "No push location known or specified."))
1386
1403
            else:
1387
1404
                display_url = urlutils.unescape_for_display(stored_loc,
1388
 
                        self.outf.encoding)
 
1405
                                                            self.outf.encoding)
1389
1406
                note(gettext("Using saved push location: %s") % display_url)
1390
1407
                location = stored_loc
1391
1408
 
1392
1409
        _show_push_branch(br_from, revision_id, location, self.outf,
1393
 
            verbose=verbose, overwrite=overwrite, remember=remember,
1394
 
            stacked_on=stacked_on, create_prefix=create_prefix,
1395
 
            use_existing_dir=use_existing_dir, no_tree=no_tree,
1396
 
            lossy=lossy)
 
1410
                          verbose=verbose, overwrite=overwrite, remember=remember,
 
1411
                          stacked_on=stacked_on, create_prefix=create_prefix,
 
1412
                          use_existing_dir=use_existing_dir, no_tree=no_tree,
 
1413
                          lossy=lossy)
1397
1414
 
1398
1415
 
1399
1416
class cmd_branch(Command):
1413
1430
    _see_also = ['checkout']
1414
1431
    takes_args = ['from_location', 'to_location?']
1415
1432
    takes_options = ['revision',
1416
 
        Option('hardlink', help='Hard-link working tree files where possible.'),
1417
 
        Option('files-from', type=text_type,
1418
 
               help="Get file contents from this tree."),
1419
 
        Option('no-tree',
1420
 
            help="Create a branch without a working-tree."),
1421
 
        Option('switch',
1422
 
            help="Switch the checkout in the current directory "
1423
 
                 "to the new branch."),
1424
 
        Option('stacked',
1425
 
            help='Create a stacked branch referring to the source branch. '
1426
 
                'The new branch will depend on the availability of the source '
1427
 
                'branch for all operations.'),
1428
 
        Option('standalone',
1429
 
               help='Do not use a shared repository, even if available.'),
1430
 
        Option('use-existing-dir',
1431
 
               help='By default branch will fail if the target'
1432
 
                    ' directory exists, but does not already'
1433
 
                    ' have a control directory.  This flag will'
1434
 
                    ' allow branch to proceed.'),
1435
 
        Option('bind',
1436
 
            help="Bind new branch to from location."),
1437
 
        ]
 
1433
                     Option(
 
1434
                         'hardlink', help='Hard-link working tree files where possible.'),
 
1435
                     Option('files-from', type=text_type,
 
1436
                            help="Get file contents from this tree."),
 
1437
                     Option('no-tree',
 
1438
                            help="Create a branch without a working-tree."),
 
1439
                     Option('switch',
 
1440
                            help="Switch the checkout in the current directory "
 
1441
                            "to the new branch."),
 
1442
                     Option('stacked',
 
1443
                            help='Create a stacked branch referring to the source branch. '
 
1444
                            'The new branch will depend on the availability of the source '
 
1445
                            'branch for all operations.'),
 
1446
                     Option('standalone',
 
1447
                            help='Do not use a shared repository, even if available.'),
 
1448
                     Option('use-existing-dir',
 
1449
                            help='By default branch will fail if the target'
 
1450
                            ' directory exists, but does not already'
 
1451
                            ' have a control directory.  This flag will'
 
1452
                            ' allow branch to proceed.'),
 
1453
                     Option('bind',
 
1454
                            help="Bind new branch to from location."),
 
1455
                     ]
1438
1456
 
1439
1457
    def run(self, from_location, to_location=None, revision=None,
1440
1458
            hardlink=False, stacked=False, standalone=False, no_tree=False,
1471
1489
            except errors.NotBranchError:
1472
1490
                if not use_existing_dir:
1473
1491
                    raise errors.BzrCommandError(gettext('Target directory "%s" '
1474
 
                        'already exists.') % to_location)
 
1492
                                                         'already exists.') % to_location)
1475
1493
                else:
1476
1494
                    to_dir = None
1477
1495
            else:
1517
1535
        # We therefore need a try/except here and not just 'if stacked:'
1518
1536
        try:
1519
1537
            note(gettext('Created new stacked branch referring to %s.') %
1520
 
                branch.get_stacked_on_url())
 
1538
                 branch.get_stacked_on_url())
1521
1539
        except (errors.NotStacked, _mod_branch.UnstackableBranchFormat,
1522
 
            errors.UnstackableRepositoryFormat) as e:
1523
 
            note(ngettext('Branched %d revision.', 'Branched %d revisions.', branch.revno()) % branch.revno())
 
1540
                errors.UnstackableRepositoryFormat) as e:
 
1541
            revno = branch.revno()
 
1542
            if revno is not None:
 
1543
                note(ngettext('Branched %d revision.',
 
1544
                              'Branched %d revisions.',
 
1545
                              branch.revno()) % revno)
 
1546
            else:
 
1547
                note(gettext('Created new branch.'))
1524
1548
        if bind:
1525
1549
            # Bind to the parent
1526
1550
            parent_branch = Branch.open(from_location)
1531
1555
            wt, _ = WorkingTree.open_containing('.')
1532
1556
            _mod_switch.switch(wt.controldir, branch)
1533
1557
            note(gettext('Switched to branch: %s'),
1534
 
                urlutils.unescape_for_display(branch.base, 'utf-8'))
 
1558
                 urlutils.unescape_for_display(branch.base, 'utf-8'))
1535
1559
 
1536
1560
 
1537
1561
class cmd_branches(Command):
1543
1567
 
1544
1568
    takes_args = ['location?']
1545
1569
    takes_options = [
1546
 
                  Option('recursive', short_name='R',
1547
 
                         help='Recursively scan for branches rather than '
1548
 
                              'just looking in the specified location.')]
 
1570
        Option('recursive', short_name='R',
 
1571
               help='Recursively scan for branches rather than '
 
1572
               'just looking in the specified location.')]
1549
1573
 
1550
1574
    def run(self, location=".", recursive=False):
1551
1575
        if recursive:
1587
1611
class cmd_checkout(Command):
1588
1612
    __doc__ = """Create a new checkout of an existing branch.
1589
1613
 
1590
 
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree for
1591
 
    the branch found in '.'. This is useful if you have removed the working tree
1592
 
    or if it was never created - i.e. if you pushed the branch to its current
1593
 
    location using SFTP.
 
1614
    If BRANCH_LOCATION is omitted, checkout will reconstitute a working tree
 
1615
    for the branch found in '.'. This is useful if you have removed the working
 
1616
    tree or if it was never created - i.e. if you pushed the branch to its
 
1617
    current location using SFTP.
1594
1618
 
1595
 
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION will
1596
 
    be used.  In other words, "checkout ../foo/bar" will attempt to create ./bar.
1597
 
    If the BRANCH_LOCATION has no / or path separator embedded, the TO_LOCATION
1598
 
    is derived from the BRANCH_LOCATION by stripping a leading scheme or drive
1599
 
    identifier, if any. For example, "checkout lp:foo-bar" will attempt to
1600
 
    create ./foo-bar.
 
1619
    If the TO_LOCATION is omitted, the last component of the BRANCH_LOCATION
 
1620
    will be used.  In other words, "checkout ../foo/bar" will attempt to create
 
1621
    ./bar.  If the BRANCH_LOCATION has no / or path separator embedded, the
 
1622
    TO_LOCATION is derived from the BRANCH_LOCATION by stripping a leading
 
1623
    scheme or drive identifier, if any. For example, "checkout lp:foo-bar" will
 
1624
    attempt to create ./foo-bar.
1601
1625
 
1602
1626
    To retrieve the branch as of a particular revision, supply the --revision
1603
 
    parameter, as in "checkout foo/bar -r 5". Note that this will be immediately
1604
 
    out of date [so you cannot commit] but it may be useful (i.e. to examine old
1605
 
    code.)
 
1627
    parameter, as in "checkout foo/bar -r 5". Note that this will be
 
1628
    immediately out of date [so you cannot commit] but it may be useful (i.e.
 
1629
    to examine old code.)
1606
1630
    """
1607
1631
 
1608
1632
    _see_also = ['checkouts', 'branch', 'working-trees', 'remove-tree']
1647
1671
        # if the source and to_location are the same,
1648
1672
        # and there is no working tree,
1649
1673
        # then reconstitute a branch
1650
 
        if (osutils.abspath(to_location) ==
1651
 
            osutils.abspath(branch_location)):
 
1674
        if osutils.abspath(to_location) == osutils.abspath(branch_location):
1652
1675
            try:
1653
1676
                source.controldir.open_workingtree()
1654
1677
            except errors.NoWorkingTree:
1691
1714
 
1692
1715
    This will perform a merge of the destination revision (the tip of the
1693
1716
    branch, or the specified revision) into the working tree, and then make
1694
 
    that revision the basis revision for the working tree.  
 
1717
    that revision the basis revision for the working tree.
1695
1718
 
1696
1719
    You can use this to visit an older revision, or to update a working tree
1697
1720
    that is out of date from its branch.
1698
 
    
 
1721
 
1699
1722
    If there are any uncommitted changes in the tree, they will be carried
1700
1723
    across and remain as uncommitted changes after the update.  To discard
1701
1724
    these changes, use 'brz revert'.  The uncommitted changes may conflict
1712
1735
    out the old content of that file to a new location.
1713
1736
 
1714
1737
    The 'dir' argument, if given, must be the location of the root of a
1715
 
    working tree to update.  By default, the working tree that contains the 
 
1738
    working tree to update.  By default, the working tree that contains the
1716
1739
    current working directory is used.
1717
1740
    """
1718
1741
 
1767
1790
        if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1768
1791
            revno = branch.revision_id_to_dotted_revno(revision_id)
1769
1792
            note(gettext("Tree is up to date at revision {0} of branch {1}"
1770
 
                        ).format('.'.join(map(str, revno)), branch_location))
 
1793
                         ).format('.'.join(map(str, revno)), branch_location))
1771
1794
            return 0
1772
1795
        view_info = _get_view_info_for_change_reporter(tree)
1773
1796
        change_reporter = delta._ChangeReporter(
1782
1805
                show_base=show_base)
1783
1806
        except errors.NoSuchRevision as e:
1784
1807
            raise errors.BzrCommandError(gettext(
1785
 
                                  "branch has no revision %s\n"
1786
 
                                  "brz update --revision only works"
1787
 
                                  " for a revision in the branch history")
1788
 
                                  % (e.revision))
 
1808
                "branch has no revision %s\n"
 
1809
                "brz update --revision only works"
 
1810
                " for a revision in the branch history")
 
1811
                % (e.revision))
1789
1812
        revno = tree.branch.revision_id_to_dotted_revno(
1790
1813
            _mod_revision.ensure_null(tree.last_revision()))
1791
1814
        note(gettext('Updated to revision {0} of branch {1}').format(
1793
1816
        parent_ids = tree.get_parent_ids()
1794
1817
        if parent_ids[1:] and parent_ids[1:] != existing_pending_merges:
1795
1818
            note(gettext('Your local commits will now show as pending merges with '
1796
 
                 "'brz status', and can be committed with 'brz commit'."))
 
1819
                         "'brz status', and can be committed with 'brz commit'."))
1797
1820
        if conflicts != 0:
1798
1821
            return 1
1799
1822
        else:
1855
1878
    """
1856
1879
    takes_args = ['file*']
1857
1880
    takes_options = ['verbose',
1858
 
        Option('new', help='Only remove files that have never been committed.'),
1859
 
        RegistryOption.from_kwargs('file-deletion-strategy',
1860
 
            'The file deletion mode to be used.',
1861
 
            title='Deletion Strategy', value_switches=True, enum_switch=False,
1862
 
            safe='Backup changed files (default).',
1863
 
            keep='Delete from brz but leave the working copy.',
1864
 
            no_backup='Don\'t backup changed files.'),
1865
 
        ]
 
1881
                     Option(
 
1882
                         'new', help='Only remove files that have never been committed.'),
 
1883
                     RegistryOption.from_kwargs('file-deletion-strategy',
 
1884
                                                'The file deletion mode to be used.',
 
1885
                                                title='Deletion Strategy', value_switches=True, enum_switch=False,
 
1886
                                                safe='Backup changed files (default).',
 
1887
                                                keep='Delete from brz but leave the working copy.',
 
1888
                                                no_backup='Don\'t backup changed files.'),
 
1889
                     ]
1866
1890
    aliases = ['rm', 'del']
1867
1891
    encoding_type = 'replace'
1868
1892
 
1869
1893
    def run(self, file_list, verbose=False, new=False,
1870
 
        file_deletion_strategy='safe'):
 
1894
            file_deletion_strategy='safe'):
1871
1895
 
1872
1896
        tree, file_list = WorkingTree.open_containing_paths(file_list)
1873
1897
 
1879
1903
        # some such?
1880
1904
        if new:
1881
1905
            added = tree.changes_from(tree.basis_tree(),
1882
 
                specific_files=file_list).added
 
1906
                                      specific_files=file_list).added
1883
1907
            file_list = sorted([f[0] for f in added], reverse=True)
1884
1908
            if len(file_list) == 0:
1885
1909
                raise errors.BzrCommandError(gettext('No matching files.'))
1894
1918
            file_list = sorted(missing, reverse=True)
1895
1919
            file_deletion_strategy = 'keep'
1896
1920
        tree.remove(file_list, verbose=verbose, to_file=self.outf,
1897
 
            keep_files=file_deletion_strategy=='keep',
1898
 
            force=(file_deletion_strategy=='no-backup'))
 
1921
                    keep_files=file_deletion_strategy == 'keep',
 
1922
                    force=(file_deletion_strategy == 'no-backup'))
1899
1923
 
1900
1924
 
1901
1925
class cmd_file_id(Command):
1990
2014
        self.add_cleanup(branch.lock_read().unlock)
1991
2015
        graph = branch.repository.get_graph()
1992
2016
        history = list(graph.iter_lefthand_ancestry(branch.last_revision(),
1993
 
            [_mod_revision.NULL_REVISION]))
 
2017
                                                    [_mod_revision.NULL_REVISION]))
1994
2018
        for revid in reversed(history):
1995
2019
            self.outf.write(revid)
1996
2020
            self.outf.write('\n')
2018
2042
        self.add_cleanup(b.repository.lock_read().unlock)
2019
2043
        graph = b.repository.get_graph()
2020
2044
        revisions = [revid for revid, parents in
2021
 
            graph.iter_ancestry([last_revision])]
 
2045
                     graph.iter_ancestry([last_revision])]
2022
2046
        for revision_id in reversed(revisions):
2023
2047
            if _mod_revision.is_null(revision_id):
2024
2048
                continue
2054
2078
        Option('create-prefix',
2055
2079
               help='Create the path leading up to the branch '
2056
2080
                    'if it does not already exist.'),
2057
 
         RegistryOption('format',
2058
 
                help='Specify a format for this branch. '
2059
 
                'See "help formats" for a full list.',
2060
 
                lazy_registry=('breezy.controldir', 'format_registry'),
2061
 
                converter=lambda name: controldir.format_registry.make_controldir(name),
2062
 
                value_switches=True,
2063
 
                title="Branch format",
2064
 
                ),
2065
 
         Option('append-revisions-only',
2066
 
                help='Never change revnos or the existing log.'
2067
 
                '  Append revisions to it only.'),
2068
 
         Option('no-tree',
2069
 
                'Create a branch without a working tree.')
2070
 
         ]
 
2081
        RegistryOption('format',
 
2082
                       help='Specify a format for this branch. '
 
2083
                       'See "help formats" for a full list.',
 
2084
                       lazy_registry=('breezy.controldir', 'format_registry'),
 
2085
                       converter=lambda name: controldir.format_registry.make_controldir(
 
2086
                            name),
 
2087
                       value_switches=True,
 
2088
                       title="Branch format",
 
2089
                       ),
 
2090
        Option('append-revisions-only',
 
2091
               help='Never change revnos or the existing log.'
 
2092
               '  Append revisions to it only.'),
 
2093
        Option('no-tree',
 
2094
               'Create a branch without a working tree.')
 
2095
        ]
 
2096
 
2071
2097
    def run(self, location=None, format=None, append_revisions_only=False,
2072
2098
            create_prefix=False, no_tree=False):
2073
2099
        if format is None:
2087
2113
        except errors.NoSuchFile:
2088
2114
            if not create_prefix:
2089
2115
                raise errors.BzrCommandError(gettext("Parent directory of %s"
2090
 
                    " does not exist."
2091
 
                    "\nYou may supply --create-prefix to create all"
2092
 
                    " leading parent directories.")
2093
 
                    % location)
 
2116
                                                     " does not exist."
 
2117
                                                     "\nYou may supply --create-prefix to create all"
 
2118
                                                     " leading parent directories.")
 
2119
                                             % location)
2094
2120
            to_transport.create_prefix()
2095
2121
 
2096
2122
        try:
2097
 
            a_controldir = controldir.ControlDir.open_from_transport(to_transport)
 
2123
            a_controldir = controldir.ControlDir.open_from_transport(
 
2124
                to_transport)
2098
2125
        except errors.NotBranchError:
2099
2126
            # really a NotBzrDir error...
2100
2127
            create_branch = controldir.ControlDir.create_branch_convenience
2110
2137
            from .transport.local import LocalTransport
2111
2138
            if a_controldir.has_branch():
2112
2139
                if (isinstance(to_transport, LocalTransport)
2113
 
                    and not a_controldir.has_workingtree()):
2114
 
                        raise errors.BranchExistsWithoutWorkingTree(location)
 
2140
                        and not a_controldir.has_workingtree()):
 
2141
                    raise errors.BranchExistsWithoutWorkingTree(location)
2115
2142
                raise errors.AlreadyBranchError(location)
2116
2143
            branch = a_controldir.create_branch()
2117
2144
            if not no_tree and not a_controldir.has_workingtree():
2121
2148
                branch.set_append_revisions_only(True)
2122
2149
            except errors.UpgradeRequired:
2123
2150
                raise errors.BzrCommandError(gettext('This branch format cannot be set'
2124
 
                    ' to append-revisions-only.  Try --default.'))
 
2151
                                                     ' to append-revisions-only.  Try --default.'))
2125
2152
        if not is_quiet():
2126
2153
            from .info import describe_layout, describe_format
2127
2154
            try:
2132
2159
            layout = describe_layout(repository, branch, tree).lower()
2133
2160
            format = describe_format(a_controldir, repository, branch, tree)
2134
2161
            self.outf.write(gettext("Created a {0} (format: {1})\n").format(
2135
 
                  layout, format))
 
2162
                layout, format))
2136
2163
            if repository.is_shared():
2137
 
                #XXX: maybe this can be refactored into transport.path_or_url()
 
2164
                # XXX: maybe this can be refactored into transport.path_or_url()
2138
2165
                url = repository.controldir.root_transport.external_url()
2139
2166
                try:
2140
2167
                    url = urlutils.local_path_from_url(url)
2148
2175
 
2149
2176
    New branches created under the repository directory will store their
2150
2177
    revisions in the repository, not in the branch directory.  For branches
2151
 
    with shared history, this reduces the amount of storage needed and 
 
2178
    with shared history, this reduces the amount of storage needed and
2152
2179
    speeds up the creation of new branches.
2153
2180
 
2154
2181
    If the --no-trees option is given then the branches in the repository
2155
 
    will not have working trees by default.  They will still exist as 
2156
 
    directories on disk, but they will not have separate copies of the 
 
2182
    will not have working trees by default.  They will still exist as
 
2183
    directories on disk, but they will not have separate copies of the
2157
2184
    files at a certain revision.  This can be useful for repositories that
2158
2185
    store branches which are interacted with through checkouts or remote
2159
2186
    branches, such as on a server.
2174
2201
    _see_also = ['init', 'branch', 'checkout', 'repositories']
2175
2202
    takes_args = ["location"]
2176
2203
    takes_options = [RegistryOption('format',
2177
 
                            help='Specify a format for this repository. See'
2178
 
                                 ' "brz help formats" for details.',
2179
 
                            lazy_registry=('breezy.controldir', 'format_registry'),
2180
 
                            converter=lambda name: controldir.format_registry.make_controldir(name),
2181
 
                            value_switches=True, title='Repository format'),
 
2204
                                    help='Specify a format for this repository. See'
 
2205
                                    ' "brz help formats" for details.',
 
2206
                                    lazy_registry=(
 
2207
                                        'breezy.controldir', 'format_registry'),
 
2208
                                    converter=lambda name: controldir.format_registry.make_controldir(
 
2209
                                        name),
 
2210
                                    value_switches=True, title='Repository format'),
2182
2211
                     Option('no-trees',
2183
 
                             help='Branches in the repository will default to'
2184
 
                                  ' not having a working tree.'),
2185
 
                    ]
 
2212
                            help='Branches in the repository will default to'
 
2213
                            ' not having a working tree.'),
 
2214
                     ]
2186
2215
    aliases = ["init-repo"]
2187
2216
 
2188
2217
    def run(self, location, format=None, no_trees=False):
2201
2230
 
2202
2231
        (repo, newdir, require_stacking, repository_policy) = (
2203
2232
            format.initialize_on_transport_ex(to_transport,
2204
 
            create_prefix=True, make_working_trees=not no_trees,
2205
 
            shared_repo=True, force_new_repo=True,
2206
 
            use_existing_dir=True,
2207
 
            repo_format_name=repo_format_name))
 
2233
                                              create_prefix=True, make_working_trees=not no_trees,
 
2234
                                              shared_repo=True, force_new_repo=True,
 
2235
                                              use_existing_dir=True,
 
2236
                                              repo_format_name=repo_format_name))
2208
2237
        if not is_quiet():
2209
2238
            from .info import show_bzrdir_info
2210
2239
            show_bzrdir_info(newdir, verbose=0, outfile=self.outf)
2225
2254
 
2226
2255
    Note that when using the -r argument with a range of revisions, the
2227
2256
    differences are computed between the two specified revisions.  That
2228
 
    is, the command does not show the changes introduced by the first 
2229
 
    revision in the range.  This differs from the interpretation of 
 
2257
    is, the command does not show the changes introduced by the first
 
2258
    revision in the range.  This differs from the interpretation of
2230
2259
    revision ranges used by "brz log" which includes the first revision
2231
2260
    in the range.
2232
2261
 
2258
2287
            brz diff -c2
2259
2288
 
2260
2289
        To see the changes introduced by revision X::
2261
 
        
 
2290
 
2262
2291
            brz diff -cX
2263
2292
 
2264
2293
        Note that in the case of a merge, the -c option shows the changes
2306
2335
               help='Set prefixes added to old and new filenames, as '
2307
2336
                    'two values separated by a colon. (eg "old/:new/").'),
2308
2337
        Option('old',
2309
 
            help='Branch/tree to compare from.',
2310
 
            type=text_type,
2311
 
            ),
 
2338
               help='Branch/tree to compare from.',
 
2339
               type=text_type,
 
2340
               ),
2312
2341
        Option('new',
2313
 
            help='Branch/tree to compare to.',
2314
 
            type=text_type,
2315
 
            ),
 
2342
               help='Branch/tree to compare to.',
 
2343
               type=text_type,
 
2344
               ),
2316
2345
        'revision',
2317
2346
        'change',
2318
2347
        Option('using',
2319
 
            help='Use this command to compare files.',
2320
 
            type=text_type,
2321
 
            ),
 
2348
               help='Use this command to compare files.',
 
2349
               type=text_type,
 
2350
               ),
2322
2351
        RegistryOption('format',
2323
 
            short_name='F',
2324
 
            help='Diff format to use.',
2325
 
            lazy_registry=('breezy.diff', 'format_registry'),
2326
 
            title='Diff format'),
 
2352
                       short_name='F',
 
2353
                       help='Diff format to use.',
 
2354
                       lazy_registry=('breezy.diff', 'format_registry'),
 
2355
                       title='Diff format'),
2327
2356
        Option('context',
2328
 
            help='How many lines of context to show.',
2329
 
            type=int,
2330
 
            ),
 
2357
               help='How many lines of context to show.',
 
2358
               type=int,
 
2359
               ),
2331
2360
        ]
2332
2361
    aliases = ['di', 'dif']
2333
2362
    encoding_type = 'exact'
2337
2366
            prefix=None, old=None, new=None, using=None, format=None,
2338
2367
            context=None):
2339
2368
        from .diff import (get_trees_and_branches_to_diff_locked,
2340
 
            show_diff_trees)
 
2369
                           show_diff_trees)
2341
2370
 
2342
2371
        if prefix == u'0':
2343
2372
            # diff -p0 format
2355
2384
 
2356
2385
        if revision and len(revision) > 2:
2357
2386
            raise errors.BzrCommandError(gettext('brz diff --revision takes exactly'
2358
 
                                         ' one or two revision specifiers'))
 
2387
                                                 ' one or two revision specifiers'))
2359
2388
 
2360
2389
        if using is not None and format is not None:
2361
2390
            raise errors.BzrCommandError(gettext(
2440
2469
        self.add_cleanup(wt.lock_read().unlock)
2441
2470
        basis = wt.basis_tree()
2442
2471
        self.add_cleanup(basis.lock_read().unlock)
2443
 
        root_id = wt.get_root_id()
2444
2472
        for path in wt.all_versioned_paths():
2445
2473
            if basis.has_filename(path):
2446
2474
                continue
2461
2489
    directory."""
2462
2490
 
2463
2491
    takes_args = ['filename?']
 
2492
 
2464
2493
    @display_command
2465
2494
    def run(self, filename=None):
2466
2495
        """Print the branch root."""
2608
2637
      line tools: you may prefer qlog or viz from qbzr or bzr-gtk, the
2609
2638
      bzr-explorer shell, or the Loggerhead web interface.  See the Bazaar
2610
2639
      Plugin Guide <http://doc.bazaar.canonical.com/plugins/en/> and
2611
 
      <http://wiki.bazaar.canonical.com/IDEIntegration>.  
 
2640
      <http://wiki.bazaar.canonical.com/IDEIntegration>.
2612
2641
 
2613
2642
      You may find it useful to add the aliases below to ``breezy.conf``::
2614
2643
 
2642
2671
    takes_args = ['file*']
2643
2672
    _see_also = ['log-formats', 'revisionspec']
2644
2673
    takes_options = [
2645
 
            Option('forward',
2646
 
                   help='Show from oldest to newest.'),
2647
 
            'timezone',
2648
 
            custom_help('verbose',
2649
 
                   help='Show files changed in each revision.'),
2650
 
            'show-ids',
2651
 
            'revision',
2652
 
            Option('change',
2653
 
                   type=breezy.option._parse_revision_str,
2654
 
                   short_name='c',
2655
 
                   help='Show just the specified revision.'
2656
 
                   ' See also "help revisionspec".'),
2657
 
            'log-format',
2658
 
            RegistryOption('authors',
2659
 
                'What names to list as authors - first, all or committer.',
2660
 
                title='Authors',
2661
 
                lazy_registry=('breezy.log', 'author_list_registry'),
2662
 
            ),
2663
 
            Option('levels',
2664
 
                   short_name='n',
2665
 
                   help='Number of levels to display - 0 for all, 1 for flat.',
2666
 
                   argname='N',
2667
 
                   type=_parse_levels),
2668
 
            Option('message',
2669
 
                   help='Show revisions whose message matches this '
2670
 
                        'regular expression.',
2671
 
                   type=text_type,
2672
 
                   hidden=True),
2673
 
            Option('limit',
2674
 
                   short_name='l',
2675
 
                   help='Limit the output to the first N revisions.',
2676
 
                   argname='N',
2677
 
                   type=_parse_limit),
2678
 
            Option('show-diff',
2679
 
                   short_name='p',
2680
 
                   help='Show changes made in each revision as a patch.'),
2681
 
            Option('include-merged',
2682
 
                   help='Show merged revisions like --levels 0 does.'),
2683
 
            Option('include-merges', hidden=True,
2684
 
                   help='Historical alias for --include-merged.'),
2685
 
            Option('omit-merges',
2686
 
                   help='Do not report commits with more than one parent.'),
2687
 
            Option('exclude-common-ancestry',
2688
 
                   help='Display only the revisions that are not part'
2689
 
                   ' of both ancestries (require -rX..Y).'
2690
 
                   ),
2691
 
            Option('signatures',
2692
 
                   help='Show digital signature validity.'),
2693
 
            ListOption('match',
2694
 
                short_name='m',
2695
 
                help='Show revisions whose properties match this '
2696
 
                'expression.',
2697
 
                type=text_type),
2698
 
            ListOption('match-message',
2699
 
                   help='Show revisions whose message matches this '
2700
 
                   'expression.',
2701
 
                type=text_type),
2702
 
            ListOption('match-committer',
 
2674
        Option('forward',
 
2675
               help='Show from oldest to newest.'),
 
2676
        'timezone',
 
2677
        custom_help('verbose',
 
2678
                    help='Show files changed in each revision.'),
 
2679
        'show-ids',
 
2680
        'revision',
 
2681
        Option('change',
 
2682
               type=breezy.option._parse_revision_str,
 
2683
               short_name='c',
 
2684
               help='Show just the specified revision.'
 
2685
               ' See also "help revisionspec".'),
 
2686
        'log-format',
 
2687
        RegistryOption('authors',
 
2688
                       'What names to list as authors - first, all or committer.',
 
2689
                       title='Authors',
 
2690
                       lazy_registry=(
 
2691
                           'breezy.log', 'author_list_registry'),
 
2692
                       ),
 
2693
        Option('levels',
 
2694
               short_name='n',
 
2695
               help='Number of levels to display - 0 for all, 1 for flat.',
 
2696
               argname='N',
 
2697
               type=_parse_levels),
 
2698
        Option('message',
 
2699
               help='Show revisions whose message matches this '
 
2700
               'regular expression.',
 
2701
               type=text_type,
 
2702
               hidden=True),
 
2703
        Option('limit',
 
2704
               short_name='l',
 
2705
               help='Limit the output to the first N revisions.',
 
2706
               argname='N',
 
2707
               type=_parse_limit),
 
2708
        Option('show-diff',
 
2709
               short_name='p',
 
2710
               help='Show changes made in each revision as a patch.'),
 
2711
        Option('include-merged',
 
2712
               help='Show merged revisions like --levels 0 does.'),
 
2713
        Option('include-merges', hidden=True,
 
2714
               help='Historical alias for --include-merged.'),
 
2715
        Option('omit-merges',
 
2716
               help='Do not report commits with more than one parent.'),
 
2717
        Option('exclude-common-ancestry',
 
2718
               help='Display only the revisions that are not part'
 
2719
               ' of both ancestries (require -rX..Y).'
 
2720
               ),
 
2721
        Option('signatures',
 
2722
               help='Show digital signature validity.'),
 
2723
        ListOption('match',
 
2724
                   short_name='m',
 
2725
                   help='Show revisions whose properties match this '
 
2726
                   'expression.',
 
2727
                   type=text_type),
 
2728
        ListOption('match-message',
 
2729
                   help='Show revisions whose message matches this '
 
2730
                   'expression.',
 
2731
                   type=text_type),
 
2732
        ListOption('match-committer',
2703
2733
                   help='Show revisions whose committer matches this '
2704
2734
                   'expression.',
2705
 
                type=text_type),
2706
 
            ListOption('match-author',
 
2735
                   type=text_type),
 
2736
        ListOption('match-author',
2707
2737
                   help='Show revisions whose authors match this '
2708
2738
                   'expression.',
2709
 
                type=text_type),
2710
 
            ListOption('match-bugs',
 
2739
                   type=text_type),
 
2740
        ListOption('match-bugs',
2711
2741
                   help='Show revisions whose bugs match this '
2712
2742
                   'expression.',
2713
 
                type=text_type)
2714
 
            ]
 
2743
                   type=text_type)
 
2744
        ]
2715
2745
    encoding_type = 'replace'
2716
2746
 
2717
2747
    @display_command
2746
2776
        if include_merged is None:
2747
2777
            include_merged = False
2748
2778
        if (exclude_common_ancestry
2749
 
            and (revision is None or len(revision) != 2)):
 
2779
                and (revision is None or len(revision) != 2)):
2750
2780
            raise errors.BzrCommandError(gettext(
2751
2781
                '--exclude-common-ancestry requires -r with two revisions'))
2752
2782
        if include_merged:
2823
2853
        if log_format is None:
2824
2854
            log_format = log.log_formatter_registry.get_default(b)
2825
2855
        # Make a non-encoding output to include the diffs - bug 328007
2826
 
        unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
 
2856
        unencoded_output = ui.ui_factory.make_output_stream(
 
2857
            encoding_type='exact')
2827
2858
        lf = log_format(show_ids=show_ids, to_file=self.outf,
2828
2859
                        to_exact_file=unencoded_output,
2829
2860
                        show_timezone=timezone,
2846
2877
        # file that isn't a directory without showing a delta" case.
2847
2878
        partial_history = revision and b.repository._format.supports_chks
2848
2879
        match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2849
 
            or delta_type or partial_history)
 
2880
                              or delta_type or partial_history)
2850
2881
 
2851
2882
        match_dict = {}
2852
2883
        if match:
2922
2953
        rev_id2 = revision_range[1].rev_id
2923
2954
    return rev_id1, rev_id2
2924
2955
 
 
2956
 
2925
2957
def get_log_format(long=False, short=False, line=False, default='long'):
2926
2958
    log_format = default
2927
2959
    if long:
2947
2979
        tree, relpath = WorkingTree.open_containing(filename)
2948
2980
        with tree.lock_read():
2949
2981
            touching_revs = log.find_touching_revisions(
2950
 
                    tree.branch.repository, tree.branch.last_revision(), tree, relpath)
 
2982
                tree.branch.repository, tree.branch.last_revision(), tree, relpath)
2951
2983
            for revno, revision_id, what in reversed(list(touching_revs)):
2952
2984
                self.outf.write("%6d %s\n" % (revno, what))
2953
2985
 
2959
2991
    _see_also = ['status', 'cat']
2960
2992
    takes_args = ['path?']
2961
2993
    takes_options = [
2962
 
            'verbose',
2963
 
            'revision',
2964
 
            Option('recursive', short_name='R',
2965
 
                   help='Recurse into subdirectories.'),
2966
 
            Option('from-root',
2967
 
                   help='Print paths relative to the root of the branch.'),
2968
 
            Option('unknown', short_name='u',
2969
 
                help='Print unknown files.'),
2970
 
            Option('versioned', help='Print versioned files.',
2971
 
                   short_name='V'),
2972
 
            Option('ignored', short_name='i',
2973
 
                help='Print ignored files.'),
2974
 
            Option('kind', short_name='k',
2975
 
                   help=('List entries of a particular kind: file, '
2976
 
                         'directory, symlink, tree-reference.'),
2977
 
                   type=text_type),
2978
 
            'null',
2979
 
            'show-ids',
2980
 
            'directory',
2981
 
            ]
 
2994
        'verbose',
 
2995
        'revision',
 
2996
        Option('recursive', short_name='R',
 
2997
               help='Recurse into subdirectories.'),
 
2998
        Option('from-root',
 
2999
               help='Print paths relative to the root of the branch.'),
 
3000
        Option('unknown', short_name='u',
 
3001
               help='Print unknown files.'),
 
3002
        Option('versioned', help='Print versioned files.',
 
3003
               short_name='V'),
 
3004
        Option('ignored', short_name='i',
 
3005
               help='Print ignored files.'),
 
3006
        Option('kind', short_name='k',
 
3007
               help=('List entries of a particular kind: file, '
 
3008
                     'directory, symlink, tree-reference.'),
 
3009
               type=text_type),
 
3010
        'null',
 
3011
        'show-ids',
 
3012
        'directory',
 
3013
        ]
 
3014
 
2982
3015
    @display_command
2983
3016
    def run(self, revision=None, verbose=False,
2984
3017
            recursive=False, from_root=False,
2989
3022
            raise errors.BzrCommandError(gettext('invalid kind specified'))
2990
3023
 
2991
3024
        if verbose and null:
2992
 
            raise errors.BzrCommandError(gettext('Cannot set both --verbose and --null'))
 
3025
            raise errors.BzrCommandError(
 
3026
                gettext('Cannot set both --verbose and --null'))
2993
3027
        all = not (unknown or versioned or ignored)
2994
3028
 
2995
 
        selection = {'I':ignored, '?':unknown, 'V':versioned}
 
3029
        selection = {'I': ignored, '?': unknown, 'V': versioned}
2996
3030
 
2997
3031
        if path is None:
2998
3032
            fs_path = '.'
2999
3033
        else:
3000
3034
            if from_root:
3001
3035
                raise errors.BzrCommandError(gettext('cannot specify both --from-root'
3002
 
                                             ' and PATH'))
 
3036
                                                     ' and PATH'))
3003
3037
            fs_path = path
3004
3038
        tree, branch, relpath = \
3005
3039
            _open_directory_or_containing_tree_or_branch(fs_path, directory)
3025
3059
 
3026
3060
        self.add_cleanup(tree.lock_read().unlock)
3027
3061
        for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
3028
 
            from_dir=relpath, recursive=recursive):
 
3062
                                                         from_dir=relpath, recursive=recursive):
3029
3063
            # Apply additional masking
3030
3064
            if not all and not selection[fc]:
3031
3065
                continue
3091
3125
 
3092
3126
    If a .bzrignore file does not exist, the ignore command
3093
3127
    will create one and add the specified files or patterns to the newly
3094
 
    created file. The ignore command will also automatically add the 
 
3128
    created file. The ignore command will also automatically add the
3095
3129
    .bzrignore file to be versioned. Creating a .bzrignore file without
3096
3130
    the use of the ignore command will require an explicit add command.
3097
3131
 
3099
3133
    After adding, editing or deleting that file either indirectly by
3100
3134
    using this command or directly by using an editor, be sure to commit
3101
3135
    it.
3102
 
    
 
3136
 
3103
3137
    Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows
3104
3138
    the global ignore file can be found in the application data directory as
3105
3139
    C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore.
3109
3143
    Patterns prefixed with '!' are exceptions to ignore patterns and take
3110
3144
    precedence over regular ignores.  Such exceptions are used to specify
3111
3145
    files that should be versioned which would otherwise be ignored.
3112
 
    
 
3146
 
3113
3147
    Patterns prefixed with '!!' act as regular ignore patterns, but have
3114
3148
    precedence over the '!' exception patterns.
3115
3149
 
3116
 
    :Notes: 
3117
 
        
 
3150
    :Notes:
 
3151
 
3118
3152
    * Ignore patterns containing shell wildcards must be quoted from
3119
3153
      the shell on Unix.
3120
3154
 
3149
3183
        Ignore everything but the "debian" toplevel directory::
3150
3184
 
3151
3185
            brz ignore "RE:(?!debian/).*"
3152
 
        
 
3186
 
3153
3187
        Ignore everything except the "local" toplevel directory,
3154
3188
        but always ignore autosave files ending in ~, even under local/::
3155
 
        
 
3189
 
3156
3190
            brz ignore "*"
3157
3191
            brz ignore "!./local"
3158
3192
            brz ignore "!!*~"
3161
3195
    _see_also = ['status', 'ignored', 'patterns']
3162
3196
    takes_args = ['name_pattern*']
3163
3197
    takes_options = ['directory',
3164
 
        Option('default-rules',
3165
 
               help='Display the default ignore rules that brz uses.')
3166
 
        ]
 
3198
                     Option('default-rules',
 
3199
                            help='Display the default ignore rules that brz uses.')
 
3200
                     ]
3167
3201
 
3168
3202
    def run(self, name_pattern_list=None, default_rules=None,
3169
3203
            directory=u'.'):
3175
3209
            return
3176
3210
        if not name_pattern_list:
3177
3211
            raise errors.BzrCommandError(gettext("ignore requires at least one "
3178
 
                "NAME_PATTERN or --default-rules."))
 
3212
                                                 "NAME_PATTERN or --default-rules."))
3179
3213
        name_pattern_list = [globbing.normalize_pattern(p)
3180
3214
                             for p in name_pattern_list]
3181
3215
        bad_patterns = ''
3185
3219
                bad_patterns_count += 1
3186
3220
                bad_patterns += ('\n  %s' % p)
3187
3221
        if bad_patterns:
3188
 
            msg = (ngettext('Invalid ignore pattern found. %s', 
 
3222
            msg = (ngettext('Invalid ignore pattern found. %s',
3189
3223
                            'Invalid ignore patterns found. %s',
3190
3224
                            bad_patterns_count) % bad_patterns)
3191
3225
            ui.ui_factory.show_error(msg)
3192
3226
            raise lazy_regex.InvalidPattern('')
3193
3227
        for name_pattern in name_pattern_list:
3194
3228
            if (name_pattern[0] == '/' or
3195
 
                (len(name_pattern) > 1 and name_pattern[1] == ':')):
 
3229
                    (len(name_pattern) > 1 and name_pattern[1] == ':')):
3196
3230
                raise errors.BzrCommandError(gettext(
3197
3231
                    "NAME_PATTERN should not be an absolute path"))
3198
3232
        tree, relpath = WorkingTree.open_containing(directory)
3208
3242
                    matches.append(filename)
3209
3243
        if len(matches) > 0:
3210
3244
            self.outf.write(gettext("Warning: the following files are version "
3211
 
                  "controlled and match your ignore pattern:\n%s"
3212
 
                  "\nThese files will continue to be version controlled"
3213
 
                  " unless you 'brz remove' them.\n") % ("\n".join(matches),))
 
3245
                                    "controlled and match your ignore pattern:\n%s"
 
3246
                                    "\nThese files will continue to be version controlled"
 
3247
                                    " unless you 'brz remove' them.\n") % ("\n".join(matches),))
3214
3248
 
3215
3249
 
3216
3250
class cmd_ignored(Command):
3235
3269
        for path, file_class, kind, file_id, entry in tree.list_files():
3236
3270
            if file_class != 'I':
3237
3271
                continue
3238
 
            ## XXX: Slightly inefficient since this was already calculated
 
3272
            # XXX: Slightly inefficient since this was already calculated
3239
3273
            pat = tree.is_ignored(path)
3240
3274
            self.outf.write('%-50s %s\n' % (path, pat))
3241
3275
 
3257
3291
        except ValueError:
3258
3292
            raise errors.BzrCommandError(gettext("not a valid revision-number: %r")
3259
3293
                                         % revno)
3260
 
        revid = WorkingTree.open_containing(directory)[0].branch.get_rev_id(revno)
 
3294
        revid = WorkingTree.open_containing(
 
3295
            directory)[0].branch.get_rev_id(revno)
3261
3296
        self.outf.write("%s\n" % revid.decode('utf-8'))
3262
3297
 
3263
3298
 
3293
3328
    encoding_type = 'exact'
3294
3329
    takes_args = ['dest', 'branch_or_subdir?']
3295
3330
    takes_options = ['directory',
3296
 
        Option('format',
3297
 
               help="Type of file to export to.",
3298
 
               type=text_type),
3299
 
        'revision',
3300
 
        Option('filters', help='Apply content filters to export the '
3301
 
                'convenient form.'),
3302
 
        Option('root',
3303
 
               type=text_type,
3304
 
               help="Name of the root directory inside the exported file."),
3305
 
        Option('per-file-timestamps',
3306
 
               help='Set modification time of files to that of the last '
3307
 
                    'revision in which it was changed.'),
3308
 
        Option('uncommitted',
3309
 
               help='Export the working tree contents rather than that of the '
3310
 
                    'last revision.'),
3311
 
        ]
 
3331
                     Option('format',
 
3332
                            help="Type of file to export to.",
 
3333
                            type=text_type),
 
3334
                     'revision',
 
3335
                     Option('filters', help='Apply content filters to export the '
 
3336
                            'convenient form.'),
 
3337
                     Option('root',
 
3338
                            type=text_type,
 
3339
                            help="Name of the root directory inside the exported file."),
 
3340
                     Option('per-file-timestamps',
 
3341
                            help='Set modification time of files to that of the last '
 
3342
                            'revision in which it was changed.'),
 
3343
                     Option('uncommitted',
 
3344
                            help='Export the working tree contents rather than that of the '
 
3345
                            'last revision.'),
 
3346
                     ]
 
3347
 
3312
3348
    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
3313
 
        root=None, filters=False, per_file_timestamps=False, uncommitted=False,
3314
 
        directory=u'.'):
 
3349
            root=None, filters=False, per_file_timestamps=False, uncommitted=False,
 
3350
            directory=u'.'):
3315
3351
        from .export import export, guess_format, get_root_name
3316
3352
 
3317
3353
        if branch_or_subdir is None:
3329
3365
            export_tree = tree
3330
3366
        else:
3331
3367
            export_tree = _get_one_revision_tree(
3332
 
                    'export', revision, branch=b,
3333
 
                    tree=tree)
 
3368
                'export', revision, branch=b,
 
3369
                tree=tree)
3334
3370
 
3335
3371
        if format is None:
3336
3372
            format = guess_format(dest)
3346
3382
        if filters:
3347
3383
            from breezy.filter_tree import ContentFilterTree
3348
3384
            export_tree = ContentFilterTree(
3349
 
                    export_tree, export_tree._content_filter_stack)
 
3385
                export_tree, export_tree._content_filter_stack)
3350
3386
 
3351
3387
        try:
3352
3388
            export(export_tree, dest, format, root, subdir,
3367
3403
 
3368
3404
    _see_also = ['ls']
3369
3405
    takes_options = ['directory',
3370
 
        Option('name-from-revision', help='The path name in the old tree.'),
3371
 
        Option('filters', help='Apply content filters to display the '
3372
 
                'convenience form.'),
3373
 
        'revision',
3374
 
        ]
 
3406
                     Option('name-from-revision',
 
3407
                            help='The path name in the old tree.'),
 
3408
                     Option('filters', help='Apply content filters to display the '
 
3409
                            'convenience form.'),
 
3410
                     'revision',
 
3411
                     ]
3375
3412
    takes_args = ['filename']
3376
3413
    encoding_type = 'exact'
3377
3414
 
3380
3417
            filters=False, directory=None):
3381
3418
        if revision is not None and len(revision) != 1:
3382
3419
            raise errors.BzrCommandError(gettext("brz cat --revision takes exactly"
3383
 
                                         " one revision specifier"))
 
3420
                                                 " one revision specifier"))
3384
3421
        tree, branch, relpath = \
3385
3422
            _open_directory_or_containing_tree_or_branch(filename, directory)
3386
3423
        self.add_cleanup(branch.lock_read().unlock)
3388
3425
                         name_from_revision, filters)
3389
3426
 
3390
3427
    def _run(self, tree, b, relpath, filename, revision, name_from_revision,
3391
 
        filtered):
 
3428
             filtered):
3392
3429
        import shutil
3393
3430
        if tree is None:
3394
3431
            tree = b.basis_tree()
3422
3459
        relpath = rev_tree.id2path(actual_file_id)
3423
3460
        if filtered:
3424
3461
            from .filter_tree import ContentFilterTree
3425
 
            filter_tree = ContentFilterTree(rev_tree,
3426
 
                rev_tree._content_filter_stack)
3427
 
            fileobj = filter_tree.get_file(relpath, actual_file_id)
 
3462
            filter_tree = ContentFilterTree(
 
3463
                rev_tree, rev_tree._content_filter_stack)
 
3464
            fileobj = filter_tree.get_file(relpath)
3428
3465
        else:
3429
 
            fileobj = rev_tree.get_file(relpath, actual_file_id)
 
3466
            fileobj = rev_tree.get_file(relpath)
3430
3467
        shutil.copyfileobj(fileobj, self.outf)
3431
3468
        self.cleanup_now()
3432
3469
 
3434
3471
class cmd_local_time_offset(Command):
3435
3472
    __doc__ = """Show the offset in seconds from GMT to local time."""
3436
3473
    hidden = True
 
3474
 
3437
3475
    @display_command
3438
3476
    def run(self):
3439
3477
        self.outf.write("%s\n" % osutils.local_time_offset())
3440
3478
 
3441
3479
 
3442
 
 
3443
3480
class cmd_commit(Command):
3444
3481
    __doc__ = """Commit changes into a new revision.
3445
3482
 
3459
3496
      If selected files are specified, only changes to those files are
3460
3497
      committed.  If a directory is specified then the directory and
3461
3498
      everything within it is committed.
3462
 
  
 
3499
 
3463
3500
      When excludes are given, they take precedence over selected files.
3464
3501
      For example, to commit only changes within foo, but not changes
3465
3502
      within foo/bar::
3466
 
  
 
3503
 
3467
3504
        brz commit foo -x foo/bar
3468
 
  
 
3505
 
3469
3506
      A selective commit after a merge is not yet supported.
3470
3507
 
3471
3508
    :Custom authors:
3476
3513
      "John Doe <jdoe@example.com>". If there is more than one author of
3477
3514
      the change you can specify the option multiple times, once for each
3478
3515
      author.
3479
 
  
 
3516
 
3480
3517
    :Checks:
3481
3518
 
3482
3519
      A common mistake is to forget to add a new file or directory before
3500
3537
    _see_also = ['add', 'bugs', 'hooks', 'uncommit']
3501
3538
    takes_args = ['selected*']
3502
3539
    takes_options = [
3503
 
            ListOption('exclude', type=text_type, short_name='x',
3504
 
                help="Do not consider changes made to a given path."),
3505
 
            Option('message', type=text_type,
3506
 
                   short_name='m',
3507
 
                   help="Description of the new revision."),
3508
 
            'verbose',
3509
 
             Option('unchanged',
3510
 
                    help='Commit even if nothing has changed.'),
3511
 
             Option('file', type=text_type,
3512
 
                    short_name='F',
3513
 
                    argname='msgfile',
3514
 
                    help='Take commit message from this file.'),
3515
 
             Option('strict',
3516
 
                    help="Refuse to commit if there are unknown "
3517
 
                    "files in the working tree."),
3518
 
             Option('commit-time', type=text_type,
3519
 
                    help="Manually set a commit time using commit date "
3520
 
                    "format, e.g. '2009-10-10 08:00:00 +0100'."),
3521
 
             ListOption('fixes', type=text_type,
3522
 
                    help="Mark a bug as being fixed by this revision "
3523
 
                         "(see \"brz help bugs\")."),
3524
 
             ListOption('author', type=text_type,
3525
 
                    help="Set the author's name, if it's different "
3526
 
                         "from the committer."),
3527
 
             Option('local',
3528
 
                    help="Perform a local commit in a bound "
3529
 
                         "branch.  Local commits are not pushed to "
3530
 
                         "the master branch until a normal commit "
3531
 
                         "is performed."
3532
 
                    ),
3533
 
             Option('show-diff', short_name='p',
3534
 
                    help='When no message is supplied, show the diff along'
3535
 
                    ' with the status summary in the message editor.'),
3536
 
             Option('lossy', 
3537
 
                    help='When committing to a foreign version control '
3538
 
                    'system do not push data that can not be natively '
3539
 
                    'represented.'),
3540
 
             ]
 
3540
        ListOption(
 
3541
            'exclude', type=text_type, short_name='x',
 
3542
            help="Do not consider changes made to a given path."),
 
3543
        Option('message', type=text_type,
 
3544
               short_name='m',
 
3545
               help="Description of the new revision."),
 
3546
        'verbose',
 
3547
        Option('unchanged',
 
3548
               help='Commit even if nothing has changed.'),
 
3549
        Option('file', type=text_type,
 
3550
               short_name='F',
 
3551
               argname='msgfile',
 
3552
               help='Take commit message from this file.'),
 
3553
        Option('strict',
 
3554
               help="Refuse to commit if there are unknown "
 
3555
               "files in the working tree."),
 
3556
        Option('commit-time', type=text_type,
 
3557
               help="Manually set a commit time using commit date "
 
3558
               "format, e.g. '2009-10-10 08:00:00 +0100'."),
 
3559
        ListOption(
 
3560
            'bugs', type=text_type,
 
3561
            help="Link to a related bug. (see \"brz help bugs\")."),
 
3562
        ListOption(
 
3563
            'fixes', type=text_type,
 
3564
            help="Mark a bug as being fixed by this revision "
 
3565
                 "(see \"brz help bugs\")."),
 
3566
        ListOption(
 
3567
            'author', type=text_type,
 
3568
            help="Set the author's name, if it's different "
 
3569
                 "from the committer."),
 
3570
        Option('local',
 
3571
               help="Perform a local commit in a bound "
 
3572
                    "branch.  Local commits are not pushed to "
 
3573
                    "the master branch until a normal commit "
 
3574
                    "is performed."
 
3575
               ),
 
3576
        Option('show-diff', short_name='p',
 
3577
               help='When no message is supplied, show the diff along'
 
3578
               ' with the status summary in the message editor.'),
 
3579
        Option('lossy',
 
3580
               help='When committing to a foreign version control '
 
3581
               'system do not push data that can not be natively '
 
3582
               'represented.'), ]
3541
3583
    aliases = ['ci', 'checkin']
3542
3584
 
3543
 
    def _iter_bug_fix_urls(self, fixes, branch):
3544
 
        default_bugtracker  = None
 
3585
    def _iter_bug_urls(self, bugs, branch, status):
 
3586
        default_bugtracker = None
3545
3587
        # Configure the properties for bug fixing attributes.
3546
 
        for fixed_bug in fixes:
3547
 
            tokens = fixed_bug.split(':')
 
3588
        for bug in bugs:
 
3589
            tokens = bug.split(':')
3548
3590
            if len(tokens) == 1:
3549
3591
                if default_bugtracker is None:
3550
3592
                    branch_config = branch.get_config_stack()
3556
3598
                        "'tracker:id' or specify a default bug tracker "
3557
3599
                        "using the `bugtracker` option.\nSee "
3558
3600
                        "\"brz help bugs\" for more information on this "
3559
 
                        "feature. Commit refused.") % fixed_bug)
 
3601
                        "feature. Commit refused.") % bug)
3560
3602
                tag = default_bugtracker
3561
3603
                bug_id = tokens[0]
3562
3604
            elif len(tokens) != 2:
3563
3605
                raise errors.BzrCommandError(gettext(
3564
3606
                    "Invalid bug %s. Must be in the form of 'tracker:id'. "
3565
3607
                    "See \"brz help bugs\" for more information on this "
3566
 
                    "feature.\nCommit refused.") % fixed_bug)
 
3608
                    "feature.\nCommit refused.") % bug)
3567
3609
            else:
3568
3610
                tag, bug_id = tokens
3569
3611
            try:
3570
 
                yield bugtracker.get_bug_url(tag, branch, bug_id)
 
3612
                yield bugtracker.get_bug_url(tag, branch, bug_id), status
3571
3613
            except bugtracker.UnknownBugTrackerAbbreviation:
3572
3614
                raise errors.BzrCommandError(gettext(
3573
 
                    'Unrecognized bug %s. Commit refused.') % fixed_bug)
 
3615
                    'Unrecognized bug %s. Commit refused.') % bug)
3574
3616
            except bugtracker.MalformedBugIdentifier as e:
3575
3617
                raise errors.BzrCommandError(gettext(
3576
3618
                    u"%s\nCommit refused.") % (e,))
3577
3619
 
3578
3620
    def run(self, message=None, file=None, verbose=False, selected_list=None,
3579
 
            unchanged=False, strict=False, local=False, fixes=None,
 
3621
            unchanged=False, strict=False, local=False, fixes=None, bugs=None,
3580
3622
            author=None, show_diff=False, exclude=None, commit_time=None,
3581
3623
            lossy=False):
 
3624
        import itertools
3582
3625
        from .commit import (
3583
3626
            PointlessCommit,
3584
3627
            )
3612
3655
 
3613
3656
        if fixes is None:
3614
3657
            fixes = []
 
3658
        if bugs is None:
 
3659
            bugs = []
3615
3660
        bug_property = bugtracker.encode_fixes_bug_urls(
3616
 
            self._iter_bug_fix_urls(fixes, tree.branch))
 
3661
            itertools.chain(
 
3662
                self._iter_bug_urls(bugs, tree.branch, bugtracker.RELATED),
 
3663
                self._iter_bug_urls(fixes, tree.branch, bugtracker.FIXED)))
3617
3664
        if bug_property:
3618
3665
            properties[u'bugs'] = bug_property
3619
3666
 
3632
3679
                warning_msg = (
3633
3680
                    'The commit message is a file name: "%(f)s".\n'
3634
3681
                    '(use --file "%(f)s" to take commit message from that file)'
3635
 
                    % { 'f': message })
 
3682
                    % {'f': message})
3636
3683
                ui.ui_factory.show_warning(warning_msg)
3637
3684
            if '\r' in message:
3638
3685
                message = message.replace('\r\n', '\n')
3652
3699
                # No message supplied: make one up.
3653
3700
                # text is the status of the tree
3654
3701
                text = make_commit_message_template_encoded(tree,
3655
 
                        selected_list, diff=show_diff,
3656
 
                        output_encoding=osutils.get_user_encoding())
 
3702
                                                            selected_list, diff=show_diff,
 
3703
                                                            output_encoding=osutils.get_user_encoding())
3657
3704
                # start_message is the template generated from hooks
3658
3705
                # XXX: Warning - looks like hooks return unicode,
3659
3706
                # make_commit_message_template_encoded returns user encoding.
3661
3708
                # avoid this.
3662
3709
                my_message = set_commit_message(commit_obj)
3663
3710
                if my_message is None:
3664
 
                    start_message = generate_commit_message_template(commit_obj)
 
3711
                    start_message = generate_commit_message_template(
 
3712
                        commit_obj)
3665
3713
                    if start_message is not None:
3666
3714
                        start_message = start_message.encode(
3667
 
                                osutils.get_user_encoding())
 
3715
                            osutils.get_user_encoding())
3668
3716
                    my_message = edit_commit_message_encoded(text,
3669
 
                        start_message=start_message)
 
3717
                                                             start_message=start_message)
3670
3718
                if my_message is None:
3671
3719
                    raise errors.BzrCommandError(gettext("please specify a commit"
3672
 
                        " message with either --message or --file"))
 
3720
                                                         " message with either --message or --file"))
3673
3721
                if my_message == "":
3674
3722
                    raise errors.BzrCommandError(gettext("Empty commit message specified."
3675
 
                            " Please specify a commit message with either"
3676
 
                            " --message or --file or leave a blank message"
3677
 
                            " with --message \"\"."))
 
3723
                                                         " Please specify a commit message with either"
 
3724
                                                         " --message or --file or leave a blank message"
 
3725
                                                         " with --message \"\"."))
3678
3726
            return my_message
3679
3727
 
3680
3728
        # The API permits a commit with a filter of [] to mean 'select nothing'
3692
3740
                        lossy=lossy)
3693
3741
        except PointlessCommit:
3694
3742
            raise errors.BzrCommandError(gettext("No changes to commit."
3695
 
                " Please 'brz add' the files you want to commit, or use"
3696
 
                " --unchanged to force an empty commit."))
 
3743
                                                 " Please 'brz add' the files you want to commit, or use"
 
3744
                                                 " --unchanged to force an empty commit."))
3697
3745
        except ConflictsInTree:
3698
3746
            raise errors.BzrCommandError(gettext('Conflicts detected in working '
3699
 
                'tree.  Use "brz conflicts" to list, "brz resolve FILE" to'
3700
 
                ' resolve.'))
 
3747
                                                 'tree.  Use "brz conflicts" to list, "brz resolve FILE" to'
 
3748
                                                 ' resolve.'))
3701
3749
        except StrictCommitFailed:
3702
3750
            raise errors.BzrCommandError(gettext("Commit refused because there are"
3703
 
                              " unknown files in the working tree."))
 
3751
                                                 " unknown files in the working tree."))
3704
3752
        except errors.BoundBranchOutOfDate as e:
3705
3753
            e.extra_help = (gettext("\n"
3706
 
                'To commit to master branch, run update and then commit.\n'
3707
 
                'You can also pass --local to commit to continue working '
3708
 
                'disconnected.'))
 
3754
                                    'To commit to master branch, run update and then commit.\n'
 
3755
                                    'You can also pass --local to commit to continue working '
 
3756
                                    'disconnected.'))
3709
3757
            raise
3710
3758
 
3711
3759
 
3816
3864
    takes_args = ['url?']
3817
3865
    takes_options = [
3818
3866
        RegistryOption('format',
3819
 
            help='Upgrade to a specific format.  See "brz help'
3820
 
                 ' formats" for details.',
3821
 
            lazy_registry=('breezy.controldir', 'format_registry'),
3822
 
            converter=lambda name: controldir.format_registry.make_controldir(name),
3823
 
            value_switches=True, title='Branch format'),
 
3867
                       help='Upgrade to a specific format.  See "brz help'
 
3868
                       ' formats" for details.',
 
3869
                       lazy_registry=('breezy.controldir', 'format_registry'),
 
3870
                       converter=lambda name: controldir.format_registry.make_controldir(
 
3871
                           name),
 
3872
                       value_switches=True, title='Branch format'),
3824
3873
        Option('clean',
3825
 
            help='Remove the backup.bzr directory if successful.'),
 
3874
               help='Remove the backup.bzr directory if successful.'),
3826
3875
        Option('dry-run',
3827
 
            help="Show what would be done, but don't actually do anything."),
 
3876
               help="Show what would be done, but don't actually do anything."),
3828
3877
    ]
3829
3878
 
3830
3879
    def run(self, url='.', format=None, clean=False, dry_run=False):
3850
3899
 
3851
3900
            brz whoami "Frank Chu <fchu@example.com>"
3852
3901
    """
3853
 
    takes_options = [ 'directory',
3854
 
                      Option('email',
3855
 
                             help='Display email address only.'),
3856
 
                      Option('branch',
3857
 
                             help='Set identity for the current branch instead of '
3858
 
                                  'globally.'),
3859
 
                    ]
 
3902
    takes_options = ['directory',
 
3903
                     Option('email',
 
3904
                            help='Display email address only.'),
 
3905
                     Option('branch',
 
3906
                            help='Set identity for the current branch instead of '
 
3907
                            'globally.'),
 
3908
                     ]
3860
3909
    takes_args = ['name?']
3861
3910
    encoding_type = 'replace'
3862
3911
 
3881
3930
 
3882
3931
        if email:
3883
3932
            raise errors.BzrCommandError(gettext("--email can only be used to display existing "
3884
 
                                         "identity"))
 
3933
                                                 "identity"))
3885
3934
 
3886
3935
        # display a warning if an email address isn't included in the given name.
3887
3936
        try:
3888
3937
            _mod_config.extract_email_address(name)
3889
 
        except _mod_config.NoEmailInUsername as e:
 
3938
        except _mod_config.NoEmailInUsername:
3890
3939
            warning('"%s" does not seem to contain an email address.  '
3891
3940
                    'This is allowed, but not recommended.', name)
3892
3941
 
3917
3966
    _see_also = ['info']
3918
3967
    takes_args = ['nickname?']
3919
3968
    takes_options = ['directory']
 
3969
 
3920
3970
    def run(self, nickname=None, directory=u'.'):
3921
3971
        branch = Branch.open_containing(directory)[0]
3922
3972
        if nickname is None:
3965
4015
            if equal_pos == -1:
3966
4016
                self.print_alias(name)
3967
4017
            else:
3968
 
                self.set_alias(name[:equal_pos], name[equal_pos+1:])
 
4018
                self.set_alias(name[:equal_pos], name[equal_pos + 1:])
3969
4019
 
3970
4020
    def remove_alias(self, alias_name):
3971
4021
        if alias_name is None:
4050
4100
    """
4051
4101
    # NB: this is used from the class without creating an instance, which is
4052
4102
    # why it does not have a self parameter.
 
4103
 
4053
4104
    def get_transport_type(typestring):
4054
4105
        """Parse and return a transport specifier."""
4055
4106
        if typestring == "sftp":
4069
4120
    takes_args = ['testspecs*']
4070
4121
    takes_options = ['verbose',
4071
4122
                     Option('one',
4072
 
                             help='Stop when one test fails.',
4073
 
                             short_name='1',
4074
 
                             ),
 
4123
                            help='Stop when one test fails.',
 
4124
                            short_name='1',
 
4125
                            ),
4075
4126
                     Option('transport',
4076
4127
                            help='Use a different transport by default '
4077
4128
                                 'throughout the test suite.',
4091
4142
                     Option('list-only',
4092
4143
                            help='List the tests instead of running them.'),
4093
4144
                     RegistryOption('parallel',
4094
 
                        help="Run the test suite in parallel.",
4095
 
                        lazy_registry=('breezy.tests', 'parallel_registry'),
4096
 
                        value_switches=False,
4097
 
                        ),
 
4145
                                    help="Run the test suite in parallel.",
 
4146
                                    lazy_registry=(
 
4147
                                        'breezy.tests', 'parallel_registry'),
 
4148
                                    value_switches=False,
 
4149
                                    ),
4098
4150
                     Option('randomize', type=text_type, argname="SEED",
4099
4151
                            help='Randomize the order of tests using the given'
4100
4152
                                 ' seed or "now" for the current time.'),
4114
4166
                                help='Turn on a selftest debug flag.'),
4115
4167
                     ListOption('starting-with', type=text_type, argname='TESTID',
4116
4168
                                param_name='starting_with', short_name='s',
4117
 
                                help=
4118
 
                                'Load only the tests starting with TESTID.'),
 
4169
                                help='Load only the tests starting with TESTID.'),
4119
4170
                     Option('sync',
4120
4171
                            help="By default we disable fsync and fdatasync"
4121
4172
                                 " while running the test suite.")
4149
4200
            from . import tests
4150
4201
        except ImportError:
4151
4202
            raise errors.BzrCommandError("tests not available. Install the "
4152
 
                "breezy tests to run the breezy testsuite.")
 
4203
                                         "breezy tests to run the breezy testsuite.")
4153
4204
 
4154
4205
        if testspecs_list is not None:
4155
4206
            pattern = '|'.join(testspecs_list)
4164
4215
                    "to use --subunit."))
4165
4216
            self.additional_selftest_args['runner_class'] = SubUnitBzrRunnerv1
4166
4217
            # On Windows, disable automatic conversion of '\n' to '\r\n' in
4167
 
            # stdout, which would corrupt the subunit stream. 
 
4218
            # stdout, which would corrupt the subunit stream.
4168
4219
            # FIXME: This has been fixed in subunit trunk (>0.0.5) so the
4169
4220
            # following code can be deleted when it's sufficiently deployed
4170
4221
            # -- vila/mgz 20100514
4171
4222
            if (sys.platform == "win32"
4172
 
                and getattr(sys.stdout, 'fileno', None) is not None):
 
4223
                    and getattr(sys.stdout, 'fileno', None) is not None):
4173
4224
                import msvcrt
4174
4225
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
4175
4226
        if subunit2:
4196
4247
        if not sync:
4197
4248
            self._disable_fsync()
4198
4249
        selftest_kwargs = {"verbose": verbose,
4199
 
                          "pattern": pattern,
4200
 
                          "stop_on_failure": one,
4201
 
                          "transport": transport,
4202
 
                          "test_suite_factory": test_suite_factory,
4203
 
                          "lsprof_timed": lsprof_timed,
4204
 
                          "lsprof_tests": lsprof_tests,
4205
 
                          "matching_tests_first": first,
4206
 
                          "list_only": list_only,
4207
 
                          "random_seed": randomize,
4208
 
                          "exclude_pattern": exclude_pattern,
4209
 
                          "strict": strict,
4210
 
                          "load_list": load_list,
4211
 
                          "debug_flags": debugflag,
4212
 
                          "starting_with": starting_with
4213
 
                          }
 
4250
                           "pattern": pattern,
 
4251
                           "stop_on_failure": one,
 
4252
                           "transport": transport,
 
4253
                           "test_suite_factory": test_suite_factory,
 
4254
                           "lsprof_timed": lsprof_timed,
 
4255
                           "lsprof_tests": lsprof_tests,
 
4256
                           "matching_tests_first": first,
 
4257
                           "list_only": list_only,
 
4258
                           "random_seed": randomize,
 
4259
                           "exclude_pattern": exclude_pattern,
 
4260
                           "strict": strict,
 
4261
                           "load_list": load_list,
 
4262
                           "debug_flags": debugflag,
 
4263
                           "starting_with": starting_with
 
4264
                           }
4214
4265
        selftest_kwargs.update(self.additional_selftest_args)
4215
4266
 
4216
4267
        # Make deprecation warnings visible, unless -Werror is set
4281
4332
        base_rev_id = graph.find_unique_lca(last1, last2)
4282
4333
 
4283
4334
        self.outf.write(gettext('merge base is revision %s\n') %
4284
 
                base_rev_id.decode('utf-8'))
 
4335
                        base_rev_id.decode('utf-8'))
4285
4336
 
4286
4337
 
4287
4338
class cmd_merge(Command):
4382
4433
        Option('uncommitted', help='Apply uncommitted changes'
4383
4434
               ' from a working copy, instead of branch changes.'),
4384
4435
        Option('pull', help='If the destination is already'
4385
 
                ' completely merged into the source, pull from the'
4386
 
                ' source rather than merging.  When this happens,'
4387
 
                ' you do not need to commit the result.'),
 
4436
               ' completely merged into the source, pull from the'
 
4437
               ' source rather than merging.  When this happens,'
 
4438
               ' you do not need to commit the result.'),
4388
4439
        custom_help('directory',
4389
 
               help='Branch to merge into, '
 
4440
                    help='Branch to merge into, '
4390
4441
                    'rather than the one containing the working directory.'),
4391
4442
        Option('preview', help='Instead of merging, show a diff of the'
4392
4443
               ' merge.'),
4393
4444
        Option('interactive', help='Select changes interactively.',
4394
 
            short_name='i')
 
4445
               short_name='i')
4395
4446
    ]
4396
4447
 
4397
4448
    def run(self, location=None, revision=None, force=False,
4404
4455
        if merge_type is None:
4405
4456
            merge_type = _mod_merge.Merge3Merger
4406
4457
 
4407
 
        if directory is None: directory = u'.'
 
4458
        if directory is None:
 
4459
            directory = u'.'
4408
4460
        possible_transports = []
4409
4461
        merger = None
4410
4462
        allow_pending = True
4411
4463
        verified = 'inapplicable'
4412
4464
 
4413
4465
        tree = WorkingTree.open_containing(directory)[0]
4414
 
        if tree.branch.revno() == 0:
 
4466
        if tree.branch.last_revision() == _mod_revision.NULL_REVISION:
4415
4467
            raise errors.BzrCommandError(gettext('Merging into empty branches not currently supported, '
4416
 
                                         'https://bugs.launchpad.net/bzr/+bug/308562'))
 
4468
                                                 'https://bugs.launchpad.net/bzr/+bug/308562'))
4417
4469
 
4418
4470
        # die as quickly as possible if there are uncommitted changes
4419
4471
        if not force:
4429
4481
        if location is not None:
4430
4482
            try:
4431
4483
                mergeable = bundle.read_mergeable_from_url(location,
4432
 
                    possible_transports=possible_transports)
 
4484
                                                           possible_transports=possible_transports)
4433
4485
            except errors.NotABundle:
4434
4486
                mergeable = None
4435
4487
            else:
4436
4488
                if uncommitted:
4437
4489
                    raise errors.BzrCommandError(gettext('Cannot use --uncommitted'
4438
 
                        ' with bundles or merge directives.'))
 
4490
                                                         ' with bundles or merge directives.'))
4439
4491
 
4440
4492
                if revision is not None:
4441
4493
                    raise errors.BzrCommandError(gettext(
4442
4494
                        'Cannot use -r with merge directives or bundles'))
4443
4495
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
4444
 
                   mergeable)
 
4496
                                                                    mergeable)
4445
4497
 
4446
4498
        if merger is None and uncommitted:
4447
4499
            if revision is not None and len(revision) > 0:
4448
4500
                raise errors.BzrCommandError(gettext('Cannot use --uncommitted and'
4449
 
                    ' --revision at the same time.'))
 
4501
                                                     ' --revision at the same time.'))
4450
4502
            merger = self.get_merger_from_uncommitted(tree, location, None)
4451
4503
            allow_pending = False
4452
4504
 
4453
4505
        if merger is None:
4454
4506
            merger, allow_pending = self._get_merger_from_branch(tree,
4455
 
                location, revision, remember, possible_transports, None)
 
4507
                                                                 location, revision, remember, possible_transports, None)
4456
4508
 
4457
4509
        merger.merge_type = merge_type
4458
4510
        merger.reprocess = reprocess
4459
4511
        merger.show_base = show_base
4460
4512
        self.sanity_check_merger(merger)
4461
4513
        if (merger.base_rev_id == merger.other_rev_id and
4462
 
            merger.other_rev_id is not None):
 
4514
                merger.other_rev_id is not None):
4463
4515
            # check if location is a nonexistent file (and not a branch) to
4464
4516
            # disambiguate the 'Nothing to do'
4465
4517
            if merger.interesting_files:
4466
4518
                if not merger.other_tree.has_filename(
4467
 
                    merger.interesting_files[0]):
 
4519
                        merger.interesting_files[0]):
4468
4520
                    note(gettext("merger: ") + str(merger))
4469
4521
                    raise errors.PathsDoNotExist([location])
4470
4522
            note(gettext('Nothing to do.'))
4471
4523
            return 0
4472
4524
        if pull and not preview:
4473
4525
            if merger.interesting_files is not None:
4474
 
                raise errors.BzrCommandError(gettext('Cannot pull individual files'))
 
4526
                raise errors.BzrCommandError(
 
4527
                    gettext('Cannot pull individual files'))
4475
4528
            if (merger.base_rev_id == tree.last_revision()):
4476
4529
                result = tree.pull(merger.other_branch, False,
4477
4530
                                   merger.other_rev_id)
4536
4589
 
4537
4590
    def sanity_check_merger(self, merger):
4538
4591
        if (merger.show_base and
4539
 
            not merger.merge_type is _mod_merge.Merge3Merger):
 
4592
                merger.merge_type is not _mod_merge.Merge3Merger):
4540
4593
            raise errors.BzrCommandError(gettext("Show-base is not supported for this"
4541
 
                                         " merge type. %s") % merger.merge_type)
 
4594
                                                 " merge type. %s") % merger.merge_type)
4542
4595
        if merger.reprocess is None:
4543
4596
            if merger.show_base:
4544
4597
                merger.reprocess = False
4547
4600
                merger.reprocess = merger.merge_type.supports_reprocess
4548
4601
        if merger.reprocess and not merger.merge_type.supports_reprocess:
4549
4602
            raise errors.BzrCommandError(gettext("Conflict reduction is not supported"
4550
 
                                         " for merge type %s.") %
 
4603
                                                 " for merge type %s.") %
4551
4604
                                         merger.merge_type)
4552
4605
        if merger.reprocess and merger.show_base:
4553
4606
            raise errors.BzrCommandError(gettext("Cannot do conflict reduction and"
4554
 
                                         " show base."))
 
4607
                                                 " show base."))
4555
4608
 
4556
4609
        if (merger.merge_type.requires_file_merge_plan and
4557
4610
            (not getattr(merger.this_tree, 'plan_file_merge', None) or
4559
4612
             (merger.base_tree is not None and
4560
4613
                 not getattr(merger.base_tree, 'plan_file_merge', None)))):
4561
4614
            raise errors.BzrCommandError(
4562
 
                 gettext('Plan file merge unsupported: '
4563
 
                         'Merge type incompatible with tree formats.'))
 
4615
                gettext('Plan file merge unsupported: '
 
4616
                        'Merge type incompatible with tree formats.'))
4564
4617
 
4565
4618
    def _get_merger_from_branch(self, tree, location, revision, remember,
4566
4619
                                possible_transports, pb):
4567
4620
        """Produce a merger from a location, assuming it refers to a branch."""
4568
4621
        # find the branch locations
4569
4622
        other_loc, user_location = self._select_branch_location(tree, location,
4570
 
            revision, -1)
 
4623
                                                                revision, -1)
4571
4624
        if revision is not None and len(revision) == 2:
4572
4625
            base_loc, _unused = self._select_branch_location(tree,
4573
 
                location, revision, 0)
 
4626
                                                             location, revision, 0)
4574
4627
        else:
4575
4628
            base_loc = other_loc
4576
4629
        # Open the branches
4577
4630
        other_branch, other_path = Branch.open_containing(other_loc,
4578
 
            possible_transports)
 
4631
                                                          possible_transports)
4579
4632
        if base_loc == other_loc:
4580
4633
            base_branch = other_branch
4581
4634
        else:
4582
4635
            base_branch, base_path = Branch.open_containing(base_loc,
4583
 
                possible_transports)
 
4636
                                                            possible_transports)
4584
4637
        # Find the revision ids
4585
4638
        other_revision_id = None
4586
4639
        base_revision_id = None
4598
4651
        # - user ask to remember or there is no previous location set to merge
4599
4652
        #   from and user didn't ask to *not* remember
4600
4653
        if (user_location is not None
4601
 
            and ((remember
4602
 
                  or (remember is None
4603
 
                      and tree.branch.get_submit_branch() is None)))):
 
4654
            and ((remember or
 
4655
                 (remember is None and
 
4656
                  tree.branch.get_submit_branch() is None)))):
4604
4657
            tree.branch.set_submit_branch(other_branch.base)
4605
4658
        # Merge tags (but don't set them in the master branch yet, the user
4606
4659
        # might revert this merge).  Commit will propagate them.
4607
4660
        other_branch.tags.merge_to(tree.branch.tags, ignore_master=True)
4608
4661
        merger = _mod_merge.Merger.from_revision_ids(tree,
4609
 
            other_revision_id, base_revision_id, other_branch, base_branch)
 
4662
                                                     other_revision_id, base_revision_id, other_branch, base_branch)
4610
4663
        if other_path != '':
4611
4664
            allow_pending = False
4612
4665
            merger.interesting_files = [other_path]
4647
4700
            will be the user-entered location.
4648
4701
        """
4649
4702
        if (revision is not None and index is not None
4650
 
            and revision[index] is not None):
 
4703
                and revision[index] is not None):
4651
4704
            branch = revision[index].get_branch()
4652
4705
            if branch is not None:
4653
4706
                return branch, branch
4669
4722
            stored_location_type = "parent"
4670
4723
        mutter("%s", stored_location)
4671
4724
        if stored_location is None:
4672
 
            raise errors.BzrCommandError(gettext("No location specified or remembered"))
 
4725
            raise errors.BzrCommandError(
 
4726
                gettext("No location specified or remembered"))
4673
4727
        display_url = urlutils.unescape_for_display(stored_location, 'utf-8')
4674
4728
        note(gettext("{0} remembered {1} location {2}").format(verb_string,
4675
 
                stored_location_type, display_url))
 
4729
                                                               stored_location_type, display_url))
4676
4730
        return stored_location
4677
4731
 
4678
4732
 
4700
4754
    """
4701
4755
    takes_args = ['file*']
4702
4756
    takes_options = [
4703
 
            'merge-type',
4704
 
            'reprocess',
4705
 
            Option('show-base',
4706
 
                   help="Show base revision text in conflicts."),
4707
 
            ]
 
4757
        'merge-type',
 
4758
        'reprocess',
 
4759
        Option('show-base',
 
4760
               help="Show base revision text in conflicts."),
 
4761
        ]
4708
4762
 
4709
4763
    def run(self, file_list=None, merge_type=None, show_base=False,
4710
4764
            reprocess=False):
4715
4769
        self.add_cleanup(tree.lock_write().unlock)
4716
4770
        parents = tree.get_parent_ids()
4717
4771
        if len(parents) != 2:
4718
 
            raise errors.BzrCommandError(gettext("Sorry, remerge only works after normal"
4719
 
                                         " merges.  Not cherrypicking or"
4720
 
                                         " multi-merges."))
4721
 
        repository = tree.branch.repository
 
4772
            raise errors.BzrCommandError(
 
4773
                gettext("Sorry, remerge only works after normal"
 
4774
                        " merges.  Not cherrypicking or multi-merges."))
4722
4775
        interesting_files = None
4723
4776
        new_conflicts = []
4724
4777
        conflicts = tree.conflicts()
4731
4784
                if tree.kind(filename) != "directory":
4732
4785
                    continue
4733
4786
 
4734
 
                for path, ie in tree.iter_entries_by_dir(specific_files=[filename]):
 
4787
                for path, ie in tree.iter_entries_by_dir(
 
4788
                        specific_files=[filename]):
4735
4789
                    interesting_files.add(path)
4736
4790
            new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4737
4791
        else:
4845
4899
    def _revert_tree_to_revision(tree, revision, file_list, no_backup):
4846
4900
        rev_tree = _get_one_revision_tree('revert', revision, tree=tree)
4847
4901
        tree.revert(file_list, rev_tree, not no_backup, None,
4848
 
            report_changes=True)
 
4902
                    report_changes=True)
4849
4903
 
4850
4904
 
4851
4905
class cmd_assert_fail(Command):
4864
4918
 
4865
4919
    _see_also = ['topics']
4866
4920
    takes_options = [
4867
 
            Option('long', 'Show help on all commands.'),
4868
 
            ]
 
4921
        Option('long', 'Show help on all commands.'),
 
4922
        ]
4869
4923
    takes_args = ['topic?']
4870
4924
    aliases = ['?', '--help', '-?', '-h']
4871
4925
 
4900
4954
    To filter on a range of revisions, you can use the command -r begin..end
4901
4955
    -r revision requests a specific revision, -r ..end or -r begin.. are
4902
4956
    also valid.
4903
 
            
 
4957
 
4904
4958
    :Exit values:
4905
4959
        1 - some missing revisions
4906
4960
        0 - no missing revisions
4942
4996
        'show-ids',
4943
4997
        'verbose',
4944
4998
        custom_help('revision',
4945
 
             help='Filter on other branch revisions (inclusive). '
4946
 
                'See "help revisionspec" for details.'),
 
4999
                    help='Filter on other branch revisions (inclusive). '
 
5000
                    'See "help revisionspec" for details.'),
4947
5001
        Option('my-revision',
4948
 
            type=_parse_revision_str,
4949
 
            help='Filter on local branch revisions (inclusive). '
4950
 
                'See "help revisionspec" for details.'),
 
5002
               type=_parse_revision_str,
 
5003
               help='Filter on local branch revisions (inclusive). '
 
5004
               'See "help revisionspec" for details.'),
4951
5005
        Option('include-merged',
4952
5006
               'Show all revisions in addition to the mainline ones.'),
4953
5007
        Option('include-merges', hidden=True,
4963
5017
            include_merged=None, revision=None, my_revision=None,
4964
5018
            directory=u'.'):
4965
5019
        from breezy.missing import find_unmerged, iter_log_revisions
 
5020
 
4966
5021
        def message(s):
4967
5022
            if not is_quiet():
4968
5023
                self.outf.write(s)
4990
5045
            other_branch = parent
4991
5046
            if other_branch is None:
4992
5047
                raise errors.BzrCommandError(gettext("No peer location known"
4993
 
                                             " or specified."))
 
5048
                                                     " or specified."))
4994
5049
            display_url = urlutils.unescape_for_display(parent,
4995
5050
                                                        self.outf.encoding)
4996
5051
            message(gettext("Using saved parent location: {0}\n").format(
5004
5059
 
5005
5060
        local_revid_range = _revision_range_to_revid_range(
5006
5061
            _get_revision_range(my_revision, local_branch,
5007
 
                self.name()))
 
5062
                                self.name()))
5008
5063
 
5009
5064
        remote_revid_range = _revision_range_to_revid_range(
5010
5065
            _get_revision_range(revision,
5011
 
                remote_branch, self.name()))
 
5066
                                remote_branch, self.name()))
5012
5067
 
5013
5068
        local_extra, remote_extra = find_unmerged(
5014
5069
            local_branch, remote_branch, restrict,
5027
5082
        status_code = 0
5028
5083
        if local_extra and not theirs_only:
5029
5084
            message(ngettext("You have %d extra revision:\n",
5030
 
                             "You have %d extra revisions:\n", 
 
5085
                             "You have %d extra revisions:\n",
5031
5086
                             len(local_extra)) %
5032
 
                len(local_extra))
 
5087
                    len(local_extra))
5033
5088
            rev_tag_dict = {}
5034
5089
            if local_branch.supports_tags():
5035
5090
                rev_tag_dict = local_branch.tags.get_reverse_tag_dict()
5036
5091
            for revision in iter_log_revisions(local_extra,
5037
 
                                local_branch.repository,
5038
 
                                verbose,
5039
 
                                rev_tag_dict):
 
5092
                                               local_branch.repository,
 
5093
                                               verbose,
 
5094
                                               rev_tag_dict):
5040
5095
                lf.log_revision(revision)
5041
5096
            printed_local = True
5042
5097
            status_code = 1
5049
5104
            message(ngettext("You are missing %d revision:\n",
5050
5105
                             "You are missing %d revisions:\n",
5051
5106
                             len(remote_extra)) %
5052
 
                len(remote_extra))
 
5107
                    len(remote_extra))
5053
5108
            if remote_branch.supports_tags():
5054
5109
                rev_tag_dict = remote_branch.tags.get_reverse_tag_dict()
5055
5110
            for revision in iter_log_revisions(remote_extra,
5056
 
                                remote_branch.repository,
5057
 
                                verbose,
5058
 
                                rev_tag_dict):
 
5111
                                               remote_branch.repository,
 
5112
                                               verbose,
 
5113
                                               rev_tag_dict):
5059
5114
                lf.log_revision(revision)
5060
5115
            status_code = 1
5061
5116
 
5101
5156
    _see_also = ['repositories']
5102
5157
    takes_args = ['branch_or_repo?']
5103
5158
    takes_options = [
5104
 
        Option('clean-obsolete-packs', 'Delete obsolete packs to save disk space.'),
 
5159
        Option('clean-obsolete-packs',
 
5160
               'Delete obsolete packs to save disk space.'),
5105
5161
        ]
5106
5162
 
5107
5163
    def run(self, branch_or_repo='.', clean_obsolete_packs=False):
5146
5202
class cmd_testament(Command):
5147
5203
    __doc__ = """Show testament (signing-form) of a revision."""
5148
5204
    takes_options = [
5149
 
            'revision',
5150
 
            Option('long', help='Produce long-format testament.'),
5151
 
            Option('strict',
5152
 
                   help='Produce a strict-format testament.')]
 
5205
        'revision',
 
5206
        Option('long', help='Produce long-format testament.'),
 
5207
        Option('strict',
 
5208
               help='Produce a strict-format testament.')]
5153
5209
    takes_args = ['branch?']
5154
5210
    encoding_type = 'exact'
 
5211
 
5155
5212
    @display_command
5156
5213
    def run(self, branch=u'.', revision=None, long=False, strict=False):
5157
5214
        from .testament import Testament, StrictTestament
5221
5278
            # If there is a tree and we're not annotating historical
5222
5279
            # versions, annotate the working tree's content.
5223
5280
            annotate_file_tree(wt, relpath, self.outf, long, all,
5224
 
                show_ids=show_ids, file_id=file_id)
 
5281
                               show_ids=show_ids)
5225
5282
        else:
5226
5283
            annotate_file_tree(tree, relpath, self.outf, long, all,
5227
 
                show_ids=show_ids, branch=branch, file_id=file_id)
 
5284
                               show_ids=show_ids, branch=branch)
5228
5285
 
5229
5286
 
5230
5287
class cmd_re_sign(Command):
5231
5288
    __doc__ = """Create a digital signature for an existing revision."""
5232
5289
    # TODO be able to replace existing ones.
5233
5290
 
5234
 
    hidden = True # is this right ?
 
5291
    hidden = True  # is this right ?
5235
5292
    takes_args = ['revision_id*']
5236
5293
    takes_options = ['directory', 'revision']
5237
5294
 
5238
5295
    def run(self, revision_id_list=None, revision=None, directory=u'.'):
5239
5296
        if revision_id_list is not None and revision is not None:
5240
 
            raise errors.BzrCommandError(gettext('You can only supply one of revision_id or --revision'))
 
5297
            raise errors.BzrCommandError(
 
5298
                gettext('You can only supply one of revision_id or --revision'))
5241
5299
        if revision_id_list is None and revision is None:
5242
 
            raise errors.BzrCommandError(gettext('You must supply either --revision or a revision_id'))
 
5300
            raise errors.BzrCommandError(
 
5301
                gettext('You must supply either --revision or a revision_id'))
5243
5302
        b = WorkingTree.open_containing(directory)[0].branch
5244
5303
        self.add_cleanup(b.lock_write().unlock)
5245
5304
        return self._run(b, revision_id_list, revision)
5252
5311
                for revision_id in revision_id_list:
5253
5312
                    revision_id = cache_utf8.encode(revision_id)
5254
5313
                    b.repository.sign_revision(revision_id, gpg_strategy)
5255
 
            except:
 
5314
            except BaseException:
5256
5315
                b.repository.abort_write_group()
5257
5316
                raise
5258
5317
            else:
5263
5322
                b.repository.start_write_group()
5264
5323
                try:
5265
5324
                    b.repository.sign_revision(rev_id, gpg_strategy)
5266
 
                except:
 
5325
                except BaseException:
5267
5326
                    b.repository.abort_write_group()
5268
5327
                    raise
5269
5328
                else:
5277
5336
                if to_revid is None:
5278
5337
                    to_revno = b.revno()
5279
5338
                if from_revno is None or to_revno is None:
5280
 
                    raise errors.BzrCommandError(gettext('Cannot sign a range of non-revision-history revisions'))
 
5339
                    raise errors.BzrCommandError(
 
5340
                        gettext('Cannot sign a range of non-revision-history revisions'))
5281
5341
                b.repository.start_write_group()
5282
5342
                try:
5283
5343
                    for revno in range(from_revno, to_revno + 1):
5284
5344
                        b.repository.sign_revision(b.get_rev_id(revno),
5285
5345
                                                   gpg_strategy)
5286
 
                except:
 
5346
                except BaseException:
5287
5347
                    b.repository.abort_write_group()
5288
5348
                    raise
5289
5349
                else:
5290
5350
                    b.repository.commit_write_group()
5291
5351
            else:
5292
 
                raise errors.BzrCommandError(gettext('Please supply either one revision, or a range.'))
 
5352
                raise errors.BzrCommandError(
 
5353
                    gettext('Please supply either one revision, or a range.'))
5293
5354
 
5294
5355
 
5295
5356
class cmd_bind(Command):
5314
5375
            try:
5315
5376
                location = b.get_old_bound_location()
5316
5377
            except errors.UpgradeRequired:
5317
 
                raise errors.BzrCommandError(gettext('No location supplied.  '
5318
 
                    'This format does not remember old locations.'))
 
5378
                raise errors.BzrCommandError(
 
5379
                    gettext('No location supplied.  '
 
5380
                            'This format does not remember old locations.'))
5319
5381
            else:
5320
5382
                if location is None:
5321
5383
                    if b.get_bound_location() is not None:
5329
5391
        try:
5330
5392
            b.bind(b_other)
5331
5393
        except errors.DivergedBranches:
5332
 
            raise errors.BzrCommandError(gettext('These branches have diverged.'
5333
 
                                         ' Try merging, and then bind again.'))
 
5394
            raise errors.BzrCommandError(
 
5395
                gettext('These branches have diverged.'
 
5396
                        ' Try merging, and then bind again.'))
5334
5397
        if b.get_config().has_explicit_nickname():
5335
5398
            b.nick = b_other.nick
5336
5399
 
5374
5437
    # information in shared branches as well.
5375
5438
    _see_also = ['commit']
5376
5439
    takes_options = ['verbose', 'revision',
5377
 
                    Option('dry-run', help='Don\'t actually make changes.'),
5378
 
                    Option('force', help='Say yes to all questions.'),
5379
 
                    Option('keep-tags',
5380
 
                           help='Keep tags that point to removed revisions.'),
5381
 
                    Option('local',
5382
 
                           help="Only remove the commits from the local branch"
5383
 
                                " when in a checkout."
5384
 
                           ),
5385
 
                    ]
 
5440
                     Option('dry-run', help='Don\'t actually make changes.'),
 
5441
                     Option('force', help='Say yes to all questions.'),
 
5442
                     Option('keep-tags',
 
5443
                            help='Keep tags that point to removed revisions.'),
 
5444
                     Option('local',
 
5445
                            help="Only remove the commits from the local "
 
5446
                            "branch when in a checkout."
 
5447
                            ),
 
5448
                     ]
5386
5449
    takes_args = ['location?']
5387
5450
    aliases = []
5388
5451
    encoding_type = 'replace'
5444
5507
 
5445
5508
        if dry_run:
5446
5509
            self.outf.write(gettext('Dry-run, pretending to remove'
5447
 
                            ' the above revisions.\n'))
 
5510
                                    ' the above revisions.\n'))
5448
5511
        else:
5449
 
            self.outf.write(gettext('The above revision(s) will be removed.\n'))
 
5512
            self.outf.write(
 
5513
                gettext('The above revision(s) will be removed.\n'))
5450
5514
 
5451
5515
        if not force:
5452
5516
            if not ui.ui_factory.confirm_action(
5460
5524
               last_rev_id, rev_id)
5461
5525
        uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose,
5462
5526
                 revno=revno, local=local, keep_tags=keep_tags)
5463
 
        self.outf.write(gettext('You can restore the old tip by running:\n'
5464
 
             '  brz pull . -r revid:%s\n') % last_rev_id.decode('utf-8'))
 
5527
        self.outf.write(
 
5528
            gettext('You can restore the old tip by running:\n'
 
5529
                    '  brz pull . -r revid:%s\n')
 
5530
            % last_rev_id.decode('utf-8'))
5465
5531
 
5466
5532
 
5467
5533
class cmd_break_lock(Command):
5487
5553
        Option('config',
5488
5554
               help='LOCATION is the directory where the config lock is.'),
5489
5555
        Option('force',
5490
 
            help='Do not ask for confirmation before breaking the lock.'),
 
5556
               help='Do not ask for confirmation before breaking the lock.'),
5491
5557
        ]
5492
5558
 
5493
5559
    def run(self, location=None, config=False, force=False):
5495
5561
            location = u'.'
5496
5562
        if force:
5497
5563
            ui.ui_factory = ui.ConfirmationUserInterfacePolicy(ui.ui_factory,
5498
 
                None,
5499
 
                {'breezy.lockdir.break': True})
 
5564
                                                               None,
 
5565
                                                               {'breezy.lockdir.break': True})
5500
5566
        if config:
5501
5567
            conf = _mod_config.LockableConfig(file_name=location)
5502
5568
            conf.break_lock()
5531
5597
        Option('inet',
5532
5598
               help='Serve on stdin/out for use from inetd or sshd.'),
5533
5599
        RegistryOption('protocol',
5534
 
               help="Protocol to serve.",
5535
 
               lazy_registry=('breezy.transport', 'transport_server_registry'),
5536
 
               value_switches=True),
 
5600
                       help="Protocol to serve.",
 
5601
                       lazy_registry=('breezy.transport',
 
5602
                                      'transport_server_registry'),
 
5603
                       value_switches=True),
5537
5604
        Option('listen',
5538
 
               help='Listen for connections on nominated address.', type=text_type),
 
5605
               help='Listen for connections on nominated address.',
 
5606
               type=text_type),
5539
5607
        Option('port',
5540
5608
               help='Listen for connections on nominated port.  Passing 0 as '
5541
5609
                    'the port number will result in a dynamically allocated '
5542
5610
                    'port.  The default port depends on the protocol.',
5543
5611
               type=int),
5544
5612
        custom_help('directory',
5545
 
               help='Serve contents of this directory.'),
 
5613
                    help='Serve contents of this directory.'),
5546
5614
        Option('allow-writes',
5547
5615
               help='By default the server is a readonly server.  Supplying '
5548
5616
                    '--allow-writes enables write access to the contents of '
5551
5619
                    'external authentication is arranged supplying this '
5552
5620
                    'option leads to global uncontrolled write access to your '
5553
5621
                    'file system.'
5554
 
                ),
 
5622
               ),
5555
5623
        Option('client-timeout', type=float,
5556
5624
               help='Override the default idle client timeout (5min).'),
5557
5625
        ]
5587
5655
    _see_also = ['split']
5588
5656
    takes_args = ['tree']
5589
5657
    takes_options = [
5590
 
            Option('reference', help='Join by reference.', hidden=True),
5591
 
            ]
 
5658
        Option('reference', help='Join by reference.', hidden=True),
 
5659
        ]
5592
5660
 
5593
5661
    def run(self, tree, reference=False):
5594
5662
        from breezy.mutabletree import BadReferenceTarget
5608
5676
                # XXX: Would be better to just raise a nicely printable
5609
5677
                # exception from the real origin.  Also below.  mbp 20070306
5610
5678
                raise errors.BzrCommandError(
5611
 
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5679
                    gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5612
5680
        else:
5613
5681
            try:
5614
5682
                containing_tree.subsume(sub_tree)
5615
5683
            except errors.BadSubsumeSource as e:
5616
5684
                raise errors.BzrCommandError(
5617
 
                       gettext("Cannot join {0}.  {1}").format(tree, e.reason))
 
5685
                    gettext("Cannot join {0}.  {1}").format(tree, e.reason))
5618
5686
 
5619
5687
 
5620
5688
class cmd_split(Command):
5634
5702
 
5635
5703
    def run(self, tree):
5636
5704
        containing_tree, subdir = WorkingTree.open_containing(tree)
5637
 
        sub_id = containing_tree.path2id(subdir)
5638
 
        if sub_id is None:
 
5705
        if not containing_tree.is_versioned(subdir):
5639
5706
            raise errors.NotVersionedError(subdir)
5640
5707
        try:
5641
 
            containing_tree.extract(subdir, sub_id)
 
5708
            containing_tree.extract(subdir)
5642
5709
        except errors.RootNotRich:
5643
5710
            raise errors.RichRootUpgradeRequired(containing_tree.branch.base)
5644
5711
 
5668
5735
 
5669
5736
    takes_options = [
5670
5737
        'directory',
5671
 
        RegistryOption.from_kwargs('patch-type',
 
5738
        RegistryOption.from_kwargs(
 
5739
            'patch-type',
5672
5740
            'The type of patch to include in the directive.',
5673
5741
            title='Patch type',
5674
5742
            value_switches=True,
5678
5746
            plain='No patch, just directive.'),
5679
5747
        Option('sign', help='GPG-sign the directive.'), 'revision',
5680
5748
        Option('mail-to', type=text_type,
5681
 
            help='Instead of printing the directive, email to this address.'),
 
5749
               help='Instead of printing the directive, email to this '
 
5750
               'address.'),
5682
5751
        Option('message', type=text_type, short_name='m',
5683
 
            help='Message to use when committing this merge.')
 
5752
               help='Message to use when committing this merge.')
5684
5753
        ]
5685
5754
 
5686
5755
    encoding_type = 'exact'
5704
5773
        if submit_branch is None:
5705
5774
            submit_branch = branch.get_parent()
5706
5775
        if submit_branch is None:
5707
 
            raise errors.BzrCommandError(gettext('No submit branch specified or known'))
 
5776
            raise errors.BzrCommandError(
 
5777
                gettext('No submit branch specified or known'))
5708
5778
 
5709
5779
        stored_public_branch = branch.get_public_branch()
5710
5780
        if public_branch is None:
5713
5783
            # FIXME: Should be done only if we succeed ? -- vila 2012-01-03
5714
5784
            branch.set_public_branch(public_branch)
5715
5785
        if not include_bundle and public_branch is None:
5716
 
            raise errors.BzrCommandError(gettext('No public branch specified or'
5717
 
                                         ' known'))
 
5786
            raise errors.BzrCommandError(
 
5787
                gettext('No public branch specified or known'))
5718
5788
        base_revision_id = None
5719
5789
        if revision is not None:
5720
5790
            if len(revision) > 2:
5721
 
                raise errors.BzrCommandError(gettext('brz merge-directive takes '
5722
 
                    'at most two one revision identifiers'))
 
5791
                raise errors.BzrCommandError(
 
5792
                    gettext('brz merge-directive takes '
 
5793
                            'at most two one revision identifiers'))
5723
5794
            revision_id = revision[-1].as_revision_id(branch)
5724
5795
            if len(revision) == 2:
5725
5796
                base_revision_id = revision[0].as_revision_id(branch)
5759
5830
      branch.
5760
5831
 
5761
5832
    `brz send` creates a compact data set that, when applied using brz
5762
 
    merge, has the same effect as merging from the source branch.  
5763
 
    
 
5833
    merge, has the same effect as merging from the source branch.
 
5834
 
5764
5835
    By default the merge directive is self-contained and can be applied to any
5765
5836
    branch containing submit_branch in its ancestory without needing access to
5766
5837
    the source branch.
5767
 
    
 
5838
 
5768
5839
    If --no-bundle is specified, then Bazaar doesn't send the contents of the
5769
5840
    revisions, but only a structured request to merge from the
5770
5841
    public_location.  In that case the public_branch is needed and it must be
5796
5867
    If the preferred client can't be found (or used), your editor will be used.
5797
5868
 
5798
5869
    To use a specific mail program, set the mail_client configuration option.
5799
 
    (For Thunderbird 1.5, this works around some bugs.)  Supported values for
5800
 
    specific clients are "claws", "evolution", "kmail", "mail.app" (MacOS X's
5801
 
    Mail.app), "mutt", and "thunderbird"; generic options are "default",
5802
 
    "editor", "emacsclient", "mapi", and "xdg-email".  Plugins may also add
5803
 
    supported clients.
 
5870
    Supported values for specific clients are "claws", "evolution", "kmail",
 
5871
    "mail.app" (MacOS X's Mail.app), "mutt", and "thunderbird"; generic options
 
5872
    are "default", "editor", "emacsclient", "mapi", and "xdg-email".  Plugins
 
5873
    may also add supported clients.
5804
5874
 
5805
5875
    If mail is being sent, a to address is required.  This can be supplied
5806
5876
    either on the commandline, by setting the submit_to configuration
5807
5877
    option in the branch itself or the child_submit_to configuration option
5808
5878
    in the submit branch.
5809
5879
 
5810
 
    Two formats are currently supported: "4" uses revision bundle format 4 and
5811
 
    merge directive format 2.  It is significantly faster and smaller than
5812
 
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
5813
 
    default.  "0.9" uses revision bundle format 0.9 and merge directive
5814
 
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
5815
 
 
5816
5880
    The merge directives created by brz send may be applied using brz merge or
5817
5881
    brz pull by specifying a file containing a merge directive as the location.
5818
5882
 
5893
5957
    branch is used in the merge instructions.  This means that a local mirror
5894
5958
    can be used as your actual submit branch, once you have set public_branch
5895
5959
    for that mirror.
5896
 
 
5897
 
    Two formats are currently supported: "4" uses revision bundle format 4 and
5898
 
    merge directive format 2.  It is significantly faster and smaller than
5899
 
    older formats.  It is compatible with Bazaar 0.19 and later.  It is the
5900
 
    default.  "0.9" uses revision bundle format 0.9 and merge directive
5901
 
    format 1.  It is compatible with Bazaar 0.12 - 0.18.
5902
5960
    """
5903
5961
 
5904
5962
    takes_options = [
5936
5994
            output = '-'
5937
5995
        from .send import send
5938
5996
        return send(submit_branch, revision, public_branch, remember,
5939
 
                         format, no_bundle, no_patch, output,
5940
 
                         kwargs.get('from', '.'), None, None, None,
5941
 
                         self.outf, strict=strict)
 
5997
                    format, no_bundle, no_patch, output,
 
5998
                    kwargs.get('from', '.'), None, None, None,
 
5999
                    self.outf, strict=strict)
5942
6000
 
5943
6001
 
5944
6002
class cmd_tag(Command):
5957
6015
    To rename a tag (change the name but keep it on the same revsion), run ``brz
5958
6016
    tag new-name -r tag:old-name`` and then ``brz tag --delete oldname``.
5959
6017
 
5960
 
    If no tag name is specified it will be determined through the 
 
6018
    If no tag name is specified it will be determined through the
5961
6019
    'automatic_tag_name' hook. This can e.g. be used to automatically tag
5962
6020
    upstream releases by reading configure.ac. See ``brz help hooks`` for
5963
6021
    details.
5967
6025
    takes_args = ['tag_name?']
5968
6026
    takes_options = [
5969
6027
        Option('delete',
5970
 
            help='Delete this tag rather than placing it.',
5971
 
            ),
 
6028
               help='Delete this tag rather than placing it.',
 
6029
               ),
5972
6030
        custom_help('directory',
5973
 
            help='Branch in which to place the tag.'),
 
6031
                    help='Branch in which to place the tag.'),
5974
6032
        Option('force',
5975
 
            help='Replace existing tags.',
5976
 
            ),
 
6033
               help='Replace existing tags.',
 
6034
               ),
5977
6035
        'revision',
5978
6036
        ]
5979
6037
 
5987
6045
        self.add_cleanup(branch.lock_write().unlock)
5988
6046
        if delete:
5989
6047
            if tag_name is None:
5990
 
                raise errors.BzrCommandError(gettext("No tag specified to delete."))
 
6048
                raise errors.BzrCommandError(
 
6049
                    gettext("No tag specified to delete."))
5991
6050
            branch.tags.delete_tag(tag_name)
5992
6051
            note(gettext('Deleted tag %s.') % tag_name)
5993
6052
        else:
6029
6088
    _see_also = ['tag']
6030
6089
    takes_options = [
6031
6090
        custom_help('directory',
6032
 
            help='Branch whose tags should be displayed.'),
 
6091
                    help='Branch whose tags should be displayed.'),
6033
6092
        RegistryOption('sort',
6034
 
            'Sort tags by different criteria.', title='Sorting',
6035
 
            lazy_registry=('breezy.tag', 'tag_sort_methods')
6036
 
            ),
 
6093
                       'Sort tags by different criteria.', title='Sorting',
 
6094
                       lazy_registry=('breezy.tag', 'tag_sort_methods')
 
6095
                       ),
6037
6096
        'show-ids',
6038
6097
        'revision',
6039
6098
    ]
6075
6134
            self.outf.write('%-20s %s\n' % (tag, revspec))
6076
6135
 
6077
6136
    def _tags_for_range(self, branch, revision):
6078
 
        range_valid = True
6079
6137
        rev1, rev2 = _get_revision_range(revision, branch, self.name())
6080
6138
        revid1, revid2 = rev1.rev_id, rev2.rev_id
6081
6139
        # _get_revision_range will always set revid2 if it's not specified.
6093
6151
        tagged_revids = branch.tags.get_reverse_tag_dict()
6094
6152
        found = []
6095
6153
        for r in branch.iter_merge_sorted_revisions(
6096
 
            start_revision_id=revid2, stop_revision_id=revid1,
6097
 
            stop_rule='include'):
 
6154
                start_revision_id=revid2, stop_revision_id=revid1,
 
6155
                stop_rule='include'):
6098
6156
            revid_tags = tagged_revids.get(r[0], None)
6099
6157
            if revid_tags:
6100
6158
                found.extend([(tag, r[0]) for tag in revid_tags])
6127
6185
            tree='Reconfigure to be an unbound branch with a working tree.',
6128
6186
            checkout='Reconfigure to be a bound branch with a working tree.',
6129
6187
            lightweight_checkout='Reconfigure to be a lightweight'
6130
 
                ' checkout (with no local history).',
 
6188
            ' checkout (with no local history).',
6131
6189
            ),
6132
6190
        RegistryOption.from_kwargs(
6133
6191
            'repository_type',
6135
6193
            help='Location fo the repository.',
6136
6194
            value_switches=True, enum_switch=False,
6137
6195
            standalone='Reconfigure to be a standalone branch '
6138
 
                '(i.e. stop using shared repository).',
 
6196
            '(i.e. stop using shared repository).',
6139
6197
            use_shared='Reconfigure to use a shared repository.',
6140
6198
            ),
6141
6199
        RegistryOption.from_kwargs(
6144
6202
            help='Whether new branches in the repository have trees.',
6145
6203
            value_switches=True, enum_switch=False,
6146
6204
            with_trees='Reconfigure repository to create '
6147
 
                'working trees on branches by default.',
 
6205
            'working trees on branches by default.',
6148
6206
            with_no_trees='Reconfigure repository to not create '
6149
 
                'working trees on branches by default.'
 
6207
            'working trees on branches by default.'
6150
6208
            ),
6151
6209
        Option('bind-to', help='Branch to bind checkout to.', type=text_type),
6152
6210
        Option('force',
6153
 
            help='Perform reconfiguration even if local changes'
6154
 
            ' will be lost.'),
 
6211
               help='Perform reconfiguration even if local changes'
 
6212
               ' will be lost.'),
6155
6213
        Option('stacked-on',
6156
 
            help='Reconfigure a branch to be stacked on another branch.',
6157
 
            type=text_type,
6158
 
            ),
 
6214
               help='Reconfigure a branch to be stacked on another branch.',
 
6215
               type=text_type,
 
6216
               ),
6159
6217
        Option('unstacked',
6160
 
            help='Reconfigure a branch to be unstacked.  This '
6161
 
                'may require copying substantial data into it.',
6162
 
            ),
 
6218
               help='Reconfigure a branch to be unstacked.  This '
 
6219
               'may require copying substantial data into it.',
 
6220
               ),
6163
6221
        ]
6164
6222
 
6165
6223
    def run(self, location=None, bind_to=None, force=False,
6167
6225
            stacked_on=None, unstacked=None):
6168
6226
        directory = controldir.ControlDir.open(location)
6169
6227
        if stacked_on and unstacked:
6170
 
            raise errors.BzrCommandError(gettext("Can't use both --stacked-on and --unstacked"))
 
6228
            raise errors.BzrCommandError(
 
6229
                gettext("Can't use both --stacked-on and --unstacked"))
6171
6230
        elif stacked_on is not None:
6172
6231
            reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
6173
6232
        elif unstacked:
6177
6236
        # to ban it.
6178
6237
        if (tree_type is None and
6179
6238
            repository_type is None and
6180
 
            repository_trees is None):
 
6239
                repository_trees is None):
6181
6240
            if stacked_on or unstacked:
6182
6241
                return
6183
6242
            else:
6184
6243
                raise errors.BzrCommandError(gettext('No target configuration '
6185
 
                    'specified'))
 
6244
                                                     'specified'))
6186
6245
        reconfiguration = None
6187
6246
        if tree_type == 'branch':
6188
6247
            reconfiguration = reconfigure.Reconfigure.to_branch(directory)
6241
6300
    takes_args = ['to_location?']
6242
6301
    takes_options = ['directory',
6243
6302
                     Option('force',
6244
 
                        help='Switch even if local commits will be lost.'),
 
6303
                            help='Switch even if local commits will be lost.'),
6245
6304
                     'revision',
6246
6305
                     Option('create-branch', short_name='b',
6247
 
                        help='Create the target branch from this one before'
6248
 
                             ' switching to it.'),
 
6306
                            help='Create the target branch from this one before'
 
6307
                            ' switching to it.'),
6249
6308
                     Option('store',
6250
 
                        help='Store and restore uncommitted changes in the'
6251
 
                             ' branch.'),
6252
 
                    ]
 
6309
                            help='Store and restore uncommitted changes in the'
 
6310
                            ' branch.'),
 
6311
                     ]
6253
6312
 
6254
6313
    def run(self, to_location=None, force=False, create_branch=False,
6255
6314
            revision=None, directory=u'.', store=False):
6258
6317
        revision = _get_one_revision('switch', revision)
6259
6318
        possible_transports = []
6260
6319
        control_dir = controldir.ControlDir.open_containing(tree_location,
6261
 
            possible_transports=possible_transports)[0]
 
6320
                                                            possible_transports=possible_transports)[0]
6262
6321
        if to_location is None:
6263
6322
            if revision is None:
6264
6323
                raise errors.BzrCommandError(gettext('You must supply either a'
6265
 
                                             ' revision or a location'))
 
6324
                                                     ' revision or a location'))
6266
6325
            to_location = tree_location
6267
6326
        try:
6268
6327
            branch = control_dir.open_branch(
6275
6334
            if branch is None:
6276
6335
                raise errors.BzrCommandError(
6277
6336
                    gettext('cannot create branch without source branch'))
6278
 
            to_location = lookup_new_sibling_branch(control_dir, to_location,
6279
 
                 possible_transports=possible_transports)
6280
 
            to_branch = branch.controldir.sprout(to_location,
6281
 
                 possible_transports=possible_transports,
6282
 
                 source_branch=branch).open_branch()
 
6337
            to_location = lookup_new_sibling_branch(
 
6338
                control_dir, to_location,
 
6339
                possible_transports=possible_transports)
 
6340
            if revision is not None:
 
6341
                revision = revision.as_revision_id(branch)
 
6342
            to_branch = branch.controldir.sprout(
 
6343
                to_location,
 
6344
                possible_transports=possible_transports,
 
6345
                revision_id=revision,
 
6346
                source_branch=branch).open_branch()
6283
6347
        else:
6284
6348
            try:
6285
6349
                to_branch = Branch.open(to_location,
6286
 
                    possible_transports=possible_transports)
 
6350
                                        possible_transports=possible_transports)
6287
6351
            except errors.NotBranchError:
6288
 
                to_branch = open_sibling_branch(control_dir, to_location,
 
6352
                to_branch = open_sibling_branch(
 
6353
                    control_dir, to_location,
6289
6354
                    possible_transports=possible_transports)
6290
 
        if revision is not None:
6291
 
            revision = revision.as_revision_id(to_branch)
 
6355
            if revision is not None:
 
6356
                revision = revision.as_revision_id(to_branch)
6292
6357
        try:
6293
6358
            switch.switch(control_dir, to_branch, force, revision_id=revision,
6294
6359
                          store_uncommitted=store)
6295
6360
        except controldir.BranchReferenceLoop:
6296
6361
            raise errors.BzrCommandError(
6297
 
                    gettext('switching would create a branch reference loop. '
6298
 
                            'Use the "bzr up" command to switch to a '
6299
 
                            'different revision.'))
 
6362
                gettext('switching would create a branch reference loop. '
 
6363
                        'Use the "bzr up" command to switch to a '
 
6364
                        'different revision.'))
6300
6365
        if had_explicit_nick:
6301
 
            branch = control_dir.open_branch() #get the new branch!
 
6366
            branch = control_dir.open_branch()  # get the new branch!
6302
6367
            branch.nick = to_branch.nick
6303
6368
        note(gettext('Switched to branch: %s'),
6304
 
            urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6305
 
 
 
6369
             urlutils.unescape_for_display(to_branch.base, 'utf-8'))
6306
6370
 
6307
6371
 
6308
6372
class cmd_view(Command):
6371
6435
    takes_args = ['file*']
6372
6436
    takes_options = [
6373
6437
        Option('all',
6374
 
            help='Apply list or delete action to all views.',
6375
 
            ),
 
6438
               help='Apply list or delete action to all views.',
 
6439
               ),
6376
6440
        Option('delete',
6377
 
            help='Delete the view.',
6378
 
            ),
 
6441
               help='Delete the view.',
 
6442
               ),
6379
6443
        Option('name',
6380
 
            help='Name of the view to define, list or delete.',
6381
 
            type=text_type,
6382
 
            ),
 
6444
               help='Name of the view to define, list or delete.',
 
6445
               type=text_type,
 
6446
               ),
6383
6447
        Option('switch',
6384
 
            help='Name of the view to switch to.',
6385
 
            type=text_type,
6386
 
            ),
 
6448
               help='Name of the view to switch to.',
 
6449
               type=text_type,
 
6450
               ),
6387
6451
        ]
6388
6452
 
6389
6453
    def run(self, file_list,
6393
6457
            switch=None,
6394
6458
            ):
6395
6459
        tree, file_list = WorkingTree.open_containing_paths(file_list,
6396
 
            apply_view=False)
 
6460
                                                            apply_view=False)
6397
6461
        current_view, view_dict = tree.views.get_view_info()
6398
6462
        if name is None:
6399
6463
            name = current_view
6408
6472
                tree.views.set_view_info(None, {})
6409
6473
                self.outf.write(gettext("Deleted all views.\n"))
6410
6474
            elif name is None:
6411
 
                raise errors.BzrCommandError(gettext("No current view to delete"))
 
6475
                raise errors.BzrCommandError(
 
6476
                    gettext("No current view to delete"))
6412
6477
            else:
6413
6478
                tree.views.delete_view(name)
6414
6479
                self.outf.write(gettext("Deleted '%s' view.\n") % name)
6421
6486
                    "Both --switch and --all specified"))
6422
6487
            elif switch == 'off':
6423
6488
                if current_view is None:
6424
 
                    raise errors.BzrCommandError(gettext("No current view to disable"))
 
6489
                    raise errors.BzrCommandError(
 
6490
                        gettext("No current view to disable"))
6425
6491
                tree.views.set_view_info(None, view_dict)
6426
 
                self.outf.write(gettext("Disabled '%s' view.\n") % (current_view))
 
6492
                self.outf.write(gettext("Disabled '%s' view.\n") %
 
6493
                                (current_view))
6427
6494
            else:
6428
6495
                tree.views.set_view_info(switch, view_dict)
6429
6496
                view_str = views.view_display_str(tree.views.lookup_view())
6430
 
                self.outf.write(gettext("Using '{0}' view: {1}\n").format(switch, view_str))
 
6497
                self.outf.write(
 
6498
                    gettext("Using '{0}' view: {1}\n").format(switch, view_str))
6431
6499
        elif all:
6432
6500
            if view_dict:
6433
6501
                self.outf.write(gettext('Views defined:\n'))
6449
6517
                    "Cannot change the 'off' pseudo view"))
6450
6518
            tree.views.set_view(name, sorted(file_list))
6451
6519
            view_str = views.view_display_str(tree.views.lookup_view())
6452
 
            self.outf.write(gettext("Using '{0}' view: {1}\n").format(name, view_str))
 
6520
            self.outf.write(
 
6521
                gettext("Using '{0}' view: {1}\n").format(name, view_str))
6453
6522
        else:
6454
6523
            # list the files
6455
6524
            if name is None:
6457
6526
                self.outf.write(gettext('No current view.\n'))
6458
6527
            else:
6459
6528
                view_str = views.view_display_str(tree.views.lookup_view(name))
6460
 
                self.outf.write(gettext("'{0}' view is: {1}\n").format(name, view_str))
 
6529
                self.outf.write(
 
6530
                    gettext("'{0}' view is: {1}\n").format(name, view_str))
6461
6531
 
6462
6532
 
6463
6533
class cmd_hooks(Command):
6483
6553
class cmd_remove_branch(Command):
6484
6554
    __doc__ = """Remove a branch.
6485
6555
 
6486
 
    This will remove the branch from the specified location but 
 
6556
    This will remove the branch from the specified location but
6487
6557
    will keep any working tree or repository in place.
6488
6558
 
6489
6559
    :Examples:
6497
6567
    takes_args = ["location?"]
6498
6568
 
6499
6569
    takes_options = ['directory',
6500
 
        Option('force', help='Remove branch even if it is the active branch.')]
 
6570
                     Option('force', help='Remove branch even if it is the active branch.')]
6501
6571
 
6502
6572
    aliases = ["rmbranch"]
6503
6573
 
6509
6579
            except errors.NotBranchError:
6510
6580
                active_branch = None
6511
6581
            if (active_branch is not None and
6512
 
                br.control_url == active_branch.control_url):
 
6582
                    br.control_url == active_branch.control_url):
6513
6583
                raise errors.BzrCommandError(
6514
6584
                    gettext("Branch is active. Use --force to remove it."))
6515
6585
        br.controldir.destroy_branch(br.name)
6545
6615
 
6546
6616
        change_editor = PROGRAM @new_path @old_path
6547
6617
 
6548
 
    where @new_path is replaced with the path of the new version of the 
6549
 
    file and @old_path is replaced with the path of the old version of 
6550
 
    the file.  The PROGRAM should save the new file with the desired 
 
6618
    where @new_path is replaced with the path of the new version of the
 
6619
    file and @old_path is replaced with the path of the old version of
 
6620
    the file.  The PROGRAM should save the new file with the desired
6551
6621
    contents of the file in the working tree.
6552
 
        
 
6622
 
6553
6623
    """
6554
6624
 
6555
6625
    takes_args = ['file*']
6578
6648
            writer = breezy.option.diff_writer_registry.get()
6579
6649
        try:
6580
6650
            shelver = Shelver.from_args(writer(self.outf), revision, all,
6581
 
                file_list, message, destroy=destroy, directory=directory)
 
6651
                                        file_list, message, destroy=destroy, directory=directory)
6582
6652
            try:
6583
6653
                shelver.run()
6584
6654
            finally:
6661
6731
                     Option('dry-run', help='Show files to delete instead of'
6662
6732
                            ' deleting them.'),
6663
6733
                     Option('force', help='Do not prompt before deleting.')]
 
6734
 
6664
6735
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
6665
6736
            force=False, directory=u'.'):
6666
6737
        from .clean_tree import clean_tree
6692
6763
        branchdir = '.'
6693
6764
        if path is not None:
6694
6765
            branchdir = path
6695
 
        tree, branch, relpath =(
 
6766
        tree, branch, relpath = (
6696
6767
            controldir.ControlDir.open_containing_tree_or_branch(branchdir))
6697
6768
        if path is not None:
6698
6769
            path = relpath
6724
6795
 
6725
6796
    hidden = True
6726
6797
    takes_options = [Option('plugin',
6727
 
                            help='Export help text from named command '\
 
6798
                            help='Export help text from named command '
6728
6799
                                 '(defaults to all built in commands).',
6729
6800
                            type=text_type),
6730
6801
                     Option('include-duplicates',
6731
6802
                            help='Output multiple copies of the same msgid '
6732
6803
                                 'string if it appears more than once.'),
6733
 
                            ]
 
6804
                     ]
6734
6805
 
6735
6806
    def run(self, plugin=None, include_duplicates=False):
6736
6807
        from .export_pot import export_pot
6804
6875
    # register lazy builtins from other modules; called at startup and should
6805
6876
    # be only called once.
6806
6877
    for (name, aliases, module_name) in [
6807
 
        ('cmd_bisect', [], 'breezy.bisect'),
6808
 
        ('cmd_bundle_info', [], 'breezy.bundle.commands'),
6809
 
        ('cmd_config', [], 'breezy.config'),
6810
 
        ('cmd_dump_btree', [], 'breezy.bzr.debug_commands'),
6811
 
        ('cmd_version_info', [], 'breezy.cmd_version_info'),
6812
 
        ('cmd_resolve', ['resolved'], 'breezy.conflicts'),
6813
 
        ('cmd_conflicts', [], 'breezy.conflicts'),
6814
 
        ('cmd_ping', [], 'breezy.bzr.smart.ping'),
6815
 
        ('cmd_sign_my_commits', [], 'breezy.commit_signature_commands'),
6816
 
        ('cmd_verify_signatures', [], 'breezy.commit_signature_commands'),
6817
 
        ('cmd_test_script', [], 'breezy.cmd_test_script'),
6818
 
        ]:
 
6878
            ('cmd_bisect', [], 'breezy.bisect'),
 
6879
            ('cmd_bundle_info', [], 'breezy.bundle.commands'),
 
6880
            ('cmd_config', [], 'breezy.config'),
 
6881
            ('cmd_dump_btree', [], 'breezy.bzr.debug_commands'),
 
6882
            ('cmd_version_info', [], 'breezy.cmd_version_info'),
 
6883
            ('cmd_resolve', ['resolved'], 'breezy.conflicts'),
 
6884
            ('cmd_conflicts', [], 'breezy.conflicts'),
 
6885
            ('cmd_ping', [], 'breezy.bzr.smart.ping'),
 
6886
            ('cmd_sign_my_commits', [], 'breezy.commit_signature_commands'),
 
6887
            ('cmd_verify_signatures', [], 'breezy.commit_signature_commands'),
 
6888
            ('cmd_test_script', [], 'breezy.cmd_test_script'),
 
6889
            ]:
6819
6890
        builtin_command_registry.register_lazy(name, aliases, module_name)