0.1.1
by Michael Ellerman
Initial import |
1 |
#!/usr/bin/python
|
2 |
||
0.1.6
by Michael Ellerman
Move selection code into HunkSelector class |
3 |
from patches import parse_patches |
0.1.1
by Michael Ellerman
Initial import |
4 |
import os |
5 |
import sys |
|
6 |
import string |
|
0.1.23
by Michael Ellerman
Incorporate Aaron's changes from bzrtools. |
7 |
import glob |
8 |
import bzrlib |
|
9 |
from bzrlib.commands import Command |
|
10 |
from bzrlib.branch import Branch |
|
11 |
from bzrlib import DEFAULT_IGNORE |
|
12 |
from hunk_selector import HunkSelector |
|
0.1.35
by Michael Ellerman
Use DiffStat rather than calling out to /bin/diffstat |
13 |
from diffstat import DiffStat |
0.1.23
by Michael Ellerman
Incorporate Aaron's changes from bzrtools. |
14 |
|
15 |
DEFAULT_IGNORE.append('./.bzr-shelf*') |
|
0.1.1
by Michael Ellerman
Initial import |
16 |
|
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
17 |
class QuitException(Exception): |
18 |
pass
|
|
19 |
||
20 |
class Shelf(object): |
|
0.1.38
by Michael Ellerman
Shelf() takes a location which specifies where to open the branch. |
21 |
def __init__(self, location): |
22 |
self.branch = Branch.open_containing(location)[0] |
|
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
23 |
|
24 |
def shelf_suffix(self, index): |
|
25 |
if index == 0: |
|
26 |
return "" |
|
27 |
else: |
|
28 |
return "-%d" % index |
|
29 |
||
30 |
def next_shelf(self): |
|
31 |
def name_sequence(): |
|
32 |
i = 0 |
|
33 |
while True: |
|
34 |
yield self.shelf_suffix(i) |
|
35 |
i = i + 1 |
|
36 |
||
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
37 |
stem = os.path.join(self.branch.base, '.bzr-shelf') |
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
38 |
for end in name_sequence(): |
39 |
name = stem + end |
|
40 |
if not os.path.exists(name): |
|
41 |
return name |
|
42 |
||
43 |
def last_shelf(self): |
|
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
44 |
stem = os.path.join(self.branch.base, '.bzr-shelf') |
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
45 |
shelves = glob.glob(stem) |
46 |
shelves.extend(glob.glob(stem + '-*')) |
|
47 |
def shelf_index(name): |
|
48 |
if name == stem: |
|
49 |
return 0 |
|
50 |
return int(name[len(stem)+1:]) |
|
51 |
shelvenums = [shelf_index(f) for f in shelves] |
|
52 |
shelvenums.sort() |
|
53 |
||
54 |
if len(shelvenums) == 0: |
|
55 |
return None |
|
56 |
return stem + self.shelf_suffix(shelvenums[-1]) |
|
57 |
||
58 |
def get_shelf_message(self, shelf): |
|
59 |
prefix = "# shelf: " |
|
60 |
if not shelf.startswith(prefix): |
|
61 |
return None |
|
62 |
return shelf[len(prefix):shelf.index('\n')] |
|
63 |
||
64 |
def unshelve(self): |
|
65 |
shelf = self.last_shelf() |
|
66 |
||
67 |
if shelf is None: |
|
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
68 |
raise Exception("No shelf found in '%s'" % self.branch.base) |
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
69 |
|
70 |
patch = open(shelf, 'r').read() |
|
71 |
||
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 |
|
76 |
else: |
|
77 |
print >>sys.stderr, "" |
|
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
78 |
pipe = os.popen('patch -d %s -s -p0' % self.branch.base, 'w') |
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
79 |
pipe.write(patch) |
80 |
pipe.flush() |
|
81 |
||
82 |
if pipe.close() is not None: |
|
83 |
raise Exception("Failed running patch!") |
|
84 |
||
85 |
os.remove(shelf) |
|
0.1.35
by Michael Ellerman
Use DiffStat rather than calling out to /bin/diffstat |
86 |
|
87 |
diff_stat = DiffStat(self.get_patches(None, None)) |
|
88 |
print 'Diff status is now:\n', diff_stat |
|
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
89 |
|
90 |
return True |
|
91 |
||
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
92 |
def get_patches(self, revision, file_list): |
93 |
from StringIO import StringIO |
|
94 |
from bzrlib.diff import show_diff |
|
95 |
out = StringIO() |
|
96 |
show_diff(self.branch, revision, specific_files=file_list, output=out) |
|
97 |
out.seek(0) |
|
98 |
return out.readlines() |
|
99 |
||
0.1.28
by Michael Ellerman
Implement "bzr shelve --all". |
100 |
def shelve(self, all_hunks=False, message=None, revision=None, |
101 |
file_list=None): |
|
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
102 |
patches = parse_patches(self.get_patches(revision, file_list)) |
103 |
||
0.1.28
by Michael Ellerman
Implement "bzr shelve --all". |
104 |
if not all_hunks: |
105 |
try: |
|
106 |
patches = HunkSelector(patches).select() |
|
107 |
except QuitException: |
|
108 |
return False |
|
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
109 |
|
110 |
if len(patches) == 0: |
|
111 |
print >>sys.stderr, 'Nothing to shelve' |
|
112 |
return True |
|
113 |
||
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)) |
|
122 |
||
123 |
shelf.flush() |
|
124 |
os.fsync(shelf.fileno()) |
|
125 |
shelf.close() |
|
126 |
||
127 |
print >>sys.stderr, "Reverting shelved patches" |
|
0.1.31
by Michael Ellerman
- Keep our branch around, and use it directly instead of bzr_root. |
128 |
pipe = os.popen('patch -d %s -sR -p0' % self.branch.base, 'w') |
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
129 |
for patch in patches: |
130 |
pipe.write(str(patch)) |
|
131 |
pipe.flush() |
|
132 |
||
133 |
if pipe.close() is not None: |
|
134 |
raise Exception("Failed running patch!") |
|
135 |
||
0.1.35
by Michael Ellerman
Use DiffStat rather than calling out to /bin/diffstat |
136 |
diff_stat = DiffStat(self.get_patches(None, None)) |
137 |
print 'Diff status is now:\n', diff_stat |
|
0.1.27
by Michael Ellerman
Move all shelf functions into a class. Only logic change is we save the |
138 |
|
139 |
return True |
|
140 |