comparison states.py @ 23:423c62a146c7

add rollback support.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Fri, 01 Jul 2011 16:00:19 +0200
parents 93dd72d028a1
children 20ac7fa3fd29
comparison
equal deleted inserted replaced
22:93dd72d028a1 23:423c62a146c7
15 1 mutable 15 1 mutable
16 2 private 16 2 private
17 17
18 name are not fixed yet. 18 name are not fixed yet.
19 ''' 19 '''
20 import os
20 from functools import partial 21 from functools import partial
22
21 from mercurial.i18n import _ 23 from mercurial.i18n import _
22 from mercurial import cmdutil 24 from mercurial import cmdutil
23 from mercurial import scmutil 25 from mercurial import scmutil
24 from mercurial import context 26 from mercurial import context
25 from mercurial import revset 27 from mercurial import revset
29 from mercurial.node import nullid, hex, short 31 from mercurial.node import nullid, hex, short
30 from mercurial import discovery 32 from mercurial import discovery
31 from mercurial import extensions 33 from mercurial import extensions
32 from mercurial import wireproto 34 from mercurial import wireproto
33 from mercurial import pushkey 35 from mercurial import pushkey
36 from mercurial.lock import release
34 37
35 38
36 _NOSHARE=2 39 _NOSHARE=2
37 _MUTABLE=1 40 _MUTABLE=1
38 41
194 197
195 ocancopy =repo.cancopy 198 ocancopy =repo.cancopy
196 opull = repo.pull 199 opull = repo.pull
197 opush = repo.push 200 opush = repo.push
198 o_tag = repo._tag 201 o_tag = repo._tag
202 orollback = repo.rollback
203 o_writejournal = repo._writejournal
199 class statefulrepo(repo.__class__): 204 class statefulrepo(repo.__class__):
200 205
201 def nodestate(self, node): 206 def nodestate(self, node):
202 rev = self.changelog.rev(node) 207 rev = self.changelog.rev(node)
203 for state in STATES[::-1]: 208 for state in STATES[::-1]:
234 finally: 239 finally:
235 f.close() 240 f.close()
236 except IOError: 241 except IOError:
237 pass 242 pass
238 return heads 243 return heads
239 def _readstatesheads(self): 244
245 def _readstatesheads(self, undo=False):
240 statesheads = {} 246 statesheads = {}
241 for state in STATES: 247 for state in STATES:
242 if state.trackheads: 248 if state.trackheads:
243 filename = 'states/%s-heads' % state.name 249 filemask = 'states/%s-heads'
250 filename = filemask % state.name
244 statesheads[state] = self._readheadsfile(filename) 251 statesheads[state] = self._readheadsfile(filename)
245 return statesheads 252 return statesheads
246 253
247 def _writeheadsfile(self, filename, heads): 254 def _writeheadsfile(self, filename, heads):
248 f = self.opener(filename, 'w', atomictemp=True) 255 f = self.opener(filename, 'w', atomictemp=True)
331 else: 338 else:
332 self.ui.debug('server has immutableheads enabled, merging lists') 339 self.ui.debug('server has immutableheads enabled, merging lists')
333 remote = map(node.bin, remote.listkeys('immutableheads')) 340 remote = map(node.bin, remote.listkeys('immutableheads'))
334 return remote 341 return remote
335 342
343 ### Tag support
344
336 def _tag(self, names, node, *args, **kwargs): 345 def _tag(self, names, node, *args, **kwargs):
337 tagnode = o_tag(names, node, *args, **kwargs) 346 tagnode = o_tag(names, node, *args, **kwargs)
338 self.setstate(ST0, [node, tagnode]) 347 self.setstate(ST0, [node, tagnode])
339 return tagnode 348 return tagnode
340 349
350 ### rollback support
351
352 def _writejournal(self, desc):
353 entries = list(o_writejournal(desc))
354 for state in STATES:
355 if state.trackheads:
356 filename = 'states/%s-heads' % state.name
357 filepath = self.join(filename)
358 if os.path.exists(filepath):
359 journalname = 'states/journal.%s-heads' % state.name
360 journalpath = self.join(journalname)
361 util.copyfile(filepath, journalpath)
362 entries.append(journalpath)
363 return tuple(entries)
364
365 def rollback(self, dryrun=False):
366 wlock = lock = None
367 try:
368 wlock = self.wlock()
369 lock = self.lock()
370 ret = orollback(dryrun)
371 if not (ret or dryrun): #rollback did not failed
372 for state in STATES:
373 if state.trackheads:
374 src = self.join('states/undo.%s-heads') % state.name
375 dest = self.join('states/%s-heads') % state.name
376 if os.path.exists(src):
377 util.rename(src, dest)
378 elif os.path.exists(dest): #unlink in any case
379 os.unlink(dest)
380 self.__dict__.pop('_statesheads', None)
381 return ret
382 finally:
383 release(lock, wlock)
384
341 repo.__class__ = statefulrepo 385 repo.__class__ = statefulrepo
342 386