annotate hgext/pushexperiment.py @ 923:a94ce5400e1b stable

evolve: protect call to rebase within a wlock (#42, #35, #16) Without a wlock, repo.commit would blow away the dirstate's parents on OSes that have no 'os.symlink' support in python, leading evolve to produce a merge instead of a rebase. If a user ran the rebase command instead of evolve, then things would work because rebase is wrapped in a giant wlock. Unfortunately, we can't use the same idea of wrapping the evolve command in one giant wlock because that's too early in the process. If the lock did wrap the entire evolve command, then the working directory would save its current parents which, since rebase hasn't been called yet, would be just p1. Therefore, we need to obtain the lock *after* the dirstate's parents are changed but *before* the call to rebase. This way ensures that when a conflict happens the working directory correctly shows both parent changeset.
author Sean Farley <sean.michael.farley@gmail.com>
date Fri, 25 Apr 2014 19:58:33 -0500
parents 05ec92d8150d
children 196c650d5ba9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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