10
name = os.path.basename(args.pop(0))
12
if name not in ['shelve', 'unshelve']:
13
raise Exception("Unknown command name '%s'" % name)
16
if args[0] == '--bzr-usage':
19
elif args[0] == '--bzr-help':
20
print 'Shelve a patch, you can get it back later with unshelve.'
23
raise Exception("Don't understand args %s" % args)
31
root = run_bzr('root')[0].strip()
32
shelf = os.path.join(root, '.bzr-shelf')
34
if not os.path.exists(shelf):
35
raise Exception("No shelf found in '%s'" % shelf)
37
patch = open(shelf, 'r').read()
39
print >>sys.stderr, "Reapplying shelved patches"
40
pipe = os.popen('patch -d %s -s -p0' % root, 'w')
44
if pipe.close() is not None:
45
raise Exception("Failed running patch!")
48
print 'Diff status is now:'
49
os.system('bzr diff | diffstat')
9
from bzrlib.commands import Command
10
from bzrlib.branch import Branch
11
from bzrlib import DEFAULT_IGNORE
12
from hunk_selector import HunkSelector
13
from diffstat import DiffStat
15
DEFAULT_IGNORE.append('./.bzr-shelf*')
53
17
class QuitException(Exception):
57
patches = parse_patches(run_bzr('diff'))
59
patches = HunkSelector(patches).select()
64
print >>sys.stderr, 'Nothing to shelve'
67
root = run_bzr('root')[0].strip()
68
shelf = os.path.join(root, '.bzr-shelf')
69
print >>sys.stderr, "Saving shelved patches to", shelf
70
shelf = open(shelf, 'a')
73
shelf.write(str(patch))
76
os.fsync(shelf.fileno())
79
print >>sys.stderr, "Reverting shelved patches"
80
pipe = os.popen('patch -d %s -sR -p0' % root, 'w')
82
pipe.write(str(patch))
85
if pipe.close() is not None:
86
raise Exception("Failed running patch!")
88
print 'Diff status is now:'
89
os.system('bzr diff | diffstat')
96
pipe = os.popen('bzr %s' % string.join(args, ' '), 'r')
97
lines = pipe.readlines()
98
if pipe.close() is not None:
99
raise Exception("Failed running bzr")
105
def __init__(self, char, action, help, default=False):
108
self.default = default
112
Option('n', 'shelve', 'shelve this change for the moment.',
114
Option('y', 'keep', 'keep this change in your tree.'),
115
Option('d', 'done', 'done, skip to the end.'),
116
Option('i', 'invert', 'invert the current selection of all hunks.'),
117
Option('s', 'status', 'show status of hunks.'),
118
Option('q', 'quit', 'quit')
122
Option('y', 'continue', 'proceed to shelve selected changes.',
124
Option('r', 'restart', 'restart the hunk selection loop.'),
125
Option('s', 'status', 'show status of hunks.'),
126
Option('i', 'invert', 'invert the current selection of all hunks.'),
127
Option('q', 'quit', 'quit')
130
def __init__(self, patches):
131
self.patches = patches
133
for patch in patches:
134
for hunk in patch.hunks:
135
# everything's shelved by default
137
self.total_hunks += 1
139
def __get_option(self, char):
140
for opt in self.standard_options:
143
raise Exception('Option "%s" not found!' % char)
145
def __select_loop(self):
147
for patch in self.patches:
21
def __init__(self, location):
22
self.branch = Branch.open_containing(location)[0]
24
def shelf_suffix(self, index):
150
while i < len(patch.hunks):
151
hunk = patch.hunks[i]
153
print patch.get_header(), hunk
157
prompt = 'Keep this change? (%d of %d)' \
158
% (j, self.total_hunks)
161
self.__get_option('n').default = True
162
self.__get_option('y').default = False
164
self.__get_option('n').default = False
165
self.__get_option('y').default = True
167
action = self.__ask_user(prompt, self.standard_options)
170
hunk.selected = False
171
elif action == 'shelve':
173
elif action == 'done':
175
elif action == 'invert':
176
self.__invert_selection()
179
elif action == 'status':
182
elif action == 'quit':
189
if self.total_hunks == 0:
194
if not self.__select_loop():
199
prompt = "Shelve these changes, or restart?"
200
action = self.__ask_user(prompt, self.end_options)
202
if action == 'continue':
205
elif action == 'quit':
207
elif action == 'status':
209
elif action == 'invert':
210
self.__invert_selection()
211
elif action == 'restart':
215
for patch in self.patches:
217
for hunk in patch.hunks:
223
for patch in self.patches:
230
def __invert_selection(self):
231
for patch in self.patches:
232
for hunk in patch.hunks:
233
if hunk.__dict__.has_key('selected'):
234
hunk.selected = not hunk.selected
238
def __show_status(self):
240
for patch in self.patches:
241
print ' %s' % patch.oldname
244
for hunk in patch.hunks:
250
print ' %d hunks to be shelved' % shelve
251
print ' %d hunks to be kept' % keep
255
fd = sys.stdin.fileno()
256
settings = termios.tcgetattr(fd)
259
ch = sys.stdin.read(1)
261
termios.tcsetattr(fd, termios.TCSADRAIN, settings)
264
def __ask_user(self, prompt, options):
266
sys.stdout.write(prompt)
267
sys.stdout.write(' [')
271
sys.stdout.write(opt.char)
272
sys.stdout.write('?] (%s): ' % default.char)
274
response = self.__getchar()
276
# default, which we see as newline, is 'n'
277
if response in ['\n', '\r', '\r\n']:
278
response = default.char
280
print response # because echo is off
283
if opt.char == response:
287
print ' %s - %s' % (opt.char, opt.help)
34
yield self.shelf_suffix(i)
37
stem = os.path.join(self.branch.base, '.bzr-shelf')
38
for end in name_sequence():
40
if not os.path.exists(name):
44
stem = os.path.join(self.branch.base, '.bzr-shelf')
45
shelves = glob.glob(stem)
46
shelves.extend(glob.glob(stem + '-*'))
47
def shelf_index(name):
50
return int(name[len(stem)+1:])
51
shelvenums = [shelf_index(f) for f in shelves]
54
if len(shelvenums) == 0:
56
return stem + self.shelf_suffix(shelvenums[-1])
58
def get_shelf_message(self, shelf):
60
if not shelf.startswith(prefix):
62
return shelf[len(prefix):shelf.index('\n')]
65
shelf = self.last_shelf()
68
raise Exception("No shelf found in '%s'" % self.branch.base)
70
patch = open(shelf, 'r').read()
72
print >>sys.stderr, "Reapplying shelved patches",
73
message = self.get_shelf_message(patch)
74
if message is not None:
75
print >>sys.stderr, ' "%s"' % message
77
print >>sys.stderr, ""
78
pipe = os.popen('patch -d %s -s -p0' % self.branch.base, 'w')
82
if pipe.close() is not None:
83
raise Exception("Failed running patch!")
87
diff_stat = DiffStat(self.get_patches(None, None))
88
print 'Diff status is now:\n', diff_stat
92
def get_patches(self, revision, file_list):
93
from StringIO import StringIO
94
from bzrlib.diff import show_diff
96
show_diff(self.branch, revision, specific_files=file_list, output=out)
98
return out.readlines()
100
def shelve(self, all_hunks=False, message=None, revision=None,
102
patches = parse_patches(self.get_patches(revision, file_list))
106
patches = HunkSelector(patches).select()
107
except QuitException:
110
if len(patches) == 0:
111
print >>sys.stderr, 'Nothing to shelve'
114
shelf = self.next_shelf()
115
print >>sys.stderr, "Saving shelved patches to", shelf
116
shelf = open(shelf, 'a')
117
if message is not None:
118
assert '\n' not in message
119
shelf.write("# shelf: %s\n" % message)
120
for patch in patches:
121
shelf.write(str(patch))
124
os.fsync(shelf.fileno())
127
print >>sys.stderr, "Reverting shelved patches"
128
pipe = os.popen('patch -d %s -sR -p0' % self.branch.base, 'w')
129
for patch in patches:
130
pipe.write(str(patch))
133
if pipe.close() is not None:
134
raise Exception("Failed running patch!")
136
diff_stat = DiffStat(self.get_patches(None, None))
137
print 'Diff status is now:\n', diff_stat