chiark / gitweb /
991e64e72815757674aad8da2c5dd5d2d018c5d6
[stgit] / stgit / lib / transaction.py
1 from stgit import exception
2 from stgit.out import *
3
4 class TransactionException(exception.StgException):
5     pass
6
7 def print_current_patch(old_applied, new_applied):
8     def now_at(pn):
9         out.info('Now at patch "%s"' % pn)
10     if not old_applied and not new_applied:
11         pass
12     elif not old_applied:
13         now_at(new_applied[-1])
14     elif not new_applied:
15         out.info('No patch applied')
16     elif old_applied[-1] == new_applied[-1]:
17         pass
18     else:
19         now_at(new_applied[-1])
20
21 class StackTransaction(object):
22     def __init__(self, stack, msg):
23         self.__stack = stack
24         self.__msg = msg
25         self.__patches = {}
26         self.__applied = list(self.__stack.patchorder.applied)
27         self.__unapplied = list(self.__stack.patchorder.unapplied)
28     def __set_patches(self, val):
29         self.__patches = dict(val)
30     patches = property(lambda self: self.__patches, __set_patches)
31     def __set_applied(self, val):
32         self.__applied = list(val)
33     applied = property(lambda self: self.__applied, __set_applied)
34     def __set_unapplied(self, val):
35         self.__unapplied = list(val)
36     unapplied = property(lambda self: self.__unapplied, __set_unapplied)
37     def __check_consistency(self):
38         remaining = set(self.__applied + self.__unapplied)
39         for pn, commit in self.__patches.iteritems():
40             if commit == None:
41                 assert self.__stack.patches.exists(pn)
42             else:
43                 assert pn in remaining
44     def run(self):
45         self.__check_consistency()
46
47         # Get new head commit.
48         if self.__applied:
49             top_patch = self.__applied[-1]
50             try:
51                 new_head = self.__patches[top_patch]
52             except KeyError:
53                 new_head = self.__stack.patches.get(top_patch).commit
54         else:
55             new_head = self.__stack.base
56
57         # Set branch head.
58         if new_head == self.__stack.head:
59             pass # same commit: OK
60         elif new_head.data.tree == self.__stack.head.data.tree:
61             pass # same tree: OK
62         else:
63             # We can't handle this case yet.
64             raise TransactionException('Error: HEAD tree changed')
65         self.__stack.set_head(new_head, self.__msg)
66
67         # Write patches.
68         for pn, commit in self.__patches.iteritems():
69             if self.__stack.patches.exists(pn):
70                 p = self.__stack.patches.get(pn)
71                 if commit == None:
72                     p.delete()
73                 else:
74                     p.set_commit(commit, self.__msg)
75             else:
76                 self.__stack.patches.new(pn, commit, self.__msg)
77         print_current_patch(self.__stack.patchorder.applied, self.__applied)
78         self.__stack.patchorder.applied = self.__applied
79         self.__stack.patchorder.unapplied = self.__unapplied