~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commit.py

'bzr commit' shows a progress bar. This is useful for commits over sftp
where commit can take an appreciable time. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
256
256
            self.reporter = reporter
257
257
 
258
258
        self.work_tree.lock_write()
 
259
        self.pb = bzrlib.ui.ui_factory.nested_progress_bar()
259
260
        try:
 
261
            # Cannot commit with conflicts present.
 
262
            if len(self.work_tree.conflicts())>0:
 
263
                raise ConflictsInTree
 
264
 
260
265
            # setup the bound branch variables as needed.
261
266
            self._check_bound_branch()
262
267
 
304
309
            self.work_inv = self.work_tree.inventory
305
310
            self.basis_tree = self.work_tree.basis_tree()
306
311
            self.basis_inv = self.basis_tree.inventory
 
312
            # one to finish, one for rev and inventory, and one for each
 
313
            # inventory entry, and the same for the new inventory.
 
314
            # note that this estimate is too long when we do a partial tree
 
315
            # commit which excludes some new files from being considered.
 
316
            # The estimate is corrected when we populate the new inv.
 
317
            self.pb_total = len(self.basis_inv) + len(self.work_inv) + 3 - 1
 
318
            self.pb_count = 0
307
319
 
308
320
            self._gather_parents()
309
321
            if len(self.parents) > 1 and self.specific_files:
321
333
                    or self.new_inv != self.basis_inv):
322
334
                raise PointlessCommit()
323
335
 
324
 
            if len(self.work_tree.conflicts())>0:
325
 
                raise ConflictsInTree
326
 
 
 
336
            self._emit_progress_update()
327
337
            self.inv_sha1 = self.branch.repository.add_inventory(
328
338
                self.rev_id,
329
339
                self.new_inv,
330
340
                self.present_parents
331
341
                )
 
342
            self._emit_progress_update()
332
343
            self._make_revision()
333
344
            # revision data is in the local branch now.
334
345
            
358
369
                                  {'branch':self.branch,
359
370
                                   'bzrlib':bzrlib,
360
371
                                   'rev_id':self.rev_id})
 
372
            self._emit_progress_update()
361
373
        finally:
362
 
            self._cleanup_bound_branch()
363
 
            self.work_tree.unlock()
 
374
            self._cleanup()
364
375
 
365
376
    def _check_bound_branch(self):
366
377
        """Check to see if the local branch is bound.
412
423
####                self.master_branch.repository.fetch(self.bound_branch.repository,
413
424
####                                                    revision_id=revision_id)
414
425
 
 
426
    def _cleanup(self):
 
427
        """Cleanup any open locks, progress bars etc."""
 
428
        cleanups = [self._cleanup_bound_branch,
 
429
                    self.work_tree.unlock,
 
430
                    self.pb.finished]
 
431
        found_exception = None
 
432
        for cleanup in cleanups:
 
433
            try:
 
434
                cleanup()
 
435
            # we want every cleanup to run no matter what.
 
436
            # so we have a catchall here, but we will raise the
 
437
            # last encountered exception up the stack: and
 
438
            # typically this will be useful enough.
 
439
            except Exception, e:
 
440
                found_exception = e
 
441
        if found_exception is not None: 
 
442
            # dont do a plan raise, because the last exception may have been
 
443
            # trashed, e is our sure-to-work exception even though it loses the
 
444
            # full traceback. XXX: RBC 20060421 perhaps we could check the
 
445
            # exc_info and if its the same one do a plain raise otherwise 
 
446
            # 'raise e' as we do now.
 
447
            raise e
 
448
 
415
449
    def _cleanup_bound_branch(self):
416
450
        """Executed at the end of a try/finally to cleanup a bound branch.
417
451
 
515
549
        # XXX: Need to think more here about when the user has
516
550
        # made a specific decision on a particular value -- c.f.
517
551
        # mark-merge.  
 
552
 
 
553
        # iter_entries does not visit the ROOT_ID node so we need to call
 
554
        # self._emit_progress_update once by hand.
 
555
        self._emit_progress_update()
518
556
        for path, ie in self.new_inv.iter_entries():
 
557
            self._emit_progress_update()
519
558
            previous_entries = ie.find_previous_heads(
520
559
                self.parent_invs,
521
560
                self.weave_store,
552
591
        """
553
592
        mutter("Selecting files for commit with filter %s", self.specific_files)
554
593
        self.new_inv = Inventory(revision_id=self.rev_id)
 
594
        # iter_entries does not visit the ROOT_ID node so we need to call
 
595
        # self._emit_progress_update once by hand.
 
596
        self._emit_progress_update()
555
597
        for path, new_ie in self.work_inv.iter_entries():
 
598
            self._emit_progress_update()
556
599
            file_id = new_ie.file_id
557
600
            mutter('check %s {%s}', path, new_ie.file_id)
558
601
            if self.specific_files:
578
621
            mutter('%s selected for commit', path)
579
622
            self._select_entry(new_ie)
580
623
 
 
624
    def _emit_progress_update(self):
 
625
        """Emit an update to the progress bar."""
 
626
        self.pb.update("Committing", self.pb_count, self.pb_total)
 
627
        self.pb_count += 1
 
628
 
581
629
    def _select_entry(self, new_ie):
582
630
        """Make new_ie be considered for committing."""
583
631
        ie = new_ie.copy()
589
637
        """Carry the file unchanged from the basis revision."""
590
638
        if self.basis_inv.has_id(file_id):
591
639
            self.new_inv.add(self.basis_inv[file_id].copy())
 
640
        else:
 
641
            # this entry is new and not being committed
 
642
            self.pb_total -= 1
592
643
 
593
644
    def _report_deletes(self):
594
645
        for path, ie in self.basis_inv.iter_entries():