3
from patches import parse_patches
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
14
from subprocess import Popen, PIPE
16
DEFAULT_IGNORE.append('./.bzr-shelf*')
18
class QuitException(Exception):
22
def __init__(self, location):
23
self.branch = Branch.open_containing(location)[0]
25
def shelf_suffix(self, index):
35
yield self.shelf_suffix(i)
38
stem = os.path.join(self.branch.base, '.bzr-shelf')
39
for end in name_sequence():
41
if not os.path.exists(name):
45
stem = os.path.join(self.branch.base, '.bzr-shelf')
46
shelves = glob.glob(stem)
47
shelves.extend(glob.glob(stem + '-*'))
48
def shelf_index(name):
51
return int(name[len(stem)+1:])
52
shelvenums = [shelf_index(f) for f in shelves]
55
if len(shelvenums) == 0:
57
return stem + self.shelf_suffix(shelvenums[-1])
59
def get_shelf_message(self, shelf):
61
if not shelf.startswith(prefix):
63
return shelf[len(prefix):shelf.index('\n')]
66
shelf = self.last_shelf()
69
raise Exception("No shelf found in '%s'" % self.branch.base)
71
patch = open(shelf, 'r').read()
73
print >>sys.stderr, "Reapplying shelved patches",
74
message = self.get_shelf_message(patch)
75
if message is not None:
76
print >>sys.stderr, ' "%s"' % message
78
print >>sys.stderr, ""
79
run_patch(self.branch.base, (patch,))
82
diff_stat = DiffStat(self.get_patches(None, None))
83
print 'Diff status is now:\n', diff_stat
87
def get_patches(self, revision, file_list):
88
from StringIO import StringIO
89
from bzrlib.diff import show_diff
91
show_diff(self.branch, revision, specific_files=file_list, output=out)
93
return out.readlines()
95
def shelve(self, all_hunks=False, message=None, revision=None,
97
patches = parse_patches(self.get_patches(revision, file_list))
101
patches = HunkSelector(patches).select()
102
except QuitException:
105
if len(patches) == 0:
106
print >>sys.stderr, 'Nothing to shelve'
109
shelf = self.next_shelf()
110
print >>sys.stderr, "Saving shelved patches to", shelf
111
shelf = open(shelf, 'a')
112
if message is not None:
113
assert '\n' not in message
114
shelf.write("# shelf: %s\n" % message)
115
for patch in patches:
116
shelf.write(str(patch))
119
os.fsync(shelf.fileno())
122
print >>sys.stderr, "Reverting shelved patches"
123
run_patch(self.branch.base, patches, reverse=True)
125
diff_stat = DiffStat(self.get_patches(None, None))
126
print 'Diff status is now:\n', diff_stat
130
def run_patch(branch_base, patches, reverse=False):
131
args = ['patch', '-d', branch_base, '-s', '-p0', '-f']
134
process = Popen(args, stdin=PIPE)
135
for patch in patches:
136
process.stdin.write(str(patch))
137
process.stdin.close()
138
result = process.wait()
139
if result not in (0, 1):
140
raise Exception("Error applying patches")