Advertisement
Guest User

Untitled

a guest
May 28th, 2014
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 14.41 KB | None | 0 0
  1. # HG changeset patch
  2. # User Durham Goode <durham@fb.com>
  3. # Date 1399499314 25200
  4. #      Wed May 07 14:48:34 2014 -0700
  5. # Node ID 9999b5d32f4ebe1cbd7f5313b0cf53bfe208f3f6
  6. # Parent  d19164a018a175cda640066a1f32651834e4f011
  7. Phase cache in transaction
  8.  
  9. diff --git a/mercurial/commands.py b/mercurial/commands.py
  10. --- a/mercurial/commands.py
  11. +++ b/mercurial/commands.py
  12. @@ -4478,8 +4478,10 @@
  13.              ctx = repo[r]
  14.              ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
  15.      else:
  16. -        lock = repo.lock()
  17. +        lock = tr = None
  18.          try:
  19. +            lock = repo.lock()
  20. +            tr = repo.transaction("phase")
  21.              # set phase
  22.              if not revs:
  23.                  raise util.Abort(_('empty revision set'))
  24. @@ -4488,8 +4490,9 @@
  25.              phases.advanceboundary(repo, targetphase, nodes)
  26.              if opts['force']:
  27.                  phases.retractboundary(repo, targetphase, nodes)
  28. +            tr.close()
  29.          finally:
  30. -            lock.release()
  31. +            release(tr, lock)
  32.          # moving revision from public to draft may hide them
  33.          # We have to check result on an unfiltered repository
  34.          unfi = repo.unfiltered()
  35. diff --git a/mercurial/exchange.py b/mercurial/exchange.py
  36. --- a/mercurial/exchange.py
  37. +++ b/mercurial/exchange.py
  38. @@ -377,34 +377,40 @@
  39.          # courtesy to publish changesets possibly locally draft
  40.          # on the remote.
  41.          remotephases = {'publishing': 'True'}
  42. -    if not remotephases: # old server or public only reply from non-publishing
  43. -        _localphasemove(pushop, cheads)
  44. -        # don't push any phase data as there is nothing to push
  45. -    else:
  46. -        ana = phases.analyzeremotephases(pushop.repo, cheads,
  47. -                                         remotephases)
  48. -        pheads, droots = ana
  49. -        ### Apply remote phase on local
  50. -        if remotephases.get('publishing', False):
  51. +
  52. +    tr = pushop.repo.transaction("phases")
  53. +    try:
  54. +        if not remotephases: # old server or public only reply from non-publishing
  55.              _localphasemove(pushop, cheads)
  56. -        else: # publish = False
  57. -            _localphasemove(pushop, pheads)
  58. -            _localphasemove(pushop, cheads, phases.draft)
  59. -        ### Apply local phase on remote
  60. +            # don't push any phase data as there is nothing to push
  61. +        else:
  62. +            ana = phases.analyzeremotephases(pushop.repo, cheads,
  63. +                                             remotephases)
  64. +            pheads, droots = ana
  65. +            ### Apply remote phase on local
  66. +            if remotephases.get('publishing', False):
  67. +                _localphasemove(pushop, cheads)
  68. +            else: # publish = False
  69. +                _localphasemove(pushop, pheads)
  70. +                _localphasemove(pushop, cheads, phases.draft)
  71. +            ### Apply local phase on remote
  72.  
  73. -        # Get the list of all revs draft on remote by public here.
  74. -        # XXX Beware that revset break if droots is not strictly
  75. -        # XXX root we may want to ensure it is but it is costly
  76. -        outdated =  unfi.set('heads((%ln::%ln) and public())',
  77. -                             droots, cheads)
  78. -        for newremotehead in outdated:
  79. -            r = pushop.remote.pushkey('phases',
  80. -                                      newremotehead.hex(),
  81. -                                      str(phases.draft),
  82. -                                      str(phases.public))
  83. -            if not r:
  84. -                pushop.ui.warn(_('updating %s to public failed!\n')
  85. -                                       % newremotehead)
  86. +            # Get the list of all revs draft on remote by public here.
  87. +            # XXX Beware that revset break if droots is not strictly
  88. +            # XXX root we may want to ensure it is but it is costly
  89. +            outdated =  unfi.set('heads((%ln::%ln) and public())',
  90. +                                 droots, cheads)
  91. +            for newremotehead in outdated:
  92. +                r = pushop.remote.pushkey('phases',
  93. +                                          newremotehead.hex(),
  94. +                                          str(phases.draft),
  95. +                                          str(phases.public))
  96. +                if not r:
  97. +                    pushop.ui.warn(_('updating %s to public failed!\n')
  98. +                                           % newremotehead)
  99. +        tr.close()
  100. +    finally:
  101. +        tr.release()
  102.  
  103.  def _localphasemove(pushop, nodes, phase=phases.public):
  104.      """move <nodes> to <phase> in the local source repo"""
  105. diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
  106. --- a/mercurial/localrepo.py
  107. +++ b/mercurial/localrepo.py
  108. @@ -862,6 +862,8 @@
  109.  
  110.          def onclose():
  111.              self.store.write(tr)
  112. +            if hasunfilteredcache(self, '_phasecache'):
  113. +                self._phasecache.write(tr)
  114.  
  115.          self._writejournal(desc)
  116.          renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
  117. @@ -876,10 +878,12 @@
  118.  
  119.      def _journalfiles(self):
  120.          return ((self.svfs, 'journal'),
  121. +                (self.svfs, 'journal.backupfiles'),
  122.                  (self.vfs, 'journal.dirstate'),
  123.                  (self.vfs, 'journal.branch'),
  124.                  (self.vfs, 'journal.desc'),
  125.                  (self.vfs, 'journal.bookmarks'),
  126. +                (self.svfs, 'journal.fncache'),
  127.                  (self.svfs, 'journal.phaseroots'))
  128.  
  129.      def undofiles(self):
  130. @@ -894,8 +898,6 @@
  131.                            "%d\n%s\n" % (len(self), desc))
  132.          self.opener.write("journal.bookmarks",
  133.                            self.opener.tryread("bookmarks"))
  134. -        self.sopener.write("journal.phaseroots",
  135. -                           self.sopener.tryread("phaseroots"))
  136.  
  137.      def recover(self):
  138.          lock = self.lock()
  139. @@ -956,39 +958,43 @@
  140.          if dryrun:
  141.              return 0
  142.  
  143. -        parents = self.dirstate.parents()
  144. -        self.destroying()
  145. -        transaction.rollback(self.sopener, 'undo', ui.warn)
  146. -        if self.vfs.exists('undo.bookmarks'):
  147. -            self.vfs.rename('undo.bookmarks', 'bookmarks')
  148. -        if self.svfs.exists('undo.phaseroots'):
  149. -            self.svfs.rename('undo.phaseroots', 'phaseroots')
  150. -        self.invalidate()
  151. +        tr = self.transaction("rollback")
  152. +        try:
  153. +            parents = self.dirstate.parents()
  154. +            self.destroying(tr)
  155. +            transaction.rollback(self.sopener, 'undo', ui.warn)
  156. +            if self.vfs.exists('undo.bookmarks'):
  157. +                self.vfs.rename('undo.bookmarks', 'bookmarks')
  158. +            self.invalidate()
  159.  
  160. -        parentgone = (parents[0] not in self.changelog.nodemap or
  161. -                      parents[1] not in self.changelog.nodemap)
  162. -        if parentgone:
  163. -            self.vfs.rename('undo.dirstate', 'dirstate')
  164. -            try:
  165. -                branch = self.opener.read('undo.branch')
  166. -                self.dirstate.setbranch(encoding.tolocal(branch))
  167. -            except IOError:
  168. -                ui.warn(_('named branch could not be reset: '
  169. -                          'current branch is still \'%s\'\n')
  170. -                        % self.dirstate.branch())
  171. +            parentgone = (parents[0] not in self.changelog.nodemap or
  172. +                          parents[1] not in self.changelog.nodemap)
  173. +            if parentgone:
  174. +                self.vfs.rename('undo.dirstate', 'dirstate')
  175. +                try:
  176. +                    branch = self.opener.read('undo.branch')
  177. +                    self.dirstate.setbranch(encoding.tolocal(branch))
  178. +                except IOError:
  179. +                    ui.warn(_('named branch could not be reset: '
  180. +                              'current branch is still \'%s\'\n')
  181. +                            % self.dirstate.branch())
  182.  
  183. -            self.dirstate.invalidate()
  184. -            parents = tuple([p.rev() for p in self.parents()])
  185. -            if len(parents) > 1:
  186. -                ui.status(_('working directory now based on '
  187. -                            'revisions %d and %d\n') % parents)
  188. -            else:
  189. -                ui.status(_('working directory now based on '
  190. -                            'revision %d\n') % parents)
  191. -        # TODO: if we know which new heads may result from this rollback, pass
  192. -        # them to destroy(), which will prevent the branchhead cache from being
  193. -        # invalidated.
  194. -        self.destroyed()
  195. +                self.dirstate.invalidate()
  196. +                parents = tuple([p.rev() for p in self.parents()])
  197. +                if len(parents) > 1:
  198. +                    ui.status(_('working directory now based on '
  199. +                                'revisions %d and %d\n') % parents)
  200. +                else:
  201. +                    ui.status(_('working directory now based on '
  202. +                                'revision %d\n') % parents)
  203. +            # TODO: if we know which new heads may result from this rollback,
  204. +            # pass them to destroy(), which will prevent the branchhead cache
  205. +            # from being invalidated.
  206. +            self.destroyed(tr)
  207. +            tr.close()
  208. +        finally:
  209. +            tr.release()
  210. +
  211.          return 0
  212.  
  213.      def invalidatecaches(self):
  214. @@ -1079,8 +1085,6 @@
  215.              return l
  216.  
  217.          def unlock():
  218. -            if hasunfilteredcache(self, '_phasecache'):
  219. -                self._phasecache.write()
  220.              for k, ce in self._filecache.items():
  221.                  if k == 'dirstate' or k not in self.__dict__:
  222.                      continue
  223. @@ -1442,7 +1446,7 @@
  224.              lock.release()
  225.  
  226.      @unfilteredmethod
  227. -    def destroying(self):
  228. +    def destroying(self, tr):
  229.          '''Inform the repository that nodes are about to be destroyed.
  230.          Intended for use by strip and rollback, so there's a common
  231.          place for anything that has to be done before destroying history.
  232. @@ -1457,10 +1461,10 @@
  233.          # dirty after committing. Then when we strip, the repo is invalidated,
  234.          # causing those changes to disappear.
  235.          if '_phasecache' in vars(self):
  236. -            self._phasecache.write()
  237. +            self._phasecache.write(tr)
  238.  
  239.      @unfilteredmethod
  240. -    def destroyed(self):
  241. +    def destroyed(self, tr):
  242.          '''Inform the repository that nodes have been destroyed.
  243.          Intended for use by strip and rollback, so there's a common
  244.          place for anything that has to be done after destroying history.
  245. @@ -1474,7 +1478,7 @@
  246.          # causing it to reload next time it is accessed, or simply filter
  247.          # the removed nodes now and write the updated cache.
  248.          self._phasecache.filterunknown(self)
  249. -        self._phasecache.write()
  250. +        self._phasecache.write(tr)
  251.  
  252.          # update the 'served' branch cache to help read only server process
  253.          # Thanks to branchcache collaboration this is done from the nearest
  254. diff --git a/mercurial/phases.py b/mercurial/phases.py
  255. --- a/mercurial/phases.py
  256. +++ b/mercurial/phases.py
  257. @@ -191,9 +191,11 @@
  258.              self._phaserevs = self.getphaserevs(repo, rebuild=True)
  259.          return self._phaserevs[rev]
  260.  
  261. -    def write(self):
  262. +    def write(self, tr):
  263.          if not self.dirty:
  264.              return
  265. +
  266. +        tr.addbackup('phaseroots')
  267.          f = self.opener('phaseroots', 'w', atomictemp=True)
  268.          try:
  269.              for phase, roots in enumerate(self.phaseroots):
  270. @@ -212,6 +214,10 @@
  271.          # Be careful to preserve shallow-copied values: do not update
  272.          # phaseroots values, replace them.
  273.  
  274. +        tr = repo._transref and repo._transref() or None
  275. +        if not tr:
  276. +            raise Exception("NO TRANSACTION ON ADVANCE BOUNDARY")
  277. +
  278.          repo = repo.unfiltered()
  279.          delroots = [] # set of root deleted by this path
  280.          for phase in xrange(targetphase + 1, len(allphases)):
  281. @@ -236,6 +242,10 @@
  282.          # Be careful to preserve shallow-copied values: do not update
  283.          # phaseroots values, replace them.
  284.  
  285. +        tr = repo._transref and repo._transref() or None
  286. +        if not tr:
  287. +            raise Exception("NO TRANSACTION ON RETRACT BOUNDARY")
  288. +
  289.          repo = repo.unfiltered()
  290.          currentroots = self.phaseroots[targetphase]
  291.          newroots = [n for n in nodes
  292. @@ -255,6 +265,7 @@
  293.  
  294.          Nothing is lost as unknown nodes only hold data for their descendants.
  295.          """
  296. +
  297.          filtered = False
  298.          nodemap = repo.changelog.nodemap # to filter unknown nodes
  299.          for phase, nodes in enumerate(self.phaseroots):
  300. diff --git a/mercurial/repair.py b/mercurial/repair.py
  301. --- a/mercurial/repair.py
  302. +++ b/mercurial/repair.py
  303. @@ -49,7 +49,6 @@
  304.  
  305.  def strip(ui, repo, nodelist, backup="all", topic='backup'):
  306.      repo = repo.unfiltered()
  307. -    repo.destroying()
  308.  
  309.      cl = repo.changelog
  310.      # TODO handle undo of merge sets
  311. @@ -123,6 +122,8 @@
  312.      mfst = repo.manifest
  313.  
  314.      tr = repo.transaction("strip")
  315. +    repo.destroying(tr)
  316. +
  317.      offset = len(tr.entries)
  318.  
  319.      try:
  320. @@ -139,6 +140,8 @@
  321.                  repo.sopener(file, 'a').truncate(troffset)
  322.                  if troffset == 0:
  323.                      repo.store.markremoved(file)
  324. +
  325. +            repo.destroyed(tr)
  326.              tr.close()
  327.          except: # re-raises
  328.              tr.abort()
  329. @@ -179,5 +182,3 @@
  330.              ui.warn(_("strip failed, partial bundle stored in '%s'\n")
  331.                      % vfs.join(chgrpfile))
  332.          raise
  333. -
  334. -    repo.destroyed()
  335. diff --git a/mercurial/transaction.py b/mercurial/transaction.py
  336. --- a/mercurial/transaction.py
  337. +++ b/mercurial/transaction.py
  338. @@ -169,7 +169,7 @@
  339.  
  340.          self.backupentries.append((file, backupfile, None))
  341.          self.backupmap[file] = len(self.backupentries) - 1
  342. -        self.backupsfile.write("%s\0%s\0" % (file, backupfile))
  343. +        self.backupsfile.write("%s\n" % (file))
  344.          self.backupsfile.flush()
  345.  
  346.      @active
  347. @@ -297,11 +297,11 @@
  348.      backupjournal = "%s.backupfiles" % file
  349.      if opener.exists(backupjournal):
  350.          fp = opener.open(backupjournal)
  351. -        data = fp.read()
  352. -        if len(data) > 0:
  353. -            parts = data.split('\0')
  354. -            for i in xrange(0, len(parts), 2):
  355. -                f, b = parts[i:i + 1]
  356. -                backupentries.append((f, b, None))
  357. +        lines = fp.readlines()
  358. +        fp.close()
  359. +        for l in lines:
  360. +            f = l[:-1]
  361. +            backup = '%s.%s' % (file, f)
  362. +            backupentries.append((f, backup, None))
  363.  
  364.      _playback(file, report, opener, entries, backupentries)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement