~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit.py

  • Committer: Patch Queue Manager
  • Date: 2011-10-14 16:54:26 UTC
  • mfrom: (6216.1.1 remove-this-file)
  • Revision ID: pqm@pqm.ubuntu.com-20111014165426-tjix4e6idryf1r2z
(jelmer) Remove an accidentally committed .THIS file. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
52
52
from bzrlib import (
53
53
    debug,
54
54
    errors,
55
 
    revision,
56
55
    trace,
57
56
    tree,
 
57
    ui,
58
58
    )
59
59
from bzrlib.branch import Branch
60
60
from bzrlib.cleanup import OperationWithCleanups
72
72
from bzrlib.inventory import Inventory, InventoryEntry, make_entry
73
73
from bzrlib import symbol_versioning
74
74
from bzrlib.urlutils import unescape_for_display
75
 
import bzrlib.ui
76
 
 
 
75
from bzrlib.i18n import gettext
77
76
 
78
77
class NullCommitReporter(object):
79
78
    """I report on progress of a commit."""
114
113
        note(format, *args)
115
114
 
116
115
    def snapshot_change(self, change, path):
117
 
        if path == '' and change in ('added', 'modified'):
 
116
        if path == '' and change in (gettext('added'), gettext('modified')):
118
117
            return
119
118
        self._note("%s %s", change, path)
120
119
 
128
127
                                   "to started.", DeprecationWarning,
129
128
                                   stacklevel=2)
130
129
            location = ''
131
 
        self._note('Committing%s', location)
 
130
        self._note(gettext('Committing%s'), location)
132
131
 
133
132
    def completed(self, revno, rev_id):
134
 
        self._note('Committed revision %d.', revno)
 
133
        self._note(gettext('Committed revision %d.'), revno)
135
134
        # self._note goes to the console too; so while we want to log the
136
135
        # rev_id, we can't trivially only log it. (See bug 526425). Long
137
136
        # term we should rearrange the reporting structure, but for now
140
139
        mutter('Committed revid %s as revno %d.', rev_id, revno)
141
140
 
142
141
    def deleted(self, path):
143
 
        self._note('deleted %s', path)
 
142
        self._note(gettext('deleted %s'), path)
144
143
 
145
144
    def missing(self, path):
146
 
        self._note('missing %s', path)
 
145
        self._note(gettext('missing %s'), path)
147
146
 
148
147
    def renamed(self, change, old_path, new_path):
149
148
        self._note('%s %s => %s', change, old_path, new_path)
229
228
               message_callback=None,
230
229
               recursive='down',
231
230
               exclude=None,
232
 
               possible_master_transports=None):
 
231
               possible_master_transports=None,
 
232
               lossy=False):
233
233
        """Commit working copy as a new revision.
234
234
 
235
235
        :param message: the commit message (it or message_callback is required)
262
262
        :param exclude: None or a list of relative paths to exclude from the
263
263
            commit. Pending changes to excluded files will be ignored by the
264
264
            commit.
 
265
        :param lossy: When committing to a foreign VCS, ignore any
 
266
            data that can not be natively represented.
265
267
        """
266
268
        operation = OperationWithCleanups(self._commit)
267
269
        self.revprops = revprops or {}
283
285
               message_callback=message_callback,
284
286
               recursive=recursive,
285
287
               exclude=exclude,
286
 
               possible_master_transports=possible_master_transports)
 
288
               possible_master_transports=possible_master_transports,
 
289
               lossy=lossy)
287
290
 
288
291
    def _commit(self, operation, message, timestamp, timezone, committer,
289
292
            specific_files, rev_id, allow_pointless, strict, verbose,
290
293
            working_tree, local, reporter, message_callback, recursive,
291
 
            exclude, possible_master_transports):
 
294
            exclude, possible_master_transports, lossy):
292
295
        mutter('preparing to commit')
293
296
 
294
297
        if working_tree is None:
326
329
                minimum_path_selection(specific_files))
327
330
        else:
328
331
            self.specific_files = None
329
 
            
 
332
 
330
333
        self.allow_pointless = allow_pointless
331
334
        self.message_callback = message_callback
332
335
        self.timestamp = timestamp
346
349
            not self.branch.repository._format.supports_tree_reference and
347
350
            (self.branch.repository._format.fast_deltas or
348
351
             len(self.parents) < 2))
349
 
        self.pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
352
        self.pb = ui.ui_factory.nested_progress_bar()
350
353
        operation.add_cleanup(self.pb.finished)
351
354
        self.basis_revid = self.work_tree.last_revision()
352
355
        self.basis_tree = self.work_tree.basis_tree()
380
383
        self.pb_stage_count = 0
381
384
        self.pb_stage_total = 5
382
385
        if self.bound_branch:
383
 
            self.pb_stage_total += 1
 
386
            # 2 extra stages: "Uploading data to master branch" and "Merging
 
387
            # tags to master branch"
 
388
            self.pb_stage_total += 2
384
389
        self.pb.show_pct = False
385
390
        self.pb.show_spinner = False
386
391
        self.pb.show_eta = False
398
403
 
399
404
        # Collect the changes
400
405
        self._set_progress_stage("Collecting changes", counter=True)
 
406
        self._lossy = lossy
401
407
        self.builder = self.branch.get_commit_builder(self.parents,
402
 
            self.config, timestamp, timezone, committer, self.revprops, rev_id)
 
408
            self.config, timestamp, timezone, committer, self.revprops,
 
409
            rev_id, lossy=lossy)
 
410
        if not self.builder.supports_record_entry_contents and self.exclude:
 
411
            self.builder.abort()
 
412
            raise errors.ExcludesUnsupported(self.branch.repository)
403
413
 
404
414
        try:
405
415
            self.builder.will_record_deletes()
432
442
        except Exception, e:
433
443
            mutter("aborting commit write group because of exception:")
434
444
            trace.log_exception_quietly()
435
 
            note("aborting commit write group: %r" % (e,))
436
445
            self.builder.abort()
437
446
            raise
438
447
 
444
453
            self._set_progress_stage("Uploading data to master branch")
445
454
            # 'commit' to the master first so a timeout here causes the
446
455
            # local branch to be out of date
447
 
            self.master_branch.import_last_revision_info(
448
 
                self.branch.repository, new_revno, self.rev_id)
 
456
            (new_revno, self.rev_id) = self.master_branch.import_last_revision_info_and_tags(
 
457
                self.branch, new_revno, self.rev_id, lossy=lossy)
 
458
            if lossy:
 
459
                self.branch.fetch(self.master_branch, self.rev_id)
449
460
 
450
461
        # and now do the commit locally.
451
462
        self.branch.set_last_revision_info(new_revno, self.rev_id)
452
463
 
 
464
        # Merge local tags to remote
 
465
        if self.bound_branch:
 
466
            self._set_progress_stage("Merging tags to master branch")
 
467
            tag_updates, tag_conflicts = self.branch.tags.merge_to(
 
468
                self.master_branch.tags)
 
469
            if tag_conflicts:
 
470
                warning_lines = ['    ' + name for name, _, _ in tag_conflicts]
 
471
                note( gettext("Conflicting tags in bound branch:\n{0}".format(
 
472
                    "\n".join(warning_lines))) )
 
473
 
453
474
        # Make the working tree be up to date with the branch. This
454
475
        # includes automatic changes scheduled to be made to the tree, such
455
476
        # as updating its basis and unversioning paths that were missing.
473
494
        # A merge with no effect on files
474
495
        if len(self.parents) > 1:
475
496
            return
476
 
        # TODO: we could simplify this by using self.builder.basis_delta.
477
 
 
478
 
        # The initial commit adds a root directory, but this in itself is not
479
 
        # a worthwhile commit.
480
 
        if (self.basis_revid == revision.NULL_REVISION and
481
 
            ((self.builder.new_inventory is not None and
482
 
             len(self.builder.new_inventory) == 1) or
483
 
            len(self.builder._basis_delta) == 1)):
484
 
            raise PointlessCommit()
485
497
        if self.builder.any_changes():
486
498
            return
487
499
        raise PointlessCommit()
683
695
                # Reset the new path (None) and new versioned flag (False)
684
696
                change = (change[0], (change[1][0], None), change[2],
685
697
                    (change[3][0], False)) + change[4:]
 
698
                new_path = change[1][1]
 
699
                versioned = False
686
700
            elif kind == 'tree-reference':
687
701
                if self.recursive == 'down':
688
702
                    self._commit_nested_tree(change[0], change[1][1])
692
706
                    if new_path is None:
693
707
                        reporter.deleted(old_path)
694
708
                    elif old_path is None:
695
 
                        reporter.snapshot_change('added', new_path)
 
709
                        reporter.snapshot_change(gettext('added'), new_path)
696
710
                    elif old_path != new_path:
697
 
                        reporter.renamed('renamed', old_path, new_path)
 
711
                        reporter.renamed(gettext('renamed'), old_path, new_path)
698
712
                    else:
699
713
                        if (new_path or 
700
714
                            self.work_tree.branch.repository._format.rich_root_data):
701
715
                            # Don't report on changes to '' in non rich root
702
716
                            # repositories.
703
 
                            reporter.snapshot_change('modified', new_path)
 
717
                            reporter.snapshot_change(gettext('modified'), new_path)
704
718
            self._next_progress_entry()
705
719
        # Unversion IDs that were found to be deleted
706
720
        self.deleted_ids = deleted_ids
712
726
        if self.specific_files or self.exclude:
713
727
            specific_files = self.specific_files or []
714
728
            for path, old_ie in self.basis_inv.iter_entries():
715
 
                if old_ie.file_id in self.builder.new_inventory:
 
729
                if self.builder.new_inventory.has_id(old_ie.file_id):
716
730
                    # already added - skip.
717
731
                    continue
718
732
                if (is_inside_any(specific_files, path)
929
943
            self.reporter.renamed(change, old_path, path)
930
944
            self._next_progress_entry()
931
945
        else:
932
 
            if change == 'unchanged':
 
946
            if change == gettext('unchanged'):
933
947
                return
934
948
            self.reporter.snapshot_change(change, path)
935
949
            self._next_progress_entry()
951
965
 
952
966
    def _emit_progress(self):
953
967
        if self.pb_entries_count is not None:
954
 
            text = "%s [%d] - Stage" % (self.pb_stage_name,
 
968
            text = gettext("{0} [{1}] - Stage").format(self.pb_stage_name,
955
969
                self.pb_entries_count)
956
970
        else:
957
 
            text = "%s - Stage" % (self.pb_stage_name, )
 
971
            text = gettext("%s - Stage") % (self.pb_stage_name, )
958
972
        self.pb.update(text, self.pb_stage_count, self.pb_stage_total)
959
973
 
960
974
    def _set_specific_file_ids(self):