3
from patches import parse_patches
5
from errors import CommandError
9
from bzrlib.commands import Command
10
from bzrlib.branch import Branch
11
from bzrlib import DEFAULT_IGNORE
6
12
from hunk_selector import ShelveHunkSelector, UnshelveHunkSelector
7
13
from diffstat import DiffStat
8
from patchsource import PatchSource, FilePatchSource
15
DEFAULT_IGNORE.append('./.bzr-shelf*')
17
class QuitException(Exception):
12
20
class Shelf(object):
13
def __init__(self, base, name='default'):
15
shelf_base = os.path.join(self.base, BASE_DIR)
16
self.shelf_dir = os.path.join(shelf_base, name)
21
def __init__(self, location, name='default'):
22
self.branch = Branch.open_containing(location)[0]
23
base = self.branch.controlfilename('x-shelf')
24
self.shelf_dir = os.path.join(base, name)
18
for dir in [shelf_base, self.shelf_dir]:
19
if not os.path.isdir(dir):
26
# FIXME surely there's an easier way to do this?
27
t = self.branch._transport
28
for dir in [base, self.shelf_dir]:
22
32
def __path(self, idx):
23
33
return os.path.join(self.shelf_dir, '%.2d' % idx)
47
57
return shelf[len(prefix):shelf.index('\n')]
49
def __show_status(self, source):
50
if source.can_live_update():
51
diff_stat = DiffStat(source.readlines())
52
print 'Diff status is now:\n', diff_stat
54
def unshelve(self, patch_source, pick_hunks=False):
59
def unshelve(self, pick_hunks=False):
55
60
shelf = self.last_shelf()
58
raise CommandError("No shelf found in '%s'" % self.base)
63
raise Exception("No shelf found in '%s'" % self.branch.base)
60
patches = FilePatchSource(shelf).readpatches()
65
patches = parse_patches(open(shelf, 'r').readlines())
62
to_unshelve, to_remain = UnshelveHunkSelector(patches).select()
68
patches = UnshelveHunkSelector(patches).select()
67
if len(to_unshelve) == 0:
68
raise CommandError('Nothing to unshelve')
73
print >>sys.stderr, 'Nothing to unshelve'
70
76
print >>sys.stderr, "Reapplying shelved patches",
71
77
message = self.get_shelf_message(open(shelf, 'r').read())
73
79
print >>sys.stderr, ' "%s"' % message
75
81
print >>sys.stderr, ""
77
pipe = os.popen('patch -d %s -s -p0' % self.base, 'w')
78
for patch in to_unshelve:
82
pipe = os.popen('patch -d %s -s -p0' % self.branch.base, 'w')
79
84
pipe.write(str(patch))
82
87
if pipe.close() is not None:
83
raise CommandError("Failed running patch!")
85
if len(to_remain) == 0:
89
for patch in to_remain:
93
self.__show_status(patch_source)
95
def shelve(self, patch_source, pick_hunks=False, message=None):
96
patches = patch_source.readpatches()
88
raise Exception("Failed running patch!")
92
diff_stat = DiffStat(self.get_patches(None, None))
93
print 'Diff status is now:\n', diff_stat
97
def get_patches(self, revision, file_list):
98
from StringIO import StringIO
99
from bzrlib.diff import show_diff
101
show_diff(self.branch, revision, specific_files=file_list, output=out)
103
return out.readlines()
105
def shelve(self, pick_hunks=False, message=None, revision=None,
107
patches = parse_patches(self.get_patches(revision, file_list))
99
to_shelve = ShelveHunkSelector(patches).select()[0]
111
patches = ShelveHunkSelector(patches).select()
112
except QuitException:
103
if len(to_shelve) == 0:
104
raise CommandError('Nothing to shelve')
115
if len(patches) == 0:
116
print >>sys.stderr, 'Nothing to shelve'
106
119
shelf = self.next_shelf()
107
120
print >>sys.stderr, "Saving shelved patches to", shelf
119
132
print >>sys.stderr, "Reverting shelved patches"
120
pipe = os.popen('patch -d %s -sR -p0' % self.base, 'w')
121
for patch in to_shelve:
133
pipe = os.popen('patch -d %s -sR -p0' % self.branch.base, 'w')
134
for patch in patches:
122
135
pipe.write(str(patch))
125
138
if pipe.close() is not None:
126
raise CommandError("Failed running patch!")
128
self.__show_status(patch_source)
139
raise Exception("Failed running patch!")
141
diff_stat = DiffStat(self.get_patches(None, None))
142
print 'Diff status is now:\n', diff_stat