hgext/pushexperiment.py
author Laurent Charignon <lcharignon@fb.com>
Mon, 30 Mar 2015 13:31:09 -0700
changeset 1234 c15d4677f2ba
parent 1217 196c650d5ba9
child 1465 777e5c369d99
permissions -rw-r--r--
inhibit: ensure that no obsolete changesets are visible after a bookmark change When creating a bookmark, we could reveal obsolete changesets. We are inhibiting the obsolete changesets resulting from a bookmark change. There are two ways to record bookmark changes to disk and we wrap both.
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"""
1217
196c650d5ba9 pushexperiment: remove use of obsolete._enabled
Durham Goode <durham@fb.com>
parents: 732
diff changeset
    52
    if not (obsolete.isenabled(repo, obsolete.exchangeopt) and
196c650d5ba9 pushexperiment: remove use of obsolete._enabled
Durham Goode <durham@fb.com>
parents: 732
diff changeset
    53
            repo.obsstore):
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    54
        return
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    55
    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
    56
        return # already pushed before changeset
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    57
        remote.push_experiment_pushobsmarkers_0(obsfp)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    58
        return
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    59
    return orig(repo, remote)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    60
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    61
728
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    62
def client_notifypushend(self):
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    63
    """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
    64
    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
    65
    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
    66
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    67
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    68
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
    69
    """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
    70
    proto.redirect()
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    71
    repo.hook('notifypushend')
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    72
    return wireproto.pushres(0)
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    73
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    74
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    75
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
    76
    """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
    77
    if not remote.canpush():
05ec92d8150d pushexperiment: guard against non-push-capable remotes
Julien Cristau <julien.cristau@logilab.fr>
parents: 731
diff changeset
    78
        raise util.Abort(_("destination does not support push"))
1217
196c650d5ba9 pushexperiment: remove use of obsolete._enabled
Durham Goode <durham@fb.com>
parents: 732
diff changeset
    79
    if (obsolete.isenabled(repo, obsolete.exchangeopt) and repo.obsstore
729
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    80
        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
    81
        # 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
    82
        try:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    83
            obsfp = repo.sopener('obsstore')
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    84
        except IOError as e:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    85
            if e.errno != errno.ENOENT:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    86
                raise
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    87
        else:
2e46caeb2890 push obsolescence marker before anything else
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 728
diff changeset
    88
            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
    89
    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
    90
    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
    91
        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
    92
    return ret
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    93
5d368ae3d5a0 add notification at the end of push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 727
diff changeset
    94
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    95
def capabilities(orig, repo, proto):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    96
    """wrapper to advertise new capability"""
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    97
    caps = orig(repo, proto)
1217
196c650d5ba9 pushexperiment: remove use of obsolete._enabled
Durham Goode <durham@fb.com>
parents: 732
diff changeset
    98
    if obsolete.isenabled(repo, obsolete.exchangeopt):
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
    99
        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
   100
    caps += ' _push_experiment_notifypushend_0'
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   101
    return caps
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
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   104
def extsetup(ui):
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   105
    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
   106
    wireproto.wirepeer.push_experiment_notifypushend_0 = client_notifypushend
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   107
    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
   108
    wireproto.commands['push_experiment_notifypushend_0'] = (srv_notifypushend, '')
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   109
    extensions.wrapfunction(wireproto, 'capabilities', capabilities)
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   110
    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
   111
    extensions.wrapfunction(localrepo.localrepository, 'push', augmented_push)
727
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   112
cb907cf3b556 Add a new pushexperiment extension
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff changeset
   113