bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 0.3.1
by John Arbash Meinel Creating a plugin for uncommitting the last revision. | 1 | #!/usr/bin/env python
 | 
| 2 | """\
 | |
| 3 | Remove the last revision from the history of the current branch.
 | |
| 4 | """
 | |
| 5 | ||
| 6 | import os | |
| 7 | import bzrlib | |
| 1558.9.1
by Aaron Bentley Fix uncommit to handle bound branches, and to do locking | 8 | from bzrlib.errors import BoundBranchOutOfDate | 
| 0.3.1
by John Arbash Meinel Creating a plugin for uncommitting the last revision. | 9 | |
| 10 | def test_remove(filename): | |
| 11 | if os.path.exists(filename): | |
| 12 | os.remove(filename) | |
| 13 | else: | |
| 14 | print '* file does not exist: %r' % filename | |
| 15 | ||
| 16 | ||
| 1558.1.12
by Aaron Bentley Got uncommit working properly with checkouts | 17 | def uncommit(branch, dry_run=False, verbose=False, revno=None, tree=None): | 
| 0.3.1
by John Arbash Meinel Creating a plugin for uncommitting the last revision. | 18 | """Remove the last revision from the supplied branch. | 
| 19 | ||
| 1185.62.10
by John Arbash Meinel Removed --all from bzr uncommit, it was broken anyway. | 20 |     :param dry_run: Don't actually change anything
 | 
| 21 |     :param verbose: Print each step as you do it
 | |
| 22 |     :param revno: Remove back to this revision
 | |
| 0.3.1
by John Arbash Meinel Creating a plugin for uncommitting the last revision. | 23 |     """
 | 
| 24 | from bzrlib.atomicfile import AtomicFile | |
| 1558.9.1
by Aaron Bentley Fix uncommit to handle bound branches, and to do locking | 25 | unlockable = [] | 
| 26 | try: | |
| 1558.1.12
by Aaron Bentley Got uncommit working properly with checkouts | 27 | if tree is not None: | 
| 1558.9.1
by Aaron Bentley Fix uncommit to handle bound branches, and to do locking | 28 | tree.lock_write() | 
| 29 | unlockable.append(tree) | |
| 30 | ||
| 31 | branch.lock_write() | |
| 32 | unlockable.append(branch) | |
| 33 | ||
| 34 | master = branch.get_master_branch() | |
| 35 | if master is not None: | |
| 36 | master.lock_write() | |
| 37 | unlockable.append(master) | |
| 38 | rh = branch.revision_history() | |
| 39 | if master is not None and rh[-1] != master.last_revision(): | |
| 40 | raise BoundBranchOutOfDate(branch, master) | |
| 41 | if revno is None: | |
| 42 | revno = len(rh) | |
| 43 | ||
| 44 | files_to_remove = [] | |
| 45 | for r in range(revno-1, len(rh)): | |
| 46 | rev_id = rh.pop() | |
| 47 | if verbose: | |
| 48 | print 'Removing revno %d: %s' % (len(rh)+1, rev_id) | |
| 49 | ||
| 50 | ||
| 51 |         # Committing before we start removing files, because
 | |
| 52 |         # once we have removed at least one, all the rest are invalid.
 | |
| 53 | if not dry_run: | |
| 54 | if master is not None: | |
| 55 | master.set_revision_history(rh) | |
| 56 | branch.set_revision_history(rh) | |
| 57 | if tree is not None: | |
| 58 | tree.set_last_revision(branch.last_revision()) | |
| 59 | finally: | |
| 60 | for item in reversed(unlockable): | |
| 61 | item.unlock() |