/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/commit.py

  • Committer: Jelmer Vernooij
  • Date: 2019-06-02 02:35:46 UTC
  • mfrom: (7309 work)
  • mto: This revision was merged to the branch mainline in revision 7319.
  • Revision ID: jelmer@jelmer.uk-20190602023546-lqco868tnv26d8ow
merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
    debug,
55
55
    errors,
56
56
    trace,
57
 
    tree,
58
57
    ui,
59
58
    )
60
59
from .branch import Branch
67
66
from .osutils import (get_user_encoding,
68
67
                      is_inside_any,
69
68
                      minimum_path_selection,
70
 
                      splitpath,
71
69
                      )
72
70
from .trace import mutter, note, is_quiet
73
71
from .urlutils import unescape_for_display
101
99
        new_path = change[1][1]
102
100
 
103
101
        new_excluded = (new_path is not None and
104
 
            is_inside_any(exclude, new_path))
 
102
                        is_inside_any(exclude, new_path))
105
103
 
106
104
        old_excluded = (old_path is not None and
107
 
            is_inside_any(exclude, old_path))
 
105
                        is_inside_any(exclude, old_path))
108
106
 
109
107
        if old_excluded and new_excluded:
110
108
            continue
194
192
            the working directory; these should be removed from the
195
193
            working inventory.
196
194
    """
 
195
 
197
196
    def __init__(self,
198
197
                 reporter=None,
199
198
                 config_stack=None):
211
210
            revprops = {}
212
211
        if possible_master_transports is None:
213
212
            possible_master_transports = []
214
 
        if (not u'branch-nick' in revprops and
 
213
        if (u'branch-nick' not in revprops and
215
214
                branch.repository._format.supports_storing_branch_nick):
216
215
            revprops[u'branch-nick'] = branch._get_nick(
217
216
                local,
224
223
                for individual in authors:
225
224
                    if '\n' in individual:
226
225
                        raise AssertionError('\\n is not a valid character '
227
 
                                'in an author identity')
 
226
                                             'in an author identity')
228
227
                revprops[u'authors'] = '\n'.join(authors)
229
228
        return revprops
230
229
 
251
250
        """Commit working copy as a new revision.
252
251
 
253
252
        :param message: the commit message (it or message_callback is required)
254
 
        :param message_callback: A callback: message = message_callback(cmt_obj)
 
253
        :param message_callback: A callback: message =
 
254
            message_callback(cmt_obj)
255
255
 
256
256
        :param timestamp: if not None, seconds-since-epoch for a
257
257
            postdated/predated commit.
288
288
        # XXX: Can be set on __init__ or passed in - this is a bit ugly.
289
289
        self.config_stack = config or self.config_stack
290
290
        return operation.run(
291
 
               message=message,
292
 
               timestamp=timestamp,
293
 
               timezone=timezone,
294
 
               committer=committer,
295
 
               specific_files=specific_files,
296
 
               rev_id=rev_id,
297
 
               allow_pointless=allow_pointless,
298
 
               strict=strict,
299
 
               verbose=verbose,
300
 
               working_tree=working_tree,
301
 
               local=local,
302
 
               reporter=reporter,
303
 
               message_callback=message_callback,
304
 
               recursive=recursive,
305
 
               exclude=exclude,
306
 
               possible_master_transports=possible_master_transports,
307
 
               lossy=lossy)
 
291
            message=message,
 
292
            timestamp=timestamp,
 
293
            timezone=timezone,
 
294
            committer=committer,
 
295
            specific_files=specific_files,
 
296
            rev_id=rev_id,
 
297
            allow_pointless=allow_pointless,
 
298
            strict=strict,
 
299
            verbose=verbose,
 
300
            working_tree=working_tree,
 
301
            local=local,
 
302
            reporter=reporter,
 
303
            message_callback=message_callback,
 
304
            recursive=recursive,
 
305
            exclude=exclude,
 
306
            possible_master_transports=possible_master_transports,
 
307
            lossy=lossy)
308
308
 
309
309
    def _commit(self, operation, message, timestamp, timezone, committer,
310
 
            specific_files, rev_id, allow_pointless, strict, verbose,
311
 
            working_tree, local, reporter, message_callback, recursive,
312
 
            exclude, possible_master_transports, lossy):
 
310
                specific_files, rev_id, allow_pointless, strict, verbose,
 
311
                working_tree, local, reporter, message_callback, recursive,
 
312
                exclude, possible_master_transports, lossy):
313
313
        mutter('preparing to commit')
314
314
 
315
315
        if working_tree is None:
324
324
            if message is not None:
325
325
                if isinstance(message, bytes):
326
326
                    message = message.decode(get_user_encoding())
327
 
                message_callback = lambda x: message
 
327
 
 
328
                def message_callback(x):
 
329
                    return message
328
330
            else:
329
331
                raise BzrError("The message or message_callback keyword"
330
332
                               " parameter is required for commit().")
411
413
        # Collect the changes
412
414
        self._set_progress_stage("Collecting changes", counter=True)
413
415
        self._lossy = lossy
414
 
        self.builder = self.branch.get_commit_builder(self.parents,
415
 
            self.config_stack, timestamp, timezone, committer, self.revprops,
416
 
            rev_id, lossy=lossy)
 
416
        self.builder = self.branch.get_commit_builder(
 
417
            self.parents, self.config_stack, timestamp, timezone, committer,
 
418
            self.revprops, rev_id, lossy=lossy)
417
419
 
418
420
        if self.builder.updates_branch and self.bound_branch:
419
421
            self.builder.abort()
448
450
            # Add revision data to the local branch
449
451
            self.rev_id = self.builder.commit(self.message)
450
452
 
451
 
        except Exception as e:
 
453
        except Exception:
452
454
            mutter("aborting commit write group because of exception:")
453
455
            trace.log_exception_quietly()
454
456
            self.builder.abort()
462
464
        self.work_tree.unversion(self.deleted_paths)
463
465
        self._set_progress_stage("Updating the working tree")
464
466
        self.work_tree.update_basis_by_delta(self.rev_id,
465
 
             self.builder.get_basis_delta())
 
467
                                             self.builder.get_basis_delta())
466
468
        self.reporter.completed(new_revno, self.rev_id)
467
469
        self._process_post_hooks(old_revno, new_revno)
468
470
        return self.rev_id
497
499
        else:
498
500
            try:
499
501
                self._process_pre_hooks(old_revno, new_revno)
500
 
            except:
 
502
            except BaseException:
501
503
                # The commit builder will already have updated the branch,
502
504
                # revert it.
503
505
                self.branch.set_last_revision_info(old_revno, old_revid)
510
512
                self.master_branch.tags)
511
513
            if tag_conflicts:
512
514
                warning_lines = ['    ' + name for name, _, _ in tag_conflicts]
513
 
                note( gettext("Conflicting tags in bound branch:\n{0}".format(
514
 
                    "\n".join(warning_lines))) )
 
515
                note(gettext("Conflicting tags in bound branch:\n{0}".format(
 
516
                    "\n".join(warning_lines))))
515
517
 
516
518
    def _select_reporter(self):
517
519
        """Select the CommitReporter to use."""
551
553
        # If the master branch is bound, we must fail
552
554
        master_bound_location = self.master_branch.get_bound_location()
553
555
        if master_bound_location:
554
 
            raise errors.CommitToDoubleBoundBranch(self.branch,
555
 
                    self.master_branch, master_bound_location)
 
556
            raise errors.CommitToDoubleBoundBranch(
 
557
                self.branch, self.master_branch, master_bound_location)
556
558
 
557
559
        # TODO: jam 20051230 We could automatically push local
558
560
        #       commits to the remote branch if they would fit.
560
562
        #       to local.
561
563
 
562
564
        # Make sure the local branch is identical to the master
563
 
        master_info = self.master_branch.last_revision_info()
564
 
        local_info = self.branch.last_revision_info()
565
 
        if local_info != master_info:
 
565
        master_revid = self.master_branch.last_revision()
 
566
        local_revid = self.branch.last_revision()
 
567
        if local_revid != master_revid:
566
568
            raise errors.BoundBranchOutOfDate(self.branch,
567
 
                    self.master_branch)
 
569
                                              self.master_branch)
568
570
 
569
571
        # Now things are ready to change the master branch
570
572
        # so grab the lock
586
588
            # - in a checkout scenario the tree may have no
587
589
            # parents but the branch may do.
588
590
            first_tree_parent = breezy.revision.NULL_REVISION
589
 
        old_revno, master_last = self.master_branch.last_revision_info()
 
591
        try:
 
592
            old_revno, master_last = self.master_branch.last_revision_info()
 
593
        except errors.UnsupportedOperation:
 
594
            master_last = self.master_branch.last_revision()
 
595
            old_revno = self.branch.revision_id_to_revno(master_last)
590
596
        if master_last != first_tree_parent:
591
597
            if master_last != breezy.revision.NULL_REVISION:
592
598
                raise errors.OutOfDateTree(self.work_tree)
614
620
            # this would be nicer with twisted.python.reflect.namedAny
615
621
            for hook in hooks:
616
622
                result = eval(hook + '(branch, rev_id)',
617
 
                              {'branch':self.branch,
618
 
                               'breezy':breezy,
619
 
                               'rev_id':self.rev_id})
 
623
                              {'branch': self.branch,
 
624
                               'breezy': breezy,
 
625
                               'rev_id': self.rev_id})
620
626
        # process new style post commit hooks
621
627
        self._process_hooks("post_commit", old_revno, new_revno)
622
628
 
642
648
        if hook_name == "pre_commit":
643
649
            future_tree = self.builder.revision_tree()
644
650
            tree_delta = future_tree.changes_from(self.basis_tree,
645
 
                                             include_root=True)
 
651
                                                  include_root=True)
646
652
 
647
653
        for hook in Branch.hooks[hook_name]:
648
654
            # show the running hook in the progress bar. As hooks may
670
676
        mutter("Selecting files for commit with filter %r", specific_files)
671
677
 
672
678
        self._check_strict()
673
 
        iter_changes = self.work_tree.iter_changes(self.basis_tree,
674
 
            specific_files=specific_files)
 
679
        iter_changes = self.work_tree.iter_changes(
 
680
            self.basis_tree, specific_files=specific_files)
675
681
        if self.exclude:
676
682
            iter_changes = filter_excluded(iter_changes, self.exclude)
677
683
        iter_changes = self._filter_iter_changes(iter_changes)
678
 
        for file_id, path, fs_hash in self.builder.record_iter_changes(
679
 
            self.work_tree, self.basis_revid, iter_changes):
680
 
            self.work_tree._observed_sha1(file_id, path, fs_hash)
 
684
        for path, fs_hash in self.builder.record_iter_changes(
 
685
                self.work_tree, self.basis_revid, iter_changes):
 
686
            self.work_tree._observed_sha1(path, fs_hash)
681
687
 
682
688
    def _filter_iter_changes(self, iter_changes):
683
689
        """Process iter_changes.
684
690
 
685
 
        This method reports on the changes in iter_changes to the user, and 
 
691
        This method reports on the changes in iter_changes to the user, and
686
692
        converts 'missing' entries in the iter_changes iterator to 'deleted'
687
693
        entries. 'missing' entries have their
688
694
 
706
712
                deleted_paths.append(change[1][1])
707
713
                # Reset the new path (None) and new versioned flag (False)
708
714
                change = (change[0], (change[1][0], None), change[2],
709
 
                    (change[3][0], False)) + change[4:]
 
715
                          (change[3][0], False)) + change[4:]
710
716
                new_path = change[1][1]
711
717
                versioned = False
712
718
            elif kind == 'tree-reference':
713
719
                if self.recursive == 'down':
714
 
                    self._commit_nested_tree(change[0], change[1][1])
 
720
                    self._commit_nested_tree(change[1][1])
715
721
            if change[3][0] or change[3][1]:
716
722
                yield change
717
723
                if report_changes:
720
726
                    elif old_path is None:
721
727
                        reporter.snapshot_change(gettext('added'), new_path)
722
728
                    elif old_path != new_path:
723
 
                        reporter.renamed(gettext('renamed'), old_path, new_path)
 
729
                        reporter.renamed(gettext('renamed'),
 
730
                                         old_path, new_path)
724
731
                    else:
725
 
                        if (new_path or 
726
 
                            self.work_tree.branch.repository._format.rich_root_data):
 
732
                        if (new_path
 
733
                                or self.work_tree.branch.repository._format.rich_root_data):
727
734
                            # Don't report on changes to '' in non rich root
728
735
                            # repositories.
729
 
                            reporter.snapshot_change(gettext('modified'), new_path)
 
736
                            reporter.snapshot_change(
 
737
                                gettext('modified'), new_path)
730
738
            self._next_progress_entry()
731
739
        # Unversion files that were found to be deleted
732
740
        self.deleted_paths = deleted_paths
740
748
            for unknown in self.work_tree.unknowns():
741
749
                raise StrictCommitFailed()
742
750
 
743
 
    def _commit_nested_tree(self, file_id, path):
 
751
    def _commit_nested_tree(self, path):
744
752
        "Commit a nested tree."
745
 
        sub_tree = self.work_tree.get_nested_tree(path, file_id)
 
753
        sub_tree = self.work_tree.get_nested_tree(path)
746
754
        # FIXME: be more comprehensive here:
747
755
        # this works when both trees are in --trees repository,
748
756
        # but when both are bound to a different repository,
750
758
        # finally implement the explicit-caches approach design
751
759
        # a while back - RBC 20070306.
752
760
        if sub_tree.branch.repository.has_same_location(
753
 
            self.work_tree.branch.repository):
 
761
                self.work_tree.branch.repository):
754
762
            sub_tree.branch.repository = \
755
763
                self.work_tree.branch.repository
756
764
        try:
757
765
            return sub_tree.commit(message=None, revprops=self.revprops,
758
 
                recursive=self.recursive,
759
 
                message_callback=self.message_callback,
760
 
                timestamp=self.timestamp, timezone=self.timezone,
761
 
                committer=self.committer,
762
 
                allow_pointless=self.allow_pointless,
763
 
                strict=self.strict, verbose=self.verbose,
764
 
                local=self.local, reporter=self.reporter)
 
766
                                   recursive=self.recursive,
 
767
                                   message_callback=self.message_callback,
 
768
                                   timestamp=self.timestamp,
 
769
                                   timezone=self.timezone,
 
770
                                   committer=self.committer,
 
771
                                   allow_pointless=self.allow_pointless,
 
772
                                   strict=self.strict, verbose=self.verbose,
 
773
                                   local=self.local, reporter=self.reporter)
765
774
        except PointlessCommit:
766
 
            return self.work_tree.get_reference_revision(path, file_id)
 
775
            return self.work_tree.get_reference_revision(path)
767
776
 
768
777
    def _set_progress_stage(self, name, counter=False):
769
778
        """Set the progress stage and emit an update to the progress bar."""
783
792
    def _emit_progress(self):
784
793
        if self.pb_entries_count is not None:
785
794
            text = gettext("{0} [{1}] - Stage").format(self.pb_stage_name,
786
 
                self.pb_entries_count)
 
795
                                                       self.pb_entries_count)
787
796
        else:
788
797
            text = gettext("%s - Stage") % (self.pb_stage_name, )
789
798
        self.pb.update(text, self.pb_stage_count, self.pb_stage_total)