~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shelf.py

  • Committer: Aaron Bentley
  • Date: 2005-06-15 15:25:13 UTC
  • Revision ID: abentley@panoramicfeedback.com-20050615152512-e2afe3f794604a12
Added Michael Ellerman's shelf/unshelf

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import patches
 
4
import os
 
5
import sys
 
6
import string
 
7
from bzrlib.commands import Command
 
8
 
 
9
def parse_args(args):
 
10
    if len(args) == 2 and args[1] == '--bzr-usage':
 
11
        print '\n'
 
12
        return True
 
13
    elif len(args) == 2 and args[1] == '--bzr-help':
 
14
        print 'Shelve a patch, you can get it back later with unshelve.'
 
15
        return True
 
16
    elif len(args) == 1:
 
17
        pass
 
18
    else:
 
19
        raise Exception("Don't understand args %s" % args)
 
20
 
 
21
    return False
 
22
 
 
23
def unshelve():
 
24
    root = run_bzr('root')[0].strip()
 
25
    shelf = os.path.join(root, '.bzr-shelf')
 
26
 
 
27
    if not os.path.exists(shelf):
 
28
        raise Exception("No shelf found in '%s'" % shelf)
 
29
 
 
30
    patch = open(shelf, 'r').read()
 
31
 
 
32
    print >>sys.stderr, "Reapplying shelved patches"
 
33
    pipe = os.popen('patch -d %s -s -p0' % root, 'w')
 
34
    pipe.write(patch)
 
35
    pipe.flush()
 
36
 
 
37
    if pipe.close() is not None:
 
38
        raise Exception("Failed running patch!")
 
39
 
 
40
    os.remove(shelf)
 
41
    print 'Diff status is now:'
 
42
    os.system('bzr diff | diffstat')
 
43
 
 
44
    return True
 
45
 
 
46
def shelve():
 
47
    diff_lines = run_bzr('diff')
 
48
    patch_list = patches.parse_patches(diff_lines.__iter__())
 
49
    to_shelve = prompt_user(patch_list)
 
50
 
 
51
    if len(to_shelve) == 0:
 
52
        print >>sys.stderr, 'Nothing to shelve'
 
53
        return True
 
54
 
 
55
    root = run_bzr('root')[0].strip()
 
56
    shelf = os.path.join(root, '.bzr-shelf')
 
57
    print >>sys.stderr, "Saving shelved patches to", shelf
 
58
    shelf = open(shelf, 'a')
 
59
 
 
60
    for patch in to_shelve:
 
61
        shelf.write(str(patch))
 
62
 
 
63
    shelf.flush()
 
64
    os.fsync(shelf.fileno())
 
65
    shelf.close()
 
66
 
 
67
    print >>sys.stderr, "Reverting shelved patches"
 
68
    pipe = os.popen('patch -d %s -sR -p0' % root, 'w')
 
69
    for patch in to_shelve:
 
70
       pipe.write(str(patch))
 
71
    pipe.flush()
 
72
 
 
73
    if pipe.close() is not None:
 
74
        raise Exception("Failed running patch!")
 
75
 
 
76
    print 'Diff status is now:'
 
77
    os.system('bzr diff | diffstat')
 
78
 
 
79
    return True
 
80
 
 
81
def run_bzr(args):
 
82
    if type(args) is str:
 
83
        args = [ args ]
 
84
    pipe = os.popen('bzr %s' % string.join(args, ' '), 'r')
 
85
    lines = pipe.readlines()
 
86
    if pipe.close() is not None:
 
87
        raise Exception("Failed running bzr")
 
88
    return lines
 
89
 
 
90
def prompt_user(patch_list):
 
91
    total = 0
 
92
    for patch in patch_list:
 
93
        total += len(patch.hunks)
 
94
 
 
95
    out = sys.stdout
 
96
    inp = sys.stdin
 
97
 
 
98
    to_shelve = []
 
99
    i = 1
 
100
    for patch in patch_list:
 
101
        if patch.oldname != patch.newname:
 
102
            name = "%s -> %s" % (patch.oldname, patch.newname)
 
103
        else:
 
104
            name = patch.oldname
 
105
 
 
106
        hunks = patch.hunks[:]
 
107
        for hunk in hunks:
 
108
            print name
 
109
            print hunk
 
110
            while True:
 
111
                out.write('Shelve this change? (%d of %d) [yn] ' % (i, total))
 
112
                line = inp.readline().strip().lower()
 
113
                if line == 'y' or line == 'yes':
 
114
                    break
 
115
                elif line == 'n' or line == 'no':
 
116
                    patch.hunks.remove(hunk)
 
117
                    break
 
118
 
 
119
            i += 1
 
120
 
 
121
        if len(patch.hunks) > 0:
 
122
            to_shelve.append(patch)
 
123
 
 
124
    return to_shelve
 
125
 
 
126
class cmd_shelve(Command):
 
127
    """Temporarily remove some changes from the current tree.
 
128
    Use 'unshelve' to restore these changes.
 
129
    """
 
130
 
 
131
    def run(self):
 
132
        return shelve()
 
133
 
 
134
class cmd_unshelve(Command):
 
135
    """Restore previously-shelved changes to the current tree.
 
136
    See also 'shelve'.
 
137
    """
 
138
    def run(self):
 
139
        return unshelve()