hgext/pushexperiment.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Thu, 02 Oct 2014 14:16:32 -0500
changeset 1117 98f4e356a431
parent 732 05ec92d8150d
child 1217 196c650d5ba9
permissions -rw-r--r--
merge with stable
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     1
"""Small extension altering some push behavior
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     2
731
63ce4384be50 pushexperiment: fix doc typos
Julien Cristau <julien.cristau@logilab.fr>
parents: 729
diff changeset
     3
- Add a new wire protocol command to exchange obsolescence markers. Sending the
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     4
  raw file as a binary instead of using pushkey hack.
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
     5
- Add a "push done" notification
731
63ce4384be50 pushexperiment: fix doc typos
Julien Cristau <julien.cristau@logilab.fr>
parents: 729
diff changeset
     6
- Push obsolescence marker before anything else (This works around the lack of global transaction)
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     7
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     8
"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
     9
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    10
import errno
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    11
from StringIO import StringIO
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    12
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    13
from mercurial.i18n import _
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    14
from mercurial import extensions
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    15
from mercurial import wireproto
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    16
from mercurial import obsolete
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    17
from mercurial import localrepo
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    18
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    19
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    20
def client_pushobsmarkers(self, obsfile):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    21
    """wireprotocol peer method"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    22
    self.requirecap('_push_experiment_pushobsmarkers_0',
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    23
                    _('push obsolete markers faster'))
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    24
    ret, output = self._callpush('push_experiment_pushobsmarkers_0', obsfile)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    25
    for l in output.splitlines(True):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    26
        self.ui.status(_('remote: '), l)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    27
    return ret
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    28
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    29
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    30
def srv_pushobsmarkers(repo, proto):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    31
    """wireprotocol command"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    32
    fp = StringIO()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    33
    proto.redirect()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    34
    proto.getfile(fp)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    35
    data = fp.getvalue()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    36
    fp.close()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    37
    lock = repo.lock()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    38
    try:
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    39
        tr = repo.transaction('pushkey: obsolete markers')
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    40
        try:
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    41
            repo.obsstore.mergemarkers(tr, data)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    42
            tr.close()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    43
        finally:
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    44
            tr.release()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    45
    finally:
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    46
        lock.release()
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    47
    return wireproto.pushres(0)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    48
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    49
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    50
def syncpush(orig, repo, remote):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    51
    """wraper for obsolete.syncpush to use the fast way if possible"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    52
    if not (obsolete._enabled and repo.obsstore):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    53
        return
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    54
    if remote.capable('_push_experiment_pushobsmarkers_0'):
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    55
        return # already pushed before changeset
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    56
        remote.push_experiment_pushobsmarkers_0(obsfp)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    57
        return
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    58
    return orig(repo, remote)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    59
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    60
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    61
def client_notifypushend(self):
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    62
    """wire peer  command to notify a push is done"""
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    63
    self.requirecap('_push_experiment_notifypushend_0', _('hook once push is all done'))
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    64
    return self._call('push_experiment_notifypushend_0')
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    65
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    66
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    67
def srv_notifypushend(repo, proto):
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    68
    """wire protocol command to notify a push is done"""
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    69
    proto.redirect()
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    70
    repo.hook('notifypushend')
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    71
    return wireproto.pushres(0)
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    72
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    73
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    74
def augmented_push(orig, repo, remote, *args, **kwargs):
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    75
    """push wrapped that call the wire protocol command"""
732
05ec92d8150d pushexperiment: guard against non-push-capable remotes
Julien Cristau <julien.cristau@logilab.fr>
parents: 731
diff changeset
    76
    if not remote.canpush():
05ec92d8150d pushexperiment: guard against non-push-capable remotes
Julien Cristau <julien.cristau@logilab.fr>
parents: 731
diff changeset
    77
        raise util.Abort(_("destination does not support push"))
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    78
    if (obsolete._enabled and repo.obsstore
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    79
        and remote.capable('_push_experiment_pushobsmarkers_0')):
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    80
        # push marker early to limit damage of pushing too early.
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    81
        try:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    82
            obsfp = repo.sopener('obsstore')
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    83
        except IOError as e:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    84
            if e.errno != errno.ENOENT:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    85
                raise
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    86
        else:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    87
            remote.push_experiment_pushobsmarkers_0(obsfp)
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    88
    ret = orig(repo, remote, *args, **kwargs)
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    89
    if remote.capable('_push_experiment_notifypushend_0'):
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    90
        remote.push_experiment_notifypushend_0()
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    91
    return ret
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    92
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    93
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    94
def capabilities(orig, repo, proto):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    95
    """wrapper to advertise new capability"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    96
    caps = orig(repo, proto)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    97
    if obsolete._enabled:
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    98
        caps += ' _push_experiment_pushobsmarkers_0'
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    99
    caps += ' _push_experiment_notifypushend_0'
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   100
    return caps
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   101
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   102
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   103
def extsetup(ui):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   104
    wireproto.wirepeer.push_experiment_pushobsmarkers_0 = client_pushobsmarkers
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
   105
    wireproto.wirepeer.push_experiment_notifypushend_0 = client_notifypushend
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   106
    wireproto.commands['push_experiment_pushobsmarkers_0'] = (srv_pushobsmarkers, '')
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
   107
    wireproto.commands['push_experiment_notifypushend_0'] = (srv_notifypushend, '')
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   108
    extensions.wrapfunction(wireproto, 'capabilities', capabilities)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   109
    extensions.wrapfunction(obsolete, 'syncpush', syncpush)
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
   110
    extensions.wrapfunction(localrepo.localrepository, 'push', augmented_push)
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   111
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   112