76 if self.trackheads: |
76 if self.trackheads: |
77 return "%sheads" % self.name |
77 return "%sheads" % self.name |
78 else: |
78 else: |
79 return 'heads' |
79 return 'heads' |
80 |
80 |
81 STDRAFT = state('draft', _NOSHARE | _MUTABLE) |
81 ST2 = state('draft', _NOSHARE | _MUTABLE) |
82 STREADY = state('ready', _MUTABLE, next=STDRAFT) |
82 ST1 = state('ready', _MUTABLE, next=ST2) |
83 STPUBLISHED = state('published', next=STREADY) |
83 ST0 = state('published', next=ST1) |
84 |
84 |
85 STATES = (STPUBLISHED, STREADY, STDRAFT) |
85 STATES = (ST0, ST1, ST2) |
86 |
86 |
87 # util function |
87 # util function |
88 ############################# |
88 ############################# |
89 def noderange(repo, revsets): |
89 def noderange(repo, revsets): |
90 return map(repo.changelog.node, |
90 return map(repo.changelog.node, |
114 |
114 |
115 # New commands |
115 # New commands |
116 ############################# |
116 ############################# |
117 |
117 |
118 def cmdsetstate(ui, repo, statename, *changesets): |
118 def cmdsetstate(ui, repo, statename, *changesets): |
119 """turn private changesets into public ones""" |
119 """change changeset state""" |
120 #assert repo.ui.configbool('private', 'enable', False) |
|
121 for state in STATES: # few states |
120 for state in STATES: # few states |
122 if state.name == statename: |
121 if state.name == statename: |
123 break |
122 break |
124 else: |
123 else: |
125 raise util.Abort(_('unknown state: %s') % statename) |
124 raise util.Abort(_('unknown state: %s') % statename) |
152 extensions.wrapfunction(discovery, 'findcommonincoming', filterprivatein) |
151 extensions.wrapfunction(discovery, 'findcommonincoming', filterprivatein) |
153 |
152 |
154 # Write protocols |
153 # Write protocols |
155 #################### |
154 #################### |
156 def heads(repo, proto): |
155 def heads(repo, proto): |
157 h = repo._publicheads |
156 h = repo._readyheads |
158 return wireproto.encodelist(h) + "\n" |
157 return wireproto.encodelist(h) + "\n" |
159 |
158 |
160 def _reducehead(wirerepo, heads): |
159 def _reducehead(wirerepo, heads): |
161 """heads filtering is done repo side""" |
160 """heads filtering is done repo side""" |
162 return heads |
161 return heads |
172 o_cancopy =repo.cancopy |
171 o_cancopy =repo.cancopy |
173 class statefulrepo(repo.__class__): |
172 class statefulrepo(repo.__class__): |
174 |
173 |
175 def nodestate(self, node): |
174 def nodestate(self, node): |
176 rev = self.changelog.rev(node) |
175 rev = self.changelog.rev(node) |
177 for head in self._publicheads: |
176 for head in self._readyheads: |
178 revhead = self.changelog.rev(head) |
177 revhead = self.changelog.rev(head) |
179 if self.changelog.descendant(revhead, rev): |
178 if self.changelog.descendant(revhead, rev): |
180 return STATES[2] |
179 return STATES[2] |
181 for head in self._frozenheads: |
180 for head in self._publishedheads: |
182 revhead = self.changelog.rev(head) |
181 revhead = self.changelog.rev(head) |
183 if self.changelog.descendant(revhead, rev): |
182 if self.changelog.descendant(revhead, rev): |
184 return STATES[1] |
183 return STATES[1] |
185 return STATES[0] |
184 return STATES[0] |
186 |
185 |
|
186 |
187 @property |
187 @property |
188 def _publicheads(self): |
188 def _readyheads(self): |
189 if self.ui.configbool('states', 'private', False): |
189 if self.ui.configbool('states', ST1.next.name, False): |
190 return self._statesheads[STREADY] |
190 return self._statesheads[ST1] |
191 return self.heads() |
191 return self.heads() |
192 |
192 |
193 @property |
193 @property |
194 def _frozenheads(self): |
194 def _publishedheads(self): |
195 if self.ui.configbool('states', 'liquid', False): |
195 if self.ui.configbool('states', ST0.next.name, False): |
196 return self._statesheads[STPUBLISHED] |
196 return self._statesheads[ST0] |
197 return self.heads() |
197 return self.heads() |
198 |
198 |
199 @util.propertycache |
199 @util.propertycache |
200 def _statesheads(self): |
200 def _statesheads(self): |
201 return self._readstatesheads() |
201 return self._readstatesheads() |
212 except IOError: |
212 except IOError: |
213 pass |
213 pass |
214 return heads |
214 return heads |
215 def _readstatesheads(self): |
215 def _readstatesheads(self): |
216 statesheads = {} |
216 statesheads = {} |
217 statesheads[STPUBLISHED] = self._readheadsfile('frozenheads') |
217 for state in STATES: |
218 statesheads[STREADY] = self._readheadsfile('publicheads') |
218 if state.trackheads: |
|
219 filename = 'states/%s-heads' % state.name |
|
220 statesheads[state] = self._readheadsfile(filename) |
219 return statesheads |
221 return statesheads |
220 |
222 |
221 def _writeheadsfile(self, filename, heads): |
223 def _writeheadsfile(self, filename, heads): |
222 f = self.opener(filename, 'w', atomictemp=True) |
224 f = self.opener(filename, 'w', atomictemp=True) |
223 try: |
225 try: |
227 finally: |
229 finally: |
228 f.close() |
230 f.close() |
229 |
231 |
230 def _writestateshead(self): |
232 def _writestateshead(self): |
231 # transaction! |
233 # transaction! |
232 self._writeheadsfile('frozenheads', self._statesheads[STPUBLISHED]) |
234 for state in STATES: |
233 self._writeheadsfile('publicheads', self._statesheads[STREADY]) |
235 if state.trackheads: |
|
236 filename = 'states/%s-heads' % state.name |
|
237 self._writeheadsfile(filename, self._statesheads[state]) |
234 |
238 |
235 def setstate(self, state, nodes): |
239 def setstate(self, state, nodes): |
236 """freeze targets changeset and it's ancestors. |
240 """freeze targets changeset and it's ancestors. |
237 |
241 |
238 Simplify the list of head.""" |
242 Simplify the list of head.""" |
252 def _reducehead(self, candidates): |
256 def _reducehead(self, candidates): |
253 selected = set() |
257 selected = set() |
254 for candidate in candidates: |
258 for candidate in candidates: |
255 rev = self.changelog.rev(candidate) |
259 rev = self.changelog.rev(candidate) |
256 ok = True |
260 ok = True |
257 for h in self._publicheads: |
261 for h in self._readyheads: |
258 revh = self.changelog.rev(h) |
262 revh = self.changelog.rev(h) |
259 if self.changelog.descendant(revh, rev): |
263 if self.changelog.descendant(revh, rev): |
260 ok = False |
264 ok = False |
261 selected.add(h) |
265 selected.add(h) |
262 if ok: |
266 if ok: |
263 selected.add(candidate) |
267 selected.add(candidate) |
264 return sorted(selected) |
268 return sorted(selected) |
265 |
269 |
266 def cancopy(self): |
270 def cancopy(self): |
267 return o_cancopy() and (self._publicheads == self.heads()) |
271 return o_cancopy() and (self._readyheads == self.heads()) |
268 |
272 |
269 repo.__class__ = statefulrepo |
273 repo.__class__ = statefulrepo |
270 |
274 |