states.py
changeset 12 6312fc525a54
parent 11 47ba990eff0e
child 13 e95e8cf7988f
equal deleted inserted replaced
11:47ba990eff0e 12:6312fc525a54
    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