comparison mercurial/exchange.py @ 22019:9fcf772f15ff

push: perform phases discovery before the push This will allow including phase information in the same bundle2 as the changesets.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 30 Jul 2014 19:26:47 -0700
parents ddb56e7e1b92
children 311979b773fb
comparison
equal deleted inserted replaced
22018:ddb56e7e1b92 22019:9fcf772f15ff
75 self.outgoing = None 75 self.outgoing = None
76 # all remote heads before the push 76 # all remote heads before the push
77 self.remoteheads = None 77 self.remoteheads = None
78 # testable as a boolean indicating if any nodes are missing locally. 78 # testable as a boolean indicating if any nodes are missing locally.
79 self.incoming = None 79 self.incoming = None
80 # phases changes that must be pushed along side the changesets
81 self.outdatedphases = None
82 # phases changes that must be pushed if changeset push fails
83 self.fallbackoutdatedphases = None
80 84
81 @util.propertycache 85 @util.propertycache
82 def futureheads(self): 86 def futureheads(self):
83 """future remote heads if the changeset push succeeds""" 87 """future remote heads if the changeset push succeeds"""
84 return self.outgoing.missingheads 88 return self.outgoing.missingheads
234 outgoing = fco(unfi, pushop.remote, onlyheads=pushop.revs, 238 outgoing = fco(unfi, pushop.remote, onlyheads=pushop.revs,
235 commoninc=commoninc, force=pushop.force) 239 commoninc=commoninc, force=pushop.force)
236 pushop.outgoing = outgoing 240 pushop.outgoing = outgoing
237 pushop.remoteheads = remoteheads 241 pushop.remoteheads = remoteheads
238 pushop.incoming = inc 242 pushop.incoming = inc
243
244 @pushdiscovery('phase')
245 def _pushdiscoveryphase(pushop):
246 """discover the phase that needs to be pushed
247
248 (computed for both success and failure case for changesets push)"""
249 outgoing = pushop.outgoing
250 unfi = pushop.repo.unfiltered()
251 remotephases = pushop.remote.listkeys('phases')
252 publishing = remotephases.get('publishing', False)
253 ana = phases.analyzeremotephases(pushop.repo,
254 pushop.fallbackheads,
255 remotephases)
256 pheads, droots = ana
257 extracond = ''
258 if not publishing:
259 extracond = ' and public()'
260 revset = 'heads((%%ln::%%ln) %s)' % extracond
261 # Get the list of all revs draft on remote by public here.
262 # XXX Beware that revset break if droots is not strictly
263 # XXX root we may want to ensure it is but it is costly
264 fallback = list(unfi.set(revset, droots, pushop.fallbackheads))
265 if not outgoing.missing:
266 future = fallback
267 else:
268 # adds changeset we are going to push as draft
269 #
270 # should not be necessary for pushblishing server, but because of an
271 # issue fixed in xxxxx we have to do it anyway.
272 fdroots = list(unfi.set('roots(%ln + %ln::)',
273 outgoing.missing, droots))
274 fdroots = [f.node() for f in fdroots]
275 future = list(unfi.set(revset, fdroots, pushop.futureheads))
276 pushop.outdatedphases = future
277 pushop.fallbackoutdatedphases = fallback
239 278
240 def _pushcheckoutgoing(pushop): 279 def _pushcheckoutgoing(pushop):
241 outgoing = pushop.outgoing 280 outgoing = pushop.outgoing
242 unfi = pushop.repo.unfiltered() 281 unfi = pushop.repo.unfiltered()
243 if not outgoing.missing: 282 if not outgoing.missing:
406 # change 445 # change
407 pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url()) 446 pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url())
408 447
409 def _pushsyncphase(pushop): 448 def _pushsyncphase(pushop):
410 """synchronise phase information locally and remotely""" 449 """synchronise phase information locally and remotely"""
411 unfi = pushop.repo.unfiltered()
412 cheads = pushop.commonheads 450 cheads = pushop.commonheads
413 # even when we don't push, exchanging phase data is useful 451 # even when we don't push, exchanging phase data is useful
414 remotephases = pushop.remote.listkeys('phases') 452 remotephases = pushop.remote.listkeys('phases')
415 if (pushop.ui.configbool('ui', '_usedassubrepo', False) 453 if (pushop.ui.configbool('ui', '_usedassubrepo', False)
416 and remotephases # server supports phases 454 and remotephases # server supports phases
439 else: # publish = False 477 else: # publish = False
440 _localphasemove(pushop, pheads) 478 _localphasemove(pushop, pheads)
441 _localphasemove(pushop, cheads, phases.draft) 479 _localphasemove(pushop, cheads, phases.draft)
442 ### Apply local phase on remote 480 ### Apply local phase on remote
443 481
444 # Get the list of all revs draft on remote by public here. 482 if pushop.ret:
445 # XXX Beware that revset break if droots is not strictly 483 outdated = pushop.outdatedphases
446 # XXX root we may want to ensure it is but it is costly 484 else:
447 outdated = unfi.set('heads((%ln::%ln) and public())', 485 outdated = pushop.fallbackoutdatedphases
448 droots, cheads) 486
487 # filter heads already turned public by the push
488 outdated = [c for c in outdated if c.node() not in pheads]
449 489
450 b2caps = bundle2.bundle2caps(pushop.remote) 490 b2caps = bundle2.bundle2caps(pushop.remote)
451 if 'b2x:pushkey' in b2caps: 491 if 'b2x:pushkey' in b2caps:
452 # server supports bundle2, let's do a batched push through it 492 # server supports bundle2, let's do a batched push through it
453 # 493 #