~bzr-pqm/bzr/bzr.dev

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()