##// END OF EJS Templates
push: perform phases discovery before the push...
Pierre-Yves David -
r22019:9fcf772f default
parent child Browse files
Show More
@@ -1,881 +1,921 b''
1 # exchange.py - utility to exchange data between repos.
1 # exchange.py - utility to exchange data between repos.
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 from node import hex, nullid
9 from node import hex, nullid
10 import errno, urllib
10 import errno, urllib
11 import util, scmutil, changegroup, base85, error
11 import util, scmutil, changegroup, base85, error
12 import discovery, phases, obsolete, bookmarks, bundle2, pushkey
12 import discovery, phases, obsolete, bookmarks, bundle2, pushkey
13
13
14 def readbundle(ui, fh, fname, vfs=None):
14 def readbundle(ui, fh, fname, vfs=None):
15 header = changegroup.readexactly(fh, 4)
15 header = changegroup.readexactly(fh, 4)
16
16
17 alg = None
17 alg = None
18 if not fname:
18 if not fname:
19 fname = "stream"
19 fname = "stream"
20 if not header.startswith('HG') and header.startswith('\0'):
20 if not header.startswith('HG') and header.startswith('\0'):
21 fh = changegroup.headerlessfixup(fh, header)
21 fh = changegroup.headerlessfixup(fh, header)
22 header = "HG10"
22 header = "HG10"
23 alg = 'UN'
23 alg = 'UN'
24 elif vfs:
24 elif vfs:
25 fname = vfs.join(fname)
25 fname = vfs.join(fname)
26
26
27 magic, version = header[0:2], header[2:4]
27 magic, version = header[0:2], header[2:4]
28
28
29 if magic != 'HG':
29 if magic != 'HG':
30 raise util.Abort(_('%s: not a Mercurial bundle') % fname)
30 raise util.Abort(_('%s: not a Mercurial bundle') % fname)
31 if version == '10':
31 if version == '10':
32 if alg is None:
32 if alg is None:
33 alg = changegroup.readexactly(fh, 2)
33 alg = changegroup.readexactly(fh, 2)
34 return changegroup.unbundle10(fh, alg)
34 return changegroup.unbundle10(fh, alg)
35 elif version == '2X':
35 elif version == '2X':
36 return bundle2.unbundle20(ui, fh, header=magic + version)
36 return bundle2.unbundle20(ui, fh, header=magic + version)
37 else:
37 else:
38 raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
38 raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
39
39
40
40
41 class pushoperation(object):
41 class pushoperation(object):
42 """A object that represent a single push operation
42 """A object that represent a single push operation
43
43
44 It purpose is to carry push related state and very common operation.
44 It purpose is to carry push related state and very common operation.
45
45
46 A new should be created at the beginning of each push and discarded
46 A new should be created at the beginning of each push and discarded
47 afterward.
47 afterward.
48 """
48 """
49
49
50 def __init__(self, repo, remote, force=False, revs=None, newbranch=False):
50 def __init__(self, repo, remote, force=False, revs=None, newbranch=False):
51 # repo we push from
51 # repo we push from
52 self.repo = repo
52 self.repo = repo
53 self.ui = repo.ui
53 self.ui = repo.ui
54 # repo we push to
54 # repo we push to
55 self.remote = remote
55 self.remote = remote
56 # force option provided
56 # force option provided
57 self.force = force
57 self.force = force
58 # revs to be pushed (None is "all")
58 # revs to be pushed (None is "all")
59 self.revs = revs
59 self.revs = revs
60 # allow push of new branch
60 # allow push of new branch
61 self.newbranch = newbranch
61 self.newbranch = newbranch
62 # did a local lock get acquired?
62 # did a local lock get acquired?
63 self.locallocked = None
63 self.locallocked = None
64 # step already performed
64 # step already performed
65 # (used to check what steps have been already performed through bundle2)
65 # (used to check what steps have been already performed through bundle2)
66 self.stepsdone = set()
66 self.stepsdone = set()
67 # Integer version of the push result
67 # Integer version of the push result
68 # - None means nothing to push
68 # - None means nothing to push
69 # - 0 means HTTP error
69 # - 0 means HTTP error
70 # - 1 means we pushed and remote head count is unchanged *or*
70 # - 1 means we pushed and remote head count is unchanged *or*
71 # we have outgoing changesets but refused to push
71 # we have outgoing changesets but refused to push
72 # - other values as described by addchangegroup()
72 # - other values as described by addchangegroup()
73 self.ret = None
73 self.ret = None
74 # discover.outgoing object (contains common and outgoing data)
74 # discover.outgoing object (contains common and outgoing data)
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
85
89
86 @util.propertycache
90 @util.propertycache
87 def fallbackheads(self):
91 def fallbackheads(self):
88 """future remote heads if the changeset push fails"""
92 """future remote heads if the changeset push fails"""
89 if self.revs is None:
93 if self.revs is None:
90 # not target to push, all common are relevant
94 # not target to push, all common are relevant
91 return self.outgoing.commonheads
95 return self.outgoing.commonheads
92 unfi = self.repo.unfiltered()
96 unfi = self.repo.unfiltered()
93 # I want cheads = heads(::missingheads and ::commonheads)
97 # I want cheads = heads(::missingheads and ::commonheads)
94 # (missingheads is revs with secret changeset filtered out)
98 # (missingheads is revs with secret changeset filtered out)
95 #
99 #
96 # This can be expressed as:
100 # This can be expressed as:
97 # cheads = ( (missingheads and ::commonheads)
101 # cheads = ( (missingheads and ::commonheads)
98 # + (commonheads and ::missingheads))"
102 # + (commonheads and ::missingheads))"
99 # )
103 # )
100 #
104 #
101 # while trying to push we already computed the following:
105 # while trying to push we already computed the following:
102 # common = (::commonheads)
106 # common = (::commonheads)
103 # missing = ((commonheads::missingheads) - commonheads)
107 # missing = ((commonheads::missingheads) - commonheads)
104 #
108 #
105 # We can pick:
109 # We can pick:
106 # * missingheads part of common (::commonheads)
110 # * missingheads part of common (::commonheads)
107 common = set(self.outgoing.common)
111 common = set(self.outgoing.common)
108 nm = self.repo.changelog.nodemap
112 nm = self.repo.changelog.nodemap
109 cheads = [node for node in self.revs if nm[node] in common]
113 cheads = [node for node in self.revs if nm[node] in common]
110 # and
114 # and
111 # * commonheads parents on missing
115 # * commonheads parents on missing
112 revset = unfi.set('%ln and parents(roots(%ln))',
116 revset = unfi.set('%ln and parents(roots(%ln))',
113 self.outgoing.commonheads,
117 self.outgoing.commonheads,
114 self.outgoing.missing)
118 self.outgoing.missing)
115 cheads.extend(c.node() for c in revset)
119 cheads.extend(c.node() for c in revset)
116 return cheads
120 return cheads
117
121
118 @property
122 @property
119 def commonheads(self):
123 def commonheads(self):
120 """set of all common heads after changeset bundle push"""
124 """set of all common heads after changeset bundle push"""
121 if self.ret:
125 if self.ret:
122 return self.futureheads
126 return self.futureheads
123 else:
127 else:
124 return self.fallbackheads
128 return self.fallbackheads
125
129
126 def push(repo, remote, force=False, revs=None, newbranch=False):
130 def push(repo, remote, force=False, revs=None, newbranch=False):
127 '''Push outgoing changesets (limited by revs) from a local
131 '''Push outgoing changesets (limited by revs) from a local
128 repository to remote. Return an integer:
132 repository to remote. Return an integer:
129 - None means nothing to push
133 - None means nothing to push
130 - 0 means HTTP error
134 - 0 means HTTP error
131 - 1 means we pushed and remote head count is unchanged *or*
135 - 1 means we pushed and remote head count is unchanged *or*
132 we have outgoing changesets but refused to push
136 we have outgoing changesets but refused to push
133 - other values as described by addchangegroup()
137 - other values as described by addchangegroup()
134 '''
138 '''
135 pushop = pushoperation(repo, remote, force, revs, newbranch)
139 pushop = pushoperation(repo, remote, force, revs, newbranch)
136 if pushop.remote.local():
140 if pushop.remote.local():
137 missing = (set(pushop.repo.requirements)
141 missing = (set(pushop.repo.requirements)
138 - pushop.remote.local().supported)
142 - pushop.remote.local().supported)
139 if missing:
143 if missing:
140 msg = _("required features are not"
144 msg = _("required features are not"
141 " supported in the destination:"
145 " supported in the destination:"
142 " %s") % (', '.join(sorted(missing)))
146 " %s") % (', '.join(sorted(missing)))
143 raise util.Abort(msg)
147 raise util.Abort(msg)
144
148
145 # there are two ways to push to remote repo:
149 # there are two ways to push to remote repo:
146 #
150 #
147 # addchangegroup assumes local user can lock remote
151 # addchangegroup assumes local user can lock remote
148 # repo (local filesystem, old ssh servers).
152 # repo (local filesystem, old ssh servers).
149 #
153 #
150 # unbundle assumes local user cannot lock remote repo (new ssh
154 # unbundle assumes local user cannot lock remote repo (new ssh
151 # servers, http servers).
155 # servers, http servers).
152
156
153 if not pushop.remote.canpush():
157 if not pushop.remote.canpush():
154 raise util.Abort(_("destination does not support push"))
158 raise util.Abort(_("destination does not support push"))
155 # get local lock as we might write phase data
159 # get local lock as we might write phase data
156 locallock = None
160 locallock = None
157 try:
161 try:
158 locallock = pushop.repo.lock()
162 locallock = pushop.repo.lock()
159 pushop.locallocked = True
163 pushop.locallocked = True
160 except IOError, err:
164 except IOError, err:
161 pushop.locallocked = False
165 pushop.locallocked = False
162 if err.errno != errno.EACCES:
166 if err.errno != errno.EACCES:
163 raise
167 raise
164 # source repo cannot be locked.
168 # source repo cannot be locked.
165 # We do not abort the push, but just disable the local phase
169 # We do not abort the push, but just disable the local phase
166 # synchronisation.
170 # synchronisation.
167 msg = 'cannot lock source repository: %s\n' % err
171 msg = 'cannot lock source repository: %s\n' % err
168 pushop.ui.debug(msg)
172 pushop.ui.debug(msg)
169 try:
173 try:
170 pushop.repo.checkpush(pushop)
174 pushop.repo.checkpush(pushop)
171 lock = None
175 lock = None
172 unbundle = pushop.remote.capable('unbundle')
176 unbundle = pushop.remote.capable('unbundle')
173 if not unbundle:
177 if not unbundle:
174 lock = pushop.remote.lock()
178 lock = pushop.remote.lock()
175 try:
179 try:
176 _pushdiscovery(pushop)
180 _pushdiscovery(pushop)
177 if (pushop.repo.ui.configbool('experimental', 'bundle2-exp',
181 if (pushop.repo.ui.configbool('experimental', 'bundle2-exp',
178 False)
182 False)
179 and pushop.remote.capable('bundle2-exp')):
183 and pushop.remote.capable('bundle2-exp')):
180 _pushbundle2(pushop)
184 _pushbundle2(pushop)
181 _pushchangeset(pushop)
185 _pushchangeset(pushop)
182 _pushsyncphase(pushop)
186 _pushsyncphase(pushop)
183 _pushobsolete(pushop)
187 _pushobsolete(pushop)
184 finally:
188 finally:
185 if lock is not None:
189 if lock is not None:
186 lock.release()
190 lock.release()
187 finally:
191 finally:
188 if locallock is not None:
192 if locallock is not None:
189 locallock.release()
193 locallock.release()
190
194
191 _pushbookmark(pushop)
195 _pushbookmark(pushop)
192 return pushop.ret
196 return pushop.ret
193
197
194 # list of steps to perform discovery before push
198 # list of steps to perform discovery before push
195 pushdiscoveryorder = []
199 pushdiscoveryorder = []
196
200
197 # Mapping between step name and function
201 # Mapping between step name and function
198 #
202 #
199 # This exists to help extensions wrap steps if necessary
203 # This exists to help extensions wrap steps if necessary
200 pushdiscoverymapping = {}
204 pushdiscoverymapping = {}
201
205
202 def pushdiscovery(stepname):
206 def pushdiscovery(stepname):
203 """decorator for function performing discovery before push
207 """decorator for function performing discovery before push
204
208
205 The function is added to the step -> function mapping and appended to the
209 The function is added to the step -> function mapping and appended to the
206 list of steps. Beware that decorated function will be added in order (this
210 list of steps. Beware that decorated function will be added in order (this
207 may matter).
211 may matter).
208
212
209 You can only use this decorator for a new step, if you want to wrap a step
213 You can only use this decorator for a new step, if you want to wrap a step
210 from an extension, change the pushdiscovery dictionary directly."""
214 from an extension, change the pushdiscovery dictionary directly."""
211 def dec(func):
215 def dec(func):
212 assert stepname not in pushdiscoverymapping
216 assert stepname not in pushdiscoverymapping
213 pushdiscoverymapping[stepname] = func
217 pushdiscoverymapping[stepname] = func
214 pushdiscoveryorder.append(stepname)
218 pushdiscoveryorder.append(stepname)
215 return func
219 return func
216 return dec
220 return dec
217
221
218
222
219
223
220 def _pushdiscovery(pushop):
224 def _pushdiscovery(pushop):
221 """Run all discovery steps"""
225 """Run all discovery steps"""
222 for stepname in pushdiscoveryorder:
226 for stepname in pushdiscoveryorder:
223 step = pushdiscoverymapping[stepname]
227 step = pushdiscoverymapping[stepname]
224 step(pushop)
228 step(pushop)
225
229
226 @pushdiscovery('changeset')
230 @pushdiscovery('changeset')
227 def _pushdiscoverychangeset(pushop):
231 def _pushdiscoverychangeset(pushop):
228 """discover the changeset that need to be pushed"""
232 """discover the changeset that need to be pushed"""
229 unfi = pushop.repo.unfiltered()
233 unfi = pushop.repo.unfiltered()
230 fci = discovery.findcommonincoming
234 fci = discovery.findcommonincoming
231 commoninc = fci(unfi, pushop.remote, force=pushop.force)
235 commoninc = fci(unfi, pushop.remote, force=pushop.force)
232 common, inc, remoteheads = commoninc
236 common, inc, remoteheads = commoninc
233 fco = discovery.findcommonoutgoing
237 fco = discovery.findcommonoutgoing
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
239
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
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:
244 # nothing to push
283 # nothing to push
245 scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
284 scmutil.nochangesfound(unfi.ui, unfi, outgoing.excluded)
246 return False
285 return False
247 # something to push
286 # something to push
248 if not pushop.force:
287 if not pushop.force:
249 # if repo.obsstore == False --> no obsolete
288 # if repo.obsstore == False --> no obsolete
250 # then, save the iteration
289 # then, save the iteration
251 if unfi.obsstore:
290 if unfi.obsstore:
252 # this message are here for 80 char limit reason
291 # this message are here for 80 char limit reason
253 mso = _("push includes obsolete changeset: %s!")
292 mso = _("push includes obsolete changeset: %s!")
254 mst = "push includes %s changeset: %s!"
293 mst = "push includes %s changeset: %s!"
255 # plain versions for i18n tool to detect them
294 # plain versions for i18n tool to detect them
256 _("push includes unstable changeset: %s!")
295 _("push includes unstable changeset: %s!")
257 _("push includes bumped changeset: %s!")
296 _("push includes bumped changeset: %s!")
258 _("push includes divergent changeset: %s!")
297 _("push includes divergent changeset: %s!")
259 # If we are to push if there is at least one
298 # If we are to push if there is at least one
260 # obsolete or unstable changeset in missing, at
299 # obsolete or unstable changeset in missing, at
261 # least one of the missinghead will be obsolete or
300 # least one of the missinghead will be obsolete or
262 # unstable. So checking heads only is ok
301 # unstable. So checking heads only is ok
263 for node in outgoing.missingheads:
302 for node in outgoing.missingheads:
264 ctx = unfi[node]
303 ctx = unfi[node]
265 if ctx.obsolete():
304 if ctx.obsolete():
266 raise util.Abort(mso % ctx)
305 raise util.Abort(mso % ctx)
267 elif ctx.troubled():
306 elif ctx.troubled():
268 raise util.Abort(_(mst)
307 raise util.Abort(_(mst)
269 % (ctx.troubles()[0],
308 % (ctx.troubles()[0],
270 ctx))
309 ctx))
271 newbm = pushop.ui.configlist('bookmarks', 'pushing')
310 newbm = pushop.ui.configlist('bookmarks', 'pushing')
272 discovery.checkheads(unfi, pushop.remote, outgoing,
311 discovery.checkheads(unfi, pushop.remote, outgoing,
273 pushop.remoteheads,
312 pushop.remoteheads,
274 pushop.newbranch,
313 pushop.newbranch,
275 bool(pushop.incoming),
314 bool(pushop.incoming),
276 newbm)
315 newbm)
277 return True
316 return True
278
317
279 # List of names of steps to perform for an outgoing bundle2, order matters.
318 # List of names of steps to perform for an outgoing bundle2, order matters.
280 b2partsgenorder = []
319 b2partsgenorder = []
281
320
282 # Mapping between step name and function
321 # Mapping between step name and function
283 #
322 #
284 # This exists to help extensions wrap steps if necessary
323 # This exists to help extensions wrap steps if necessary
285 b2partsgenmapping = {}
324 b2partsgenmapping = {}
286
325
287 def b2partsgenerator(stepname):
326 def b2partsgenerator(stepname):
288 """decorator for function generating bundle2 part
327 """decorator for function generating bundle2 part
289
328
290 The function is added to the step -> function mapping and appended to the
329 The function is added to the step -> function mapping and appended to the
291 list of steps. Beware that decorated functions will be added in order
330 list of steps. Beware that decorated functions will be added in order
292 (this may matter).
331 (this may matter).
293
332
294 You can only use this decorator for new steps, if you want to wrap a step
333 You can only use this decorator for new steps, if you want to wrap a step
295 from an extension, attack the b2partsgenmapping dictionary directly."""
334 from an extension, attack the b2partsgenmapping dictionary directly."""
296 def dec(func):
335 def dec(func):
297 assert stepname not in b2partsgenmapping
336 assert stepname not in b2partsgenmapping
298 b2partsgenmapping[stepname] = func
337 b2partsgenmapping[stepname] = func
299 b2partsgenorder.append(stepname)
338 b2partsgenorder.append(stepname)
300 return func
339 return func
301 return dec
340 return dec
302
341
303 @b2partsgenerator('changeset')
342 @b2partsgenerator('changeset')
304 def _pushb2ctx(pushop, bundler):
343 def _pushb2ctx(pushop, bundler):
305 """handle changegroup push through bundle2
344 """handle changegroup push through bundle2
306
345
307 addchangegroup result is stored in the ``pushop.ret`` attribute.
346 addchangegroup result is stored in the ``pushop.ret`` attribute.
308 """
347 """
309 if 'changesets' in pushop.stepsdone:
348 if 'changesets' in pushop.stepsdone:
310 return
349 return
311 pushop.stepsdone.add('changesets')
350 pushop.stepsdone.add('changesets')
312 # Send known heads to the server for race detection.
351 # Send known heads to the server for race detection.
313 pushop.stepsdone.add('changesets')
352 pushop.stepsdone.add('changesets')
314 if not _pushcheckoutgoing(pushop):
353 if not _pushcheckoutgoing(pushop):
315 return
354 return
316 pushop.repo.prepushoutgoinghooks(pushop.repo,
355 pushop.repo.prepushoutgoinghooks(pushop.repo,
317 pushop.remote,
356 pushop.remote,
318 pushop.outgoing)
357 pushop.outgoing)
319 if not pushop.force:
358 if not pushop.force:
320 bundler.newpart('B2X:CHECK:HEADS', data=iter(pushop.remoteheads))
359 bundler.newpart('B2X:CHECK:HEADS', data=iter(pushop.remoteheads))
321 cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
360 cg = changegroup.getlocalbundle(pushop.repo, 'push', pushop.outgoing)
322 cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg.getchunks())
361 cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg.getchunks())
323 def handlereply(op):
362 def handlereply(op):
324 """extract addchangroup returns from server reply"""
363 """extract addchangroup returns from server reply"""
325 cgreplies = op.records.getreplies(cgpart.id)
364 cgreplies = op.records.getreplies(cgpart.id)
326 assert len(cgreplies['changegroup']) == 1
365 assert len(cgreplies['changegroup']) == 1
327 pushop.ret = cgreplies['changegroup'][0]['return']
366 pushop.ret = cgreplies['changegroup'][0]['return']
328 return handlereply
367 return handlereply
329
368
330
369
331 def _pushbundle2(pushop):
370 def _pushbundle2(pushop):
332 """push data to the remote using bundle2
371 """push data to the remote using bundle2
333
372
334 The only currently supported type of data is changegroup but this will
373 The only currently supported type of data is changegroup but this will
335 evolve in the future."""
374 evolve in the future."""
336 bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
375 bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote))
337 # create reply capability
376 # create reply capability
338 capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
377 capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
339 bundler.newpart('b2x:replycaps', data=capsblob)
378 bundler.newpart('b2x:replycaps', data=capsblob)
340 replyhandlers = []
379 replyhandlers = []
341 for partgenname in b2partsgenorder:
380 for partgenname in b2partsgenorder:
342 partgen = b2partsgenmapping[partgenname]
381 partgen = b2partsgenmapping[partgenname]
343 ret = partgen(pushop, bundler)
382 ret = partgen(pushop, bundler)
344 if callable(ret):
383 if callable(ret):
345 replyhandlers.append(ret)
384 replyhandlers.append(ret)
346 # do not push if nothing to push
385 # do not push if nothing to push
347 if bundler.nbparts <= 1:
386 if bundler.nbparts <= 1:
348 return
387 return
349 stream = util.chunkbuffer(bundler.getchunks())
388 stream = util.chunkbuffer(bundler.getchunks())
350 try:
389 try:
351 reply = pushop.remote.unbundle(stream, ['force'], 'push')
390 reply = pushop.remote.unbundle(stream, ['force'], 'push')
352 except error.BundleValueError, exc:
391 except error.BundleValueError, exc:
353 raise util.Abort('missing support for %s' % exc)
392 raise util.Abort('missing support for %s' % exc)
354 try:
393 try:
355 op = bundle2.processbundle(pushop.repo, reply)
394 op = bundle2.processbundle(pushop.repo, reply)
356 except error.BundleValueError, exc:
395 except error.BundleValueError, exc:
357 raise util.Abort('missing support for %s' % exc)
396 raise util.Abort('missing support for %s' % exc)
358 for rephand in replyhandlers:
397 for rephand in replyhandlers:
359 rephand(op)
398 rephand(op)
360
399
361 def _pushchangeset(pushop):
400 def _pushchangeset(pushop):
362 """Make the actual push of changeset bundle to remote repo"""
401 """Make the actual push of changeset bundle to remote repo"""
363 if 'changesets' in pushop.stepsdone:
402 if 'changesets' in pushop.stepsdone:
364 return
403 return
365 pushop.stepsdone.add('changesets')
404 pushop.stepsdone.add('changesets')
366 if not _pushcheckoutgoing(pushop):
405 if not _pushcheckoutgoing(pushop):
367 return
406 return
368 pushop.repo.prepushoutgoinghooks(pushop.repo,
407 pushop.repo.prepushoutgoinghooks(pushop.repo,
369 pushop.remote,
408 pushop.remote,
370 pushop.outgoing)
409 pushop.outgoing)
371 outgoing = pushop.outgoing
410 outgoing = pushop.outgoing
372 unbundle = pushop.remote.capable('unbundle')
411 unbundle = pushop.remote.capable('unbundle')
373 # TODO: get bundlecaps from remote
412 # TODO: get bundlecaps from remote
374 bundlecaps = None
413 bundlecaps = None
375 # create a changegroup from local
414 # create a changegroup from local
376 if pushop.revs is None and not (outgoing.excluded
415 if pushop.revs is None and not (outgoing.excluded
377 or pushop.repo.changelog.filteredrevs):
416 or pushop.repo.changelog.filteredrevs):
378 # push everything,
417 # push everything,
379 # use the fast path, no race possible on push
418 # use the fast path, no race possible on push
380 bundler = changegroup.bundle10(pushop.repo, bundlecaps)
419 bundler = changegroup.bundle10(pushop.repo, bundlecaps)
381 cg = changegroup.getsubset(pushop.repo,
420 cg = changegroup.getsubset(pushop.repo,
382 outgoing,
421 outgoing,
383 bundler,
422 bundler,
384 'push',
423 'push',
385 fastpath=True)
424 fastpath=True)
386 else:
425 else:
387 cg = changegroup.getlocalbundle(pushop.repo, 'push', outgoing,
426 cg = changegroup.getlocalbundle(pushop.repo, 'push', outgoing,
388 bundlecaps)
427 bundlecaps)
389
428
390 # apply changegroup to remote
429 # apply changegroup to remote
391 if unbundle:
430 if unbundle:
392 # local repo finds heads on server, finds out what
431 # local repo finds heads on server, finds out what
393 # revs it must push. once revs transferred, if server
432 # revs it must push. once revs transferred, if server
394 # finds it has different heads (someone else won
433 # finds it has different heads (someone else won
395 # commit/push race), server aborts.
434 # commit/push race), server aborts.
396 if pushop.force:
435 if pushop.force:
397 remoteheads = ['force']
436 remoteheads = ['force']
398 else:
437 else:
399 remoteheads = pushop.remoteheads
438 remoteheads = pushop.remoteheads
400 # ssh: return remote's addchangegroup()
439 # ssh: return remote's addchangegroup()
401 # http: return remote's addchangegroup() or 0 for error
440 # http: return remote's addchangegroup() or 0 for error
402 pushop.ret = pushop.remote.unbundle(cg, remoteheads,
441 pushop.ret = pushop.remote.unbundle(cg, remoteheads,
403 pushop.repo.url())
442 pushop.repo.url())
404 else:
443 else:
405 # we return an integer indicating remote head count
444 # we return an integer indicating remote head count
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
417 and pushop.ret is None # nothing was pushed
455 and pushop.ret is None # nothing was pushed
418 and remotephases.get('publishing', False)):
456 and remotephases.get('publishing', False)):
419 # When:
457 # When:
420 # - this is a subrepo push
458 # - this is a subrepo push
421 # - and remote support phase
459 # - and remote support phase
422 # - and no changeset was pushed
460 # - and no changeset was pushed
423 # - and remote is publishing
461 # - and remote is publishing
424 # We may be in issue 3871 case!
462 # We may be in issue 3871 case!
425 # We drop the possible phase synchronisation done by
463 # We drop the possible phase synchronisation done by
426 # courtesy to publish changesets possibly locally draft
464 # courtesy to publish changesets possibly locally draft
427 # on the remote.
465 # on the remote.
428 remotephases = {'publishing': 'True'}
466 remotephases = {'publishing': 'True'}
429 if not remotephases: # old server or public only reply from non-publishing
467 if not remotephases: # old server or public only reply from non-publishing
430 _localphasemove(pushop, cheads)
468 _localphasemove(pushop, cheads)
431 # don't push any phase data as there is nothing to push
469 # don't push any phase data as there is nothing to push
432 else:
470 else:
433 ana = phases.analyzeremotephases(pushop.repo, cheads,
471 ana = phases.analyzeremotephases(pushop.repo, cheads,
434 remotephases)
472 remotephases)
435 pheads, droots = ana
473 pheads, droots = ana
436 ### Apply remote phase on local
474 ### Apply remote phase on local
437 if remotephases.get('publishing', False):
475 if remotephases.get('publishing', False):
438 _localphasemove(pushop, cheads)
476 _localphasemove(pushop, cheads)
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 #
454 # This will eventually be unified with the changesets bundle2 push
494 # This will eventually be unified with the changesets bundle2 push
455 bundler = bundle2.bundle20(pushop.ui, b2caps)
495 bundler = bundle2.bundle20(pushop.ui, b2caps)
456 capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
496 capsblob = bundle2.encodecaps(pushop.repo.bundle2caps)
457 bundler.newpart('b2x:replycaps', data=capsblob)
497 bundler.newpart('b2x:replycaps', data=capsblob)
458 part2node = []
498 part2node = []
459 enc = pushkey.encode
499 enc = pushkey.encode
460 for newremotehead in outdated:
500 for newremotehead in outdated:
461 part = bundler.newpart('b2x:pushkey')
501 part = bundler.newpart('b2x:pushkey')
462 part.addparam('namespace', enc('phases'))
502 part.addparam('namespace', enc('phases'))
463 part.addparam('key', enc(newremotehead.hex()))
503 part.addparam('key', enc(newremotehead.hex()))
464 part.addparam('old', enc(str(phases.draft)))
504 part.addparam('old', enc(str(phases.draft)))
465 part.addparam('new', enc(str(phases.public)))
505 part.addparam('new', enc(str(phases.public)))
466 part2node.append((part.id, newremotehead))
506 part2node.append((part.id, newremotehead))
467 stream = util.chunkbuffer(bundler.getchunks())
507 stream = util.chunkbuffer(bundler.getchunks())
468 try:
508 try:
469 reply = pushop.remote.unbundle(stream, ['force'], 'push')
509 reply = pushop.remote.unbundle(stream, ['force'], 'push')
470 op = bundle2.processbundle(pushop.repo, reply)
510 op = bundle2.processbundle(pushop.repo, reply)
471 except error.BundleValueError, exc:
511 except error.BundleValueError, exc:
472 raise util.Abort('missing support for %s' % exc)
512 raise util.Abort('missing support for %s' % exc)
473 for partid, node in part2node:
513 for partid, node in part2node:
474 partrep = op.records.getreplies(partid)
514 partrep = op.records.getreplies(partid)
475 results = partrep['pushkey']
515 results = partrep['pushkey']
476 assert len(results) <= 1
516 assert len(results) <= 1
477 msg = None
517 msg = None
478 if not results:
518 if not results:
479 msg = _('server ignored update of %s to public!\n') % node
519 msg = _('server ignored update of %s to public!\n') % node
480 elif not int(results[0]['return']):
520 elif not int(results[0]['return']):
481 msg = _('updating %s to public failed!\n') % node
521 msg = _('updating %s to public failed!\n') % node
482 if msg is not None:
522 if msg is not None:
483 pushop.ui.warn(msg)
523 pushop.ui.warn(msg)
484
524
485 else:
525 else:
486 # fallback to independant pushkey command
526 # fallback to independant pushkey command
487 for newremotehead in outdated:
527 for newremotehead in outdated:
488 r = pushop.remote.pushkey('phases',
528 r = pushop.remote.pushkey('phases',
489 newremotehead.hex(),
529 newremotehead.hex(),
490 str(phases.draft),
530 str(phases.draft),
491 str(phases.public))
531 str(phases.public))
492 if not r:
532 if not r:
493 pushop.ui.warn(_('updating %s to public failed!\n')
533 pushop.ui.warn(_('updating %s to public failed!\n')
494 % newremotehead)
534 % newremotehead)
495
535
496 def _localphasemove(pushop, nodes, phase=phases.public):
536 def _localphasemove(pushop, nodes, phase=phases.public):
497 """move <nodes> to <phase> in the local source repo"""
537 """move <nodes> to <phase> in the local source repo"""
498 if pushop.locallocked:
538 if pushop.locallocked:
499 phases.advanceboundary(pushop.repo, phase, nodes)
539 phases.advanceboundary(pushop.repo, phase, nodes)
500 else:
540 else:
501 # repo is not locked, do not change any phases!
541 # repo is not locked, do not change any phases!
502 # Informs the user that phases should have been moved when
542 # Informs the user that phases should have been moved when
503 # applicable.
543 # applicable.
504 actualmoves = [n for n in nodes if phase < pushop.repo[n].phase()]
544 actualmoves = [n for n in nodes if phase < pushop.repo[n].phase()]
505 phasestr = phases.phasenames[phase]
545 phasestr = phases.phasenames[phase]
506 if actualmoves:
546 if actualmoves:
507 pushop.ui.status(_('cannot lock source repo, skipping '
547 pushop.ui.status(_('cannot lock source repo, skipping '
508 'local %s phase update\n') % phasestr)
548 'local %s phase update\n') % phasestr)
509
549
510 def _pushobsolete(pushop):
550 def _pushobsolete(pushop):
511 """utility function to push obsolete markers to a remote"""
551 """utility function to push obsolete markers to a remote"""
512 pushop.ui.debug('try to push obsolete markers to remote\n')
552 pushop.ui.debug('try to push obsolete markers to remote\n')
513 repo = pushop.repo
553 repo = pushop.repo
514 remote = pushop.remote
554 remote = pushop.remote
515 if (obsolete._enabled and repo.obsstore and
555 if (obsolete._enabled and repo.obsstore and
516 'obsolete' in remote.listkeys('namespaces')):
556 'obsolete' in remote.listkeys('namespaces')):
517 rslts = []
557 rslts = []
518 remotedata = repo.listkeys('obsolete')
558 remotedata = repo.listkeys('obsolete')
519 for key in sorted(remotedata, reverse=True):
559 for key in sorted(remotedata, reverse=True):
520 # reverse sort to ensure we end with dump0
560 # reverse sort to ensure we end with dump0
521 data = remotedata[key]
561 data = remotedata[key]
522 rslts.append(remote.pushkey('obsolete', key, '', data))
562 rslts.append(remote.pushkey('obsolete', key, '', data))
523 if [r for r in rslts if not r]:
563 if [r for r in rslts if not r]:
524 msg = _('failed to push some obsolete markers!\n')
564 msg = _('failed to push some obsolete markers!\n')
525 repo.ui.warn(msg)
565 repo.ui.warn(msg)
526
566
527 def _pushbookmark(pushop):
567 def _pushbookmark(pushop):
528 """Update bookmark position on remote"""
568 """Update bookmark position on remote"""
529 ui = pushop.ui
569 ui = pushop.ui
530 repo = pushop.repo.unfiltered()
570 repo = pushop.repo.unfiltered()
531 remote = pushop.remote
571 remote = pushop.remote
532 ui.debug("checking for updated bookmarks\n")
572 ui.debug("checking for updated bookmarks\n")
533 revnums = map(repo.changelog.rev, pushop.revs or [])
573 revnums = map(repo.changelog.rev, pushop.revs or [])
534 ancestors = [a for a in repo.changelog.ancestors(revnums, inclusive=True)]
574 ancestors = [a for a in repo.changelog.ancestors(revnums, inclusive=True)]
535 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
575 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid
536 ) = bookmarks.compare(repo, repo._bookmarks, remote.listkeys('bookmarks'),
576 ) = bookmarks.compare(repo, repo._bookmarks, remote.listkeys('bookmarks'),
537 srchex=hex)
577 srchex=hex)
538
578
539 for b, scid, dcid in advsrc:
579 for b, scid, dcid in advsrc:
540 if ancestors and repo[scid].rev() not in ancestors:
580 if ancestors and repo[scid].rev() not in ancestors:
541 continue
581 continue
542 if remote.pushkey('bookmarks', b, dcid, scid):
582 if remote.pushkey('bookmarks', b, dcid, scid):
543 ui.status(_("updating bookmark %s\n") % b)
583 ui.status(_("updating bookmark %s\n") % b)
544 else:
584 else:
545 ui.warn(_('updating bookmark %s failed!\n') % b)
585 ui.warn(_('updating bookmark %s failed!\n') % b)
546
586
547 class pulloperation(object):
587 class pulloperation(object):
548 """A object that represent a single pull operation
588 """A object that represent a single pull operation
549
589
550 It purpose is to carry push related state and very common operation.
590 It purpose is to carry push related state and very common operation.
551
591
552 A new should be created at the beginning of each pull and discarded
592 A new should be created at the beginning of each pull and discarded
553 afterward.
593 afterward.
554 """
594 """
555
595
556 def __init__(self, repo, remote, heads=None, force=False):
596 def __init__(self, repo, remote, heads=None, force=False):
557 # repo we pull into
597 # repo we pull into
558 self.repo = repo
598 self.repo = repo
559 # repo we pull from
599 # repo we pull from
560 self.remote = remote
600 self.remote = remote
561 # revision we try to pull (None is "all")
601 # revision we try to pull (None is "all")
562 self.heads = heads
602 self.heads = heads
563 # do we force pull?
603 # do we force pull?
564 self.force = force
604 self.force = force
565 # the name the pull transaction
605 # the name the pull transaction
566 self._trname = 'pull\n' + util.hidepassword(remote.url())
606 self._trname = 'pull\n' + util.hidepassword(remote.url())
567 # hold the transaction once created
607 # hold the transaction once created
568 self._tr = None
608 self._tr = None
569 # set of common changeset between local and remote before pull
609 # set of common changeset between local and remote before pull
570 self.common = None
610 self.common = None
571 # set of pulled head
611 # set of pulled head
572 self.rheads = None
612 self.rheads = None
573 # list of missing changeset to fetch remotely
613 # list of missing changeset to fetch remotely
574 self.fetch = None
614 self.fetch = None
575 # result of changegroup pulling (used as return code by pull)
615 # result of changegroup pulling (used as return code by pull)
576 self.cgresult = None
616 self.cgresult = None
577 # list of step remaining todo (related to future bundle2 usage)
617 # list of step remaining todo (related to future bundle2 usage)
578 self.todosteps = set(['changegroup', 'phases', 'obsmarkers'])
618 self.todosteps = set(['changegroup', 'phases', 'obsmarkers'])
579
619
580 @util.propertycache
620 @util.propertycache
581 def pulledsubset(self):
621 def pulledsubset(self):
582 """heads of the set of changeset target by the pull"""
622 """heads of the set of changeset target by the pull"""
583 # compute target subset
623 # compute target subset
584 if self.heads is None:
624 if self.heads is None:
585 # We pulled every thing possible
625 # We pulled every thing possible
586 # sync on everything common
626 # sync on everything common
587 c = set(self.common)
627 c = set(self.common)
588 ret = list(self.common)
628 ret = list(self.common)
589 for n in self.rheads:
629 for n in self.rheads:
590 if n not in c:
630 if n not in c:
591 ret.append(n)
631 ret.append(n)
592 return ret
632 return ret
593 else:
633 else:
594 # We pulled a specific subset
634 # We pulled a specific subset
595 # sync on this subset
635 # sync on this subset
596 return self.heads
636 return self.heads
597
637
598 def gettransaction(self):
638 def gettransaction(self):
599 """get appropriate pull transaction, creating it if needed"""
639 """get appropriate pull transaction, creating it if needed"""
600 if self._tr is None:
640 if self._tr is None:
601 self._tr = self.repo.transaction(self._trname)
641 self._tr = self.repo.transaction(self._trname)
602 return self._tr
642 return self._tr
603
643
604 def closetransaction(self):
644 def closetransaction(self):
605 """close transaction if created"""
645 """close transaction if created"""
606 if self._tr is not None:
646 if self._tr is not None:
607 self._tr.close()
647 self._tr.close()
608
648
609 def releasetransaction(self):
649 def releasetransaction(self):
610 """release transaction if created"""
650 """release transaction if created"""
611 if self._tr is not None:
651 if self._tr is not None:
612 self._tr.release()
652 self._tr.release()
613
653
614 def pull(repo, remote, heads=None, force=False):
654 def pull(repo, remote, heads=None, force=False):
615 pullop = pulloperation(repo, remote, heads, force)
655 pullop = pulloperation(repo, remote, heads, force)
616 if pullop.remote.local():
656 if pullop.remote.local():
617 missing = set(pullop.remote.requirements) - pullop.repo.supported
657 missing = set(pullop.remote.requirements) - pullop.repo.supported
618 if missing:
658 if missing:
619 msg = _("required features are not"
659 msg = _("required features are not"
620 " supported in the destination:"
660 " supported in the destination:"
621 " %s") % (', '.join(sorted(missing)))
661 " %s") % (', '.join(sorted(missing)))
622 raise util.Abort(msg)
662 raise util.Abort(msg)
623
663
624 lock = pullop.repo.lock()
664 lock = pullop.repo.lock()
625 try:
665 try:
626 _pulldiscovery(pullop)
666 _pulldiscovery(pullop)
627 if (pullop.repo.ui.configbool('experimental', 'bundle2-exp', False)
667 if (pullop.repo.ui.configbool('experimental', 'bundle2-exp', False)
628 and pullop.remote.capable('bundle2-exp')):
668 and pullop.remote.capable('bundle2-exp')):
629 _pullbundle2(pullop)
669 _pullbundle2(pullop)
630 if 'changegroup' in pullop.todosteps:
670 if 'changegroup' in pullop.todosteps:
631 _pullchangeset(pullop)
671 _pullchangeset(pullop)
632 if 'phases' in pullop.todosteps:
672 if 'phases' in pullop.todosteps:
633 _pullphase(pullop)
673 _pullphase(pullop)
634 if 'obsmarkers' in pullop.todosteps:
674 if 'obsmarkers' in pullop.todosteps:
635 _pullobsolete(pullop)
675 _pullobsolete(pullop)
636 pullop.closetransaction()
676 pullop.closetransaction()
637 finally:
677 finally:
638 pullop.releasetransaction()
678 pullop.releasetransaction()
639 lock.release()
679 lock.release()
640
680
641 return pullop.cgresult
681 return pullop.cgresult
642
682
643 def _pulldiscovery(pullop):
683 def _pulldiscovery(pullop):
644 """discovery phase for the pull
684 """discovery phase for the pull
645
685
646 Current handle changeset discovery only, will change handle all discovery
686 Current handle changeset discovery only, will change handle all discovery
647 at some point."""
687 at some point."""
648 tmp = discovery.findcommonincoming(pullop.repo.unfiltered(),
688 tmp = discovery.findcommonincoming(pullop.repo.unfiltered(),
649 pullop.remote,
689 pullop.remote,
650 heads=pullop.heads,
690 heads=pullop.heads,
651 force=pullop.force)
691 force=pullop.force)
652 pullop.common, pullop.fetch, pullop.rheads = tmp
692 pullop.common, pullop.fetch, pullop.rheads = tmp
653
693
654 def _pullbundle2(pullop):
694 def _pullbundle2(pullop):
655 """pull data using bundle2
695 """pull data using bundle2
656
696
657 For now, the only supported data are changegroup."""
697 For now, the only supported data are changegroup."""
658 remotecaps = bundle2.bundle2caps(pullop.remote)
698 remotecaps = bundle2.bundle2caps(pullop.remote)
659 kwargs = {'bundlecaps': caps20to10(pullop.repo)}
699 kwargs = {'bundlecaps': caps20to10(pullop.repo)}
660 # pulling changegroup
700 # pulling changegroup
661 pullop.todosteps.remove('changegroup')
701 pullop.todosteps.remove('changegroup')
662
702
663 kwargs['common'] = pullop.common
703 kwargs['common'] = pullop.common
664 kwargs['heads'] = pullop.heads or pullop.rheads
704 kwargs['heads'] = pullop.heads or pullop.rheads
665 if 'b2x:listkeys' in remotecaps:
705 if 'b2x:listkeys' in remotecaps:
666 kwargs['listkeys'] = ['phase']
706 kwargs['listkeys'] = ['phase']
667 if not pullop.fetch:
707 if not pullop.fetch:
668 pullop.repo.ui.status(_("no changes found\n"))
708 pullop.repo.ui.status(_("no changes found\n"))
669 pullop.cgresult = 0
709 pullop.cgresult = 0
670 else:
710 else:
671 if pullop.heads is None and list(pullop.common) == [nullid]:
711 if pullop.heads is None and list(pullop.common) == [nullid]:
672 pullop.repo.ui.status(_("requesting all changes\n"))
712 pullop.repo.ui.status(_("requesting all changes\n"))
673 _pullbundle2extraprepare(pullop, kwargs)
713 _pullbundle2extraprepare(pullop, kwargs)
674 if kwargs.keys() == ['format']:
714 if kwargs.keys() == ['format']:
675 return # nothing to pull
715 return # nothing to pull
676 bundle = pullop.remote.getbundle('pull', **kwargs)
716 bundle = pullop.remote.getbundle('pull', **kwargs)
677 try:
717 try:
678 op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
718 op = bundle2.processbundle(pullop.repo, bundle, pullop.gettransaction)
679 except error.BundleValueError, exc:
719 except error.BundleValueError, exc:
680 raise util.Abort('missing support for %s' % exc)
720 raise util.Abort('missing support for %s' % exc)
681
721
682 if pullop.fetch:
722 if pullop.fetch:
683 assert len(op.records['changegroup']) == 1
723 assert len(op.records['changegroup']) == 1
684 pullop.cgresult = op.records['changegroup'][0]['return']
724 pullop.cgresult = op.records['changegroup'][0]['return']
685
725
686 # processing phases change
726 # processing phases change
687 for namespace, value in op.records['listkeys']:
727 for namespace, value in op.records['listkeys']:
688 if namespace == 'phases':
728 if namespace == 'phases':
689 _pullapplyphases(pullop, value)
729 _pullapplyphases(pullop, value)
690
730
691 def _pullbundle2extraprepare(pullop, kwargs):
731 def _pullbundle2extraprepare(pullop, kwargs):
692 """hook function so that extensions can extend the getbundle call"""
732 """hook function so that extensions can extend the getbundle call"""
693 pass
733 pass
694
734
695 def _pullchangeset(pullop):
735 def _pullchangeset(pullop):
696 """pull changeset from unbundle into the local repo"""
736 """pull changeset from unbundle into the local repo"""
697 # We delay the open of the transaction as late as possible so we
737 # We delay the open of the transaction as late as possible so we
698 # don't open transaction for nothing or you break future useful
738 # don't open transaction for nothing or you break future useful
699 # rollback call
739 # rollback call
700 pullop.todosteps.remove('changegroup')
740 pullop.todosteps.remove('changegroup')
701 if not pullop.fetch:
741 if not pullop.fetch:
702 pullop.repo.ui.status(_("no changes found\n"))
742 pullop.repo.ui.status(_("no changes found\n"))
703 pullop.cgresult = 0
743 pullop.cgresult = 0
704 return
744 return
705 pullop.gettransaction()
745 pullop.gettransaction()
706 if pullop.heads is None and list(pullop.common) == [nullid]:
746 if pullop.heads is None and list(pullop.common) == [nullid]:
707 pullop.repo.ui.status(_("requesting all changes\n"))
747 pullop.repo.ui.status(_("requesting all changes\n"))
708 elif pullop.heads is None and pullop.remote.capable('changegroupsubset'):
748 elif pullop.heads is None and pullop.remote.capable('changegroupsubset'):
709 # issue1320, avoid a race if remote changed after discovery
749 # issue1320, avoid a race if remote changed after discovery
710 pullop.heads = pullop.rheads
750 pullop.heads = pullop.rheads
711
751
712 if pullop.remote.capable('getbundle'):
752 if pullop.remote.capable('getbundle'):
713 # TODO: get bundlecaps from remote
753 # TODO: get bundlecaps from remote
714 cg = pullop.remote.getbundle('pull', common=pullop.common,
754 cg = pullop.remote.getbundle('pull', common=pullop.common,
715 heads=pullop.heads or pullop.rheads)
755 heads=pullop.heads or pullop.rheads)
716 elif pullop.heads is None:
756 elif pullop.heads is None:
717 cg = pullop.remote.changegroup(pullop.fetch, 'pull')
757 cg = pullop.remote.changegroup(pullop.fetch, 'pull')
718 elif not pullop.remote.capable('changegroupsubset'):
758 elif not pullop.remote.capable('changegroupsubset'):
719 raise util.Abort(_("partial pull cannot be done because "
759 raise util.Abort(_("partial pull cannot be done because "
720 "other repository doesn't support "
760 "other repository doesn't support "
721 "changegroupsubset."))
761 "changegroupsubset."))
722 else:
762 else:
723 cg = pullop.remote.changegroupsubset(pullop.fetch, pullop.heads, 'pull')
763 cg = pullop.remote.changegroupsubset(pullop.fetch, pullop.heads, 'pull')
724 pullop.cgresult = changegroup.addchangegroup(pullop.repo, cg, 'pull',
764 pullop.cgresult = changegroup.addchangegroup(pullop.repo, cg, 'pull',
725 pullop.remote.url())
765 pullop.remote.url())
726
766
727 def _pullphase(pullop):
767 def _pullphase(pullop):
728 # Get remote phases data from remote
768 # Get remote phases data from remote
729 remotephases = pullop.remote.listkeys('phases')
769 remotephases = pullop.remote.listkeys('phases')
730 _pullapplyphases(pullop, remotephases)
770 _pullapplyphases(pullop, remotephases)
731
771
732 def _pullapplyphases(pullop, remotephases):
772 def _pullapplyphases(pullop, remotephases):
733 """apply phase movement from observed remote state"""
773 """apply phase movement from observed remote state"""
734 pullop.todosteps.remove('phases')
774 pullop.todosteps.remove('phases')
735 publishing = bool(remotephases.get('publishing', False))
775 publishing = bool(remotephases.get('publishing', False))
736 if remotephases and not publishing:
776 if remotephases and not publishing:
737 # remote is new and unpublishing
777 # remote is new and unpublishing
738 pheads, _dr = phases.analyzeremotephases(pullop.repo,
778 pheads, _dr = phases.analyzeremotephases(pullop.repo,
739 pullop.pulledsubset,
779 pullop.pulledsubset,
740 remotephases)
780 remotephases)
741 phases.advanceboundary(pullop.repo, phases.public, pheads)
781 phases.advanceboundary(pullop.repo, phases.public, pheads)
742 phases.advanceboundary(pullop.repo, phases.draft,
782 phases.advanceboundary(pullop.repo, phases.draft,
743 pullop.pulledsubset)
783 pullop.pulledsubset)
744 else:
784 else:
745 # Remote is old or publishing all common changesets
785 # Remote is old or publishing all common changesets
746 # should be seen as public
786 # should be seen as public
747 phases.advanceboundary(pullop.repo, phases.public,
787 phases.advanceboundary(pullop.repo, phases.public,
748 pullop.pulledsubset)
788 pullop.pulledsubset)
749
789
750 def _pullobsolete(pullop):
790 def _pullobsolete(pullop):
751 """utility function to pull obsolete markers from a remote
791 """utility function to pull obsolete markers from a remote
752
792
753 The `gettransaction` is function that return the pull transaction, creating
793 The `gettransaction` is function that return the pull transaction, creating
754 one if necessary. We return the transaction to inform the calling code that
794 one if necessary. We return the transaction to inform the calling code that
755 a new transaction have been created (when applicable).
795 a new transaction have been created (when applicable).
756
796
757 Exists mostly to allow overriding for experimentation purpose"""
797 Exists mostly to allow overriding for experimentation purpose"""
758 pullop.todosteps.remove('obsmarkers')
798 pullop.todosteps.remove('obsmarkers')
759 tr = None
799 tr = None
760 if obsolete._enabled:
800 if obsolete._enabled:
761 pullop.repo.ui.debug('fetching remote obsolete markers\n')
801 pullop.repo.ui.debug('fetching remote obsolete markers\n')
762 remoteobs = pullop.remote.listkeys('obsolete')
802 remoteobs = pullop.remote.listkeys('obsolete')
763 if 'dump0' in remoteobs:
803 if 'dump0' in remoteobs:
764 tr = pullop.gettransaction()
804 tr = pullop.gettransaction()
765 for key in sorted(remoteobs, reverse=True):
805 for key in sorted(remoteobs, reverse=True):
766 if key.startswith('dump'):
806 if key.startswith('dump'):
767 data = base85.b85decode(remoteobs[key])
807 data = base85.b85decode(remoteobs[key])
768 pullop.repo.obsstore.mergemarkers(tr, data)
808 pullop.repo.obsstore.mergemarkers(tr, data)
769 pullop.repo.invalidatevolatilesets()
809 pullop.repo.invalidatevolatilesets()
770 return tr
810 return tr
771
811
772 def caps20to10(repo):
812 def caps20to10(repo):
773 """return a set with appropriate options to use bundle20 during getbundle"""
813 """return a set with appropriate options to use bundle20 during getbundle"""
774 caps = set(['HG2X'])
814 caps = set(['HG2X'])
775 capsblob = bundle2.encodecaps(repo.bundle2caps)
815 capsblob = bundle2.encodecaps(repo.bundle2caps)
776 caps.add('bundle2=' + urllib.quote(capsblob))
816 caps.add('bundle2=' + urllib.quote(capsblob))
777 return caps
817 return caps
778
818
779 def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
819 def getbundle(repo, source, heads=None, common=None, bundlecaps=None,
780 **kwargs):
820 **kwargs):
781 """return a full bundle (with potentially multiple kind of parts)
821 """return a full bundle (with potentially multiple kind of parts)
782
822
783 Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
823 Could be a bundle HG10 or a bundle HG2X depending on bundlecaps
784 passed. For now, the bundle can contain only changegroup, but this will
824 passed. For now, the bundle can contain only changegroup, but this will
785 changes when more part type will be available for bundle2.
825 changes when more part type will be available for bundle2.
786
826
787 This is different from changegroup.getbundle that only returns an HG10
827 This is different from changegroup.getbundle that only returns an HG10
788 changegroup bundle. They may eventually get reunited in the future when we
828 changegroup bundle. They may eventually get reunited in the future when we
789 have a clearer idea of the API we what to query different data.
829 have a clearer idea of the API we what to query different data.
790
830
791 The implementation is at a very early stage and will get massive rework
831 The implementation is at a very early stage and will get massive rework
792 when the API of bundle is refined.
832 when the API of bundle is refined.
793 """
833 """
794 cg = None
834 cg = None
795 if kwargs.get('cg', True):
835 if kwargs.get('cg', True):
796 # build changegroup bundle here.
836 # build changegroup bundle here.
797 cg = changegroup.getbundle(repo, source, heads=heads,
837 cg = changegroup.getbundle(repo, source, heads=heads,
798 common=common, bundlecaps=bundlecaps)
838 common=common, bundlecaps=bundlecaps)
799 elif 'HG2X' not in bundlecaps:
839 elif 'HG2X' not in bundlecaps:
800 raise ValueError(_('request for bundle10 must include changegroup'))
840 raise ValueError(_('request for bundle10 must include changegroup'))
801 if bundlecaps is None or 'HG2X' not in bundlecaps:
841 if bundlecaps is None or 'HG2X' not in bundlecaps:
802 if kwargs:
842 if kwargs:
803 raise ValueError(_('unsupported getbundle arguments: %s')
843 raise ValueError(_('unsupported getbundle arguments: %s')
804 % ', '.join(sorted(kwargs.keys())))
844 % ', '.join(sorted(kwargs.keys())))
805 return cg
845 return cg
806 # very crude first implementation,
846 # very crude first implementation,
807 # the bundle API will change and the generation will be done lazily.
847 # the bundle API will change and the generation will be done lazily.
808 b2caps = {}
848 b2caps = {}
809 for bcaps in bundlecaps:
849 for bcaps in bundlecaps:
810 if bcaps.startswith('bundle2='):
850 if bcaps.startswith('bundle2='):
811 blob = urllib.unquote(bcaps[len('bundle2='):])
851 blob = urllib.unquote(bcaps[len('bundle2='):])
812 b2caps.update(bundle2.decodecaps(blob))
852 b2caps.update(bundle2.decodecaps(blob))
813 bundler = bundle2.bundle20(repo.ui, b2caps)
853 bundler = bundle2.bundle20(repo.ui, b2caps)
814 if cg:
854 if cg:
815 bundler.newpart('b2x:changegroup', data=cg.getchunks())
855 bundler.newpart('b2x:changegroup', data=cg.getchunks())
816 listkeys = kwargs.get('listkeys', ())
856 listkeys = kwargs.get('listkeys', ())
817 for namespace in listkeys:
857 for namespace in listkeys:
818 part = bundler.newpart('b2x:listkeys')
858 part = bundler.newpart('b2x:listkeys')
819 part.addparam('namespace', namespace)
859 part.addparam('namespace', namespace)
820 keys = repo.listkeys(namespace).items()
860 keys = repo.listkeys(namespace).items()
821 part.data = pushkey.encodekeys(keys)
861 part.data = pushkey.encodekeys(keys)
822 _getbundleextrapart(bundler, repo, source, heads=heads, common=common,
862 _getbundleextrapart(bundler, repo, source, heads=heads, common=common,
823 bundlecaps=bundlecaps, **kwargs)
863 bundlecaps=bundlecaps, **kwargs)
824 return util.chunkbuffer(bundler.getchunks())
864 return util.chunkbuffer(bundler.getchunks())
825
865
826 def _getbundleextrapart(bundler, repo, source, heads=None, common=None,
866 def _getbundleextrapart(bundler, repo, source, heads=None, common=None,
827 bundlecaps=None, **kwargs):
867 bundlecaps=None, **kwargs):
828 """hook function to let extensions add parts to the requested bundle"""
868 """hook function to let extensions add parts to the requested bundle"""
829 pass
869 pass
830
870
831 def check_heads(repo, their_heads, context):
871 def check_heads(repo, their_heads, context):
832 """check if the heads of a repo have been modified
872 """check if the heads of a repo have been modified
833
873
834 Used by peer for unbundling.
874 Used by peer for unbundling.
835 """
875 """
836 heads = repo.heads()
876 heads = repo.heads()
837 heads_hash = util.sha1(''.join(sorted(heads))).digest()
877 heads_hash = util.sha1(''.join(sorted(heads))).digest()
838 if not (their_heads == ['force'] or their_heads == heads or
878 if not (their_heads == ['force'] or their_heads == heads or
839 their_heads == ['hashed', heads_hash]):
879 their_heads == ['hashed', heads_hash]):
840 # someone else committed/pushed/unbundled while we
880 # someone else committed/pushed/unbundled while we
841 # were transferring data
881 # were transferring data
842 raise error.PushRaced('repository changed while %s - '
882 raise error.PushRaced('repository changed while %s - '
843 'please try again' % context)
883 'please try again' % context)
844
884
845 def unbundle(repo, cg, heads, source, url):
885 def unbundle(repo, cg, heads, source, url):
846 """Apply a bundle to a repo.
886 """Apply a bundle to a repo.
847
887
848 this function makes sure the repo is locked during the application and have
888 this function makes sure the repo is locked during the application and have
849 mechanism to check that no push race occurred between the creation of the
889 mechanism to check that no push race occurred between the creation of the
850 bundle and its application.
890 bundle and its application.
851
891
852 If the push was raced as PushRaced exception is raised."""
892 If the push was raced as PushRaced exception is raised."""
853 r = 0
893 r = 0
854 # need a transaction when processing a bundle2 stream
894 # need a transaction when processing a bundle2 stream
855 tr = None
895 tr = None
856 lock = repo.lock()
896 lock = repo.lock()
857 try:
897 try:
858 check_heads(repo, heads, 'uploading changes')
898 check_heads(repo, heads, 'uploading changes')
859 # push can proceed
899 # push can proceed
860 if util.safehasattr(cg, 'params'):
900 if util.safehasattr(cg, 'params'):
861 try:
901 try:
862 tr = repo.transaction('unbundle')
902 tr = repo.transaction('unbundle')
863 tr.hookargs['bundle2-exp'] = '1'
903 tr.hookargs['bundle2-exp'] = '1'
864 r = bundle2.processbundle(repo, cg, lambda: tr).reply
904 r = bundle2.processbundle(repo, cg, lambda: tr).reply
865 cl = repo.unfiltered().changelog
905 cl = repo.unfiltered().changelog
866 p = cl.writepending() and repo.root or ""
906 p = cl.writepending() and repo.root or ""
867 repo.hook('b2x-pretransactionclose', throw=True, source=source,
907 repo.hook('b2x-pretransactionclose', throw=True, source=source,
868 url=url, pending=p, **tr.hookargs)
908 url=url, pending=p, **tr.hookargs)
869 tr.close()
909 tr.close()
870 repo.hook('b2x-transactionclose', source=source, url=url,
910 repo.hook('b2x-transactionclose', source=source, url=url,
871 **tr.hookargs)
911 **tr.hookargs)
872 except Exception, exc:
912 except Exception, exc:
873 exc.duringunbundle2 = True
913 exc.duringunbundle2 = True
874 raise
914 raise
875 else:
915 else:
876 r = changegroup.addchangegroup(repo, cg, source, url)
916 r = changegroup.addchangegroup(repo, cg, source, url)
877 finally:
917 finally:
878 if tr is not None:
918 if tr is not None:
879 tr.release()
919 tr.release()
880 lock.release()
920 lock.release()
881 return r
921 return r
@@ -1,2139 +1,2166 b''
1 > do_push()
1 > do_push()
2 > {
2 > {
3 > user=$1
3 > user=$1
4 > shift
4 > shift
5 > echo "Pushing as user $user"
5 > echo "Pushing as user $user"
6 > echo 'hgrc = """'
6 > echo 'hgrc = """'
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
7 > sed -e 1,2d b/.hg/hgrc | grep -v fakegroups.py
8 > echo '"""'
8 > echo '"""'
9 > if test -f acl.config; then
9 > if test -f acl.config; then
10 > echo 'acl.config = """'
10 > echo 'acl.config = """'
11 > cat acl.config
11 > cat acl.config
12 > echo '"""'
12 > echo '"""'
13 > fi
13 > fi
14 > # On AIX /etc/profile sets LOGNAME read-only. So
14 > # On AIX /etc/profile sets LOGNAME read-only. So
15 > # LOGNAME=$user hg --cws a --debug push ../b
15 > # LOGNAME=$user hg --cws a --debug push ../b
16 > # fails with "This variable is read only."
16 > # fails with "This variable is read only."
17 > # Use env to work around this.
17 > # Use env to work around this.
18 > env LOGNAME=$user hg --cwd a --debug push ../b
18 > env LOGNAME=$user hg --cwd a --debug push ../b
19 > hg --cwd b rollback
19 > hg --cwd b rollback
20 > hg --cwd b --quiet tip
20 > hg --cwd b --quiet tip
21 > echo
21 > echo
22 > }
22 > }
23
23
24 > init_config()
24 > init_config()
25 > {
25 > {
26 > cat > fakegroups.py <<EOF
26 > cat > fakegroups.py <<EOF
27 > from hgext import acl
27 > from hgext import acl
28 > def fakegetusers(ui, group):
28 > def fakegetusers(ui, group):
29 > try:
29 > try:
30 > return acl._getusersorig(ui, group)
30 > return acl._getusersorig(ui, group)
31 > except:
31 > except:
32 > return ["fred", "betty"]
32 > return ["fred", "betty"]
33 > acl._getusersorig = acl._getusers
33 > acl._getusersorig = acl._getusers
34 > acl._getusers = fakegetusers
34 > acl._getusers = fakegetusers
35 > EOF
35 > EOF
36 > rm -f acl.config
36 > rm -f acl.config
37 > cat > $config <<EOF
37 > cat > $config <<EOF
38 > [hooks]
38 > [hooks]
39 > pretxnchangegroup.acl = python:hgext.acl.hook
39 > pretxnchangegroup.acl = python:hgext.acl.hook
40 > [acl]
40 > [acl]
41 > sources = push
41 > sources = push
42 > [extensions]
42 > [extensions]
43 > f=`pwd`/fakegroups.py
43 > f=`pwd`/fakegroups.py
44 > EOF
44 > EOF
45 > }
45 > }
46
46
47 $ hg init a
47 $ hg init a
48 $ cd a
48 $ cd a
49 $ mkdir foo foo/Bar quux
49 $ mkdir foo foo/Bar quux
50 $ echo 'in foo' > foo/file.txt
50 $ echo 'in foo' > foo/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
51 $ echo 'in foo/Bar' > foo/Bar/file.txt
52 $ echo 'in quux' > quux/file.py
52 $ echo 'in quux' > quux/file.py
53 $ hg add -q
53 $ hg add -q
54 $ hg ci -m 'add files' -d '1000000 0'
54 $ hg ci -m 'add files' -d '1000000 0'
55 $ echo >> foo/file.txt
55 $ echo >> foo/file.txt
56 $ hg ci -m 'change foo/file' -d '1000001 0'
56 $ hg ci -m 'change foo/file' -d '1000001 0'
57 $ echo >> foo/Bar/file.txt
57 $ echo >> foo/Bar/file.txt
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
58 $ hg ci -m 'change foo/Bar/file' -d '1000002 0'
59 $ echo >> quux/file.py
59 $ echo >> quux/file.py
60 $ hg ci -m 'change quux/file' -d '1000003 0'
60 $ hg ci -m 'change quux/file' -d '1000003 0'
61 $ hg tip --quiet
61 $ hg tip --quiet
62 3:911600dab2ae
62 3:911600dab2ae
63
63
64 $ cd ..
64 $ cd ..
65 $ hg clone -r 0 a b
65 $ hg clone -r 0 a b
66 adding changesets
66 adding changesets
67 adding manifests
67 adding manifests
68 adding file changes
68 adding file changes
69 added 1 changesets with 3 changes to 3 files
69 added 1 changesets with 3 changes to 3 files
70 updating to branch default
70 updating to branch default
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
72
72
73 $ config=b/.hg/hgrc
73 $ config=b/.hg/hgrc
74
74
75 Extension disabled for lack of a hook
75 Extension disabled for lack of a hook
76
76
77 $ do_push fred
77 $ do_push fred
78 Pushing as user fred
78 Pushing as user fred
79 hgrc = """
79 hgrc = """
80 """
80 """
81 pushing to ../b
81 pushing to ../b
82 query 1; heads
82 query 1; heads
83 searching for changes
83 searching for changes
84 all remote heads known locally
84 all remote heads known locally
85 listing keys for "phases"
85 listing keys for "bookmarks"
86 listing keys for "bookmarks"
86 3 changesets found
87 3 changesets found
87 list of changesets:
88 list of changesets:
88 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
89 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
89 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
90 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
90 911600dab2ae7a9baff75958b84fe606851ce955
91 911600dab2ae7a9baff75958b84fe606851ce955
91 bundling: 1/3 changesets (33.33%)
92 bundling: 1/3 changesets (33.33%)
92 bundling: 2/3 changesets (66.67%)
93 bundling: 2/3 changesets (66.67%)
93 bundling: 3/3 changesets (100.00%)
94 bundling: 3/3 changesets (100.00%)
94 bundling: 1/3 manifests (33.33%)
95 bundling: 1/3 manifests (33.33%)
95 bundling: 2/3 manifests (66.67%)
96 bundling: 2/3 manifests (66.67%)
96 bundling: 3/3 manifests (100.00%)
97 bundling: 3/3 manifests (100.00%)
97 bundling: foo/Bar/file.txt 1/3 files (33.33%)
98 bundling: foo/Bar/file.txt 1/3 files (33.33%)
98 bundling: foo/file.txt 2/3 files (66.67%)
99 bundling: foo/file.txt 2/3 files (66.67%)
99 bundling: quux/file.py 3/3 files (100.00%)
100 bundling: quux/file.py 3/3 files (100.00%)
100 adding changesets
101 adding changesets
101 changesets: 1 chunks
102 changesets: 1 chunks
102 add changeset ef1ea85a6374
103 add changeset ef1ea85a6374
103 changesets: 2 chunks
104 changesets: 2 chunks
104 add changeset f9cafe1212c8
105 add changeset f9cafe1212c8
105 changesets: 3 chunks
106 changesets: 3 chunks
106 add changeset 911600dab2ae
107 add changeset 911600dab2ae
107 adding manifests
108 adding manifests
108 manifests: 1/3 chunks (33.33%)
109 manifests: 1/3 chunks (33.33%)
109 manifests: 2/3 chunks (66.67%)
110 manifests: 2/3 chunks (66.67%)
110 manifests: 3/3 chunks (100.00%)
111 manifests: 3/3 chunks (100.00%)
111 adding file changes
112 adding file changes
112 adding foo/Bar/file.txt revisions
113 adding foo/Bar/file.txt revisions
113 files: 1/3 chunks (33.33%)
114 files: 1/3 chunks (33.33%)
114 adding foo/file.txt revisions
115 adding foo/file.txt revisions
115 files: 2/3 chunks (66.67%)
116 files: 2/3 chunks (66.67%)
116 adding quux/file.py revisions
117 adding quux/file.py revisions
117 files: 3/3 chunks (100.00%)
118 files: 3/3 chunks (100.00%)
118 added 3 changesets with 3 changes to 3 files
119 added 3 changesets with 3 changes to 3 files
119 updating the branch cache
120 updating the branch cache
120 listing keys for "phases"
121 listing keys for "phases"
121 try to push obsolete markers to remote
122 try to push obsolete markers to remote
122 checking for updated bookmarks
123 checking for updated bookmarks
123 listing keys for "bookmarks"
124 listing keys for "bookmarks"
124 repository tip rolled back to revision 0 (undo push)
125 repository tip rolled back to revision 0 (undo push)
125 0:6675d58eff77
126 0:6675d58eff77
126
127
127
128
128 $ echo '[hooks]' >> $config
129 $ echo '[hooks]' >> $config
129 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
130 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
130
131
131 Extension disabled for lack of acl.sources
132 Extension disabled for lack of acl.sources
132
133
133 $ do_push fred
134 $ do_push fred
134 Pushing as user fred
135 Pushing as user fred
135 hgrc = """
136 hgrc = """
136 [hooks]
137 [hooks]
137 pretxnchangegroup.acl = python:hgext.acl.hook
138 pretxnchangegroup.acl = python:hgext.acl.hook
138 """
139 """
139 pushing to ../b
140 pushing to ../b
140 query 1; heads
141 query 1; heads
141 searching for changes
142 searching for changes
142 all remote heads known locally
143 all remote heads known locally
144 listing keys for "phases"
143 invalid branchheads cache (served): tip differs
145 invalid branchheads cache (served): tip differs
144 listing keys for "bookmarks"
146 listing keys for "bookmarks"
145 3 changesets found
147 3 changesets found
146 list of changesets:
148 list of changesets:
147 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
149 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
148 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
150 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
149 911600dab2ae7a9baff75958b84fe606851ce955
151 911600dab2ae7a9baff75958b84fe606851ce955
150 bundling: 1/3 changesets (33.33%)
152 bundling: 1/3 changesets (33.33%)
151 bundling: 2/3 changesets (66.67%)
153 bundling: 2/3 changesets (66.67%)
152 bundling: 3/3 changesets (100.00%)
154 bundling: 3/3 changesets (100.00%)
153 bundling: 1/3 manifests (33.33%)
155 bundling: 1/3 manifests (33.33%)
154 bundling: 2/3 manifests (66.67%)
156 bundling: 2/3 manifests (66.67%)
155 bundling: 3/3 manifests (100.00%)
157 bundling: 3/3 manifests (100.00%)
156 bundling: foo/Bar/file.txt 1/3 files (33.33%)
158 bundling: foo/Bar/file.txt 1/3 files (33.33%)
157 bundling: foo/file.txt 2/3 files (66.67%)
159 bundling: foo/file.txt 2/3 files (66.67%)
158 bundling: quux/file.py 3/3 files (100.00%)
160 bundling: quux/file.py 3/3 files (100.00%)
159 adding changesets
161 adding changesets
160 changesets: 1 chunks
162 changesets: 1 chunks
161 add changeset ef1ea85a6374
163 add changeset ef1ea85a6374
162 changesets: 2 chunks
164 changesets: 2 chunks
163 add changeset f9cafe1212c8
165 add changeset f9cafe1212c8
164 changesets: 3 chunks
166 changesets: 3 chunks
165 add changeset 911600dab2ae
167 add changeset 911600dab2ae
166 adding manifests
168 adding manifests
167 manifests: 1/3 chunks (33.33%)
169 manifests: 1/3 chunks (33.33%)
168 manifests: 2/3 chunks (66.67%)
170 manifests: 2/3 chunks (66.67%)
169 manifests: 3/3 chunks (100.00%)
171 manifests: 3/3 chunks (100.00%)
170 adding file changes
172 adding file changes
171 adding foo/Bar/file.txt revisions
173 adding foo/Bar/file.txt revisions
172 files: 1/3 chunks (33.33%)
174 files: 1/3 chunks (33.33%)
173 adding foo/file.txt revisions
175 adding foo/file.txt revisions
174 files: 2/3 chunks (66.67%)
176 files: 2/3 chunks (66.67%)
175 adding quux/file.py revisions
177 adding quux/file.py revisions
176 files: 3/3 chunks (100.00%)
178 files: 3/3 chunks (100.00%)
177 added 3 changesets with 3 changes to 3 files
179 added 3 changesets with 3 changes to 3 files
178 calling hook pretxnchangegroup.acl: hgext.acl.hook
180 calling hook pretxnchangegroup.acl: hgext.acl.hook
179 acl: changes have source "push" - skipping
181 acl: changes have source "push" - skipping
180 updating the branch cache
182 updating the branch cache
181 listing keys for "phases"
183 listing keys for "phases"
182 try to push obsolete markers to remote
184 try to push obsolete markers to remote
183 checking for updated bookmarks
185 checking for updated bookmarks
184 listing keys for "bookmarks"
186 listing keys for "bookmarks"
185 repository tip rolled back to revision 0 (undo push)
187 repository tip rolled back to revision 0 (undo push)
186 0:6675d58eff77
188 0:6675d58eff77
187
189
188
190
189 No [acl.allow]/[acl.deny]
191 No [acl.allow]/[acl.deny]
190
192
191 $ echo '[acl]' >> $config
193 $ echo '[acl]' >> $config
192 $ echo 'sources = push' >> $config
194 $ echo 'sources = push' >> $config
193 $ do_push fred
195 $ do_push fred
194 Pushing as user fred
196 Pushing as user fred
195 hgrc = """
197 hgrc = """
196 [hooks]
198 [hooks]
197 pretxnchangegroup.acl = python:hgext.acl.hook
199 pretxnchangegroup.acl = python:hgext.acl.hook
198 [acl]
200 [acl]
199 sources = push
201 sources = push
200 """
202 """
201 pushing to ../b
203 pushing to ../b
202 query 1; heads
204 query 1; heads
203 searching for changes
205 searching for changes
204 all remote heads known locally
206 all remote heads known locally
207 listing keys for "phases"
205 invalid branchheads cache (served): tip differs
208 invalid branchheads cache (served): tip differs
206 listing keys for "bookmarks"
209 listing keys for "bookmarks"
207 3 changesets found
210 3 changesets found
208 list of changesets:
211 list of changesets:
209 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
212 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
210 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
213 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
211 911600dab2ae7a9baff75958b84fe606851ce955
214 911600dab2ae7a9baff75958b84fe606851ce955
212 bundling: 1/3 changesets (33.33%)
215 bundling: 1/3 changesets (33.33%)
213 bundling: 2/3 changesets (66.67%)
216 bundling: 2/3 changesets (66.67%)
214 bundling: 3/3 changesets (100.00%)
217 bundling: 3/3 changesets (100.00%)
215 bundling: 1/3 manifests (33.33%)
218 bundling: 1/3 manifests (33.33%)
216 bundling: 2/3 manifests (66.67%)
219 bundling: 2/3 manifests (66.67%)
217 bundling: 3/3 manifests (100.00%)
220 bundling: 3/3 manifests (100.00%)
218 bundling: foo/Bar/file.txt 1/3 files (33.33%)
221 bundling: foo/Bar/file.txt 1/3 files (33.33%)
219 bundling: foo/file.txt 2/3 files (66.67%)
222 bundling: foo/file.txt 2/3 files (66.67%)
220 bundling: quux/file.py 3/3 files (100.00%)
223 bundling: quux/file.py 3/3 files (100.00%)
221 adding changesets
224 adding changesets
222 changesets: 1 chunks
225 changesets: 1 chunks
223 add changeset ef1ea85a6374
226 add changeset ef1ea85a6374
224 changesets: 2 chunks
227 changesets: 2 chunks
225 add changeset f9cafe1212c8
228 add changeset f9cafe1212c8
226 changesets: 3 chunks
229 changesets: 3 chunks
227 add changeset 911600dab2ae
230 add changeset 911600dab2ae
228 adding manifests
231 adding manifests
229 manifests: 1/3 chunks (33.33%)
232 manifests: 1/3 chunks (33.33%)
230 manifests: 2/3 chunks (66.67%)
233 manifests: 2/3 chunks (66.67%)
231 manifests: 3/3 chunks (100.00%)
234 manifests: 3/3 chunks (100.00%)
232 adding file changes
235 adding file changes
233 adding foo/Bar/file.txt revisions
236 adding foo/Bar/file.txt revisions
234 files: 1/3 chunks (33.33%)
237 files: 1/3 chunks (33.33%)
235 adding foo/file.txt revisions
238 adding foo/file.txt revisions
236 files: 2/3 chunks (66.67%)
239 files: 2/3 chunks (66.67%)
237 adding quux/file.py revisions
240 adding quux/file.py revisions
238 files: 3/3 chunks (100.00%)
241 files: 3/3 chunks (100.00%)
239 added 3 changesets with 3 changes to 3 files
242 added 3 changesets with 3 changes to 3 files
240 calling hook pretxnchangegroup.acl: hgext.acl.hook
243 calling hook pretxnchangegroup.acl: hgext.acl.hook
241 acl: checking access for user "fred"
244 acl: checking access for user "fred"
242 acl: acl.allow.branches not enabled
245 acl: acl.allow.branches not enabled
243 acl: acl.deny.branches not enabled
246 acl: acl.deny.branches not enabled
244 acl: acl.allow not enabled
247 acl: acl.allow not enabled
245 acl: acl.deny not enabled
248 acl: acl.deny not enabled
246 acl: branch access granted: "ef1ea85a6374" on branch "default"
249 acl: branch access granted: "ef1ea85a6374" on branch "default"
247 acl: path access granted: "ef1ea85a6374"
250 acl: path access granted: "ef1ea85a6374"
248 acl: branch access granted: "f9cafe1212c8" on branch "default"
251 acl: branch access granted: "f9cafe1212c8" on branch "default"
249 acl: path access granted: "f9cafe1212c8"
252 acl: path access granted: "f9cafe1212c8"
250 acl: branch access granted: "911600dab2ae" on branch "default"
253 acl: branch access granted: "911600dab2ae" on branch "default"
251 acl: path access granted: "911600dab2ae"
254 acl: path access granted: "911600dab2ae"
252 updating the branch cache
255 updating the branch cache
253 listing keys for "phases"
256 listing keys for "phases"
254 try to push obsolete markers to remote
257 try to push obsolete markers to remote
255 checking for updated bookmarks
258 checking for updated bookmarks
256 listing keys for "bookmarks"
259 listing keys for "bookmarks"
257 repository tip rolled back to revision 0 (undo push)
260 repository tip rolled back to revision 0 (undo push)
258 0:6675d58eff77
261 0:6675d58eff77
259
262
260
263
261 Empty [acl.allow]
264 Empty [acl.allow]
262
265
263 $ echo '[acl.allow]' >> $config
266 $ echo '[acl.allow]' >> $config
264 $ do_push fred
267 $ do_push fred
265 Pushing as user fred
268 Pushing as user fred
266 hgrc = """
269 hgrc = """
267 [hooks]
270 [hooks]
268 pretxnchangegroup.acl = python:hgext.acl.hook
271 pretxnchangegroup.acl = python:hgext.acl.hook
269 [acl]
272 [acl]
270 sources = push
273 sources = push
271 [acl.allow]
274 [acl.allow]
272 """
275 """
273 pushing to ../b
276 pushing to ../b
274 query 1; heads
277 query 1; heads
275 searching for changes
278 searching for changes
276 all remote heads known locally
279 all remote heads known locally
280 listing keys for "phases"
277 invalid branchheads cache (served): tip differs
281 invalid branchheads cache (served): tip differs
278 listing keys for "bookmarks"
282 listing keys for "bookmarks"
279 3 changesets found
283 3 changesets found
280 list of changesets:
284 list of changesets:
281 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
285 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
282 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
286 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
283 911600dab2ae7a9baff75958b84fe606851ce955
287 911600dab2ae7a9baff75958b84fe606851ce955
284 bundling: 1/3 changesets (33.33%)
288 bundling: 1/3 changesets (33.33%)
285 bundling: 2/3 changesets (66.67%)
289 bundling: 2/3 changesets (66.67%)
286 bundling: 3/3 changesets (100.00%)
290 bundling: 3/3 changesets (100.00%)
287 bundling: 1/3 manifests (33.33%)
291 bundling: 1/3 manifests (33.33%)
288 bundling: 2/3 manifests (66.67%)
292 bundling: 2/3 manifests (66.67%)
289 bundling: 3/3 manifests (100.00%)
293 bundling: 3/3 manifests (100.00%)
290 bundling: foo/Bar/file.txt 1/3 files (33.33%)
294 bundling: foo/Bar/file.txt 1/3 files (33.33%)
291 bundling: foo/file.txt 2/3 files (66.67%)
295 bundling: foo/file.txt 2/3 files (66.67%)
292 bundling: quux/file.py 3/3 files (100.00%)
296 bundling: quux/file.py 3/3 files (100.00%)
293 adding changesets
297 adding changesets
294 changesets: 1 chunks
298 changesets: 1 chunks
295 add changeset ef1ea85a6374
299 add changeset ef1ea85a6374
296 changesets: 2 chunks
300 changesets: 2 chunks
297 add changeset f9cafe1212c8
301 add changeset f9cafe1212c8
298 changesets: 3 chunks
302 changesets: 3 chunks
299 add changeset 911600dab2ae
303 add changeset 911600dab2ae
300 adding manifests
304 adding manifests
301 manifests: 1/3 chunks (33.33%)
305 manifests: 1/3 chunks (33.33%)
302 manifests: 2/3 chunks (66.67%)
306 manifests: 2/3 chunks (66.67%)
303 manifests: 3/3 chunks (100.00%)
307 manifests: 3/3 chunks (100.00%)
304 adding file changes
308 adding file changes
305 adding foo/Bar/file.txt revisions
309 adding foo/Bar/file.txt revisions
306 files: 1/3 chunks (33.33%)
310 files: 1/3 chunks (33.33%)
307 adding foo/file.txt revisions
311 adding foo/file.txt revisions
308 files: 2/3 chunks (66.67%)
312 files: 2/3 chunks (66.67%)
309 adding quux/file.py revisions
313 adding quux/file.py revisions
310 files: 3/3 chunks (100.00%)
314 files: 3/3 chunks (100.00%)
311 added 3 changesets with 3 changes to 3 files
315 added 3 changesets with 3 changes to 3 files
312 calling hook pretxnchangegroup.acl: hgext.acl.hook
316 calling hook pretxnchangegroup.acl: hgext.acl.hook
313 acl: checking access for user "fred"
317 acl: checking access for user "fred"
314 acl: acl.allow.branches not enabled
318 acl: acl.allow.branches not enabled
315 acl: acl.deny.branches not enabled
319 acl: acl.deny.branches not enabled
316 acl: acl.allow enabled, 0 entries for user fred
320 acl: acl.allow enabled, 0 entries for user fred
317 acl: acl.deny not enabled
321 acl: acl.deny not enabled
318 acl: branch access granted: "ef1ea85a6374" on branch "default"
322 acl: branch access granted: "ef1ea85a6374" on branch "default"
319 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
323 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
320 transaction abort!
324 transaction abort!
321 rollback completed
325 rollback completed
322 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
326 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
323 no rollback information available
327 no rollback information available
324 0:6675d58eff77
328 0:6675d58eff77
325
329
326
330
327 fred is allowed inside foo/
331 fred is allowed inside foo/
328
332
329 $ echo 'foo/** = fred' >> $config
333 $ echo 'foo/** = fred' >> $config
330 $ do_push fred
334 $ do_push fred
331 Pushing as user fred
335 Pushing as user fred
332 hgrc = """
336 hgrc = """
333 [hooks]
337 [hooks]
334 pretxnchangegroup.acl = python:hgext.acl.hook
338 pretxnchangegroup.acl = python:hgext.acl.hook
335 [acl]
339 [acl]
336 sources = push
340 sources = push
337 [acl.allow]
341 [acl.allow]
338 foo/** = fred
342 foo/** = fred
339 """
343 """
340 pushing to ../b
344 pushing to ../b
341 query 1; heads
345 query 1; heads
342 searching for changes
346 searching for changes
343 all remote heads known locally
347 all remote heads known locally
348 listing keys for "phases"
344 invalid branchheads cache (served): tip differs
349 invalid branchheads cache (served): tip differs
345 listing keys for "bookmarks"
350 listing keys for "bookmarks"
346 3 changesets found
351 3 changesets found
347 list of changesets:
352 list of changesets:
348 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
353 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
349 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
354 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
350 911600dab2ae7a9baff75958b84fe606851ce955
355 911600dab2ae7a9baff75958b84fe606851ce955
351 bundling: 1/3 changesets (33.33%)
356 bundling: 1/3 changesets (33.33%)
352 bundling: 2/3 changesets (66.67%)
357 bundling: 2/3 changesets (66.67%)
353 bundling: 3/3 changesets (100.00%)
358 bundling: 3/3 changesets (100.00%)
354 bundling: 1/3 manifests (33.33%)
359 bundling: 1/3 manifests (33.33%)
355 bundling: 2/3 manifests (66.67%)
360 bundling: 2/3 manifests (66.67%)
356 bundling: 3/3 manifests (100.00%)
361 bundling: 3/3 manifests (100.00%)
357 bundling: foo/Bar/file.txt 1/3 files (33.33%)
362 bundling: foo/Bar/file.txt 1/3 files (33.33%)
358 bundling: foo/file.txt 2/3 files (66.67%)
363 bundling: foo/file.txt 2/3 files (66.67%)
359 bundling: quux/file.py 3/3 files (100.00%)
364 bundling: quux/file.py 3/3 files (100.00%)
360 adding changesets
365 adding changesets
361 changesets: 1 chunks
366 changesets: 1 chunks
362 add changeset ef1ea85a6374
367 add changeset ef1ea85a6374
363 changesets: 2 chunks
368 changesets: 2 chunks
364 add changeset f9cafe1212c8
369 add changeset f9cafe1212c8
365 changesets: 3 chunks
370 changesets: 3 chunks
366 add changeset 911600dab2ae
371 add changeset 911600dab2ae
367 adding manifests
372 adding manifests
368 manifests: 1/3 chunks (33.33%)
373 manifests: 1/3 chunks (33.33%)
369 manifests: 2/3 chunks (66.67%)
374 manifests: 2/3 chunks (66.67%)
370 manifests: 3/3 chunks (100.00%)
375 manifests: 3/3 chunks (100.00%)
371 adding file changes
376 adding file changes
372 adding foo/Bar/file.txt revisions
377 adding foo/Bar/file.txt revisions
373 files: 1/3 chunks (33.33%)
378 files: 1/3 chunks (33.33%)
374 adding foo/file.txt revisions
379 adding foo/file.txt revisions
375 files: 2/3 chunks (66.67%)
380 files: 2/3 chunks (66.67%)
376 adding quux/file.py revisions
381 adding quux/file.py revisions
377 files: 3/3 chunks (100.00%)
382 files: 3/3 chunks (100.00%)
378 added 3 changesets with 3 changes to 3 files
383 added 3 changesets with 3 changes to 3 files
379 calling hook pretxnchangegroup.acl: hgext.acl.hook
384 calling hook pretxnchangegroup.acl: hgext.acl.hook
380 acl: checking access for user "fred"
385 acl: checking access for user "fred"
381 acl: acl.allow.branches not enabled
386 acl: acl.allow.branches not enabled
382 acl: acl.deny.branches not enabled
387 acl: acl.deny.branches not enabled
383 acl: acl.allow enabled, 1 entries for user fred
388 acl: acl.allow enabled, 1 entries for user fred
384 acl: acl.deny not enabled
389 acl: acl.deny not enabled
385 acl: branch access granted: "ef1ea85a6374" on branch "default"
390 acl: branch access granted: "ef1ea85a6374" on branch "default"
386 acl: path access granted: "ef1ea85a6374"
391 acl: path access granted: "ef1ea85a6374"
387 acl: branch access granted: "f9cafe1212c8" on branch "default"
392 acl: branch access granted: "f9cafe1212c8" on branch "default"
388 acl: path access granted: "f9cafe1212c8"
393 acl: path access granted: "f9cafe1212c8"
389 acl: branch access granted: "911600dab2ae" on branch "default"
394 acl: branch access granted: "911600dab2ae" on branch "default"
390 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
395 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
391 transaction abort!
396 transaction abort!
392 rollback completed
397 rollback completed
393 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
398 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
394 no rollback information available
399 no rollback information available
395 0:6675d58eff77
400 0:6675d58eff77
396
401
397
402
398 Empty [acl.deny]
403 Empty [acl.deny]
399
404
400 $ echo '[acl.deny]' >> $config
405 $ echo '[acl.deny]' >> $config
401 $ do_push barney
406 $ do_push barney
402 Pushing as user barney
407 Pushing as user barney
403 hgrc = """
408 hgrc = """
404 [hooks]
409 [hooks]
405 pretxnchangegroup.acl = python:hgext.acl.hook
410 pretxnchangegroup.acl = python:hgext.acl.hook
406 [acl]
411 [acl]
407 sources = push
412 sources = push
408 [acl.allow]
413 [acl.allow]
409 foo/** = fred
414 foo/** = fred
410 [acl.deny]
415 [acl.deny]
411 """
416 """
412 pushing to ../b
417 pushing to ../b
413 query 1; heads
418 query 1; heads
414 searching for changes
419 searching for changes
415 all remote heads known locally
420 all remote heads known locally
421 listing keys for "phases"
416 invalid branchheads cache (served): tip differs
422 invalid branchheads cache (served): tip differs
417 listing keys for "bookmarks"
423 listing keys for "bookmarks"
418 3 changesets found
424 3 changesets found
419 list of changesets:
425 list of changesets:
420 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
426 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
421 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
427 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
422 911600dab2ae7a9baff75958b84fe606851ce955
428 911600dab2ae7a9baff75958b84fe606851ce955
423 bundling: 1/3 changesets (33.33%)
429 bundling: 1/3 changesets (33.33%)
424 bundling: 2/3 changesets (66.67%)
430 bundling: 2/3 changesets (66.67%)
425 bundling: 3/3 changesets (100.00%)
431 bundling: 3/3 changesets (100.00%)
426 bundling: 1/3 manifests (33.33%)
432 bundling: 1/3 manifests (33.33%)
427 bundling: 2/3 manifests (66.67%)
433 bundling: 2/3 manifests (66.67%)
428 bundling: 3/3 manifests (100.00%)
434 bundling: 3/3 manifests (100.00%)
429 bundling: foo/Bar/file.txt 1/3 files (33.33%)
435 bundling: foo/Bar/file.txt 1/3 files (33.33%)
430 bundling: foo/file.txt 2/3 files (66.67%)
436 bundling: foo/file.txt 2/3 files (66.67%)
431 bundling: quux/file.py 3/3 files (100.00%)
437 bundling: quux/file.py 3/3 files (100.00%)
432 adding changesets
438 adding changesets
433 changesets: 1 chunks
439 changesets: 1 chunks
434 add changeset ef1ea85a6374
440 add changeset ef1ea85a6374
435 changesets: 2 chunks
441 changesets: 2 chunks
436 add changeset f9cafe1212c8
442 add changeset f9cafe1212c8
437 changesets: 3 chunks
443 changesets: 3 chunks
438 add changeset 911600dab2ae
444 add changeset 911600dab2ae
439 adding manifests
445 adding manifests
440 manifests: 1/3 chunks (33.33%)
446 manifests: 1/3 chunks (33.33%)
441 manifests: 2/3 chunks (66.67%)
447 manifests: 2/3 chunks (66.67%)
442 manifests: 3/3 chunks (100.00%)
448 manifests: 3/3 chunks (100.00%)
443 adding file changes
449 adding file changes
444 adding foo/Bar/file.txt revisions
450 adding foo/Bar/file.txt revisions
445 files: 1/3 chunks (33.33%)
451 files: 1/3 chunks (33.33%)
446 adding foo/file.txt revisions
452 adding foo/file.txt revisions
447 files: 2/3 chunks (66.67%)
453 files: 2/3 chunks (66.67%)
448 adding quux/file.py revisions
454 adding quux/file.py revisions
449 files: 3/3 chunks (100.00%)
455 files: 3/3 chunks (100.00%)
450 added 3 changesets with 3 changes to 3 files
456 added 3 changesets with 3 changes to 3 files
451 calling hook pretxnchangegroup.acl: hgext.acl.hook
457 calling hook pretxnchangegroup.acl: hgext.acl.hook
452 acl: checking access for user "barney"
458 acl: checking access for user "barney"
453 acl: acl.allow.branches not enabled
459 acl: acl.allow.branches not enabled
454 acl: acl.deny.branches not enabled
460 acl: acl.deny.branches not enabled
455 acl: acl.allow enabled, 0 entries for user barney
461 acl: acl.allow enabled, 0 entries for user barney
456 acl: acl.deny enabled, 0 entries for user barney
462 acl: acl.deny enabled, 0 entries for user barney
457 acl: branch access granted: "ef1ea85a6374" on branch "default"
463 acl: branch access granted: "ef1ea85a6374" on branch "default"
458 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
464 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
459 transaction abort!
465 transaction abort!
460 rollback completed
466 rollback completed
461 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
467 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
462 no rollback information available
468 no rollback information available
463 0:6675d58eff77
469 0:6675d58eff77
464
470
465
471
466 fred is allowed inside foo/, but not foo/bar/ (case matters)
472 fred is allowed inside foo/, but not foo/bar/ (case matters)
467
473
468 $ echo 'foo/bar/** = fred' >> $config
474 $ echo 'foo/bar/** = fred' >> $config
469 $ do_push fred
475 $ do_push fred
470 Pushing as user fred
476 Pushing as user fred
471 hgrc = """
477 hgrc = """
472 [hooks]
478 [hooks]
473 pretxnchangegroup.acl = python:hgext.acl.hook
479 pretxnchangegroup.acl = python:hgext.acl.hook
474 [acl]
480 [acl]
475 sources = push
481 sources = push
476 [acl.allow]
482 [acl.allow]
477 foo/** = fred
483 foo/** = fred
478 [acl.deny]
484 [acl.deny]
479 foo/bar/** = fred
485 foo/bar/** = fred
480 """
486 """
481 pushing to ../b
487 pushing to ../b
482 query 1; heads
488 query 1; heads
483 searching for changes
489 searching for changes
484 all remote heads known locally
490 all remote heads known locally
491 listing keys for "phases"
485 invalid branchheads cache (served): tip differs
492 invalid branchheads cache (served): tip differs
486 listing keys for "bookmarks"
493 listing keys for "bookmarks"
487 3 changesets found
494 3 changesets found
488 list of changesets:
495 list of changesets:
489 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
496 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
490 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
497 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
491 911600dab2ae7a9baff75958b84fe606851ce955
498 911600dab2ae7a9baff75958b84fe606851ce955
492 bundling: 1/3 changesets (33.33%)
499 bundling: 1/3 changesets (33.33%)
493 bundling: 2/3 changesets (66.67%)
500 bundling: 2/3 changesets (66.67%)
494 bundling: 3/3 changesets (100.00%)
501 bundling: 3/3 changesets (100.00%)
495 bundling: 1/3 manifests (33.33%)
502 bundling: 1/3 manifests (33.33%)
496 bundling: 2/3 manifests (66.67%)
503 bundling: 2/3 manifests (66.67%)
497 bundling: 3/3 manifests (100.00%)
504 bundling: 3/3 manifests (100.00%)
498 bundling: foo/Bar/file.txt 1/3 files (33.33%)
505 bundling: foo/Bar/file.txt 1/3 files (33.33%)
499 bundling: foo/file.txt 2/3 files (66.67%)
506 bundling: foo/file.txt 2/3 files (66.67%)
500 bundling: quux/file.py 3/3 files (100.00%)
507 bundling: quux/file.py 3/3 files (100.00%)
501 adding changesets
508 adding changesets
502 changesets: 1 chunks
509 changesets: 1 chunks
503 add changeset ef1ea85a6374
510 add changeset ef1ea85a6374
504 changesets: 2 chunks
511 changesets: 2 chunks
505 add changeset f9cafe1212c8
512 add changeset f9cafe1212c8
506 changesets: 3 chunks
513 changesets: 3 chunks
507 add changeset 911600dab2ae
514 add changeset 911600dab2ae
508 adding manifests
515 adding manifests
509 manifests: 1/3 chunks (33.33%)
516 manifests: 1/3 chunks (33.33%)
510 manifests: 2/3 chunks (66.67%)
517 manifests: 2/3 chunks (66.67%)
511 manifests: 3/3 chunks (100.00%)
518 manifests: 3/3 chunks (100.00%)
512 adding file changes
519 adding file changes
513 adding foo/Bar/file.txt revisions
520 adding foo/Bar/file.txt revisions
514 files: 1/3 chunks (33.33%)
521 files: 1/3 chunks (33.33%)
515 adding foo/file.txt revisions
522 adding foo/file.txt revisions
516 files: 2/3 chunks (66.67%)
523 files: 2/3 chunks (66.67%)
517 adding quux/file.py revisions
524 adding quux/file.py revisions
518 files: 3/3 chunks (100.00%)
525 files: 3/3 chunks (100.00%)
519 added 3 changesets with 3 changes to 3 files
526 added 3 changesets with 3 changes to 3 files
520 calling hook pretxnchangegroup.acl: hgext.acl.hook
527 calling hook pretxnchangegroup.acl: hgext.acl.hook
521 acl: checking access for user "fred"
528 acl: checking access for user "fred"
522 acl: acl.allow.branches not enabled
529 acl: acl.allow.branches not enabled
523 acl: acl.deny.branches not enabled
530 acl: acl.deny.branches not enabled
524 acl: acl.allow enabled, 1 entries for user fred
531 acl: acl.allow enabled, 1 entries for user fred
525 acl: acl.deny enabled, 1 entries for user fred
532 acl: acl.deny enabled, 1 entries for user fred
526 acl: branch access granted: "ef1ea85a6374" on branch "default"
533 acl: branch access granted: "ef1ea85a6374" on branch "default"
527 acl: path access granted: "ef1ea85a6374"
534 acl: path access granted: "ef1ea85a6374"
528 acl: branch access granted: "f9cafe1212c8" on branch "default"
535 acl: branch access granted: "f9cafe1212c8" on branch "default"
529 acl: path access granted: "f9cafe1212c8"
536 acl: path access granted: "f9cafe1212c8"
530 acl: branch access granted: "911600dab2ae" on branch "default"
537 acl: branch access granted: "911600dab2ae" on branch "default"
531 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
538 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
532 transaction abort!
539 transaction abort!
533 rollback completed
540 rollback completed
534 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
541 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
535 no rollback information available
542 no rollback information available
536 0:6675d58eff77
543 0:6675d58eff77
537
544
538
545
539 fred is allowed inside foo/, but not foo/Bar/
546 fred is allowed inside foo/, but not foo/Bar/
540
547
541 $ echo 'foo/Bar/** = fred' >> $config
548 $ echo 'foo/Bar/** = fred' >> $config
542 $ do_push fred
549 $ do_push fred
543 Pushing as user fred
550 Pushing as user fred
544 hgrc = """
551 hgrc = """
545 [hooks]
552 [hooks]
546 pretxnchangegroup.acl = python:hgext.acl.hook
553 pretxnchangegroup.acl = python:hgext.acl.hook
547 [acl]
554 [acl]
548 sources = push
555 sources = push
549 [acl.allow]
556 [acl.allow]
550 foo/** = fred
557 foo/** = fred
551 [acl.deny]
558 [acl.deny]
552 foo/bar/** = fred
559 foo/bar/** = fred
553 foo/Bar/** = fred
560 foo/Bar/** = fred
554 """
561 """
555 pushing to ../b
562 pushing to ../b
556 query 1; heads
563 query 1; heads
557 searching for changes
564 searching for changes
558 all remote heads known locally
565 all remote heads known locally
566 listing keys for "phases"
559 invalid branchheads cache (served): tip differs
567 invalid branchheads cache (served): tip differs
560 listing keys for "bookmarks"
568 listing keys for "bookmarks"
561 3 changesets found
569 3 changesets found
562 list of changesets:
570 list of changesets:
563 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
571 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
564 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
572 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
565 911600dab2ae7a9baff75958b84fe606851ce955
573 911600dab2ae7a9baff75958b84fe606851ce955
566 bundling: 1/3 changesets (33.33%)
574 bundling: 1/3 changesets (33.33%)
567 bundling: 2/3 changesets (66.67%)
575 bundling: 2/3 changesets (66.67%)
568 bundling: 3/3 changesets (100.00%)
576 bundling: 3/3 changesets (100.00%)
569 bundling: 1/3 manifests (33.33%)
577 bundling: 1/3 manifests (33.33%)
570 bundling: 2/3 manifests (66.67%)
578 bundling: 2/3 manifests (66.67%)
571 bundling: 3/3 manifests (100.00%)
579 bundling: 3/3 manifests (100.00%)
572 bundling: foo/Bar/file.txt 1/3 files (33.33%)
580 bundling: foo/Bar/file.txt 1/3 files (33.33%)
573 bundling: foo/file.txt 2/3 files (66.67%)
581 bundling: foo/file.txt 2/3 files (66.67%)
574 bundling: quux/file.py 3/3 files (100.00%)
582 bundling: quux/file.py 3/3 files (100.00%)
575 adding changesets
583 adding changesets
576 changesets: 1 chunks
584 changesets: 1 chunks
577 add changeset ef1ea85a6374
585 add changeset ef1ea85a6374
578 changesets: 2 chunks
586 changesets: 2 chunks
579 add changeset f9cafe1212c8
587 add changeset f9cafe1212c8
580 changesets: 3 chunks
588 changesets: 3 chunks
581 add changeset 911600dab2ae
589 add changeset 911600dab2ae
582 adding manifests
590 adding manifests
583 manifests: 1/3 chunks (33.33%)
591 manifests: 1/3 chunks (33.33%)
584 manifests: 2/3 chunks (66.67%)
592 manifests: 2/3 chunks (66.67%)
585 manifests: 3/3 chunks (100.00%)
593 manifests: 3/3 chunks (100.00%)
586 adding file changes
594 adding file changes
587 adding foo/Bar/file.txt revisions
595 adding foo/Bar/file.txt revisions
588 files: 1/3 chunks (33.33%)
596 files: 1/3 chunks (33.33%)
589 adding foo/file.txt revisions
597 adding foo/file.txt revisions
590 files: 2/3 chunks (66.67%)
598 files: 2/3 chunks (66.67%)
591 adding quux/file.py revisions
599 adding quux/file.py revisions
592 files: 3/3 chunks (100.00%)
600 files: 3/3 chunks (100.00%)
593 added 3 changesets with 3 changes to 3 files
601 added 3 changesets with 3 changes to 3 files
594 calling hook pretxnchangegroup.acl: hgext.acl.hook
602 calling hook pretxnchangegroup.acl: hgext.acl.hook
595 acl: checking access for user "fred"
603 acl: checking access for user "fred"
596 acl: acl.allow.branches not enabled
604 acl: acl.allow.branches not enabled
597 acl: acl.deny.branches not enabled
605 acl: acl.deny.branches not enabled
598 acl: acl.allow enabled, 1 entries for user fred
606 acl: acl.allow enabled, 1 entries for user fred
599 acl: acl.deny enabled, 2 entries for user fred
607 acl: acl.deny enabled, 2 entries for user fred
600 acl: branch access granted: "ef1ea85a6374" on branch "default"
608 acl: branch access granted: "ef1ea85a6374" on branch "default"
601 acl: path access granted: "ef1ea85a6374"
609 acl: path access granted: "ef1ea85a6374"
602 acl: branch access granted: "f9cafe1212c8" on branch "default"
610 acl: branch access granted: "f9cafe1212c8" on branch "default"
603 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
611 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
604 transaction abort!
612 transaction abort!
605 rollback completed
613 rollback completed
606 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
614 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
607 no rollback information available
615 no rollback information available
608 0:6675d58eff77
616 0:6675d58eff77
609
617
610
618
611 $ echo 'barney is not mentioned => not allowed anywhere'
619 $ echo 'barney is not mentioned => not allowed anywhere'
612 barney is not mentioned => not allowed anywhere
620 barney is not mentioned => not allowed anywhere
613 $ do_push barney
621 $ do_push barney
614 Pushing as user barney
622 Pushing as user barney
615 hgrc = """
623 hgrc = """
616 [hooks]
624 [hooks]
617 pretxnchangegroup.acl = python:hgext.acl.hook
625 pretxnchangegroup.acl = python:hgext.acl.hook
618 [acl]
626 [acl]
619 sources = push
627 sources = push
620 [acl.allow]
628 [acl.allow]
621 foo/** = fred
629 foo/** = fred
622 [acl.deny]
630 [acl.deny]
623 foo/bar/** = fred
631 foo/bar/** = fred
624 foo/Bar/** = fred
632 foo/Bar/** = fred
625 """
633 """
626 pushing to ../b
634 pushing to ../b
627 query 1; heads
635 query 1; heads
628 searching for changes
636 searching for changes
629 all remote heads known locally
637 all remote heads known locally
638 listing keys for "phases"
630 invalid branchheads cache (served): tip differs
639 invalid branchheads cache (served): tip differs
631 listing keys for "bookmarks"
640 listing keys for "bookmarks"
632 3 changesets found
641 3 changesets found
633 list of changesets:
642 list of changesets:
634 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
643 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
635 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
644 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
636 911600dab2ae7a9baff75958b84fe606851ce955
645 911600dab2ae7a9baff75958b84fe606851ce955
637 bundling: 1/3 changesets (33.33%)
646 bundling: 1/3 changesets (33.33%)
638 bundling: 2/3 changesets (66.67%)
647 bundling: 2/3 changesets (66.67%)
639 bundling: 3/3 changesets (100.00%)
648 bundling: 3/3 changesets (100.00%)
640 bundling: 1/3 manifests (33.33%)
649 bundling: 1/3 manifests (33.33%)
641 bundling: 2/3 manifests (66.67%)
650 bundling: 2/3 manifests (66.67%)
642 bundling: 3/3 manifests (100.00%)
651 bundling: 3/3 manifests (100.00%)
643 bundling: foo/Bar/file.txt 1/3 files (33.33%)
652 bundling: foo/Bar/file.txt 1/3 files (33.33%)
644 bundling: foo/file.txt 2/3 files (66.67%)
653 bundling: foo/file.txt 2/3 files (66.67%)
645 bundling: quux/file.py 3/3 files (100.00%)
654 bundling: quux/file.py 3/3 files (100.00%)
646 adding changesets
655 adding changesets
647 changesets: 1 chunks
656 changesets: 1 chunks
648 add changeset ef1ea85a6374
657 add changeset ef1ea85a6374
649 changesets: 2 chunks
658 changesets: 2 chunks
650 add changeset f9cafe1212c8
659 add changeset f9cafe1212c8
651 changesets: 3 chunks
660 changesets: 3 chunks
652 add changeset 911600dab2ae
661 add changeset 911600dab2ae
653 adding manifests
662 adding manifests
654 manifests: 1/3 chunks (33.33%)
663 manifests: 1/3 chunks (33.33%)
655 manifests: 2/3 chunks (66.67%)
664 manifests: 2/3 chunks (66.67%)
656 manifests: 3/3 chunks (100.00%)
665 manifests: 3/3 chunks (100.00%)
657 adding file changes
666 adding file changes
658 adding foo/Bar/file.txt revisions
667 adding foo/Bar/file.txt revisions
659 files: 1/3 chunks (33.33%)
668 files: 1/3 chunks (33.33%)
660 adding foo/file.txt revisions
669 adding foo/file.txt revisions
661 files: 2/3 chunks (66.67%)
670 files: 2/3 chunks (66.67%)
662 adding quux/file.py revisions
671 adding quux/file.py revisions
663 files: 3/3 chunks (100.00%)
672 files: 3/3 chunks (100.00%)
664 added 3 changesets with 3 changes to 3 files
673 added 3 changesets with 3 changes to 3 files
665 calling hook pretxnchangegroup.acl: hgext.acl.hook
674 calling hook pretxnchangegroup.acl: hgext.acl.hook
666 acl: checking access for user "barney"
675 acl: checking access for user "barney"
667 acl: acl.allow.branches not enabled
676 acl: acl.allow.branches not enabled
668 acl: acl.deny.branches not enabled
677 acl: acl.deny.branches not enabled
669 acl: acl.allow enabled, 0 entries for user barney
678 acl: acl.allow enabled, 0 entries for user barney
670 acl: acl.deny enabled, 0 entries for user barney
679 acl: acl.deny enabled, 0 entries for user barney
671 acl: branch access granted: "ef1ea85a6374" on branch "default"
680 acl: branch access granted: "ef1ea85a6374" on branch "default"
672 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
681 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
673 transaction abort!
682 transaction abort!
674 rollback completed
683 rollback completed
675 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
684 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
676 no rollback information available
685 no rollback information available
677 0:6675d58eff77
686 0:6675d58eff77
678
687
679
688
680 barney is allowed everywhere
689 barney is allowed everywhere
681
690
682 $ echo '[acl.allow]' >> $config
691 $ echo '[acl.allow]' >> $config
683 $ echo '** = barney' >> $config
692 $ echo '** = barney' >> $config
684 $ do_push barney
693 $ do_push barney
685 Pushing as user barney
694 Pushing as user barney
686 hgrc = """
695 hgrc = """
687 [hooks]
696 [hooks]
688 pretxnchangegroup.acl = python:hgext.acl.hook
697 pretxnchangegroup.acl = python:hgext.acl.hook
689 [acl]
698 [acl]
690 sources = push
699 sources = push
691 [acl.allow]
700 [acl.allow]
692 foo/** = fred
701 foo/** = fred
693 [acl.deny]
702 [acl.deny]
694 foo/bar/** = fred
703 foo/bar/** = fred
695 foo/Bar/** = fred
704 foo/Bar/** = fred
696 [acl.allow]
705 [acl.allow]
697 ** = barney
706 ** = barney
698 """
707 """
699 pushing to ../b
708 pushing to ../b
700 query 1; heads
709 query 1; heads
701 searching for changes
710 searching for changes
702 all remote heads known locally
711 all remote heads known locally
712 listing keys for "phases"
703 invalid branchheads cache (served): tip differs
713 invalid branchheads cache (served): tip differs
704 listing keys for "bookmarks"
714 listing keys for "bookmarks"
705 3 changesets found
715 3 changesets found
706 list of changesets:
716 list of changesets:
707 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
717 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
708 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
718 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
709 911600dab2ae7a9baff75958b84fe606851ce955
719 911600dab2ae7a9baff75958b84fe606851ce955
710 bundling: 1/3 changesets (33.33%)
720 bundling: 1/3 changesets (33.33%)
711 bundling: 2/3 changesets (66.67%)
721 bundling: 2/3 changesets (66.67%)
712 bundling: 3/3 changesets (100.00%)
722 bundling: 3/3 changesets (100.00%)
713 bundling: 1/3 manifests (33.33%)
723 bundling: 1/3 manifests (33.33%)
714 bundling: 2/3 manifests (66.67%)
724 bundling: 2/3 manifests (66.67%)
715 bundling: 3/3 manifests (100.00%)
725 bundling: 3/3 manifests (100.00%)
716 bundling: foo/Bar/file.txt 1/3 files (33.33%)
726 bundling: foo/Bar/file.txt 1/3 files (33.33%)
717 bundling: foo/file.txt 2/3 files (66.67%)
727 bundling: foo/file.txt 2/3 files (66.67%)
718 bundling: quux/file.py 3/3 files (100.00%)
728 bundling: quux/file.py 3/3 files (100.00%)
719 adding changesets
729 adding changesets
720 changesets: 1 chunks
730 changesets: 1 chunks
721 add changeset ef1ea85a6374
731 add changeset ef1ea85a6374
722 changesets: 2 chunks
732 changesets: 2 chunks
723 add changeset f9cafe1212c8
733 add changeset f9cafe1212c8
724 changesets: 3 chunks
734 changesets: 3 chunks
725 add changeset 911600dab2ae
735 add changeset 911600dab2ae
726 adding manifests
736 adding manifests
727 manifests: 1/3 chunks (33.33%)
737 manifests: 1/3 chunks (33.33%)
728 manifests: 2/3 chunks (66.67%)
738 manifests: 2/3 chunks (66.67%)
729 manifests: 3/3 chunks (100.00%)
739 manifests: 3/3 chunks (100.00%)
730 adding file changes
740 adding file changes
731 adding foo/Bar/file.txt revisions
741 adding foo/Bar/file.txt revisions
732 files: 1/3 chunks (33.33%)
742 files: 1/3 chunks (33.33%)
733 adding foo/file.txt revisions
743 adding foo/file.txt revisions
734 files: 2/3 chunks (66.67%)
744 files: 2/3 chunks (66.67%)
735 adding quux/file.py revisions
745 adding quux/file.py revisions
736 files: 3/3 chunks (100.00%)
746 files: 3/3 chunks (100.00%)
737 added 3 changesets with 3 changes to 3 files
747 added 3 changesets with 3 changes to 3 files
738 calling hook pretxnchangegroup.acl: hgext.acl.hook
748 calling hook pretxnchangegroup.acl: hgext.acl.hook
739 acl: checking access for user "barney"
749 acl: checking access for user "barney"
740 acl: acl.allow.branches not enabled
750 acl: acl.allow.branches not enabled
741 acl: acl.deny.branches not enabled
751 acl: acl.deny.branches not enabled
742 acl: acl.allow enabled, 1 entries for user barney
752 acl: acl.allow enabled, 1 entries for user barney
743 acl: acl.deny enabled, 0 entries for user barney
753 acl: acl.deny enabled, 0 entries for user barney
744 acl: branch access granted: "ef1ea85a6374" on branch "default"
754 acl: branch access granted: "ef1ea85a6374" on branch "default"
745 acl: path access granted: "ef1ea85a6374"
755 acl: path access granted: "ef1ea85a6374"
746 acl: branch access granted: "f9cafe1212c8" on branch "default"
756 acl: branch access granted: "f9cafe1212c8" on branch "default"
747 acl: path access granted: "f9cafe1212c8"
757 acl: path access granted: "f9cafe1212c8"
748 acl: branch access granted: "911600dab2ae" on branch "default"
758 acl: branch access granted: "911600dab2ae" on branch "default"
749 acl: path access granted: "911600dab2ae"
759 acl: path access granted: "911600dab2ae"
750 updating the branch cache
760 updating the branch cache
751 listing keys for "phases"
761 listing keys for "phases"
752 try to push obsolete markers to remote
762 try to push obsolete markers to remote
753 checking for updated bookmarks
763 checking for updated bookmarks
754 listing keys for "bookmarks"
764 listing keys for "bookmarks"
755 repository tip rolled back to revision 0 (undo push)
765 repository tip rolled back to revision 0 (undo push)
756 0:6675d58eff77
766 0:6675d58eff77
757
767
758
768
759 wilma can change files with a .txt extension
769 wilma can change files with a .txt extension
760
770
761 $ echo '**/*.txt = wilma' >> $config
771 $ echo '**/*.txt = wilma' >> $config
762 $ do_push wilma
772 $ do_push wilma
763 Pushing as user wilma
773 Pushing as user wilma
764 hgrc = """
774 hgrc = """
765 [hooks]
775 [hooks]
766 pretxnchangegroup.acl = python:hgext.acl.hook
776 pretxnchangegroup.acl = python:hgext.acl.hook
767 [acl]
777 [acl]
768 sources = push
778 sources = push
769 [acl.allow]
779 [acl.allow]
770 foo/** = fred
780 foo/** = fred
771 [acl.deny]
781 [acl.deny]
772 foo/bar/** = fred
782 foo/bar/** = fred
773 foo/Bar/** = fred
783 foo/Bar/** = fred
774 [acl.allow]
784 [acl.allow]
775 ** = barney
785 ** = barney
776 **/*.txt = wilma
786 **/*.txt = wilma
777 """
787 """
778 pushing to ../b
788 pushing to ../b
779 query 1; heads
789 query 1; heads
780 searching for changes
790 searching for changes
781 all remote heads known locally
791 all remote heads known locally
792 listing keys for "phases"
782 invalid branchheads cache (served): tip differs
793 invalid branchheads cache (served): tip differs
783 listing keys for "bookmarks"
794 listing keys for "bookmarks"
784 3 changesets found
795 3 changesets found
785 list of changesets:
796 list of changesets:
786 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
797 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
787 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
798 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
788 911600dab2ae7a9baff75958b84fe606851ce955
799 911600dab2ae7a9baff75958b84fe606851ce955
789 bundling: 1/3 changesets (33.33%)
800 bundling: 1/3 changesets (33.33%)
790 bundling: 2/3 changesets (66.67%)
801 bundling: 2/3 changesets (66.67%)
791 bundling: 3/3 changesets (100.00%)
802 bundling: 3/3 changesets (100.00%)
792 bundling: 1/3 manifests (33.33%)
803 bundling: 1/3 manifests (33.33%)
793 bundling: 2/3 manifests (66.67%)
804 bundling: 2/3 manifests (66.67%)
794 bundling: 3/3 manifests (100.00%)
805 bundling: 3/3 manifests (100.00%)
795 bundling: foo/Bar/file.txt 1/3 files (33.33%)
806 bundling: foo/Bar/file.txt 1/3 files (33.33%)
796 bundling: foo/file.txt 2/3 files (66.67%)
807 bundling: foo/file.txt 2/3 files (66.67%)
797 bundling: quux/file.py 3/3 files (100.00%)
808 bundling: quux/file.py 3/3 files (100.00%)
798 adding changesets
809 adding changesets
799 changesets: 1 chunks
810 changesets: 1 chunks
800 add changeset ef1ea85a6374
811 add changeset ef1ea85a6374
801 changesets: 2 chunks
812 changesets: 2 chunks
802 add changeset f9cafe1212c8
813 add changeset f9cafe1212c8
803 changesets: 3 chunks
814 changesets: 3 chunks
804 add changeset 911600dab2ae
815 add changeset 911600dab2ae
805 adding manifests
816 adding manifests
806 manifests: 1/3 chunks (33.33%)
817 manifests: 1/3 chunks (33.33%)
807 manifests: 2/3 chunks (66.67%)
818 manifests: 2/3 chunks (66.67%)
808 manifests: 3/3 chunks (100.00%)
819 manifests: 3/3 chunks (100.00%)
809 adding file changes
820 adding file changes
810 adding foo/Bar/file.txt revisions
821 adding foo/Bar/file.txt revisions
811 files: 1/3 chunks (33.33%)
822 files: 1/3 chunks (33.33%)
812 adding foo/file.txt revisions
823 adding foo/file.txt revisions
813 files: 2/3 chunks (66.67%)
824 files: 2/3 chunks (66.67%)
814 adding quux/file.py revisions
825 adding quux/file.py revisions
815 files: 3/3 chunks (100.00%)
826 files: 3/3 chunks (100.00%)
816 added 3 changesets with 3 changes to 3 files
827 added 3 changesets with 3 changes to 3 files
817 calling hook pretxnchangegroup.acl: hgext.acl.hook
828 calling hook pretxnchangegroup.acl: hgext.acl.hook
818 acl: checking access for user "wilma"
829 acl: checking access for user "wilma"
819 acl: acl.allow.branches not enabled
830 acl: acl.allow.branches not enabled
820 acl: acl.deny.branches not enabled
831 acl: acl.deny.branches not enabled
821 acl: acl.allow enabled, 1 entries for user wilma
832 acl: acl.allow enabled, 1 entries for user wilma
822 acl: acl.deny enabled, 0 entries for user wilma
833 acl: acl.deny enabled, 0 entries for user wilma
823 acl: branch access granted: "ef1ea85a6374" on branch "default"
834 acl: branch access granted: "ef1ea85a6374" on branch "default"
824 acl: path access granted: "ef1ea85a6374"
835 acl: path access granted: "ef1ea85a6374"
825 acl: branch access granted: "f9cafe1212c8" on branch "default"
836 acl: branch access granted: "f9cafe1212c8" on branch "default"
826 acl: path access granted: "f9cafe1212c8"
837 acl: path access granted: "f9cafe1212c8"
827 acl: branch access granted: "911600dab2ae" on branch "default"
838 acl: branch access granted: "911600dab2ae" on branch "default"
828 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
839 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
829 transaction abort!
840 transaction abort!
830 rollback completed
841 rollback completed
831 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
842 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
832 no rollback information available
843 no rollback information available
833 0:6675d58eff77
844 0:6675d58eff77
834
845
835
846
836 file specified by acl.config does not exist
847 file specified by acl.config does not exist
837
848
838 $ echo '[acl]' >> $config
849 $ echo '[acl]' >> $config
839 $ echo 'config = ../acl.config' >> $config
850 $ echo 'config = ../acl.config' >> $config
840 $ do_push barney
851 $ do_push barney
841 Pushing as user barney
852 Pushing as user barney
842 hgrc = """
853 hgrc = """
843 [hooks]
854 [hooks]
844 pretxnchangegroup.acl = python:hgext.acl.hook
855 pretxnchangegroup.acl = python:hgext.acl.hook
845 [acl]
856 [acl]
846 sources = push
857 sources = push
847 [acl.allow]
858 [acl.allow]
848 foo/** = fred
859 foo/** = fred
849 [acl.deny]
860 [acl.deny]
850 foo/bar/** = fred
861 foo/bar/** = fred
851 foo/Bar/** = fred
862 foo/Bar/** = fred
852 [acl.allow]
863 [acl.allow]
853 ** = barney
864 ** = barney
854 **/*.txt = wilma
865 **/*.txt = wilma
855 [acl]
866 [acl]
856 config = ../acl.config
867 config = ../acl.config
857 """
868 """
858 pushing to ../b
869 pushing to ../b
859 query 1; heads
870 query 1; heads
860 searching for changes
871 searching for changes
861 all remote heads known locally
872 all remote heads known locally
873 listing keys for "phases"
862 invalid branchheads cache (served): tip differs
874 invalid branchheads cache (served): tip differs
863 listing keys for "bookmarks"
875 listing keys for "bookmarks"
864 3 changesets found
876 3 changesets found
865 list of changesets:
877 list of changesets:
866 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
878 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
867 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
879 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
868 911600dab2ae7a9baff75958b84fe606851ce955
880 911600dab2ae7a9baff75958b84fe606851ce955
869 bundling: 1/3 changesets (33.33%)
881 bundling: 1/3 changesets (33.33%)
870 bundling: 2/3 changesets (66.67%)
882 bundling: 2/3 changesets (66.67%)
871 bundling: 3/3 changesets (100.00%)
883 bundling: 3/3 changesets (100.00%)
872 bundling: 1/3 manifests (33.33%)
884 bundling: 1/3 manifests (33.33%)
873 bundling: 2/3 manifests (66.67%)
885 bundling: 2/3 manifests (66.67%)
874 bundling: 3/3 manifests (100.00%)
886 bundling: 3/3 manifests (100.00%)
875 bundling: foo/Bar/file.txt 1/3 files (33.33%)
887 bundling: foo/Bar/file.txt 1/3 files (33.33%)
876 bundling: foo/file.txt 2/3 files (66.67%)
888 bundling: foo/file.txt 2/3 files (66.67%)
877 bundling: quux/file.py 3/3 files (100.00%)
889 bundling: quux/file.py 3/3 files (100.00%)
878 adding changesets
890 adding changesets
879 changesets: 1 chunks
891 changesets: 1 chunks
880 add changeset ef1ea85a6374
892 add changeset ef1ea85a6374
881 changesets: 2 chunks
893 changesets: 2 chunks
882 add changeset f9cafe1212c8
894 add changeset f9cafe1212c8
883 changesets: 3 chunks
895 changesets: 3 chunks
884 add changeset 911600dab2ae
896 add changeset 911600dab2ae
885 adding manifests
897 adding manifests
886 manifests: 1/3 chunks (33.33%)
898 manifests: 1/3 chunks (33.33%)
887 manifests: 2/3 chunks (66.67%)
899 manifests: 2/3 chunks (66.67%)
888 manifests: 3/3 chunks (100.00%)
900 manifests: 3/3 chunks (100.00%)
889 adding file changes
901 adding file changes
890 adding foo/Bar/file.txt revisions
902 adding foo/Bar/file.txt revisions
891 files: 1/3 chunks (33.33%)
903 files: 1/3 chunks (33.33%)
892 adding foo/file.txt revisions
904 adding foo/file.txt revisions
893 files: 2/3 chunks (66.67%)
905 files: 2/3 chunks (66.67%)
894 adding quux/file.py revisions
906 adding quux/file.py revisions
895 files: 3/3 chunks (100.00%)
907 files: 3/3 chunks (100.00%)
896 added 3 changesets with 3 changes to 3 files
908 added 3 changesets with 3 changes to 3 files
897 calling hook pretxnchangegroup.acl: hgext.acl.hook
909 calling hook pretxnchangegroup.acl: hgext.acl.hook
898 acl: checking access for user "barney"
910 acl: checking access for user "barney"
899 error: pretxnchangegroup.acl hook raised an exception: [Errno *] *: '../acl.config' (glob)
911 error: pretxnchangegroup.acl hook raised an exception: [Errno *] *: '../acl.config' (glob)
900 transaction abort!
912 transaction abort!
901 rollback completed
913 rollback completed
902 abort: *: ../acl.config (glob)
914 abort: *: ../acl.config (glob)
903 no rollback information available
915 no rollback information available
904 0:6675d58eff77
916 0:6675d58eff77
905
917
906
918
907 betty is allowed inside foo/ by a acl.config file
919 betty is allowed inside foo/ by a acl.config file
908
920
909 $ echo '[acl.allow]' >> acl.config
921 $ echo '[acl.allow]' >> acl.config
910 $ echo 'foo/** = betty' >> acl.config
922 $ echo 'foo/** = betty' >> acl.config
911 $ do_push betty
923 $ do_push betty
912 Pushing as user betty
924 Pushing as user betty
913 hgrc = """
925 hgrc = """
914 [hooks]
926 [hooks]
915 pretxnchangegroup.acl = python:hgext.acl.hook
927 pretxnchangegroup.acl = python:hgext.acl.hook
916 [acl]
928 [acl]
917 sources = push
929 sources = push
918 [acl.allow]
930 [acl.allow]
919 foo/** = fred
931 foo/** = fred
920 [acl.deny]
932 [acl.deny]
921 foo/bar/** = fred
933 foo/bar/** = fred
922 foo/Bar/** = fred
934 foo/Bar/** = fred
923 [acl.allow]
935 [acl.allow]
924 ** = barney
936 ** = barney
925 **/*.txt = wilma
937 **/*.txt = wilma
926 [acl]
938 [acl]
927 config = ../acl.config
939 config = ../acl.config
928 """
940 """
929 acl.config = """
941 acl.config = """
930 [acl.allow]
942 [acl.allow]
931 foo/** = betty
943 foo/** = betty
932 """
944 """
933 pushing to ../b
945 pushing to ../b
934 query 1; heads
946 query 1; heads
935 searching for changes
947 searching for changes
936 all remote heads known locally
948 all remote heads known locally
949 listing keys for "phases"
937 invalid branchheads cache (served): tip differs
950 invalid branchheads cache (served): tip differs
938 listing keys for "bookmarks"
951 listing keys for "bookmarks"
939 3 changesets found
952 3 changesets found
940 list of changesets:
953 list of changesets:
941 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
954 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
942 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
955 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
943 911600dab2ae7a9baff75958b84fe606851ce955
956 911600dab2ae7a9baff75958b84fe606851ce955
944 bundling: 1/3 changesets (33.33%)
957 bundling: 1/3 changesets (33.33%)
945 bundling: 2/3 changesets (66.67%)
958 bundling: 2/3 changesets (66.67%)
946 bundling: 3/3 changesets (100.00%)
959 bundling: 3/3 changesets (100.00%)
947 bundling: 1/3 manifests (33.33%)
960 bundling: 1/3 manifests (33.33%)
948 bundling: 2/3 manifests (66.67%)
961 bundling: 2/3 manifests (66.67%)
949 bundling: 3/3 manifests (100.00%)
962 bundling: 3/3 manifests (100.00%)
950 bundling: foo/Bar/file.txt 1/3 files (33.33%)
963 bundling: foo/Bar/file.txt 1/3 files (33.33%)
951 bundling: foo/file.txt 2/3 files (66.67%)
964 bundling: foo/file.txt 2/3 files (66.67%)
952 bundling: quux/file.py 3/3 files (100.00%)
965 bundling: quux/file.py 3/3 files (100.00%)
953 adding changesets
966 adding changesets
954 changesets: 1 chunks
967 changesets: 1 chunks
955 add changeset ef1ea85a6374
968 add changeset ef1ea85a6374
956 changesets: 2 chunks
969 changesets: 2 chunks
957 add changeset f9cafe1212c8
970 add changeset f9cafe1212c8
958 changesets: 3 chunks
971 changesets: 3 chunks
959 add changeset 911600dab2ae
972 add changeset 911600dab2ae
960 adding manifests
973 adding manifests
961 manifests: 1/3 chunks (33.33%)
974 manifests: 1/3 chunks (33.33%)
962 manifests: 2/3 chunks (66.67%)
975 manifests: 2/3 chunks (66.67%)
963 manifests: 3/3 chunks (100.00%)
976 manifests: 3/3 chunks (100.00%)
964 adding file changes
977 adding file changes
965 adding foo/Bar/file.txt revisions
978 adding foo/Bar/file.txt revisions
966 files: 1/3 chunks (33.33%)
979 files: 1/3 chunks (33.33%)
967 adding foo/file.txt revisions
980 adding foo/file.txt revisions
968 files: 2/3 chunks (66.67%)
981 files: 2/3 chunks (66.67%)
969 adding quux/file.py revisions
982 adding quux/file.py revisions
970 files: 3/3 chunks (100.00%)
983 files: 3/3 chunks (100.00%)
971 added 3 changesets with 3 changes to 3 files
984 added 3 changesets with 3 changes to 3 files
972 calling hook pretxnchangegroup.acl: hgext.acl.hook
985 calling hook pretxnchangegroup.acl: hgext.acl.hook
973 acl: checking access for user "betty"
986 acl: checking access for user "betty"
974 acl: acl.allow.branches not enabled
987 acl: acl.allow.branches not enabled
975 acl: acl.deny.branches not enabled
988 acl: acl.deny.branches not enabled
976 acl: acl.allow enabled, 1 entries for user betty
989 acl: acl.allow enabled, 1 entries for user betty
977 acl: acl.deny enabled, 0 entries for user betty
990 acl: acl.deny enabled, 0 entries for user betty
978 acl: branch access granted: "ef1ea85a6374" on branch "default"
991 acl: branch access granted: "ef1ea85a6374" on branch "default"
979 acl: path access granted: "ef1ea85a6374"
992 acl: path access granted: "ef1ea85a6374"
980 acl: branch access granted: "f9cafe1212c8" on branch "default"
993 acl: branch access granted: "f9cafe1212c8" on branch "default"
981 acl: path access granted: "f9cafe1212c8"
994 acl: path access granted: "f9cafe1212c8"
982 acl: branch access granted: "911600dab2ae" on branch "default"
995 acl: branch access granted: "911600dab2ae" on branch "default"
983 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
996 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
984 transaction abort!
997 transaction abort!
985 rollback completed
998 rollback completed
986 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
999 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
987 no rollback information available
1000 no rollback information available
988 0:6675d58eff77
1001 0:6675d58eff77
989
1002
990
1003
991 acl.config can set only [acl.allow]/[acl.deny]
1004 acl.config can set only [acl.allow]/[acl.deny]
992
1005
993 $ echo '[hooks]' >> acl.config
1006 $ echo '[hooks]' >> acl.config
994 $ echo 'changegroup.acl = false' >> acl.config
1007 $ echo 'changegroup.acl = false' >> acl.config
995 $ do_push barney
1008 $ do_push barney
996 Pushing as user barney
1009 Pushing as user barney
997 hgrc = """
1010 hgrc = """
998 [hooks]
1011 [hooks]
999 pretxnchangegroup.acl = python:hgext.acl.hook
1012 pretxnchangegroup.acl = python:hgext.acl.hook
1000 [acl]
1013 [acl]
1001 sources = push
1014 sources = push
1002 [acl.allow]
1015 [acl.allow]
1003 foo/** = fred
1016 foo/** = fred
1004 [acl.deny]
1017 [acl.deny]
1005 foo/bar/** = fred
1018 foo/bar/** = fred
1006 foo/Bar/** = fred
1019 foo/Bar/** = fred
1007 [acl.allow]
1020 [acl.allow]
1008 ** = barney
1021 ** = barney
1009 **/*.txt = wilma
1022 **/*.txt = wilma
1010 [acl]
1023 [acl]
1011 config = ../acl.config
1024 config = ../acl.config
1012 """
1025 """
1013 acl.config = """
1026 acl.config = """
1014 [acl.allow]
1027 [acl.allow]
1015 foo/** = betty
1028 foo/** = betty
1016 [hooks]
1029 [hooks]
1017 changegroup.acl = false
1030 changegroup.acl = false
1018 """
1031 """
1019 pushing to ../b
1032 pushing to ../b
1020 query 1; heads
1033 query 1; heads
1021 searching for changes
1034 searching for changes
1022 all remote heads known locally
1035 all remote heads known locally
1036 listing keys for "phases"
1023 invalid branchheads cache (served): tip differs
1037 invalid branchheads cache (served): tip differs
1024 listing keys for "bookmarks"
1038 listing keys for "bookmarks"
1025 3 changesets found
1039 3 changesets found
1026 list of changesets:
1040 list of changesets:
1027 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1041 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1028 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1042 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1029 911600dab2ae7a9baff75958b84fe606851ce955
1043 911600dab2ae7a9baff75958b84fe606851ce955
1030 bundling: 1/3 changesets (33.33%)
1044 bundling: 1/3 changesets (33.33%)
1031 bundling: 2/3 changesets (66.67%)
1045 bundling: 2/3 changesets (66.67%)
1032 bundling: 3/3 changesets (100.00%)
1046 bundling: 3/3 changesets (100.00%)
1033 bundling: 1/3 manifests (33.33%)
1047 bundling: 1/3 manifests (33.33%)
1034 bundling: 2/3 manifests (66.67%)
1048 bundling: 2/3 manifests (66.67%)
1035 bundling: 3/3 manifests (100.00%)
1049 bundling: 3/3 manifests (100.00%)
1036 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1050 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1037 bundling: foo/file.txt 2/3 files (66.67%)
1051 bundling: foo/file.txt 2/3 files (66.67%)
1038 bundling: quux/file.py 3/3 files (100.00%)
1052 bundling: quux/file.py 3/3 files (100.00%)
1039 adding changesets
1053 adding changesets
1040 changesets: 1 chunks
1054 changesets: 1 chunks
1041 add changeset ef1ea85a6374
1055 add changeset ef1ea85a6374
1042 changesets: 2 chunks
1056 changesets: 2 chunks
1043 add changeset f9cafe1212c8
1057 add changeset f9cafe1212c8
1044 changesets: 3 chunks
1058 changesets: 3 chunks
1045 add changeset 911600dab2ae
1059 add changeset 911600dab2ae
1046 adding manifests
1060 adding manifests
1047 manifests: 1/3 chunks (33.33%)
1061 manifests: 1/3 chunks (33.33%)
1048 manifests: 2/3 chunks (66.67%)
1062 manifests: 2/3 chunks (66.67%)
1049 manifests: 3/3 chunks (100.00%)
1063 manifests: 3/3 chunks (100.00%)
1050 adding file changes
1064 adding file changes
1051 adding foo/Bar/file.txt revisions
1065 adding foo/Bar/file.txt revisions
1052 files: 1/3 chunks (33.33%)
1066 files: 1/3 chunks (33.33%)
1053 adding foo/file.txt revisions
1067 adding foo/file.txt revisions
1054 files: 2/3 chunks (66.67%)
1068 files: 2/3 chunks (66.67%)
1055 adding quux/file.py revisions
1069 adding quux/file.py revisions
1056 files: 3/3 chunks (100.00%)
1070 files: 3/3 chunks (100.00%)
1057 added 3 changesets with 3 changes to 3 files
1071 added 3 changesets with 3 changes to 3 files
1058 calling hook pretxnchangegroup.acl: hgext.acl.hook
1072 calling hook pretxnchangegroup.acl: hgext.acl.hook
1059 acl: checking access for user "barney"
1073 acl: checking access for user "barney"
1060 acl: acl.allow.branches not enabled
1074 acl: acl.allow.branches not enabled
1061 acl: acl.deny.branches not enabled
1075 acl: acl.deny.branches not enabled
1062 acl: acl.allow enabled, 1 entries for user barney
1076 acl: acl.allow enabled, 1 entries for user barney
1063 acl: acl.deny enabled, 0 entries for user barney
1077 acl: acl.deny enabled, 0 entries for user barney
1064 acl: branch access granted: "ef1ea85a6374" on branch "default"
1078 acl: branch access granted: "ef1ea85a6374" on branch "default"
1065 acl: path access granted: "ef1ea85a6374"
1079 acl: path access granted: "ef1ea85a6374"
1066 acl: branch access granted: "f9cafe1212c8" on branch "default"
1080 acl: branch access granted: "f9cafe1212c8" on branch "default"
1067 acl: path access granted: "f9cafe1212c8"
1081 acl: path access granted: "f9cafe1212c8"
1068 acl: branch access granted: "911600dab2ae" on branch "default"
1082 acl: branch access granted: "911600dab2ae" on branch "default"
1069 acl: path access granted: "911600dab2ae"
1083 acl: path access granted: "911600dab2ae"
1070 updating the branch cache
1084 updating the branch cache
1071 listing keys for "phases"
1085 listing keys for "phases"
1072 try to push obsolete markers to remote
1086 try to push obsolete markers to remote
1073 checking for updated bookmarks
1087 checking for updated bookmarks
1074 listing keys for "bookmarks"
1088 listing keys for "bookmarks"
1075 repository tip rolled back to revision 0 (undo push)
1089 repository tip rolled back to revision 0 (undo push)
1076 0:6675d58eff77
1090 0:6675d58eff77
1077
1091
1078
1092
1079 asterisk
1093 asterisk
1080
1094
1081 $ init_config
1095 $ init_config
1082
1096
1083 asterisk test
1097 asterisk test
1084
1098
1085 $ echo '[acl.allow]' >> $config
1099 $ echo '[acl.allow]' >> $config
1086 $ echo "** = fred" >> $config
1100 $ echo "** = fred" >> $config
1087
1101
1088 fred is always allowed
1102 fred is always allowed
1089
1103
1090 $ do_push fred
1104 $ do_push fred
1091 Pushing as user fred
1105 Pushing as user fred
1092 hgrc = """
1106 hgrc = """
1093 [acl]
1107 [acl]
1094 sources = push
1108 sources = push
1095 [extensions]
1109 [extensions]
1096 [acl.allow]
1110 [acl.allow]
1097 ** = fred
1111 ** = fred
1098 """
1112 """
1099 pushing to ../b
1113 pushing to ../b
1100 query 1; heads
1114 query 1; heads
1101 searching for changes
1115 searching for changes
1102 all remote heads known locally
1116 all remote heads known locally
1117 listing keys for "phases"
1103 invalid branchheads cache (served): tip differs
1118 invalid branchheads cache (served): tip differs
1104 listing keys for "bookmarks"
1119 listing keys for "bookmarks"
1105 3 changesets found
1120 3 changesets found
1106 list of changesets:
1121 list of changesets:
1107 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1122 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1108 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1123 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1109 911600dab2ae7a9baff75958b84fe606851ce955
1124 911600dab2ae7a9baff75958b84fe606851ce955
1110 bundling: 1/3 changesets (33.33%)
1125 bundling: 1/3 changesets (33.33%)
1111 bundling: 2/3 changesets (66.67%)
1126 bundling: 2/3 changesets (66.67%)
1112 bundling: 3/3 changesets (100.00%)
1127 bundling: 3/3 changesets (100.00%)
1113 bundling: 1/3 manifests (33.33%)
1128 bundling: 1/3 manifests (33.33%)
1114 bundling: 2/3 manifests (66.67%)
1129 bundling: 2/3 manifests (66.67%)
1115 bundling: 3/3 manifests (100.00%)
1130 bundling: 3/3 manifests (100.00%)
1116 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1131 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1117 bundling: foo/file.txt 2/3 files (66.67%)
1132 bundling: foo/file.txt 2/3 files (66.67%)
1118 bundling: quux/file.py 3/3 files (100.00%)
1133 bundling: quux/file.py 3/3 files (100.00%)
1119 adding changesets
1134 adding changesets
1120 changesets: 1 chunks
1135 changesets: 1 chunks
1121 add changeset ef1ea85a6374
1136 add changeset ef1ea85a6374
1122 changesets: 2 chunks
1137 changesets: 2 chunks
1123 add changeset f9cafe1212c8
1138 add changeset f9cafe1212c8
1124 changesets: 3 chunks
1139 changesets: 3 chunks
1125 add changeset 911600dab2ae
1140 add changeset 911600dab2ae
1126 adding manifests
1141 adding manifests
1127 manifests: 1/3 chunks (33.33%)
1142 manifests: 1/3 chunks (33.33%)
1128 manifests: 2/3 chunks (66.67%)
1143 manifests: 2/3 chunks (66.67%)
1129 manifests: 3/3 chunks (100.00%)
1144 manifests: 3/3 chunks (100.00%)
1130 adding file changes
1145 adding file changes
1131 adding foo/Bar/file.txt revisions
1146 adding foo/Bar/file.txt revisions
1132 files: 1/3 chunks (33.33%)
1147 files: 1/3 chunks (33.33%)
1133 adding foo/file.txt revisions
1148 adding foo/file.txt revisions
1134 files: 2/3 chunks (66.67%)
1149 files: 2/3 chunks (66.67%)
1135 adding quux/file.py revisions
1150 adding quux/file.py revisions
1136 files: 3/3 chunks (100.00%)
1151 files: 3/3 chunks (100.00%)
1137 added 3 changesets with 3 changes to 3 files
1152 added 3 changesets with 3 changes to 3 files
1138 calling hook pretxnchangegroup.acl: hgext.acl.hook
1153 calling hook pretxnchangegroup.acl: hgext.acl.hook
1139 acl: checking access for user "fred"
1154 acl: checking access for user "fred"
1140 acl: acl.allow.branches not enabled
1155 acl: acl.allow.branches not enabled
1141 acl: acl.deny.branches not enabled
1156 acl: acl.deny.branches not enabled
1142 acl: acl.allow enabled, 1 entries for user fred
1157 acl: acl.allow enabled, 1 entries for user fred
1143 acl: acl.deny not enabled
1158 acl: acl.deny not enabled
1144 acl: branch access granted: "ef1ea85a6374" on branch "default"
1159 acl: branch access granted: "ef1ea85a6374" on branch "default"
1145 acl: path access granted: "ef1ea85a6374"
1160 acl: path access granted: "ef1ea85a6374"
1146 acl: branch access granted: "f9cafe1212c8" on branch "default"
1161 acl: branch access granted: "f9cafe1212c8" on branch "default"
1147 acl: path access granted: "f9cafe1212c8"
1162 acl: path access granted: "f9cafe1212c8"
1148 acl: branch access granted: "911600dab2ae" on branch "default"
1163 acl: branch access granted: "911600dab2ae" on branch "default"
1149 acl: path access granted: "911600dab2ae"
1164 acl: path access granted: "911600dab2ae"
1150 updating the branch cache
1165 updating the branch cache
1151 listing keys for "phases"
1166 listing keys for "phases"
1152 try to push obsolete markers to remote
1167 try to push obsolete markers to remote
1153 checking for updated bookmarks
1168 checking for updated bookmarks
1154 listing keys for "bookmarks"
1169 listing keys for "bookmarks"
1155 repository tip rolled back to revision 0 (undo push)
1170 repository tip rolled back to revision 0 (undo push)
1156 0:6675d58eff77
1171 0:6675d58eff77
1157
1172
1158
1173
1159 $ echo '[acl.deny]' >> $config
1174 $ echo '[acl.deny]' >> $config
1160 $ echo "foo/Bar/** = *" >> $config
1175 $ echo "foo/Bar/** = *" >> $config
1161
1176
1162 no one is allowed inside foo/Bar/
1177 no one is allowed inside foo/Bar/
1163
1178
1164 $ do_push fred
1179 $ do_push fred
1165 Pushing as user fred
1180 Pushing as user fred
1166 hgrc = """
1181 hgrc = """
1167 [acl]
1182 [acl]
1168 sources = push
1183 sources = push
1169 [extensions]
1184 [extensions]
1170 [acl.allow]
1185 [acl.allow]
1171 ** = fred
1186 ** = fred
1172 [acl.deny]
1187 [acl.deny]
1173 foo/Bar/** = *
1188 foo/Bar/** = *
1174 """
1189 """
1175 pushing to ../b
1190 pushing to ../b
1176 query 1; heads
1191 query 1; heads
1177 searching for changes
1192 searching for changes
1178 all remote heads known locally
1193 all remote heads known locally
1194 listing keys for "phases"
1179 invalid branchheads cache (served): tip differs
1195 invalid branchheads cache (served): tip differs
1180 listing keys for "bookmarks"
1196 listing keys for "bookmarks"
1181 3 changesets found
1197 3 changesets found
1182 list of changesets:
1198 list of changesets:
1183 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1199 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1184 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1200 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1185 911600dab2ae7a9baff75958b84fe606851ce955
1201 911600dab2ae7a9baff75958b84fe606851ce955
1186 bundling: 1/3 changesets (33.33%)
1202 bundling: 1/3 changesets (33.33%)
1187 bundling: 2/3 changesets (66.67%)
1203 bundling: 2/3 changesets (66.67%)
1188 bundling: 3/3 changesets (100.00%)
1204 bundling: 3/3 changesets (100.00%)
1189 bundling: 1/3 manifests (33.33%)
1205 bundling: 1/3 manifests (33.33%)
1190 bundling: 2/3 manifests (66.67%)
1206 bundling: 2/3 manifests (66.67%)
1191 bundling: 3/3 manifests (100.00%)
1207 bundling: 3/3 manifests (100.00%)
1192 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1208 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1193 bundling: foo/file.txt 2/3 files (66.67%)
1209 bundling: foo/file.txt 2/3 files (66.67%)
1194 bundling: quux/file.py 3/3 files (100.00%)
1210 bundling: quux/file.py 3/3 files (100.00%)
1195 adding changesets
1211 adding changesets
1196 changesets: 1 chunks
1212 changesets: 1 chunks
1197 add changeset ef1ea85a6374
1213 add changeset ef1ea85a6374
1198 changesets: 2 chunks
1214 changesets: 2 chunks
1199 add changeset f9cafe1212c8
1215 add changeset f9cafe1212c8
1200 changesets: 3 chunks
1216 changesets: 3 chunks
1201 add changeset 911600dab2ae
1217 add changeset 911600dab2ae
1202 adding manifests
1218 adding manifests
1203 manifests: 1/3 chunks (33.33%)
1219 manifests: 1/3 chunks (33.33%)
1204 manifests: 2/3 chunks (66.67%)
1220 manifests: 2/3 chunks (66.67%)
1205 manifests: 3/3 chunks (100.00%)
1221 manifests: 3/3 chunks (100.00%)
1206 adding file changes
1222 adding file changes
1207 adding foo/Bar/file.txt revisions
1223 adding foo/Bar/file.txt revisions
1208 files: 1/3 chunks (33.33%)
1224 files: 1/3 chunks (33.33%)
1209 adding foo/file.txt revisions
1225 adding foo/file.txt revisions
1210 files: 2/3 chunks (66.67%)
1226 files: 2/3 chunks (66.67%)
1211 adding quux/file.py revisions
1227 adding quux/file.py revisions
1212 files: 3/3 chunks (100.00%)
1228 files: 3/3 chunks (100.00%)
1213 added 3 changesets with 3 changes to 3 files
1229 added 3 changesets with 3 changes to 3 files
1214 calling hook pretxnchangegroup.acl: hgext.acl.hook
1230 calling hook pretxnchangegroup.acl: hgext.acl.hook
1215 acl: checking access for user "fred"
1231 acl: checking access for user "fred"
1216 acl: acl.allow.branches not enabled
1232 acl: acl.allow.branches not enabled
1217 acl: acl.deny.branches not enabled
1233 acl: acl.deny.branches not enabled
1218 acl: acl.allow enabled, 1 entries for user fred
1234 acl: acl.allow enabled, 1 entries for user fred
1219 acl: acl.deny enabled, 1 entries for user fred
1235 acl: acl.deny enabled, 1 entries for user fred
1220 acl: branch access granted: "ef1ea85a6374" on branch "default"
1236 acl: branch access granted: "ef1ea85a6374" on branch "default"
1221 acl: path access granted: "ef1ea85a6374"
1237 acl: path access granted: "ef1ea85a6374"
1222 acl: branch access granted: "f9cafe1212c8" on branch "default"
1238 acl: branch access granted: "f9cafe1212c8" on branch "default"
1223 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1239 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1224 transaction abort!
1240 transaction abort!
1225 rollback completed
1241 rollback completed
1226 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1242 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1227 no rollback information available
1243 no rollback information available
1228 0:6675d58eff77
1244 0:6675d58eff77
1229
1245
1230
1246
1231 Groups
1247 Groups
1232
1248
1233 $ init_config
1249 $ init_config
1234
1250
1235 OS-level groups
1251 OS-level groups
1236
1252
1237 $ echo '[acl.allow]' >> $config
1253 $ echo '[acl.allow]' >> $config
1238 $ echo "** = @group1" >> $config
1254 $ echo "** = @group1" >> $config
1239
1255
1240 @group1 is always allowed
1256 @group1 is always allowed
1241
1257
1242 $ do_push fred
1258 $ do_push fred
1243 Pushing as user fred
1259 Pushing as user fred
1244 hgrc = """
1260 hgrc = """
1245 [acl]
1261 [acl]
1246 sources = push
1262 sources = push
1247 [extensions]
1263 [extensions]
1248 [acl.allow]
1264 [acl.allow]
1249 ** = @group1
1265 ** = @group1
1250 """
1266 """
1251 pushing to ../b
1267 pushing to ../b
1252 query 1; heads
1268 query 1; heads
1253 searching for changes
1269 searching for changes
1254 all remote heads known locally
1270 all remote heads known locally
1271 listing keys for "phases"
1255 invalid branchheads cache (served): tip differs
1272 invalid branchheads cache (served): tip differs
1256 listing keys for "bookmarks"
1273 listing keys for "bookmarks"
1257 3 changesets found
1274 3 changesets found
1258 list of changesets:
1275 list of changesets:
1259 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1276 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1260 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1277 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1261 911600dab2ae7a9baff75958b84fe606851ce955
1278 911600dab2ae7a9baff75958b84fe606851ce955
1262 bundling: 1/3 changesets (33.33%)
1279 bundling: 1/3 changesets (33.33%)
1263 bundling: 2/3 changesets (66.67%)
1280 bundling: 2/3 changesets (66.67%)
1264 bundling: 3/3 changesets (100.00%)
1281 bundling: 3/3 changesets (100.00%)
1265 bundling: 1/3 manifests (33.33%)
1282 bundling: 1/3 manifests (33.33%)
1266 bundling: 2/3 manifests (66.67%)
1283 bundling: 2/3 manifests (66.67%)
1267 bundling: 3/3 manifests (100.00%)
1284 bundling: 3/3 manifests (100.00%)
1268 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1285 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1269 bundling: foo/file.txt 2/3 files (66.67%)
1286 bundling: foo/file.txt 2/3 files (66.67%)
1270 bundling: quux/file.py 3/3 files (100.00%)
1287 bundling: quux/file.py 3/3 files (100.00%)
1271 adding changesets
1288 adding changesets
1272 changesets: 1 chunks
1289 changesets: 1 chunks
1273 add changeset ef1ea85a6374
1290 add changeset ef1ea85a6374
1274 changesets: 2 chunks
1291 changesets: 2 chunks
1275 add changeset f9cafe1212c8
1292 add changeset f9cafe1212c8
1276 changesets: 3 chunks
1293 changesets: 3 chunks
1277 add changeset 911600dab2ae
1294 add changeset 911600dab2ae
1278 adding manifests
1295 adding manifests
1279 manifests: 1/3 chunks (33.33%)
1296 manifests: 1/3 chunks (33.33%)
1280 manifests: 2/3 chunks (66.67%)
1297 manifests: 2/3 chunks (66.67%)
1281 manifests: 3/3 chunks (100.00%)
1298 manifests: 3/3 chunks (100.00%)
1282 adding file changes
1299 adding file changes
1283 adding foo/Bar/file.txt revisions
1300 adding foo/Bar/file.txt revisions
1284 files: 1/3 chunks (33.33%)
1301 files: 1/3 chunks (33.33%)
1285 adding foo/file.txt revisions
1302 adding foo/file.txt revisions
1286 files: 2/3 chunks (66.67%)
1303 files: 2/3 chunks (66.67%)
1287 adding quux/file.py revisions
1304 adding quux/file.py revisions
1288 files: 3/3 chunks (100.00%)
1305 files: 3/3 chunks (100.00%)
1289 added 3 changesets with 3 changes to 3 files
1306 added 3 changesets with 3 changes to 3 files
1290 calling hook pretxnchangegroup.acl: hgext.acl.hook
1307 calling hook pretxnchangegroup.acl: hgext.acl.hook
1291 acl: checking access for user "fred"
1308 acl: checking access for user "fred"
1292 acl: acl.allow.branches not enabled
1309 acl: acl.allow.branches not enabled
1293 acl: acl.deny.branches not enabled
1310 acl: acl.deny.branches not enabled
1294 acl: "group1" not defined in [acl.groups]
1311 acl: "group1" not defined in [acl.groups]
1295 acl: acl.allow enabled, 1 entries for user fred
1312 acl: acl.allow enabled, 1 entries for user fred
1296 acl: acl.deny not enabled
1313 acl: acl.deny not enabled
1297 acl: branch access granted: "ef1ea85a6374" on branch "default"
1314 acl: branch access granted: "ef1ea85a6374" on branch "default"
1298 acl: path access granted: "ef1ea85a6374"
1315 acl: path access granted: "ef1ea85a6374"
1299 acl: branch access granted: "f9cafe1212c8" on branch "default"
1316 acl: branch access granted: "f9cafe1212c8" on branch "default"
1300 acl: path access granted: "f9cafe1212c8"
1317 acl: path access granted: "f9cafe1212c8"
1301 acl: branch access granted: "911600dab2ae" on branch "default"
1318 acl: branch access granted: "911600dab2ae" on branch "default"
1302 acl: path access granted: "911600dab2ae"
1319 acl: path access granted: "911600dab2ae"
1303 updating the branch cache
1320 updating the branch cache
1304 listing keys for "phases"
1321 listing keys for "phases"
1305 try to push obsolete markers to remote
1322 try to push obsolete markers to remote
1306 checking for updated bookmarks
1323 checking for updated bookmarks
1307 listing keys for "bookmarks"
1324 listing keys for "bookmarks"
1308 repository tip rolled back to revision 0 (undo push)
1325 repository tip rolled back to revision 0 (undo push)
1309 0:6675d58eff77
1326 0:6675d58eff77
1310
1327
1311
1328
1312 $ echo '[acl.deny]' >> $config
1329 $ echo '[acl.deny]' >> $config
1313 $ echo "foo/Bar/** = @group1" >> $config
1330 $ echo "foo/Bar/** = @group1" >> $config
1314
1331
1315 @group is allowed inside anything but foo/Bar/
1332 @group is allowed inside anything but foo/Bar/
1316
1333
1317 $ do_push fred
1334 $ do_push fred
1318 Pushing as user fred
1335 Pushing as user fred
1319 hgrc = """
1336 hgrc = """
1320 [acl]
1337 [acl]
1321 sources = push
1338 sources = push
1322 [extensions]
1339 [extensions]
1323 [acl.allow]
1340 [acl.allow]
1324 ** = @group1
1341 ** = @group1
1325 [acl.deny]
1342 [acl.deny]
1326 foo/Bar/** = @group1
1343 foo/Bar/** = @group1
1327 """
1344 """
1328 pushing to ../b
1345 pushing to ../b
1329 query 1; heads
1346 query 1; heads
1330 searching for changes
1347 searching for changes
1331 all remote heads known locally
1348 all remote heads known locally
1349 listing keys for "phases"
1332 invalid branchheads cache (served): tip differs
1350 invalid branchheads cache (served): tip differs
1333 listing keys for "bookmarks"
1351 listing keys for "bookmarks"
1334 3 changesets found
1352 3 changesets found
1335 list of changesets:
1353 list of changesets:
1336 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1354 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1337 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1355 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1338 911600dab2ae7a9baff75958b84fe606851ce955
1356 911600dab2ae7a9baff75958b84fe606851ce955
1339 bundling: 1/3 changesets (33.33%)
1357 bundling: 1/3 changesets (33.33%)
1340 bundling: 2/3 changesets (66.67%)
1358 bundling: 2/3 changesets (66.67%)
1341 bundling: 3/3 changesets (100.00%)
1359 bundling: 3/3 changesets (100.00%)
1342 bundling: 1/3 manifests (33.33%)
1360 bundling: 1/3 manifests (33.33%)
1343 bundling: 2/3 manifests (66.67%)
1361 bundling: 2/3 manifests (66.67%)
1344 bundling: 3/3 manifests (100.00%)
1362 bundling: 3/3 manifests (100.00%)
1345 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1363 bundling: foo/Bar/file.txt 1/3 files (33.33%)
1346 bundling: foo/file.txt 2/3 files (66.67%)
1364 bundling: foo/file.txt 2/3 files (66.67%)
1347 bundling: quux/file.py 3/3 files (100.00%)
1365 bundling: quux/file.py 3/3 files (100.00%)
1348 adding changesets
1366 adding changesets
1349 changesets: 1 chunks
1367 changesets: 1 chunks
1350 add changeset ef1ea85a6374
1368 add changeset ef1ea85a6374
1351 changesets: 2 chunks
1369 changesets: 2 chunks
1352 add changeset f9cafe1212c8
1370 add changeset f9cafe1212c8
1353 changesets: 3 chunks
1371 changesets: 3 chunks
1354 add changeset 911600dab2ae
1372 add changeset 911600dab2ae
1355 adding manifests
1373 adding manifests
1356 manifests: 1/3 chunks (33.33%)
1374 manifests: 1/3 chunks (33.33%)
1357 manifests: 2/3 chunks (66.67%)
1375 manifests: 2/3 chunks (66.67%)
1358 manifests: 3/3 chunks (100.00%)
1376 manifests: 3/3 chunks (100.00%)
1359 adding file changes
1377 adding file changes
1360 adding foo/Bar/file.txt revisions
1378 adding foo/Bar/file.txt revisions
1361 files: 1/3 chunks (33.33%)
1379 files: 1/3 chunks (33.33%)
1362 adding foo/file.txt revisions
1380 adding foo/file.txt revisions
1363 files: 2/3 chunks (66.67%)
1381 files: 2/3 chunks (66.67%)
1364 adding quux/file.py revisions
1382 adding quux/file.py revisions
1365 files: 3/3 chunks (100.00%)
1383 files: 3/3 chunks (100.00%)
1366 added 3 changesets with 3 changes to 3 files
1384 added 3 changesets with 3 changes to 3 files
1367 calling hook pretxnchangegroup.acl: hgext.acl.hook
1385 calling hook pretxnchangegroup.acl: hgext.acl.hook
1368 acl: checking access for user "fred"
1386 acl: checking access for user "fred"
1369 acl: acl.allow.branches not enabled
1387 acl: acl.allow.branches not enabled
1370 acl: acl.deny.branches not enabled
1388 acl: acl.deny.branches not enabled
1371 acl: "group1" not defined in [acl.groups]
1389 acl: "group1" not defined in [acl.groups]
1372 acl: acl.allow enabled, 1 entries for user fred
1390 acl: acl.allow enabled, 1 entries for user fred
1373 acl: "group1" not defined in [acl.groups]
1391 acl: "group1" not defined in [acl.groups]
1374 acl: acl.deny enabled, 1 entries for user fred
1392 acl: acl.deny enabled, 1 entries for user fred
1375 acl: branch access granted: "ef1ea85a6374" on branch "default"
1393 acl: branch access granted: "ef1ea85a6374" on branch "default"
1376 acl: path access granted: "ef1ea85a6374"
1394 acl: path access granted: "ef1ea85a6374"
1377 acl: branch access granted: "f9cafe1212c8" on branch "default"
1395 acl: branch access granted: "f9cafe1212c8" on branch "default"
1378 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1396 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1379 transaction abort!
1397 transaction abort!
1380 rollback completed
1398 rollback completed
1381 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1399 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1382 no rollback information available
1400 no rollback information available
1383 0:6675d58eff77
1401 0:6675d58eff77
1384
1402
1385
1403
1386 Invalid group
1404 Invalid group
1387
1405
1388 Disable the fakegroups trick to get real failures
1406 Disable the fakegroups trick to get real failures
1389
1407
1390 $ grep -v fakegroups $config > config.tmp
1408 $ grep -v fakegroups $config > config.tmp
1391 $ mv config.tmp $config
1409 $ mv config.tmp $config
1392 $ echo '[acl.allow]' >> $config
1410 $ echo '[acl.allow]' >> $config
1393 $ echo "** = @unlikelytoexist" >> $config
1411 $ echo "** = @unlikelytoexist" >> $config
1394 $ do_push fred 2>&1 | grep unlikelytoexist
1412 $ do_push fred 2>&1 | grep unlikelytoexist
1395 ** = @unlikelytoexist
1413 ** = @unlikelytoexist
1396 acl: "unlikelytoexist" not defined in [acl.groups]
1414 acl: "unlikelytoexist" not defined in [acl.groups]
1397 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1415 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1398 abort: group 'unlikelytoexist' is undefined
1416 abort: group 'unlikelytoexist' is undefined
1399
1417
1400
1418
1401 Branch acl tests setup
1419 Branch acl tests setup
1402
1420
1403 $ init_config
1421 $ init_config
1404 $ cd b
1422 $ cd b
1405 $ hg up
1423 $ hg up
1406 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1424 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1407 $ hg branch foobar
1425 $ hg branch foobar
1408 marked working directory as branch foobar
1426 marked working directory as branch foobar
1409 (branches are permanent and global, did you want a bookmark?)
1427 (branches are permanent and global, did you want a bookmark?)
1410 $ hg commit -m 'create foobar'
1428 $ hg commit -m 'create foobar'
1411 $ echo 'foo contents' > abc.txt
1429 $ echo 'foo contents' > abc.txt
1412 $ hg add abc.txt
1430 $ hg add abc.txt
1413 $ hg commit -m 'foobar contents'
1431 $ hg commit -m 'foobar contents'
1414 $ cd ..
1432 $ cd ..
1415 $ hg --cwd a pull ../b
1433 $ hg --cwd a pull ../b
1416 pulling from ../b
1434 pulling from ../b
1417 searching for changes
1435 searching for changes
1418 adding changesets
1436 adding changesets
1419 adding manifests
1437 adding manifests
1420 adding file changes
1438 adding file changes
1421 added 2 changesets with 1 changes to 1 files (+1 heads)
1439 added 2 changesets with 1 changes to 1 files (+1 heads)
1422 (run 'hg heads' to see heads)
1440 (run 'hg heads' to see heads)
1423
1441
1424 Create additional changeset on foobar branch
1442 Create additional changeset on foobar branch
1425
1443
1426 $ cd a
1444 $ cd a
1427 $ hg up -C foobar
1445 $ hg up -C foobar
1428 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1446 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1429 $ echo 'foo contents2' > abc.txt
1447 $ echo 'foo contents2' > abc.txt
1430 $ hg commit -m 'foobar contents2'
1448 $ hg commit -m 'foobar contents2'
1431 $ cd ..
1449 $ cd ..
1432
1450
1433
1451
1434 No branch acls specified
1452 No branch acls specified
1435
1453
1436 $ do_push astro
1454 $ do_push astro
1437 Pushing as user astro
1455 Pushing as user astro
1438 hgrc = """
1456 hgrc = """
1439 [acl]
1457 [acl]
1440 sources = push
1458 sources = push
1441 [extensions]
1459 [extensions]
1442 """
1460 """
1443 pushing to ../b
1461 pushing to ../b
1444 query 1; heads
1462 query 1; heads
1445 searching for changes
1463 searching for changes
1446 all remote heads known locally
1464 all remote heads known locally
1465 listing keys for "phases"
1447 listing keys for "bookmarks"
1466 listing keys for "bookmarks"
1448 4 changesets found
1467 4 changesets found
1449 list of changesets:
1468 list of changesets:
1450 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1469 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1451 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1470 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1452 911600dab2ae7a9baff75958b84fe606851ce955
1471 911600dab2ae7a9baff75958b84fe606851ce955
1453 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1472 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1454 bundling: 1/4 changesets (25.00%)
1473 bundling: 1/4 changesets (25.00%)
1455 bundling: 2/4 changesets (50.00%)
1474 bundling: 2/4 changesets (50.00%)
1456 bundling: 3/4 changesets (75.00%)
1475 bundling: 3/4 changesets (75.00%)
1457 bundling: 4/4 changesets (100.00%)
1476 bundling: 4/4 changesets (100.00%)
1458 bundling: 1/4 manifests (25.00%)
1477 bundling: 1/4 manifests (25.00%)
1459 bundling: 2/4 manifests (50.00%)
1478 bundling: 2/4 manifests (50.00%)
1460 bundling: 3/4 manifests (75.00%)
1479 bundling: 3/4 manifests (75.00%)
1461 bundling: 4/4 manifests (100.00%)
1480 bundling: 4/4 manifests (100.00%)
1462 bundling: abc.txt 1/4 files (25.00%)
1481 bundling: abc.txt 1/4 files (25.00%)
1463 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1482 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1464 bundling: foo/file.txt 3/4 files (75.00%)
1483 bundling: foo/file.txt 3/4 files (75.00%)
1465 bundling: quux/file.py 4/4 files (100.00%)
1484 bundling: quux/file.py 4/4 files (100.00%)
1466 adding changesets
1485 adding changesets
1467 changesets: 1 chunks
1486 changesets: 1 chunks
1468 add changeset ef1ea85a6374
1487 add changeset ef1ea85a6374
1469 changesets: 2 chunks
1488 changesets: 2 chunks
1470 add changeset f9cafe1212c8
1489 add changeset f9cafe1212c8
1471 changesets: 3 chunks
1490 changesets: 3 chunks
1472 add changeset 911600dab2ae
1491 add changeset 911600dab2ae
1473 changesets: 4 chunks
1492 changesets: 4 chunks
1474 add changeset e8fc755d4d82
1493 add changeset e8fc755d4d82
1475 adding manifests
1494 adding manifests
1476 manifests: 1/4 chunks (25.00%)
1495 manifests: 1/4 chunks (25.00%)
1477 manifests: 2/4 chunks (50.00%)
1496 manifests: 2/4 chunks (50.00%)
1478 manifests: 3/4 chunks (75.00%)
1497 manifests: 3/4 chunks (75.00%)
1479 manifests: 4/4 chunks (100.00%)
1498 manifests: 4/4 chunks (100.00%)
1480 adding file changes
1499 adding file changes
1481 adding abc.txt revisions
1500 adding abc.txt revisions
1482 files: 1/4 chunks (25.00%)
1501 files: 1/4 chunks (25.00%)
1483 adding foo/Bar/file.txt revisions
1502 adding foo/Bar/file.txt revisions
1484 files: 2/4 chunks (50.00%)
1503 files: 2/4 chunks (50.00%)
1485 adding foo/file.txt revisions
1504 adding foo/file.txt revisions
1486 files: 3/4 chunks (75.00%)
1505 files: 3/4 chunks (75.00%)
1487 adding quux/file.py revisions
1506 adding quux/file.py revisions
1488 files: 4/4 chunks (100.00%)
1507 files: 4/4 chunks (100.00%)
1489 added 4 changesets with 4 changes to 4 files (+1 heads)
1508 added 4 changesets with 4 changes to 4 files (+1 heads)
1490 calling hook pretxnchangegroup.acl: hgext.acl.hook
1509 calling hook pretxnchangegroup.acl: hgext.acl.hook
1491 acl: checking access for user "astro"
1510 acl: checking access for user "astro"
1492 acl: acl.allow.branches not enabled
1511 acl: acl.allow.branches not enabled
1493 acl: acl.deny.branches not enabled
1512 acl: acl.deny.branches not enabled
1494 acl: acl.allow not enabled
1513 acl: acl.allow not enabled
1495 acl: acl.deny not enabled
1514 acl: acl.deny not enabled
1496 acl: branch access granted: "ef1ea85a6374" on branch "default"
1515 acl: branch access granted: "ef1ea85a6374" on branch "default"
1497 acl: path access granted: "ef1ea85a6374"
1516 acl: path access granted: "ef1ea85a6374"
1498 acl: branch access granted: "f9cafe1212c8" on branch "default"
1517 acl: branch access granted: "f9cafe1212c8" on branch "default"
1499 acl: path access granted: "f9cafe1212c8"
1518 acl: path access granted: "f9cafe1212c8"
1500 acl: branch access granted: "911600dab2ae" on branch "default"
1519 acl: branch access granted: "911600dab2ae" on branch "default"
1501 acl: path access granted: "911600dab2ae"
1520 acl: path access granted: "911600dab2ae"
1502 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1521 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1503 acl: path access granted: "e8fc755d4d82"
1522 acl: path access granted: "e8fc755d4d82"
1504 updating the branch cache
1523 updating the branch cache
1505 listing keys for "phases"
1524 listing keys for "phases"
1506 try to push obsolete markers to remote
1525 try to push obsolete markers to remote
1507 checking for updated bookmarks
1526 checking for updated bookmarks
1508 listing keys for "bookmarks"
1527 listing keys for "bookmarks"
1509 repository tip rolled back to revision 2 (undo push)
1528 repository tip rolled back to revision 2 (undo push)
1510 2:fb35475503ef
1529 2:fb35475503ef
1511
1530
1512
1531
1513 Branch acl deny test
1532 Branch acl deny test
1514
1533
1515 $ echo "[acl.deny.branches]" >> $config
1534 $ echo "[acl.deny.branches]" >> $config
1516 $ echo "foobar = *" >> $config
1535 $ echo "foobar = *" >> $config
1517 $ do_push astro
1536 $ do_push astro
1518 Pushing as user astro
1537 Pushing as user astro
1519 hgrc = """
1538 hgrc = """
1520 [acl]
1539 [acl]
1521 sources = push
1540 sources = push
1522 [extensions]
1541 [extensions]
1523 [acl.deny.branches]
1542 [acl.deny.branches]
1524 foobar = *
1543 foobar = *
1525 """
1544 """
1526 pushing to ../b
1545 pushing to ../b
1527 query 1; heads
1546 query 1; heads
1528 searching for changes
1547 searching for changes
1529 all remote heads known locally
1548 all remote heads known locally
1549 listing keys for "phases"
1530 listing keys for "bookmarks"
1550 listing keys for "bookmarks"
1531 4 changesets found
1551 4 changesets found
1532 list of changesets:
1552 list of changesets:
1533 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1553 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1534 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1554 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1535 911600dab2ae7a9baff75958b84fe606851ce955
1555 911600dab2ae7a9baff75958b84fe606851ce955
1536 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1556 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1537 bundling: 1/4 changesets (25.00%)
1557 bundling: 1/4 changesets (25.00%)
1538 bundling: 2/4 changesets (50.00%)
1558 bundling: 2/4 changesets (50.00%)
1539 bundling: 3/4 changesets (75.00%)
1559 bundling: 3/4 changesets (75.00%)
1540 bundling: 4/4 changesets (100.00%)
1560 bundling: 4/4 changesets (100.00%)
1541 bundling: 1/4 manifests (25.00%)
1561 bundling: 1/4 manifests (25.00%)
1542 bundling: 2/4 manifests (50.00%)
1562 bundling: 2/4 manifests (50.00%)
1543 bundling: 3/4 manifests (75.00%)
1563 bundling: 3/4 manifests (75.00%)
1544 bundling: 4/4 manifests (100.00%)
1564 bundling: 4/4 manifests (100.00%)
1545 bundling: abc.txt 1/4 files (25.00%)
1565 bundling: abc.txt 1/4 files (25.00%)
1546 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1566 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1547 bundling: foo/file.txt 3/4 files (75.00%)
1567 bundling: foo/file.txt 3/4 files (75.00%)
1548 bundling: quux/file.py 4/4 files (100.00%)
1568 bundling: quux/file.py 4/4 files (100.00%)
1549 adding changesets
1569 adding changesets
1550 changesets: 1 chunks
1570 changesets: 1 chunks
1551 add changeset ef1ea85a6374
1571 add changeset ef1ea85a6374
1552 changesets: 2 chunks
1572 changesets: 2 chunks
1553 add changeset f9cafe1212c8
1573 add changeset f9cafe1212c8
1554 changesets: 3 chunks
1574 changesets: 3 chunks
1555 add changeset 911600dab2ae
1575 add changeset 911600dab2ae
1556 changesets: 4 chunks
1576 changesets: 4 chunks
1557 add changeset e8fc755d4d82
1577 add changeset e8fc755d4d82
1558 adding manifests
1578 adding manifests
1559 manifests: 1/4 chunks (25.00%)
1579 manifests: 1/4 chunks (25.00%)
1560 manifests: 2/4 chunks (50.00%)
1580 manifests: 2/4 chunks (50.00%)
1561 manifests: 3/4 chunks (75.00%)
1581 manifests: 3/4 chunks (75.00%)
1562 manifests: 4/4 chunks (100.00%)
1582 manifests: 4/4 chunks (100.00%)
1563 adding file changes
1583 adding file changes
1564 adding abc.txt revisions
1584 adding abc.txt revisions
1565 files: 1/4 chunks (25.00%)
1585 files: 1/4 chunks (25.00%)
1566 adding foo/Bar/file.txt revisions
1586 adding foo/Bar/file.txt revisions
1567 files: 2/4 chunks (50.00%)
1587 files: 2/4 chunks (50.00%)
1568 adding foo/file.txt revisions
1588 adding foo/file.txt revisions
1569 files: 3/4 chunks (75.00%)
1589 files: 3/4 chunks (75.00%)
1570 adding quux/file.py revisions
1590 adding quux/file.py revisions
1571 files: 4/4 chunks (100.00%)
1591 files: 4/4 chunks (100.00%)
1572 added 4 changesets with 4 changes to 4 files (+1 heads)
1592 added 4 changesets with 4 changes to 4 files (+1 heads)
1573 calling hook pretxnchangegroup.acl: hgext.acl.hook
1593 calling hook pretxnchangegroup.acl: hgext.acl.hook
1574 acl: checking access for user "astro"
1594 acl: checking access for user "astro"
1575 acl: acl.allow.branches not enabled
1595 acl: acl.allow.branches not enabled
1576 acl: acl.deny.branches enabled, 1 entries for user astro
1596 acl: acl.deny.branches enabled, 1 entries for user astro
1577 acl: acl.allow not enabled
1597 acl: acl.allow not enabled
1578 acl: acl.deny not enabled
1598 acl: acl.deny not enabled
1579 acl: branch access granted: "ef1ea85a6374" on branch "default"
1599 acl: branch access granted: "ef1ea85a6374" on branch "default"
1580 acl: path access granted: "ef1ea85a6374"
1600 acl: path access granted: "ef1ea85a6374"
1581 acl: branch access granted: "f9cafe1212c8" on branch "default"
1601 acl: branch access granted: "f9cafe1212c8" on branch "default"
1582 acl: path access granted: "f9cafe1212c8"
1602 acl: path access granted: "f9cafe1212c8"
1583 acl: branch access granted: "911600dab2ae" on branch "default"
1603 acl: branch access granted: "911600dab2ae" on branch "default"
1584 acl: path access granted: "911600dab2ae"
1604 acl: path access granted: "911600dab2ae"
1585 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1605 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1586 transaction abort!
1606 transaction abort!
1587 rollback completed
1607 rollback completed
1588 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1608 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1589 no rollback information available
1609 no rollback information available
1590 2:fb35475503ef
1610 2:fb35475503ef
1591
1611
1592
1612
1593 Branch acl empty allow test
1613 Branch acl empty allow test
1594
1614
1595 $ init_config
1615 $ init_config
1596 $ echo "[acl.allow.branches]" >> $config
1616 $ echo "[acl.allow.branches]" >> $config
1597 $ do_push astro
1617 $ do_push astro
1598 Pushing as user astro
1618 Pushing as user astro
1599 hgrc = """
1619 hgrc = """
1600 [acl]
1620 [acl]
1601 sources = push
1621 sources = push
1602 [extensions]
1622 [extensions]
1603 [acl.allow.branches]
1623 [acl.allow.branches]
1604 """
1624 """
1605 pushing to ../b
1625 pushing to ../b
1606 query 1; heads
1626 query 1; heads
1607 searching for changes
1627 searching for changes
1608 all remote heads known locally
1628 all remote heads known locally
1629 listing keys for "phases"
1609 listing keys for "bookmarks"
1630 listing keys for "bookmarks"
1610 4 changesets found
1631 4 changesets found
1611 list of changesets:
1632 list of changesets:
1612 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1633 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1613 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1634 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1614 911600dab2ae7a9baff75958b84fe606851ce955
1635 911600dab2ae7a9baff75958b84fe606851ce955
1615 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1636 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1616 bundling: 1/4 changesets (25.00%)
1637 bundling: 1/4 changesets (25.00%)
1617 bundling: 2/4 changesets (50.00%)
1638 bundling: 2/4 changesets (50.00%)
1618 bundling: 3/4 changesets (75.00%)
1639 bundling: 3/4 changesets (75.00%)
1619 bundling: 4/4 changesets (100.00%)
1640 bundling: 4/4 changesets (100.00%)
1620 bundling: 1/4 manifests (25.00%)
1641 bundling: 1/4 manifests (25.00%)
1621 bundling: 2/4 manifests (50.00%)
1642 bundling: 2/4 manifests (50.00%)
1622 bundling: 3/4 manifests (75.00%)
1643 bundling: 3/4 manifests (75.00%)
1623 bundling: 4/4 manifests (100.00%)
1644 bundling: 4/4 manifests (100.00%)
1624 bundling: abc.txt 1/4 files (25.00%)
1645 bundling: abc.txt 1/4 files (25.00%)
1625 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1646 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1626 bundling: foo/file.txt 3/4 files (75.00%)
1647 bundling: foo/file.txt 3/4 files (75.00%)
1627 bundling: quux/file.py 4/4 files (100.00%)
1648 bundling: quux/file.py 4/4 files (100.00%)
1628 adding changesets
1649 adding changesets
1629 changesets: 1 chunks
1650 changesets: 1 chunks
1630 add changeset ef1ea85a6374
1651 add changeset ef1ea85a6374
1631 changesets: 2 chunks
1652 changesets: 2 chunks
1632 add changeset f9cafe1212c8
1653 add changeset f9cafe1212c8
1633 changesets: 3 chunks
1654 changesets: 3 chunks
1634 add changeset 911600dab2ae
1655 add changeset 911600dab2ae
1635 changesets: 4 chunks
1656 changesets: 4 chunks
1636 add changeset e8fc755d4d82
1657 add changeset e8fc755d4d82
1637 adding manifests
1658 adding manifests
1638 manifests: 1/4 chunks (25.00%)
1659 manifests: 1/4 chunks (25.00%)
1639 manifests: 2/4 chunks (50.00%)
1660 manifests: 2/4 chunks (50.00%)
1640 manifests: 3/4 chunks (75.00%)
1661 manifests: 3/4 chunks (75.00%)
1641 manifests: 4/4 chunks (100.00%)
1662 manifests: 4/4 chunks (100.00%)
1642 adding file changes
1663 adding file changes
1643 adding abc.txt revisions
1664 adding abc.txt revisions
1644 files: 1/4 chunks (25.00%)
1665 files: 1/4 chunks (25.00%)
1645 adding foo/Bar/file.txt revisions
1666 adding foo/Bar/file.txt revisions
1646 files: 2/4 chunks (50.00%)
1667 files: 2/4 chunks (50.00%)
1647 adding foo/file.txt revisions
1668 adding foo/file.txt revisions
1648 files: 3/4 chunks (75.00%)
1669 files: 3/4 chunks (75.00%)
1649 adding quux/file.py revisions
1670 adding quux/file.py revisions
1650 files: 4/4 chunks (100.00%)
1671 files: 4/4 chunks (100.00%)
1651 added 4 changesets with 4 changes to 4 files (+1 heads)
1672 added 4 changesets with 4 changes to 4 files (+1 heads)
1652 calling hook pretxnchangegroup.acl: hgext.acl.hook
1673 calling hook pretxnchangegroup.acl: hgext.acl.hook
1653 acl: checking access for user "astro"
1674 acl: checking access for user "astro"
1654 acl: acl.allow.branches enabled, 0 entries for user astro
1675 acl: acl.allow.branches enabled, 0 entries for user astro
1655 acl: acl.deny.branches not enabled
1676 acl: acl.deny.branches not enabled
1656 acl: acl.allow not enabled
1677 acl: acl.allow not enabled
1657 acl: acl.deny not enabled
1678 acl: acl.deny not enabled
1658 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1679 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1659 transaction abort!
1680 transaction abort!
1660 rollback completed
1681 rollback completed
1661 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1682 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1662 no rollback information available
1683 no rollback information available
1663 2:fb35475503ef
1684 2:fb35475503ef
1664
1685
1665
1686
1666 Branch acl allow other
1687 Branch acl allow other
1667
1688
1668 $ init_config
1689 $ init_config
1669 $ echo "[acl.allow.branches]" >> $config
1690 $ echo "[acl.allow.branches]" >> $config
1670 $ echo "* = george" >> $config
1691 $ echo "* = george" >> $config
1671 $ do_push astro
1692 $ do_push astro
1672 Pushing as user astro
1693 Pushing as user astro
1673 hgrc = """
1694 hgrc = """
1674 [acl]
1695 [acl]
1675 sources = push
1696 sources = push
1676 [extensions]
1697 [extensions]
1677 [acl.allow.branches]
1698 [acl.allow.branches]
1678 * = george
1699 * = george
1679 """
1700 """
1680 pushing to ../b
1701 pushing to ../b
1681 query 1; heads
1702 query 1; heads
1682 searching for changes
1703 searching for changes
1683 all remote heads known locally
1704 all remote heads known locally
1705 listing keys for "phases"
1684 listing keys for "bookmarks"
1706 listing keys for "bookmarks"
1685 4 changesets found
1707 4 changesets found
1686 list of changesets:
1708 list of changesets:
1687 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1709 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1688 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1710 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1689 911600dab2ae7a9baff75958b84fe606851ce955
1711 911600dab2ae7a9baff75958b84fe606851ce955
1690 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1712 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1691 bundling: 1/4 changesets (25.00%)
1713 bundling: 1/4 changesets (25.00%)
1692 bundling: 2/4 changesets (50.00%)
1714 bundling: 2/4 changesets (50.00%)
1693 bundling: 3/4 changesets (75.00%)
1715 bundling: 3/4 changesets (75.00%)
1694 bundling: 4/4 changesets (100.00%)
1716 bundling: 4/4 changesets (100.00%)
1695 bundling: 1/4 manifests (25.00%)
1717 bundling: 1/4 manifests (25.00%)
1696 bundling: 2/4 manifests (50.00%)
1718 bundling: 2/4 manifests (50.00%)
1697 bundling: 3/4 manifests (75.00%)
1719 bundling: 3/4 manifests (75.00%)
1698 bundling: 4/4 manifests (100.00%)
1720 bundling: 4/4 manifests (100.00%)
1699 bundling: abc.txt 1/4 files (25.00%)
1721 bundling: abc.txt 1/4 files (25.00%)
1700 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1722 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1701 bundling: foo/file.txt 3/4 files (75.00%)
1723 bundling: foo/file.txt 3/4 files (75.00%)
1702 bundling: quux/file.py 4/4 files (100.00%)
1724 bundling: quux/file.py 4/4 files (100.00%)
1703 adding changesets
1725 adding changesets
1704 changesets: 1 chunks
1726 changesets: 1 chunks
1705 add changeset ef1ea85a6374
1727 add changeset ef1ea85a6374
1706 changesets: 2 chunks
1728 changesets: 2 chunks
1707 add changeset f9cafe1212c8
1729 add changeset f9cafe1212c8
1708 changesets: 3 chunks
1730 changesets: 3 chunks
1709 add changeset 911600dab2ae
1731 add changeset 911600dab2ae
1710 changesets: 4 chunks
1732 changesets: 4 chunks
1711 add changeset e8fc755d4d82
1733 add changeset e8fc755d4d82
1712 adding manifests
1734 adding manifests
1713 manifests: 1/4 chunks (25.00%)
1735 manifests: 1/4 chunks (25.00%)
1714 manifests: 2/4 chunks (50.00%)
1736 manifests: 2/4 chunks (50.00%)
1715 manifests: 3/4 chunks (75.00%)
1737 manifests: 3/4 chunks (75.00%)
1716 manifests: 4/4 chunks (100.00%)
1738 manifests: 4/4 chunks (100.00%)
1717 adding file changes
1739 adding file changes
1718 adding abc.txt revisions
1740 adding abc.txt revisions
1719 files: 1/4 chunks (25.00%)
1741 files: 1/4 chunks (25.00%)
1720 adding foo/Bar/file.txt revisions
1742 adding foo/Bar/file.txt revisions
1721 files: 2/4 chunks (50.00%)
1743 files: 2/4 chunks (50.00%)
1722 adding foo/file.txt revisions
1744 adding foo/file.txt revisions
1723 files: 3/4 chunks (75.00%)
1745 files: 3/4 chunks (75.00%)
1724 adding quux/file.py revisions
1746 adding quux/file.py revisions
1725 files: 4/4 chunks (100.00%)
1747 files: 4/4 chunks (100.00%)
1726 added 4 changesets with 4 changes to 4 files (+1 heads)
1748 added 4 changesets with 4 changes to 4 files (+1 heads)
1727 calling hook pretxnchangegroup.acl: hgext.acl.hook
1749 calling hook pretxnchangegroup.acl: hgext.acl.hook
1728 acl: checking access for user "astro"
1750 acl: checking access for user "astro"
1729 acl: acl.allow.branches enabled, 0 entries for user astro
1751 acl: acl.allow.branches enabled, 0 entries for user astro
1730 acl: acl.deny.branches not enabled
1752 acl: acl.deny.branches not enabled
1731 acl: acl.allow not enabled
1753 acl: acl.allow not enabled
1732 acl: acl.deny not enabled
1754 acl: acl.deny not enabled
1733 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1755 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1734 transaction abort!
1756 transaction abort!
1735 rollback completed
1757 rollback completed
1736 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1758 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1737 no rollback information available
1759 no rollback information available
1738 2:fb35475503ef
1760 2:fb35475503ef
1739
1761
1740 $ do_push george
1762 $ do_push george
1741 Pushing as user george
1763 Pushing as user george
1742 hgrc = """
1764 hgrc = """
1743 [acl]
1765 [acl]
1744 sources = push
1766 sources = push
1745 [extensions]
1767 [extensions]
1746 [acl.allow.branches]
1768 [acl.allow.branches]
1747 * = george
1769 * = george
1748 """
1770 """
1749 pushing to ../b
1771 pushing to ../b
1750 query 1; heads
1772 query 1; heads
1751 searching for changes
1773 searching for changes
1752 all remote heads known locally
1774 all remote heads known locally
1775 listing keys for "phases"
1753 listing keys for "bookmarks"
1776 listing keys for "bookmarks"
1754 4 changesets found
1777 4 changesets found
1755 list of changesets:
1778 list of changesets:
1756 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1779 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1757 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1780 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1758 911600dab2ae7a9baff75958b84fe606851ce955
1781 911600dab2ae7a9baff75958b84fe606851ce955
1759 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1782 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1760 bundling: 1/4 changesets (25.00%)
1783 bundling: 1/4 changesets (25.00%)
1761 bundling: 2/4 changesets (50.00%)
1784 bundling: 2/4 changesets (50.00%)
1762 bundling: 3/4 changesets (75.00%)
1785 bundling: 3/4 changesets (75.00%)
1763 bundling: 4/4 changesets (100.00%)
1786 bundling: 4/4 changesets (100.00%)
1764 bundling: 1/4 manifests (25.00%)
1787 bundling: 1/4 manifests (25.00%)
1765 bundling: 2/4 manifests (50.00%)
1788 bundling: 2/4 manifests (50.00%)
1766 bundling: 3/4 manifests (75.00%)
1789 bundling: 3/4 manifests (75.00%)
1767 bundling: 4/4 manifests (100.00%)
1790 bundling: 4/4 manifests (100.00%)
1768 bundling: abc.txt 1/4 files (25.00%)
1791 bundling: abc.txt 1/4 files (25.00%)
1769 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1792 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1770 bundling: foo/file.txt 3/4 files (75.00%)
1793 bundling: foo/file.txt 3/4 files (75.00%)
1771 bundling: quux/file.py 4/4 files (100.00%)
1794 bundling: quux/file.py 4/4 files (100.00%)
1772 adding changesets
1795 adding changesets
1773 changesets: 1 chunks
1796 changesets: 1 chunks
1774 add changeset ef1ea85a6374
1797 add changeset ef1ea85a6374
1775 changesets: 2 chunks
1798 changesets: 2 chunks
1776 add changeset f9cafe1212c8
1799 add changeset f9cafe1212c8
1777 changesets: 3 chunks
1800 changesets: 3 chunks
1778 add changeset 911600dab2ae
1801 add changeset 911600dab2ae
1779 changesets: 4 chunks
1802 changesets: 4 chunks
1780 add changeset e8fc755d4d82
1803 add changeset e8fc755d4d82
1781 adding manifests
1804 adding manifests
1782 manifests: 1/4 chunks (25.00%)
1805 manifests: 1/4 chunks (25.00%)
1783 manifests: 2/4 chunks (50.00%)
1806 manifests: 2/4 chunks (50.00%)
1784 manifests: 3/4 chunks (75.00%)
1807 manifests: 3/4 chunks (75.00%)
1785 manifests: 4/4 chunks (100.00%)
1808 manifests: 4/4 chunks (100.00%)
1786 adding file changes
1809 adding file changes
1787 adding abc.txt revisions
1810 adding abc.txt revisions
1788 files: 1/4 chunks (25.00%)
1811 files: 1/4 chunks (25.00%)
1789 adding foo/Bar/file.txt revisions
1812 adding foo/Bar/file.txt revisions
1790 files: 2/4 chunks (50.00%)
1813 files: 2/4 chunks (50.00%)
1791 adding foo/file.txt revisions
1814 adding foo/file.txt revisions
1792 files: 3/4 chunks (75.00%)
1815 files: 3/4 chunks (75.00%)
1793 adding quux/file.py revisions
1816 adding quux/file.py revisions
1794 files: 4/4 chunks (100.00%)
1817 files: 4/4 chunks (100.00%)
1795 added 4 changesets with 4 changes to 4 files (+1 heads)
1818 added 4 changesets with 4 changes to 4 files (+1 heads)
1796 calling hook pretxnchangegroup.acl: hgext.acl.hook
1819 calling hook pretxnchangegroup.acl: hgext.acl.hook
1797 acl: checking access for user "george"
1820 acl: checking access for user "george"
1798 acl: acl.allow.branches enabled, 1 entries for user george
1821 acl: acl.allow.branches enabled, 1 entries for user george
1799 acl: acl.deny.branches not enabled
1822 acl: acl.deny.branches not enabled
1800 acl: acl.allow not enabled
1823 acl: acl.allow not enabled
1801 acl: acl.deny not enabled
1824 acl: acl.deny not enabled
1802 acl: branch access granted: "ef1ea85a6374" on branch "default"
1825 acl: branch access granted: "ef1ea85a6374" on branch "default"
1803 acl: path access granted: "ef1ea85a6374"
1826 acl: path access granted: "ef1ea85a6374"
1804 acl: branch access granted: "f9cafe1212c8" on branch "default"
1827 acl: branch access granted: "f9cafe1212c8" on branch "default"
1805 acl: path access granted: "f9cafe1212c8"
1828 acl: path access granted: "f9cafe1212c8"
1806 acl: branch access granted: "911600dab2ae" on branch "default"
1829 acl: branch access granted: "911600dab2ae" on branch "default"
1807 acl: path access granted: "911600dab2ae"
1830 acl: path access granted: "911600dab2ae"
1808 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1831 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1809 acl: path access granted: "e8fc755d4d82"
1832 acl: path access granted: "e8fc755d4d82"
1810 updating the branch cache
1833 updating the branch cache
1811 listing keys for "phases"
1834 listing keys for "phases"
1812 try to push obsolete markers to remote
1835 try to push obsolete markers to remote
1813 checking for updated bookmarks
1836 checking for updated bookmarks
1814 listing keys for "bookmarks"
1837 listing keys for "bookmarks"
1815 repository tip rolled back to revision 2 (undo push)
1838 repository tip rolled back to revision 2 (undo push)
1816 2:fb35475503ef
1839 2:fb35475503ef
1817
1840
1818
1841
1819 Branch acl conflicting allow
1842 Branch acl conflicting allow
1820 asterisk ends up applying to all branches and allowing george to
1843 asterisk ends up applying to all branches and allowing george to
1821 push foobar into the remote
1844 push foobar into the remote
1822
1845
1823 $ init_config
1846 $ init_config
1824 $ echo "[acl.allow.branches]" >> $config
1847 $ echo "[acl.allow.branches]" >> $config
1825 $ echo "foobar = astro" >> $config
1848 $ echo "foobar = astro" >> $config
1826 $ echo "* = george" >> $config
1849 $ echo "* = george" >> $config
1827 $ do_push george
1850 $ do_push george
1828 Pushing as user george
1851 Pushing as user george
1829 hgrc = """
1852 hgrc = """
1830 [acl]
1853 [acl]
1831 sources = push
1854 sources = push
1832 [extensions]
1855 [extensions]
1833 [acl.allow.branches]
1856 [acl.allow.branches]
1834 foobar = astro
1857 foobar = astro
1835 * = george
1858 * = george
1836 """
1859 """
1837 pushing to ../b
1860 pushing to ../b
1838 query 1; heads
1861 query 1; heads
1839 searching for changes
1862 searching for changes
1840 all remote heads known locally
1863 all remote heads known locally
1864 listing keys for "phases"
1841 listing keys for "bookmarks"
1865 listing keys for "bookmarks"
1842 4 changesets found
1866 4 changesets found
1843 list of changesets:
1867 list of changesets:
1844 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1868 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1845 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1869 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1846 911600dab2ae7a9baff75958b84fe606851ce955
1870 911600dab2ae7a9baff75958b84fe606851ce955
1847 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1871 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1848 bundling: 1/4 changesets (25.00%)
1872 bundling: 1/4 changesets (25.00%)
1849 bundling: 2/4 changesets (50.00%)
1873 bundling: 2/4 changesets (50.00%)
1850 bundling: 3/4 changesets (75.00%)
1874 bundling: 3/4 changesets (75.00%)
1851 bundling: 4/4 changesets (100.00%)
1875 bundling: 4/4 changesets (100.00%)
1852 bundling: 1/4 manifests (25.00%)
1876 bundling: 1/4 manifests (25.00%)
1853 bundling: 2/4 manifests (50.00%)
1877 bundling: 2/4 manifests (50.00%)
1854 bundling: 3/4 manifests (75.00%)
1878 bundling: 3/4 manifests (75.00%)
1855 bundling: 4/4 manifests (100.00%)
1879 bundling: 4/4 manifests (100.00%)
1856 bundling: abc.txt 1/4 files (25.00%)
1880 bundling: abc.txt 1/4 files (25.00%)
1857 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1881 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1858 bundling: foo/file.txt 3/4 files (75.00%)
1882 bundling: foo/file.txt 3/4 files (75.00%)
1859 bundling: quux/file.py 4/4 files (100.00%)
1883 bundling: quux/file.py 4/4 files (100.00%)
1860 adding changesets
1884 adding changesets
1861 changesets: 1 chunks
1885 changesets: 1 chunks
1862 add changeset ef1ea85a6374
1886 add changeset ef1ea85a6374
1863 changesets: 2 chunks
1887 changesets: 2 chunks
1864 add changeset f9cafe1212c8
1888 add changeset f9cafe1212c8
1865 changesets: 3 chunks
1889 changesets: 3 chunks
1866 add changeset 911600dab2ae
1890 add changeset 911600dab2ae
1867 changesets: 4 chunks
1891 changesets: 4 chunks
1868 add changeset e8fc755d4d82
1892 add changeset e8fc755d4d82
1869 adding manifests
1893 adding manifests
1870 manifests: 1/4 chunks (25.00%)
1894 manifests: 1/4 chunks (25.00%)
1871 manifests: 2/4 chunks (50.00%)
1895 manifests: 2/4 chunks (50.00%)
1872 manifests: 3/4 chunks (75.00%)
1896 manifests: 3/4 chunks (75.00%)
1873 manifests: 4/4 chunks (100.00%)
1897 manifests: 4/4 chunks (100.00%)
1874 adding file changes
1898 adding file changes
1875 adding abc.txt revisions
1899 adding abc.txt revisions
1876 files: 1/4 chunks (25.00%)
1900 files: 1/4 chunks (25.00%)
1877 adding foo/Bar/file.txt revisions
1901 adding foo/Bar/file.txt revisions
1878 files: 2/4 chunks (50.00%)
1902 files: 2/4 chunks (50.00%)
1879 adding foo/file.txt revisions
1903 adding foo/file.txt revisions
1880 files: 3/4 chunks (75.00%)
1904 files: 3/4 chunks (75.00%)
1881 adding quux/file.py revisions
1905 adding quux/file.py revisions
1882 files: 4/4 chunks (100.00%)
1906 files: 4/4 chunks (100.00%)
1883 added 4 changesets with 4 changes to 4 files (+1 heads)
1907 added 4 changesets with 4 changes to 4 files (+1 heads)
1884 calling hook pretxnchangegroup.acl: hgext.acl.hook
1908 calling hook pretxnchangegroup.acl: hgext.acl.hook
1885 acl: checking access for user "george"
1909 acl: checking access for user "george"
1886 acl: acl.allow.branches enabled, 1 entries for user george
1910 acl: acl.allow.branches enabled, 1 entries for user george
1887 acl: acl.deny.branches not enabled
1911 acl: acl.deny.branches not enabled
1888 acl: acl.allow not enabled
1912 acl: acl.allow not enabled
1889 acl: acl.deny not enabled
1913 acl: acl.deny not enabled
1890 acl: branch access granted: "ef1ea85a6374" on branch "default"
1914 acl: branch access granted: "ef1ea85a6374" on branch "default"
1891 acl: path access granted: "ef1ea85a6374"
1915 acl: path access granted: "ef1ea85a6374"
1892 acl: branch access granted: "f9cafe1212c8" on branch "default"
1916 acl: branch access granted: "f9cafe1212c8" on branch "default"
1893 acl: path access granted: "f9cafe1212c8"
1917 acl: path access granted: "f9cafe1212c8"
1894 acl: branch access granted: "911600dab2ae" on branch "default"
1918 acl: branch access granted: "911600dab2ae" on branch "default"
1895 acl: path access granted: "911600dab2ae"
1919 acl: path access granted: "911600dab2ae"
1896 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1920 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1897 acl: path access granted: "e8fc755d4d82"
1921 acl: path access granted: "e8fc755d4d82"
1898 updating the branch cache
1922 updating the branch cache
1899 listing keys for "phases"
1923 listing keys for "phases"
1900 try to push obsolete markers to remote
1924 try to push obsolete markers to remote
1901 checking for updated bookmarks
1925 checking for updated bookmarks
1902 listing keys for "bookmarks"
1926 listing keys for "bookmarks"
1903 repository tip rolled back to revision 2 (undo push)
1927 repository tip rolled back to revision 2 (undo push)
1904 2:fb35475503ef
1928 2:fb35475503ef
1905
1929
1906 Branch acl conflicting deny
1930 Branch acl conflicting deny
1907
1931
1908 $ init_config
1932 $ init_config
1909 $ echo "[acl.deny.branches]" >> $config
1933 $ echo "[acl.deny.branches]" >> $config
1910 $ echo "foobar = astro" >> $config
1934 $ echo "foobar = astro" >> $config
1911 $ echo "default = astro" >> $config
1935 $ echo "default = astro" >> $config
1912 $ echo "* = george" >> $config
1936 $ echo "* = george" >> $config
1913 $ do_push george
1937 $ do_push george
1914 Pushing as user george
1938 Pushing as user george
1915 hgrc = """
1939 hgrc = """
1916 [acl]
1940 [acl]
1917 sources = push
1941 sources = push
1918 [extensions]
1942 [extensions]
1919 [acl.deny.branches]
1943 [acl.deny.branches]
1920 foobar = astro
1944 foobar = astro
1921 default = astro
1945 default = astro
1922 * = george
1946 * = george
1923 """
1947 """
1924 pushing to ../b
1948 pushing to ../b
1925 query 1; heads
1949 query 1; heads
1926 searching for changes
1950 searching for changes
1927 all remote heads known locally
1951 all remote heads known locally
1952 listing keys for "phases"
1928 listing keys for "bookmarks"
1953 listing keys for "bookmarks"
1929 4 changesets found
1954 4 changesets found
1930 list of changesets:
1955 list of changesets:
1931 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1956 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1932 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1957 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1933 911600dab2ae7a9baff75958b84fe606851ce955
1958 911600dab2ae7a9baff75958b84fe606851ce955
1934 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1959 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1935 bundling: 1/4 changesets (25.00%)
1960 bundling: 1/4 changesets (25.00%)
1936 bundling: 2/4 changesets (50.00%)
1961 bundling: 2/4 changesets (50.00%)
1937 bundling: 3/4 changesets (75.00%)
1962 bundling: 3/4 changesets (75.00%)
1938 bundling: 4/4 changesets (100.00%)
1963 bundling: 4/4 changesets (100.00%)
1939 bundling: 1/4 manifests (25.00%)
1964 bundling: 1/4 manifests (25.00%)
1940 bundling: 2/4 manifests (50.00%)
1965 bundling: 2/4 manifests (50.00%)
1941 bundling: 3/4 manifests (75.00%)
1966 bundling: 3/4 manifests (75.00%)
1942 bundling: 4/4 manifests (100.00%)
1967 bundling: 4/4 manifests (100.00%)
1943 bundling: abc.txt 1/4 files (25.00%)
1968 bundling: abc.txt 1/4 files (25.00%)
1944 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1969 bundling: foo/Bar/file.txt 2/4 files (50.00%)
1945 bundling: foo/file.txt 3/4 files (75.00%)
1970 bundling: foo/file.txt 3/4 files (75.00%)
1946 bundling: quux/file.py 4/4 files (100.00%)
1971 bundling: quux/file.py 4/4 files (100.00%)
1947 adding changesets
1972 adding changesets
1948 changesets: 1 chunks
1973 changesets: 1 chunks
1949 add changeset ef1ea85a6374
1974 add changeset ef1ea85a6374
1950 changesets: 2 chunks
1975 changesets: 2 chunks
1951 add changeset f9cafe1212c8
1976 add changeset f9cafe1212c8
1952 changesets: 3 chunks
1977 changesets: 3 chunks
1953 add changeset 911600dab2ae
1978 add changeset 911600dab2ae
1954 changesets: 4 chunks
1979 changesets: 4 chunks
1955 add changeset e8fc755d4d82
1980 add changeset e8fc755d4d82
1956 adding manifests
1981 adding manifests
1957 manifests: 1/4 chunks (25.00%)
1982 manifests: 1/4 chunks (25.00%)
1958 manifests: 2/4 chunks (50.00%)
1983 manifests: 2/4 chunks (50.00%)
1959 manifests: 3/4 chunks (75.00%)
1984 manifests: 3/4 chunks (75.00%)
1960 manifests: 4/4 chunks (100.00%)
1985 manifests: 4/4 chunks (100.00%)
1961 adding file changes
1986 adding file changes
1962 adding abc.txt revisions
1987 adding abc.txt revisions
1963 files: 1/4 chunks (25.00%)
1988 files: 1/4 chunks (25.00%)
1964 adding foo/Bar/file.txt revisions
1989 adding foo/Bar/file.txt revisions
1965 files: 2/4 chunks (50.00%)
1990 files: 2/4 chunks (50.00%)
1966 adding foo/file.txt revisions
1991 adding foo/file.txt revisions
1967 files: 3/4 chunks (75.00%)
1992 files: 3/4 chunks (75.00%)
1968 adding quux/file.py revisions
1993 adding quux/file.py revisions
1969 files: 4/4 chunks (100.00%)
1994 files: 4/4 chunks (100.00%)
1970 added 4 changesets with 4 changes to 4 files (+1 heads)
1995 added 4 changesets with 4 changes to 4 files (+1 heads)
1971 calling hook pretxnchangegroup.acl: hgext.acl.hook
1996 calling hook pretxnchangegroup.acl: hgext.acl.hook
1972 acl: checking access for user "george"
1997 acl: checking access for user "george"
1973 acl: acl.allow.branches not enabled
1998 acl: acl.allow.branches not enabled
1974 acl: acl.deny.branches enabled, 1 entries for user george
1999 acl: acl.deny.branches enabled, 1 entries for user george
1975 acl: acl.allow not enabled
2000 acl: acl.allow not enabled
1976 acl: acl.deny not enabled
2001 acl: acl.deny not enabled
1977 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2002 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1978 transaction abort!
2003 transaction abort!
1979 rollback completed
2004 rollback completed
1980 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2005 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1981 no rollback information available
2006 no rollback information available
1982 2:fb35475503ef
2007 2:fb35475503ef
1983
2008
1984 User 'astro' must not be denied
2009 User 'astro' must not be denied
1985
2010
1986 $ init_config
2011 $ init_config
1987 $ echo "[acl.deny.branches]" >> $config
2012 $ echo "[acl.deny.branches]" >> $config
1988 $ echo "default = !astro" >> $config
2013 $ echo "default = !astro" >> $config
1989 $ do_push astro
2014 $ do_push astro
1990 Pushing as user astro
2015 Pushing as user astro
1991 hgrc = """
2016 hgrc = """
1992 [acl]
2017 [acl]
1993 sources = push
2018 sources = push
1994 [extensions]
2019 [extensions]
1995 [acl.deny.branches]
2020 [acl.deny.branches]
1996 default = !astro
2021 default = !astro
1997 """
2022 """
1998 pushing to ../b
2023 pushing to ../b
1999 query 1; heads
2024 query 1; heads
2000 searching for changes
2025 searching for changes
2001 all remote heads known locally
2026 all remote heads known locally
2027 listing keys for "phases"
2002 listing keys for "bookmarks"
2028 listing keys for "bookmarks"
2003 4 changesets found
2029 4 changesets found
2004 list of changesets:
2030 list of changesets:
2005 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2031 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2006 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2032 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2007 911600dab2ae7a9baff75958b84fe606851ce955
2033 911600dab2ae7a9baff75958b84fe606851ce955
2008 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2034 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2009 bundling: 1/4 changesets (25.00%)
2035 bundling: 1/4 changesets (25.00%)
2010 bundling: 2/4 changesets (50.00%)
2036 bundling: 2/4 changesets (50.00%)
2011 bundling: 3/4 changesets (75.00%)
2037 bundling: 3/4 changesets (75.00%)
2012 bundling: 4/4 changesets (100.00%)
2038 bundling: 4/4 changesets (100.00%)
2013 bundling: 1/4 manifests (25.00%)
2039 bundling: 1/4 manifests (25.00%)
2014 bundling: 2/4 manifests (50.00%)
2040 bundling: 2/4 manifests (50.00%)
2015 bundling: 3/4 manifests (75.00%)
2041 bundling: 3/4 manifests (75.00%)
2016 bundling: 4/4 manifests (100.00%)
2042 bundling: 4/4 manifests (100.00%)
2017 bundling: abc.txt 1/4 files (25.00%)
2043 bundling: abc.txt 1/4 files (25.00%)
2018 bundling: foo/Bar/file.txt 2/4 files (50.00%)
2044 bundling: foo/Bar/file.txt 2/4 files (50.00%)
2019 bundling: foo/file.txt 3/4 files (75.00%)
2045 bundling: foo/file.txt 3/4 files (75.00%)
2020 bundling: quux/file.py 4/4 files (100.00%)
2046 bundling: quux/file.py 4/4 files (100.00%)
2021 adding changesets
2047 adding changesets
2022 changesets: 1 chunks
2048 changesets: 1 chunks
2023 add changeset ef1ea85a6374
2049 add changeset ef1ea85a6374
2024 changesets: 2 chunks
2050 changesets: 2 chunks
2025 add changeset f9cafe1212c8
2051 add changeset f9cafe1212c8
2026 changesets: 3 chunks
2052 changesets: 3 chunks
2027 add changeset 911600dab2ae
2053 add changeset 911600dab2ae
2028 changesets: 4 chunks
2054 changesets: 4 chunks
2029 add changeset e8fc755d4d82
2055 add changeset e8fc755d4d82
2030 adding manifests
2056 adding manifests
2031 manifests: 1/4 chunks (25.00%)
2057 manifests: 1/4 chunks (25.00%)
2032 manifests: 2/4 chunks (50.00%)
2058 manifests: 2/4 chunks (50.00%)
2033 manifests: 3/4 chunks (75.00%)
2059 manifests: 3/4 chunks (75.00%)
2034 manifests: 4/4 chunks (100.00%)
2060 manifests: 4/4 chunks (100.00%)
2035 adding file changes
2061 adding file changes
2036 adding abc.txt revisions
2062 adding abc.txt revisions
2037 files: 1/4 chunks (25.00%)
2063 files: 1/4 chunks (25.00%)
2038 adding foo/Bar/file.txt revisions
2064 adding foo/Bar/file.txt revisions
2039 files: 2/4 chunks (50.00%)
2065 files: 2/4 chunks (50.00%)
2040 adding foo/file.txt revisions
2066 adding foo/file.txt revisions
2041 files: 3/4 chunks (75.00%)
2067 files: 3/4 chunks (75.00%)
2042 adding quux/file.py revisions
2068 adding quux/file.py revisions
2043 files: 4/4 chunks (100.00%)
2069 files: 4/4 chunks (100.00%)
2044 added 4 changesets with 4 changes to 4 files (+1 heads)
2070 added 4 changesets with 4 changes to 4 files (+1 heads)
2045 calling hook pretxnchangegroup.acl: hgext.acl.hook
2071 calling hook pretxnchangegroup.acl: hgext.acl.hook
2046 acl: checking access for user "astro"
2072 acl: checking access for user "astro"
2047 acl: acl.allow.branches not enabled
2073 acl: acl.allow.branches not enabled
2048 acl: acl.deny.branches enabled, 0 entries for user astro
2074 acl: acl.deny.branches enabled, 0 entries for user astro
2049 acl: acl.allow not enabled
2075 acl: acl.allow not enabled
2050 acl: acl.deny not enabled
2076 acl: acl.deny not enabled
2051 acl: branch access granted: "ef1ea85a6374" on branch "default"
2077 acl: branch access granted: "ef1ea85a6374" on branch "default"
2052 acl: path access granted: "ef1ea85a6374"
2078 acl: path access granted: "ef1ea85a6374"
2053 acl: branch access granted: "f9cafe1212c8" on branch "default"
2079 acl: branch access granted: "f9cafe1212c8" on branch "default"
2054 acl: path access granted: "f9cafe1212c8"
2080 acl: path access granted: "f9cafe1212c8"
2055 acl: branch access granted: "911600dab2ae" on branch "default"
2081 acl: branch access granted: "911600dab2ae" on branch "default"
2056 acl: path access granted: "911600dab2ae"
2082 acl: path access granted: "911600dab2ae"
2057 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2083 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2058 acl: path access granted: "e8fc755d4d82"
2084 acl: path access granted: "e8fc755d4d82"
2059 updating the branch cache
2085 updating the branch cache
2060 listing keys for "phases"
2086 listing keys for "phases"
2061 try to push obsolete markers to remote
2087 try to push obsolete markers to remote
2062 checking for updated bookmarks
2088 checking for updated bookmarks
2063 listing keys for "bookmarks"
2089 listing keys for "bookmarks"
2064 repository tip rolled back to revision 2 (undo push)
2090 repository tip rolled back to revision 2 (undo push)
2065 2:fb35475503ef
2091 2:fb35475503ef
2066
2092
2067
2093
2068 Non-astro users must be denied
2094 Non-astro users must be denied
2069
2095
2070 $ do_push george
2096 $ do_push george
2071 Pushing as user george
2097 Pushing as user george
2072 hgrc = """
2098 hgrc = """
2073 [acl]
2099 [acl]
2074 sources = push
2100 sources = push
2075 [extensions]
2101 [extensions]
2076 [acl.deny.branches]
2102 [acl.deny.branches]
2077 default = !astro
2103 default = !astro
2078 """
2104 """
2079 pushing to ../b
2105 pushing to ../b
2080 query 1; heads
2106 query 1; heads
2081 searching for changes
2107 searching for changes
2082 all remote heads known locally
2108 all remote heads known locally
2109 listing keys for "phases"
2083 listing keys for "bookmarks"
2110 listing keys for "bookmarks"
2084 4 changesets found
2111 4 changesets found
2085 list of changesets:
2112 list of changesets:
2086 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2113 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2087 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2114 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2088 911600dab2ae7a9baff75958b84fe606851ce955
2115 911600dab2ae7a9baff75958b84fe606851ce955
2089 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2116 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2090 bundling: 1/4 changesets (25.00%)
2117 bundling: 1/4 changesets (25.00%)
2091 bundling: 2/4 changesets (50.00%)
2118 bundling: 2/4 changesets (50.00%)
2092 bundling: 3/4 changesets (75.00%)
2119 bundling: 3/4 changesets (75.00%)
2093 bundling: 4/4 changesets (100.00%)
2120 bundling: 4/4 changesets (100.00%)
2094 bundling: 1/4 manifests (25.00%)
2121 bundling: 1/4 manifests (25.00%)
2095 bundling: 2/4 manifests (50.00%)
2122 bundling: 2/4 manifests (50.00%)
2096 bundling: 3/4 manifests (75.00%)
2123 bundling: 3/4 manifests (75.00%)
2097 bundling: 4/4 manifests (100.00%)
2124 bundling: 4/4 manifests (100.00%)
2098 bundling: abc.txt 1/4 files (25.00%)
2125 bundling: abc.txt 1/4 files (25.00%)
2099 bundling: foo/Bar/file.txt 2/4 files (50.00%)
2126 bundling: foo/Bar/file.txt 2/4 files (50.00%)
2100 bundling: foo/file.txt 3/4 files (75.00%)
2127 bundling: foo/file.txt 3/4 files (75.00%)
2101 bundling: quux/file.py 4/4 files (100.00%)
2128 bundling: quux/file.py 4/4 files (100.00%)
2102 adding changesets
2129 adding changesets
2103 changesets: 1 chunks
2130 changesets: 1 chunks
2104 add changeset ef1ea85a6374
2131 add changeset ef1ea85a6374
2105 changesets: 2 chunks
2132 changesets: 2 chunks
2106 add changeset f9cafe1212c8
2133 add changeset f9cafe1212c8
2107 changesets: 3 chunks
2134 changesets: 3 chunks
2108 add changeset 911600dab2ae
2135 add changeset 911600dab2ae
2109 changesets: 4 chunks
2136 changesets: 4 chunks
2110 add changeset e8fc755d4d82
2137 add changeset e8fc755d4d82
2111 adding manifests
2138 adding manifests
2112 manifests: 1/4 chunks (25.00%)
2139 manifests: 1/4 chunks (25.00%)
2113 manifests: 2/4 chunks (50.00%)
2140 manifests: 2/4 chunks (50.00%)
2114 manifests: 3/4 chunks (75.00%)
2141 manifests: 3/4 chunks (75.00%)
2115 manifests: 4/4 chunks (100.00%)
2142 manifests: 4/4 chunks (100.00%)
2116 adding file changes
2143 adding file changes
2117 adding abc.txt revisions
2144 adding abc.txt revisions
2118 files: 1/4 chunks (25.00%)
2145 files: 1/4 chunks (25.00%)
2119 adding foo/Bar/file.txt revisions
2146 adding foo/Bar/file.txt revisions
2120 files: 2/4 chunks (50.00%)
2147 files: 2/4 chunks (50.00%)
2121 adding foo/file.txt revisions
2148 adding foo/file.txt revisions
2122 files: 3/4 chunks (75.00%)
2149 files: 3/4 chunks (75.00%)
2123 adding quux/file.py revisions
2150 adding quux/file.py revisions
2124 files: 4/4 chunks (100.00%)
2151 files: 4/4 chunks (100.00%)
2125 added 4 changesets with 4 changes to 4 files (+1 heads)
2152 added 4 changesets with 4 changes to 4 files (+1 heads)
2126 calling hook pretxnchangegroup.acl: hgext.acl.hook
2153 calling hook pretxnchangegroup.acl: hgext.acl.hook
2127 acl: checking access for user "george"
2154 acl: checking access for user "george"
2128 acl: acl.allow.branches not enabled
2155 acl: acl.allow.branches not enabled
2129 acl: acl.deny.branches enabled, 1 entries for user george
2156 acl: acl.deny.branches enabled, 1 entries for user george
2130 acl: acl.allow not enabled
2157 acl: acl.allow not enabled
2131 acl: acl.deny not enabled
2158 acl: acl.deny not enabled
2132 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2159 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2133 transaction abort!
2160 transaction abort!
2134 rollback completed
2161 rollback completed
2135 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2162 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2136 no rollback information available
2163 no rollback information available
2137 2:fb35475503ef
2164 2:fb35475503ef
2138
2165
2139
2166
@@ -1,644 +1,645 b''
1 commit hooks can see env vars
1 commit hooks can see env vars
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ cat > .hg/hgrc <<EOF
5 $ cat > .hg/hgrc <<EOF
6 > [hooks]
6 > [hooks]
7 > commit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit"
7 > commit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit"
8 > commit.b = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit.b"
8 > commit.b = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" commit.b"
9 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" precommit"
9 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= python \"$TESTDIR/printenv.py\" precommit"
10 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxncommit"
10 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= python \"$TESTDIR/printenv.py\" pretxncommit"
11 > pretxncommit.tip = hg -q tip
11 > pretxncommit.tip = hg -q tip
12 > pre-identify = python "$TESTDIR/printenv.py" pre-identify 1
12 > pre-identify = python "$TESTDIR/printenv.py" pre-identify 1
13 > pre-cat = python "$TESTDIR/printenv.py" pre-cat
13 > pre-cat = python "$TESTDIR/printenv.py" pre-cat
14 > post-cat = python "$TESTDIR/printenv.py" post-cat
14 > post-cat = python "$TESTDIR/printenv.py" post-cat
15 > EOF
15 > EOF
16 $ echo a > a
16 $ echo a > a
17 $ hg add a
17 $ hg add a
18 $ hg commit -m a
18 $ hg commit -m a
19 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
19 precommit hook: HG_PARENT1=0000000000000000000000000000000000000000
20 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
20 pretxncommit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000 HG_PENDING=$TESTTMP/a
21 0:cb9a9f314b8b
21 0:cb9a9f314b8b
22 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
22 commit hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
23 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
23 commit.b hook: HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PARENT1=0000000000000000000000000000000000000000
24
24
25 $ hg clone . ../b
25 $ hg clone . ../b
26 updating to branch default
26 updating to branch default
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
28 $ cd ../b
28 $ cd ../b
29
29
30 changegroup hooks can see env vars
30 changegroup hooks can see env vars
31
31
32 $ cat > .hg/hgrc <<EOF
32 $ cat > .hg/hgrc <<EOF
33 > [hooks]
33 > [hooks]
34 > prechangegroup = python "$TESTDIR/printenv.py" prechangegroup
34 > prechangegroup = python "$TESTDIR/printenv.py" prechangegroup
35 > changegroup = python "$TESTDIR/printenv.py" changegroup
35 > changegroup = python "$TESTDIR/printenv.py" changegroup
36 > incoming = python "$TESTDIR/printenv.py" incoming
36 > incoming = python "$TESTDIR/printenv.py" incoming
37 > EOF
37 > EOF
38
38
39 pretxncommit and commit hooks can see both parents of merge
39 pretxncommit and commit hooks can see both parents of merge
40
40
41 $ cd ../a
41 $ cd ../a
42 $ echo b >> a
42 $ echo b >> a
43 $ hg commit -m a1 -d "1 0"
43 $ hg commit -m a1 -d "1 0"
44 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
44 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
45 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
45 pretxncommit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
46 1:ab228980c14d
46 1:ab228980c14d
47 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
47 commit hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
48 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
48 commit.b hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
49 $ hg update -C 0
49 $ hg update -C 0
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
51 $ echo b > b
51 $ echo b > b
52 $ hg add b
52 $ hg add b
53 $ hg commit -m b -d '1 0'
53 $ hg commit -m b -d '1 0'
54 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
54 precommit hook: HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
55 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
55 pretxncommit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b HG_PENDING=$TESTTMP/a
56 2:ee9deb46ab31
56 2:ee9deb46ab31
57 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
57 commit hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
58 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
58 commit.b hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
59 created new head
59 created new head
60 $ hg merge 1
60 $ hg merge 1
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 (branch merge, don't forget to commit)
62 (branch merge, don't forget to commit)
63 $ hg commit -m merge -d '2 0'
63 $ hg commit -m merge -d '2 0'
64 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
64 precommit hook: HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
65 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
65 pretxncommit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd HG_PENDING=$TESTTMP/a
66 3:07f3376c1e65
66 3:07f3376c1e65
67 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
67 commit hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
68 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
68 commit.b hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
69
69
70 test generic hooks
70 test generic hooks
71
71
72 $ hg id
72 $ hg id
73 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
73 pre-identify hook: HG_ARGS=id HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None} HG_PATS=[]
74 abort: pre-identify hook exited with status 1
74 abort: pre-identify hook exited with status 1
75 [255]
75 [255]
76 $ hg cat b
76 $ hg cat b
77 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
77 pre-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b']
78 b
78 b
79 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
79 post-cat hook: HG_ARGS=cat b HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': ''} HG_PATS=['b'] HG_RESULT=0
80
80
81 $ cd ../b
81 $ cd ../b
82 $ hg pull ../a
82 $ hg pull ../a
83 pulling from ../a
83 pulling from ../a
84 searching for changes
84 searching for changes
85 prechangegroup hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
85 prechangegroup hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 3 changesets with 2 changes to 2 files
89 added 3 changesets with 2 changes to 2 files
90 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
90 changegroup hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
91 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
91 incoming hook: HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd HG_SOURCE=pull HG_URL=file:$TESTTMP/a
92 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
92 incoming hook: HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
93 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
93 incoming hook: HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_SOURCE=pull HG_URL=file:$TESTTMP/a
94 (run 'hg update' to get a working copy)
94 (run 'hg update' to get a working copy)
95
95
96 tag hooks can see env vars
96 tag hooks can see env vars
97
97
98 $ cd ../a
98 $ cd ../a
99 $ cat >> .hg/hgrc <<EOF
99 $ cat >> .hg/hgrc <<EOF
100 > pretag = python "$TESTDIR/printenv.py" pretag
100 > pretag = python "$TESTDIR/printenv.py" pretag
101 > tag = sh -c "HG_PARENT1= HG_PARENT2= python \"$TESTDIR/printenv.py\" tag"
101 > tag = sh -c "HG_PARENT1= HG_PARENT2= python \"$TESTDIR/printenv.py\" tag"
102 > EOF
102 > EOF
103 $ hg tag -d '3 0' a
103 $ hg tag -d '3 0' a
104 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
104 pretag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
105 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
105 precommit hook: HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
106 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
106 pretxncommit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2 HG_PENDING=$TESTTMP/a
107 4:539e4b31b6dc
107 4:539e4b31b6dc
108 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
108 tag hook: HG_LOCAL=0 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2 HG_TAG=a
109 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
109 commit hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
110 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
110 commit.b hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
111 $ hg tag -l la
111 $ hg tag -l la
112 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
112 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
113 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
113 tag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=la
114
114
115 pretag hook can forbid tagging
115 pretag hook can forbid tagging
116
116
117 $ echo "pretag.forbid = python \"$TESTDIR/printenv.py\" pretag.forbid 1" >> .hg/hgrc
117 $ echo "pretag.forbid = python \"$TESTDIR/printenv.py\" pretag.forbid 1" >> .hg/hgrc
118 $ hg tag -d '4 0' fa
118 $ hg tag -d '4 0' fa
119 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
119 pretag hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
120 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
120 pretag.forbid hook: HG_LOCAL=0 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fa
121 abort: pretag.forbid hook exited with status 1
121 abort: pretag.forbid hook exited with status 1
122 [255]
122 [255]
123 $ hg tag -l fla
123 $ hg tag -l fla
124 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
124 pretag hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
125 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
125 pretag.forbid hook: HG_LOCAL=1 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_TAG=fla
126 abort: pretag.forbid hook exited with status 1
126 abort: pretag.forbid hook exited with status 1
127 [255]
127 [255]
128
128
129 pretxncommit hook can see changeset, can roll back txn, changeset no
129 pretxncommit hook can see changeset, can roll back txn, changeset no
130 more there after
130 more there after
131
131
132 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
132 $ echo "pretxncommit.forbid0 = hg tip -q" >> .hg/hgrc
133 $ echo "pretxncommit.forbid1 = python \"$TESTDIR/printenv.py\" pretxncommit.forbid 1" >> .hg/hgrc
133 $ echo "pretxncommit.forbid1 = python \"$TESTDIR/printenv.py\" pretxncommit.forbid 1" >> .hg/hgrc
134 $ echo z > z
134 $ echo z > z
135 $ hg add z
135 $ hg add z
136 $ hg -q tip
136 $ hg -q tip
137 4:539e4b31b6dc
137 4:539e4b31b6dc
138 $ hg commit -m 'fail' -d '4 0'
138 $ hg commit -m 'fail' -d '4 0'
139 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
139 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
140 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
140 pretxncommit hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
141 5:6f611f8018c1
141 5:6f611f8018c1
142 5:6f611f8018c1
142 5:6f611f8018c1
143 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
143 pretxncommit.forbid hook: HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/a
144 transaction abort!
144 transaction abort!
145 rollback completed
145 rollback completed
146 abort: pretxncommit.forbid1 hook exited with status 1
146 abort: pretxncommit.forbid1 hook exited with status 1
147 [255]
147 [255]
148 $ hg -q tip
148 $ hg -q tip
149 4:539e4b31b6dc
149 4:539e4b31b6dc
150
150
151 precommit hook can prevent commit
151 precommit hook can prevent commit
152
152
153 $ echo "precommit.forbid = python \"$TESTDIR/printenv.py\" precommit.forbid 1" >> .hg/hgrc
153 $ echo "precommit.forbid = python \"$TESTDIR/printenv.py\" precommit.forbid 1" >> .hg/hgrc
154 $ hg commit -m 'fail' -d '4 0'
154 $ hg commit -m 'fail' -d '4 0'
155 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
155 precommit hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
156 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
156 precommit.forbid hook: HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
157 abort: precommit.forbid hook exited with status 1
157 abort: precommit.forbid hook exited with status 1
158 [255]
158 [255]
159 $ hg -q tip
159 $ hg -q tip
160 4:539e4b31b6dc
160 4:539e4b31b6dc
161
161
162 preupdate hook can prevent update
162 preupdate hook can prevent update
163
163
164 $ echo "preupdate = python \"$TESTDIR/printenv.py\" preupdate" >> .hg/hgrc
164 $ echo "preupdate = python \"$TESTDIR/printenv.py\" preupdate" >> .hg/hgrc
165 $ hg update 1
165 $ hg update 1
166 preupdate hook: HG_PARENT1=ab228980c14d
166 preupdate hook: HG_PARENT1=ab228980c14d
167 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
167 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
168
168
169 update hook
169 update hook
170
170
171 $ echo "update = python \"$TESTDIR/printenv.py\" update" >> .hg/hgrc
171 $ echo "update = python \"$TESTDIR/printenv.py\" update" >> .hg/hgrc
172 $ hg update
172 $ hg update
173 preupdate hook: HG_PARENT1=539e4b31b6dc
173 preupdate hook: HG_PARENT1=539e4b31b6dc
174 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
174 update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc
175 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
176
176
177 pushkey hook
177 pushkey hook
178
178
179 $ echo "pushkey = python \"$TESTDIR/printenv.py\" pushkey" >> .hg/hgrc
179 $ echo "pushkey = python \"$TESTDIR/printenv.py\" pushkey" >> .hg/hgrc
180 $ cd ../b
180 $ cd ../b
181 $ hg bookmark -r null foo
181 $ hg bookmark -r null foo
182 $ hg push -B foo ../a
182 $ hg push -B foo ../a
183 pushing to ../a
183 pushing to ../a
184 searching for changes
184 searching for changes
185 no changes found
185 no changes found
186 exporting bookmark foo
186 exporting bookmark foo
187 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
187 pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1
188 [1]
188 [1]
189 $ cd ../a
189 $ cd ../a
190
190
191 listkeys hook
191 listkeys hook
192
192
193 $ echo "listkeys = python \"$TESTDIR/printenv.py\" listkeys" >> .hg/hgrc
193 $ echo "listkeys = python \"$TESTDIR/printenv.py\" listkeys" >> .hg/hgrc
194 $ hg bookmark -r null bar
194 $ hg bookmark -r null bar
195 $ cd ../b
195 $ cd ../b
196 $ hg pull -B bar ../a
196 $ hg pull -B bar ../a
197 pulling from ../a
197 pulling from ../a
198 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
198 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
199 no changes found
199 no changes found
200 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
200 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
201 adding remote bookmark bar
201 adding remote bookmark bar
202 importing bookmark bar
202 importing bookmark bar
203 $ cd ../a
203 $ cd ../a
204
204
205 test that prepushkey can prevent incoming keys
205 test that prepushkey can prevent incoming keys
206
206
207 $ echo "prepushkey = python \"$TESTDIR/printenv.py\" prepushkey.forbid 1" >> .hg/hgrc
207 $ echo "prepushkey = python \"$TESTDIR/printenv.py\" prepushkey.forbid 1" >> .hg/hgrc
208 $ cd ../b
208 $ cd ../b
209 $ hg bookmark -r null baz
209 $ hg bookmark -r null baz
210 $ hg push -B baz ../a
210 $ hg push -B baz ../a
211 pushing to ../a
211 pushing to ../a
212 searching for changes
212 searching for changes
213 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
213 no changes found
214 no changes found
214 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
215 listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
215 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
216 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
216 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
217 listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
217 exporting bookmark baz
218 exporting bookmark baz
218 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
219 prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000
219 abort: prepushkey hook exited with status 1
220 abort: prepushkey hook exited with status 1
220 [255]
221 [255]
221 $ cd ../a
222 $ cd ../a
222
223
223 test that prelistkeys can prevent listing keys
224 test that prelistkeys can prevent listing keys
224
225
225 $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
226 $ echo "prelistkeys = python \"$TESTDIR/printenv.py\" prelistkeys.forbid 1" >> .hg/hgrc
226 $ hg bookmark -r null quux
227 $ hg bookmark -r null quux
227 $ cd ../b
228 $ cd ../b
228 $ hg pull -B quux ../a
229 $ hg pull -B quux ../a
229 pulling from ../a
230 pulling from ../a
230 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
231 prelistkeys.forbid hook: HG_NAMESPACE=bookmarks
231 abort: prelistkeys hook exited with status 1
232 abort: prelistkeys hook exited with status 1
232 [255]
233 [255]
233 $ cd ../a
234 $ cd ../a
234 $ rm .hg/hgrc
235 $ rm .hg/hgrc
235
236
236 prechangegroup hook can prevent incoming changes
237 prechangegroup hook can prevent incoming changes
237
238
238 $ cd ../b
239 $ cd ../b
239 $ hg -q tip
240 $ hg -q tip
240 3:07f3376c1e65
241 3:07f3376c1e65
241 $ cat > .hg/hgrc <<EOF
242 $ cat > .hg/hgrc <<EOF
242 > [hooks]
243 > [hooks]
243 > prechangegroup.forbid = python "$TESTDIR/printenv.py" prechangegroup.forbid 1
244 > prechangegroup.forbid = python "$TESTDIR/printenv.py" prechangegroup.forbid 1
244 > EOF
245 > EOF
245 $ hg pull ../a
246 $ hg pull ../a
246 pulling from ../a
247 pulling from ../a
247 searching for changes
248 searching for changes
248 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
249 prechangegroup.forbid hook: HG_SOURCE=pull HG_URL=file:$TESTTMP/a
249 abort: prechangegroup.forbid hook exited with status 1
250 abort: prechangegroup.forbid hook exited with status 1
250 [255]
251 [255]
251
252
252 pretxnchangegroup hook can see incoming changes, can roll back txn,
253 pretxnchangegroup hook can see incoming changes, can roll back txn,
253 incoming changes no longer there after
254 incoming changes no longer there after
254
255
255 $ cat > .hg/hgrc <<EOF
256 $ cat > .hg/hgrc <<EOF
256 > [hooks]
257 > [hooks]
257 > pretxnchangegroup.forbid0 = hg tip -q
258 > pretxnchangegroup.forbid0 = hg tip -q
258 > pretxnchangegroup.forbid1 = python "$TESTDIR/printenv.py" pretxnchangegroup.forbid 1
259 > pretxnchangegroup.forbid1 = python "$TESTDIR/printenv.py" pretxnchangegroup.forbid 1
259 > EOF
260 > EOF
260 $ hg pull ../a
261 $ hg pull ../a
261 pulling from ../a
262 pulling from ../a
262 searching for changes
263 searching for changes
263 adding changesets
264 adding changesets
264 adding manifests
265 adding manifests
265 adding file changes
266 adding file changes
266 added 1 changesets with 1 changes to 1 files
267 added 1 changesets with 1 changes to 1 files
267 4:539e4b31b6dc
268 4:539e4b31b6dc
268 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_URL=file:$TESTTMP/a
269 pretxnchangegroup.forbid hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_PENDING=$TESTTMP/b HG_SOURCE=pull HG_URL=file:$TESTTMP/a
269 transaction abort!
270 transaction abort!
270 rollback completed
271 rollback completed
271 abort: pretxnchangegroup.forbid1 hook exited with status 1
272 abort: pretxnchangegroup.forbid1 hook exited with status 1
272 [255]
273 [255]
273 $ hg -q tip
274 $ hg -q tip
274 3:07f3376c1e65
275 3:07f3376c1e65
275
276
276 outgoing hooks can see env vars
277 outgoing hooks can see env vars
277
278
278 $ rm .hg/hgrc
279 $ rm .hg/hgrc
279 $ cat > ../a/.hg/hgrc <<EOF
280 $ cat > ../a/.hg/hgrc <<EOF
280 > [hooks]
281 > [hooks]
281 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
282 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
282 > outgoing = python "$TESTDIR/printenv.py" outgoing
283 > outgoing = python "$TESTDIR/printenv.py" outgoing
283 > EOF
284 > EOF
284 $ hg pull ../a
285 $ hg pull ../a
285 pulling from ../a
286 pulling from ../a
286 searching for changes
287 searching for changes
287 preoutgoing hook: HG_SOURCE=pull
288 preoutgoing hook: HG_SOURCE=pull
288 adding changesets
289 adding changesets
289 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
290 outgoing hook: HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10 HG_SOURCE=pull
290 adding manifests
291 adding manifests
291 adding file changes
292 adding file changes
292 added 1 changesets with 1 changes to 1 files
293 added 1 changesets with 1 changes to 1 files
293 adding remote bookmark quux
294 adding remote bookmark quux
294 (run 'hg update' to get a working copy)
295 (run 'hg update' to get a working copy)
295 $ hg rollback
296 $ hg rollback
296 repository tip rolled back to revision 3 (undo pull)
297 repository tip rolled back to revision 3 (undo pull)
297
298
298 preoutgoing hook can prevent outgoing changes
299 preoutgoing hook can prevent outgoing changes
299
300
300 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> ../a/.hg/hgrc
301 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> ../a/.hg/hgrc
301 $ hg pull ../a
302 $ hg pull ../a
302 pulling from ../a
303 pulling from ../a
303 searching for changes
304 searching for changes
304 preoutgoing hook: HG_SOURCE=pull
305 preoutgoing hook: HG_SOURCE=pull
305 preoutgoing.forbid hook: HG_SOURCE=pull
306 preoutgoing.forbid hook: HG_SOURCE=pull
306 abort: preoutgoing.forbid hook exited with status 1
307 abort: preoutgoing.forbid hook exited with status 1
307 [255]
308 [255]
308
309
309 outgoing hooks work for local clones
310 outgoing hooks work for local clones
310
311
311 $ cd ..
312 $ cd ..
312 $ cat > a/.hg/hgrc <<EOF
313 $ cat > a/.hg/hgrc <<EOF
313 > [hooks]
314 > [hooks]
314 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
315 > preoutgoing = python "$TESTDIR/printenv.py" preoutgoing
315 > outgoing = python "$TESTDIR/printenv.py" outgoing
316 > outgoing = python "$TESTDIR/printenv.py" outgoing
316 > EOF
317 > EOF
317 $ hg clone a c
318 $ hg clone a c
318 preoutgoing hook: HG_SOURCE=clone
319 preoutgoing hook: HG_SOURCE=clone
319 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
320 outgoing hook: HG_NODE=0000000000000000000000000000000000000000 HG_SOURCE=clone
320 updating to branch default
321 updating to branch default
321 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 $ rm -rf c
323 $ rm -rf c
323
324
324 preoutgoing hook can prevent outgoing changes for local clones
325 preoutgoing hook can prevent outgoing changes for local clones
325
326
326 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> a/.hg/hgrc
327 $ echo "preoutgoing.forbid = python \"$TESTDIR/printenv.py\" preoutgoing.forbid 1" >> a/.hg/hgrc
327 $ hg clone a zzz
328 $ hg clone a zzz
328 preoutgoing hook: HG_SOURCE=clone
329 preoutgoing hook: HG_SOURCE=clone
329 preoutgoing.forbid hook: HG_SOURCE=clone
330 preoutgoing.forbid hook: HG_SOURCE=clone
330 abort: preoutgoing.forbid hook exited with status 1
331 abort: preoutgoing.forbid hook exited with status 1
331 [255]
332 [255]
332
333
333 $ cd "$TESTTMP/b"
334 $ cd "$TESTTMP/b"
334
335
335 $ cat > hooktests.py <<EOF
336 $ cat > hooktests.py <<EOF
336 > from mercurial import util
337 > from mercurial import util
337 >
338 >
338 > uncallable = 0
339 > uncallable = 0
339 >
340 >
340 > def printargs(args):
341 > def printargs(args):
341 > args.pop('ui', None)
342 > args.pop('ui', None)
342 > args.pop('repo', None)
343 > args.pop('repo', None)
343 > a = list(args.items())
344 > a = list(args.items())
344 > a.sort()
345 > a.sort()
345 > print 'hook args:'
346 > print 'hook args:'
346 > for k, v in a:
347 > for k, v in a:
347 > print ' ', k, v
348 > print ' ', k, v
348 >
349 >
349 > def passhook(**args):
350 > def passhook(**args):
350 > printargs(args)
351 > printargs(args)
351 >
352 >
352 > def failhook(**args):
353 > def failhook(**args):
353 > printargs(args)
354 > printargs(args)
354 > return True
355 > return True
355 >
356 >
356 > class LocalException(Exception):
357 > class LocalException(Exception):
357 > pass
358 > pass
358 >
359 >
359 > def raisehook(**args):
360 > def raisehook(**args):
360 > raise LocalException('exception from hook')
361 > raise LocalException('exception from hook')
361 >
362 >
362 > def aborthook(**args):
363 > def aborthook(**args):
363 > raise util.Abort('raise abort from hook')
364 > raise util.Abort('raise abort from hook')
364 >
365 >
365 > def brokenhook(**args):
366 > def brokenhook(**args):
366 > return 1 + {}
367 > return 1 + {}
367 >
368 >
368 > def verbosehook(ui, **args):
369 > def verbosehook(ui, **args):
369 > ui.note('verbose output from hook\n')
370 > ui.note('verbose output from hook\n')
370 >
371 >
371 > def printtags(ui, repo, **args):
372 > def printtags(ui, repo, **args):
372 > print sorted(repo.tags())
373 > print sorted(repo.tags())
373 >
374 >
374 > class container:
375 > class container:
375 > unreachable = 1
376 > unreachable = 1
376 > EOF
377 > EOF
377
378
378 test python hooks
379 test python hooks
379
380
380 #if windows
381 #if windows
381 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
382 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
382 #else
383 #else
383 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
384 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
384 #endif
385 #endif
385 $ export PYTHONPATH
386 $ export PYTHONPATH
386
387
387 $ echo '[hooks]' > ../a/.hg/hgrc
388 $ echo '[hooks]' > ../a/.hg/hgrc
388 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
389 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
389 $ hg pull ../a 2>&1 | grep 'raised an exception'
390 $ hg pull ../a 2>&1 | grep 'raised an exception'
390 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
391 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
391
392
392 $ echo '[hooks]' > ../a/.hg/hgrc
393 $ echo '[hooks]' > ../a/.hg/hgrc
393 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
394 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
394 $ hg pull ../a 2>&1 | grep 'raised an exception'
395 $ hg pull ../a 2>&1 | grep 'raised an exception'
395 error: preoutgoing.raise hook raised an exception: exception from hook
396 error: preoutgoing.raise hook raised an exception: exception from hook
396
397
397 $ echo '[hooks]' > ../a/.hg/hgrc
398 $ echo '[hooks]' > ../a/.hg/hgrc
398 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
399 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
399 $ hg pull ../a
400 $ hg pull ../a
400 pulling from ../a
401 pulling from ../a
401 searching for changes
402 searching for changes
402 error: preoutgoing.abort hook failed: raise abort from hook
403 error: preoutgoing.abort hook failed: raise abort from hook
403 abort: raise abort from hook
404 abort: raise abort from hook
404 [255]
405 [255]
405
406
406 $ echo '[hooks]' > ../a/.hg/hgrc
407 $ echo '[hooks]' > ../a/.hg/hgrc
407 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
408 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
408 $ hg pull ../a
409 $ hg pull ../a
409 pulling from ../a
410 pulling from ../a
410 searching for changes
411 searching for changes
411 hook args:
412 hook args:
412 hooktype preoutgoing
413 hooktype preoutgoing
413 source pull
414 source pull
414 abort: preoutgoing.fail hook failed
415 abort: preoutgoing.fail hook failed
415 [255]
416 [255]
416
417
417 $ echo '[hooks]' > ../a/.hg/hgrc
418 $ echo '[hooks]' > ../a/.hg/hgrc
418 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
419 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
419 $ hg pull ../a
420 $ hg pull ../a
420 pulling from ../a
421 pulling from ../a
421 searching for changes
422 searching for changes
422 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
423 abort: preoutgoing.uncallable hook is invalid ("hooktests.uncallable" is not callable)
423 [255]
424 [255]
424
425
425 $ echo '[hooks]' > ../a/.hg/hgrc
426 $ echo '[hooks]' > ../a/.hg/hgrc
426 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
427 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
427 $ hg pull ../a
428 $ hg pull ../a
428 pulling from ../a
429 pulling from ../a
429 searching for changes
430 searching for changes
430 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
431 abort: preoutgoing.nohook hook is invalid ("hooktests.nohook" is not defined)
431 [255]
432 [255]
432
433
433 $ echo '[hooks]' > ../a/.hg/hgrc
434 $ echo '[hooks]' > ../a/.hg/hgrc
434 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
435 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
435 $ hg pull ../a
436 $ hg pull ../a
436 pulling from ../a
437 pulling from ../a
437 searching for changes
438 searching for changes
438 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
439 abort: preoutgoing.nomodule hook is invalid ("nomodule" not in a module)
439 [255]
440 [255]
440
441
441 $ echo '[hooks]' > ../a/.hg/hgrc
442 $ echo '[hooks]' > ../a/.hg/hgrc
442 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
443 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
443 $ hg pull ../a
444 $ hg pull ../a
444 pulling from ../a
445 pulling from ../a
445 searching for changes
446 searching for changes
446 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
447 abort: preoutgoing.badmodule hook is invalid (import of "nomodule" failed)
447 [255]
448 [255]
448
449
449 $ echo '[hooks]' > ../a/.hg/hgrc
450 $ echo '[hooks]' > ../a/.hg/hgrc
450 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
451 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
451 $ hg pull ../a
452 $ hg pull ../a
452 pulling from ../a
453 pulling from ../a
453 searching for changes
454 searching for changes
454 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
455 abort: preoutgoing.unreachable hook is invalid (import of "hooktests.container" failed)
455 [255]
456 [255]
456
457
457 $ echo '[hooks]' > ../a/.hg/hgrc
458 $ echo '[hooks]' > ../a/.hg/hgrc
458 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
459 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
459 $ hg pull ../a
460 $ hg pull ../a
460 pulling from ../a
461 pulling from ../a
461 searching for changes
462 searching for changes
462 hook args:
463 hook args:
463 hooktype preoutgoing
464 hooktype preoutgoing
464 source pull
465 source pull
465 adding changesets
466 adding changesets
466 adding manifests
467 adding manifests
467 adding file changes
468 adding file changes
468 added 1 changesets with 1 changes to 1 files
469 added 1 changesets with 1 changes to 1 files
469 adding remote bookmark quux
470 adding remote bookmark quux
470 (run 'hg update' to get a working copy)
471 (run 'hg update' to get a working copy)
471
472
472 make sure --traceback works
473 make sure --traceback works
473
474
474 $ echo '[hooks]' > .hg/hgrc
475 $ echo '[hooks]' > .hg/hgrc
475 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
476 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
476
477
477 $ echo aa > a
478 $ echo aa > a
478 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
479 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
479 Traceback (most recent call last):
480 Traceback (most recent call last):
480
481
481 $ cd ..
482 $ cd ..
482 $ hg init c
483 $ hg init c
483 $ cd c
484 $ cd c
484
485
485 $ cat > hookext.py <<EOF
486 $ cat > hookext.py <<EOF
486 > def autohook(**args):
487 > def autohook(**args):
487 > print "Automatically installed hook"
488 > print "Automatically installed hook"
488 >
489 >
489 > def reposetup(ui, repo):
490 > def reposetup(ui, repo):
490 > repo.ui.setconfig("hooks", "commit.auto", autohook)
491 > repo.ui.setconfig("hooks", "commit.auto", autohook)
491 > EOF
492 > EOF
492 $ echo '[extensions]' >> .hg/hgrc
493 $ echo '[extensions]' >> .hg/hgrc
493 $ echo 'hookext = hookext.py' >> .hg/hgrc
494 $ echo 'hookext = hookext.py' >> .hg/hgrc
494
495
495 $ touch foo
496 $ touch foo
496 $ hg add foo
497 $ hg add foo
497 $ hg ci -d '0 0' -m 'add foo'
498 $ hg ci -d '0 0' -m 'add foo'
498 Automatically installed hook
499 Automatically installed hook
499 $ echo >> foo
500 $ echo >> foo
500 $ hg ci --debug -d '0 0' -m 'change foo'
501 $ hg ci --debug -d '0 0' -m 'change foo'
501 foo
502 foo
502 calling hook commit.auto: hgext_hookext.autohook
503 calling hook commit.auto: hgext_hookext.autohook
503 Automatically installed hook
504 Automatically installed hook
504 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
505 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
505
506
506 $ hg showconfig hooks
507 $ hg showconfig hooks
507 hooks.commit.auto=<function autohook at *> (glob)
508 hooks.commit.auto=<function autohook at *> (glob)
508
509
509 test python hook configured with python:[file]:[hook] syntax
510 test python hook configured with python:[file]:[hook] syntax
510
511
511 $ cd ..
512 $ cd ..
512 $ mkdir d
513 $ mkdir d
513 $ cd d
514 $ cd d
514 $ hg init repo
515 $ hg init repo
515 $ mkdir hooks
516 $ mkdir hooks
516
517
517 $ cd hooks
518 $ cd hooks
518 $ cat > testhooks.py <<EOF
519 $ cat > testhooks.py <<EOF
519 > def testhook(**args):
520 > def testhook(**args):
520 > print 'hook works'
521 > print 'hook works'
521 > EOF
522 > EOF
522 $ echo '[hooks]' > ../repo/.hg/hgrc
523 $ echo '[hooks]' > ../repo/.hg/hgrc
523 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
524 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
524
525
525 $ cd ../repo
526 $ cd ../repo
526 $ hg commit -d '0 0'
527 $ hg commit -d '0 0'
527 hook works
528 hook works
528 nothing changed
529 nothing changed
529 [1]
530 [1]
530
531
531 $ echo '[hooks]' > .hg/hgrc
532 $ echo '[hooks]' > .hg/hgrc
532 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
533 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
533 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
534 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
534
535
535 $ hg up null
536 $ hg up null
536 loading update.ne hook failed:
537 loading update.ne hook failed:
537 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
538 abort: No such file or directory: $TESTTMP/d/repo/nonexistent.py
538 [255]
539 [255]
539
540
540 $ hg id
541 $ hg id
541 loading pre-identify.npmd hook failed:
542 loading pre-identify.npmd hook failed:
542 abort: No module named repo!
543 abort: No module named repo!
543 [255]
544 [255]
544
545
545 $ cd ../../b
546 $ cd ../../b
546
547
547 make sure --traceback works on hook import failure
548 make sure --traceback works on hook import failure
548
549
549 $ cat > importfail.py <<EOF
550 $ cat > importfail.py <<EOF
550 > import somebogusmodule
551 > import somebogusmodule
551 > # dereference something in the module to force demandimport to load it
552 > # dereference something in the module to force demandimport to load it
552 > somebogusmodule.whatever
553 > somebogusmodule.whatever
553 > EOF
554 > EOF
554
555
555 $ echo '[hooks]' > .hg/hgrc
556 $ echo '[hooks]' > .hg/hgrc
556 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
557 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
557
558
558 $ echo a >> a
559 $ echo a >> a
559 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
560 $ hg --traceback commit -ma 2>&1 | egrep -v '^( +File| [a-zA-Z(])'
560 exception from first failed import attempt:
561 exception from first failed import attempt:
561 Traceback (most recent call last):
562 Traceback (most recent call last):
562 ImportError: No module named somebogusmodule
563 ImportError: No module named somebogusmodule
563 exception from second failed import attempt:
564 exception from second failed import attempt:
564 Traceback (most recent call last):
565 Traceback (most recent call last):
565 ImportError: No module named hgext_importfail
566 ImportError: No module named hgext_importfail
566 Traceback (most recent call last):
567 Traceback (most recent call last):
567 Abort: precommit.importfail hook is invalid (import of "importfail" failed)
568 Abort: precommit.importfail hook is invalid (import of "importfail" failed)
568 abort: precommit.importfail hook is invalid (import of "importfail" failed)
569 abort: precommit.importfail hook is invalid (import of "importfail" failed)
569
570
570 Issue1827: Hooks Update & Commit not completely post operation
571 Issue1827: Hooks Update & Commit not completely post operation
571
572
572 commit and update hooks should run after command completion
573 commit and update hooks should run after command completion
573
574
574 $ echo '[hooks]' > .hg/hgrc
575 $ echo '[hooks]' > .hg/hgrc
575 $ echo 'commit = hg id' >> .hg/hgrc
576 $ echo 'commit = hg id' >> .hg/hgrc
576 $ echo 'update = hg id' >> .hg/hgrc
577 $ echo 'update = hg id' >> .hg/hgrc
577 $ echo bb > a
578 $ echo bb > a
578 $ hg ci -ma
579 $ hg ci -ma
579 223eafe2750c tip
580 223eafe2750c tip
580 $ hg up 0
581 $ hg up 0
581 cb9a9f314b8b
582 cb9a9f314b8b
582 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
583
584
584 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
585 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
585 that is passed to pre/post hooks
586 that is passed to pre/post hooks
586
587
587 $ echo '[hooks]' > .hg/hgrc
588 $ echo '[hooks]' > .hg/hgrc
588 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
589 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
589 $ hg id
590 $ hg id
590 cb9a9f314b8b
591 cb9a9f314b8b
591 $ hg id --verbose
592 $ hg id --verbose
592 calling hook pre-identify: hooktests.verbosehook
593 calling hook pre-identify: hooktests.verbosehook
593 verbose output from hook
594 verbose output from hook
594 cb9a9f314b8b
595 cb9a9f314b8b
595
596
596 Ensure hooks can be prioritized
597 Ensure hooks can be prioritized
597
598
598 $ echo '[hooks]' > .hg/hgrc
599 $ echo '[hooks]' > .hg/hgrc
599 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
600 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
600 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
601 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
601 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
602 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
602 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
603 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
603 $ hg id --verbose
604 $ hg id --verbose
604 calling hook pre-identify.b: hooktests.verbosehook
605 calling hook pre-identify.b: hooktests.verbosehook
605 verbose output from hook
606 verbose output from hook
606 calling hook pre-identify.a: hooktests.verbosehook
607 calling hook pre-identify.a: hooktests.verbosehook
607 verbose output from hook
608 verbose output from hook
608 calling hook pre-identify.c: hooktests.verbosehook
609 calling hook pre-identify.c: hooktests.verbosehook
609 verbose output from hook
610 verbose output from hook
610 cb9a9f314b8b
611 cb9a9f314b8b
611
612
612 new tags must be visible in pretxncommit (issue3210)
613 new tags must be visible in pretxncommit (issue3210)
613
614
614 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
615 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
615 $ hg tag -f foo
616 $ hg tag -f foo
616 ['a', 'foo', 'tip']
617 ['a', 'foo', 'tip']
617
618
618 new commits must be visible in pretxnchangegroup (issue3428)
619 new commits must be visible in pretxnchangegroup (issue3428)
619
620
620 $ cd ..
621 $ cd ..
621 $ hg init to
622 $ hg init to
622 $ echo '[hooks]' >> to/.hg/hgrc
623 $ echo '[hooks]' >> to/.hg/hgrc
623 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
624 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
624 $ echo a >> to/a
625 $ echo a >> to/a
625 $ hg --cwd to ci -Ama
626 $ hg --cwd to ci -Ama
626 adding a
627 adding a
627 $ hg clone to from
628 $ hg clone to from
628 updating to branch default
629 updating to branch default
629 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
630 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
630 $ echo aa >> from/a
631 $ echo aa >> from/a
631 $ hg --cwd from ci -mb
632 $ hg --cwd from ci -mb
632 $ hg --cwd from push
633 $ hg --cwd from push
633 pushing to $TESTTMP/to (glob)
634 pushing to $TESTTMP/to (glob)
634 searching for changes
635 searching for changes
635 adding changesets
636 adding changesets
636 adding manifests
637 adding manifests
637 adding file changes
638 adding file changes
638 added 1 changesets with 1 changes to 1 files
639 added 1 changesets with 1 changes to 1 files
639 changeset: 1:9836a07b9b9d
640 changeset: 1:9836a07b9b9d
640 tag: tip
641 tag: tip
641 user: test
642 user: test
642 date: Thu Jan 01 00:00:00 1970 +0000
643 date: Thu Jan 01 00:00:00 1970 +0000
643 summary: b
644 summary: b
644
645
@@ -1,306 +1,307 b''
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 $ hg init test
3 $ hg init test
4 $ cd test
4 $ cd test
5 $ echo foo>foo
5 $ echo foo>foo
6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
6 $ mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
7 $ echo foo>foo.d/foo
7 $ echo foo>foo.d/foo
8 $ echo bar>foo.d/bAr.hg.d/BaR
8 $ echo bar>foo.d/bAr.hg.d/BaR
9 $ echo bar>foo.d/baR.d.hg/bAR
9 $ echo bar>foo.d/baR.d.hg/bAR
10 $ hg commit -A -m 1
10 $ hg commit -A -m 1
11 adding foo
11 adding foo
12 adding foo.d/bAr.hg.d/BaR
12 adding foo.d/bAr.hg.d/BaR
13 adding foo.d/baR.d.hg/bAR
13 adding foo.d/baR.d.hg/bAR
14 adding foo.d/foo
14 adding foo.d/foo
15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
15 $ hg serve -p $HGPORT -d --pid-file=../hg1.pid -E ../error.log
16 $ hg --config server.uncompressed=False serve -p $HGPORT1 -d --pid-file=../hg2.pid
16 $ hg --config server.uncompressed=False serve -p $HGPORT1 -d --pid-file=../hg2.pid
17
17
18 Test server address cannot be reused
18 Test server address cannot be reused
19
19
20 #if windows
20 #if windows
21 $ hg serve -p $HGPORT1 2>&1
21 $ hg serve -p $HGPORT1 2>&1
22 abort: cannot start server at ':$HGPORT1': * (glob)
22 abort: cannot start server at ':$HGPORT1': * (glob)
23 [255]
23 [255]
24 #else
24 #else
25 $ hg serve -p $HGPORT1 2>&1
25 $ hg serve -p $HGPORT1 2>&1
26 abort: cannot start server at ':$HGPORT1': Address already in use
26 abort: cannot start server at ':$HGPORT1': Address already in use
27 [255]
27 [255]
28 #endif
28 #endif
29 $ cd ..
29 $ cd ..
30 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
30 $ cat hg1.pid hg2.pid >> $DAEMON_PIDS
31
31
32 clone via stream
32 clone via stream
33
33
34 $ hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1
34 $ hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1
35 streaming all changes
35 streaming all changes
36 6 files to transfer, 606 bytes of data
36 6 files to transfer, 606 bytes of data
37 transferred * bytes in * seconds (*/sec) (glob)
37 transferred * bytes in * seconds (*/sec) (glob)
38 updating to branch default
38 updating to branch default
39 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
40 $ hg verify -R copy
40 $ hg verify -R copy
41 checking changesets
41 checking changesets
42 checking manifests
42 checking manifests
43 crosschecking files in changesets and manifests
43 crosschecking files in changesets and manifests
44 checking files
44 checking files
45 4 files, 1 changesets, 4 total revisions
45 4 files, 1 changesets, 4 total revisions
46
46
47 try to clone via stream, should use pull instead
47 try to clone via stream, should use pull instead
48
48
49 $ hg clone --uncompressed http://localhost:$HGPORT1/ copy2
49 $ hg clone --uncompressed http://localhost:$HGPORT1/ copy2
50 requesting all changes
50 requesting all changes
51 adding changesets
51 adding changesets
52 adding manifests
52 adding manifests
53 adding file changes
53 adding file changes
54 added 1 changesets with 4 changes to 4 files
54 added 1 changesets with 4 changes to 4 files
55 updating to branch default
55 updating to branch default
56 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
57
57
58 clone via pull
58 clone via pull
59
59
60 $ hg clone http://localhost:$HGPORT1/ copy-pull
60 $ hg clone http://localhost:$HGPORT1/ copy-pull
61 requesting all changes
61 requesting all changes
62 adding changesets
62 adding changesets
63 adding manifests
63 adding manifests
64 adding file changes
64 adding file changes
65 added 1 changesets with 4 changes to 4 files
65 added 1 changesets with 4 changes to 4 files
66 updating to branch default
66 updating to branch default
67 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 $ hg verify -R copy-pull
68 $ hg verify -R copy-pull
69 checking changesets
69 checking changesets
70 checking manifests
70 checking manifests
71 crosschecking files in changesets and manifests
71 crosschecking files in changesets and manifests
72 checking files
72 checking files
73 4 files, 1 changesets, 4 total revisions
73 4 files, 1 changesets, 4 total revisions
74 $ cd test
74 $ cd test
75 $ echo bar > bar
75 $ echo bar > bar
76 $ hg commit -A -d '1 0' -m 2
76 $ hg commit -A -d '1 0' -m 2
77 adding bar
77 adding bar
78 $ cd ..
78 $ cd ..
79
79
80 clone over http with --update
80 clone over http with --update
81
81
82 $ hg clone http://localhost:$HGPORT1/ updated --update 0
82 $ hg clone http://localhost:$HGPORT1/ updated --update 0
83 requesting all changes
83 requesting all changes
84 adding changesets
84 adding changesets
85 adding manifests
85 adding manifests
86 adding file changes
86 adding file changes
87 added 2 changesets with 5 changes to 5 files
87 added 2 changesets with 5 changes to 5 files
88 updating to branch default
88 updating to branch default
89 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 $ hg log -r . -R updated
90 $ hg log -r . -R updated
91 changeset: 0:8b6053c928fe
91 changeset: 0:8b6053c928fe
92 user: test
92 user: test
93 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
94 summary: 1
94 summary: 1
95
95
96 $ rm -rf updated
96 $ rm -rf updated
97
97
98 incoming via HTTP
98 incoming via HTTP
99
99
100 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
100 $ hg clone http://localhost:$HGPORT1/ --rev 0 partial
101 adding changesets
101 adding changesets
102 adding manifests
102 adding manifests
103 adding file changes
103 adding file changes
104 added 1 changesets with 4 changes to 4 files
104 added 1 changesets with 4 changes to 4 files
105 updating to branch default
105 updating to branch default
106 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 $ cd partial
107 $ cd partial
108 $ touch LOCAL
108 $ touch LOCAL
109 $ hg ci -qAm LOCAL
109 $ hg ci -qAm LOCAL
110 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
110 $ hg incoming http://localhost:$HGPORT1/ --template '{desc}\n'
111 comparing with http://localhost:$HGPORT1/
111 comparing with http://localhost:$HGPORT1/
112 searching for changes
112 searching for changes
113 2
113 2
114 $ cd ..
114 $ cd ..
115
115
116 pull
116 pull
117
117
118 $ cd copy-pull
118 $ cd copy-pull
119 $ echo '[hooks]' >> .hg/hgrc
119 $ echo '[hooks]' >> .hg/hgrc
120 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup" >> .hg/hgrc
120 $ echo "changegroup = python \"$TESTDIR/printenv.py\" changegroup" >> .hg/hgrc
121 $ hg pull
121 $ hg pull
122 pulling from http://localhost:$HGPORT1/
122 pulling from http://localhost:$HGPORT1/
123 searching for changes
123 searching for changes
124 adding changesets
124 adding changesets
125 adding manifests
125 adding manifests
126 adding file changes
126 adding file changes
127 added 1 changesets with 1 changes to 1 files
127 added 1 changesets with 1 changes to 1 files
128 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=http://localhost:$HGPORT1/
128 changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=http://localhost:$HGPORT1/
129 (run 'hg update' to get a working copy)
129 (run 'hg update' to get a working copy)
130 $ cd ..
130 $ cd ..
131
131
132 clone from invalid URL
132 clone from invalid URL
133
133
134 $ hg clone http://localhost:$HGPORT/bad
134 $ hg clone http://localhost:$HGPORT/bad
135 abort: HTTP Error 404: Not Found
135 abort: HTTP Error 404: Not Found
136 [255]
136 [255]
137
137
138 test http authentication
138 test http authentication
139 + use the same server to test server side streaming preference
139 + use the same server to test server side streaming preference
140
140
141 $ cd test
141 $ cd test
142 $ cat << EOT > userpass.py
142 $ cat << EOT > userpass.py
143 > import base64
143 > import base64
144 > from mercurial.hgweb import common
144 > from mercurial.hgweb import common
145 > def perform_authentication(hgweb, req, op):
145 > def perform_authentication(hgweb, req, op):
146 > auth = req.env.get('HTTP_AUTHORIZATION')
146 > auth = req.env.get('HTTP_AUTHORIZATION')
147 > if not auth:
147 > if not auth:
148 > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who',
148 > raise common.ErrorResponse(common.HTTP_UNAUTHORIZED, 'who',
149 > [('WWW-Authenticate', 'Basic Realm="mercurial"')])
149 > [('WWW-Authenticate', 'Basic Realm="mercurial"')])
150 > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']:
150 > if base64.b64decode(auth.split()[1]).split(':', 1) != ['user', 'pass']:
151 > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no')
151 > raise common.ErrorResponse(common.HTTP_FORBIDDEN, 'no')
152 > def extsetup():
152 > def extsetup():
153 > common.permhooks.insert(0, perform_authentication)
153 > common.permhooks.insert(0, perform_authentication)
154 > EOT
154 > EOT
155 $ hg --config extensions.x=userpass.py serve -p $HGPORT2 -d --pid-file=pid \
155 $ hg --config extensions.x=userpass.py serve -p $HGPORT2 -d --pid-file=pid \
156 > --config server.preferuncompressed=True \
156 > --config server.preferuncompressed=True \
157 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
157 > --config web.push_ssl=False --config web.allow_push=* -A ../access.log
158 $ cat pid >> $DAEMON_PIDS
158 $ cat pid >> $DAEMON_PIDS
159
159
160 $ cat << EOF > get_pass.py
160 $ cat << EOF > get_pass.py
161 > import getpass
161 > import getpass
162 > def newgetpass(arg):
162 > def newgetpass(arg):
163 > return "pass"
163 > return "pass"
164 > getpass.getpass = newgetpass
164 > getpass.getpass = newgetpass
165 > EOF
165 > EOF
166
166
167 #if python243
167 #if python243
168 $ hg id http://localhost:$HGPORT2/
168 $ hg id http://localhost:$HGPORT2/
169 abort: http authorization required for http://localhost:$HGPORT2/
169 abort: http authorization required for http://localhost:$HGPORT2/
170 [255]
170 [255]
171 $ hg id http://localhost:$HGPORT2/
171 $ hg id http://localhost:$HGPORT2/
172 abort: http authorization required for http://localhost:$HGPORT2/
172 abort: http authorization required for http://localhost:$HGPORT2/
173 [255]
173 [255]
174 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
174 $ hg id --config ui.interactive=true --config extensions.getpass=get_pass.py http://user@localhost:$HGPORT2/
175 http authorization required for http://localhost:$HGPORT2/
175 http authorization required for http://localhost:$HGPORT2/
176 realm: mercurial
176 realm: mercurial
177 user: user
177 user: user
178 password: 5fed3813f7f5
178 password: 5fed3813f7f5
179 $ hg id http://user:pass@localhost:$HGPORT2/
179 $ hg id http://user:pass@localhost:$HGPORT2/
180 5fed3813f7f5
180 5fed3813f7f5
181 #endif
181 #endif
182 $ echo '[auth]' >> .hg/hgrc
182 $ echo '[auth]' >> .hg/hgrc
183 $ echo 'l.schemes=http' >> .hg/hgrc
183 $ echo 'l.schemes=http' >> .hg/hgrc
184 $ echo 'l.prefix=lo' >> .hg/hgrc
184 $ echo 'l.prefix=lo' >> .hg/hgrc
185 $ echo 'l.username=user' >> .hg/hgrc
185 $ echo 'l.username=user' >> .hg/hgrc
186 $ echo 'l.password=pass' >> .hg/hgrc
186 $ echo 'l.password=pass' >> .hg/hgrc
187 $ hg id http://localhost:$HGPORT2/
187 $ hg id http://localhost:$HGPORT2/
188 5fed3813f7f5
188 5fed3813f7f5
189 $ hg id http://localhost:$HGPORT2/
189 $ hg id http://localhost:$HGPORT2/
190 5fed3813f7f5
190 5fed3813f7f5
191 $ hg id http://user@localhost:$HGPORT2/
191 $ hg id http://user@localhost:$HGPORT2/
192 5fed3813f7f5
192 5fed3813f7f5
193 #if python243
193 #if python243
194 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
194 $ hg clone http://user:pass@localhost:$HGPORT2/ dest 2>&1
195 streaming all changes
195 streaming all changes
196 7 files to transfer, 916 bytes of data
196 7 files to transfer, 916 bytes of data
197 transferred * bytes in * seconds (*/sec) (glob)
197 transferred * bytes in * seconds (*/sec) (glob)
198 updating to branch default
198 updating to branch default
199 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
200
200
201 $ hg id http://user2@localhost:$HGPORT2/
201 $ hg id http://user2@localhost:$HGPORT2/
202 abort: http authorization required for http://localhost:$HGPORT2/
202 abort: http authorization required for http://localhost:$HGPORT2/
203 [255]
203 [255]
204 $ hg id http://user:pass2@localhost:$HGPORT2/
204 $ hg id http://user:pass2@localhost:$HGPORT2/
205 abort: HTTP Error 403: no
205 abort: HTTP Error 403: no
206 [255]
206 [255]
207
207
208 $ hg -R dest tag -r tip top
208 $ hg -R dest tag -r tip top
209 $ hg -R dest push http://user:pass@localhost:$HGPORT2/
209 $ hg -R dest push http://user:pass@localhost:$HGPORT2/
210 pushing to http://user:***@localhost:$HGPORT2/
210 pushing to http://user:***@localhost:$HGPORT2/
211 searching for changes
211 searching for changes
212 remote: adding changesets
212 remote: adding changesets
213 remote: adding manifests
213 remote: adding manifests
214 remote: adding file changes
214 remote: adding file changes
215 remote: added 1 changesets with 1 changes to 1 files
215 remote: added 1 changesets with 1 changes to 1 files
216 $ hg rollback -q
216 $ hg rollback -q
217
217
218 $ cut -c38- ../access.log
218 $ cut -c38- ../access.log
219 "GET /?cmd=capabilities HTTP/1.1" 200 -
219 "GET /?cmd=capabilities HTTP/1.1" 200 -
220 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
220 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
221 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
221 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
222 "GET /?cmd=capabilities HTTP/1.1" 200 -
222 "GET /?cmd=capabilities HTTP/1.1" 200 -
223 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
223 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
224 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
224 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
225 "GET /?cmd=capabilities HTTP/1.1" 200 -
225 "GET /?cmd=capabilities HTTP/1.1" 200 -
226 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
226 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
227 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
227 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
228 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
228 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
229 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
229 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
230 "GET /?cmd=capabilities HTTP/1.1" 200 -
230 "GET /?cmd=capabilities HTTP/1.1" 200 -
231 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
231 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
232 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
232 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
233 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
233 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
234 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
234 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
235 "GET /?cmd=capabilities HTTP/1.1" 200 -
235 "GET /?cmd=capabilities HTTP/1.1" 200 -
236 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
236 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
237 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
237 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
238 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
238 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
239 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
239 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
240 "GET /?cmd=capabilities HTTP/1.1" 200 -
240 "GET /?cmd=capabilities HTTP/1.1" 200 -
241 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
241 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
242 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
242 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
243 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
243 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
244 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
244 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
245 "GET /?cmd=capabilities HTTP/1.1" 200 -
245 "GET /?cmd=capabilities HTTP/1.1" 200 -
246 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
246 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
247 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
247 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
248 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
248 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=namespaces
249 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
249 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
250 "GET /?cmd=capabilities HTTP/1.1" 200 -
250 "GET /?cmd=capabilities HTTP/1.1" 200 -
251 "GET /?cmd=branchmap HTTP/1.1" 200 -
251 "GET /?cmd=branchmap HTTP/1.1" 200 -
252 "GET /?cmd=stream_out HTTP/1.1" 401 -
252 "GET /?cmd=stream_out HTTP/1.1" 401 -
253 "GET /?cmd=stream_out HTTP/1.1" 200 -
253 "GET /?cmd=stream_out HTTP/1.1" 200 -
254 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
254 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
255 "GET /?cmd=capabilities HTTP/1.1" 200 -
255 "GET /?cmd=capabilities HTTP/1.1" 200 -
256 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
256 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
257 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
257 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
258 "GET /?cmd=capabilities HTTP/1.1" 200 -
258 "GET /?cmd=capabilities HTTP/1.1" 200 -
259 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
259 "GET /?cmd=lookup HTTP/1.1" 200 - x-hgarg-1:key=tip
260 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
260 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=namespaces
261 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces
261 "GET /?cmd=listkeys HTTP/1.1" 403 - x-hgarg-1:namespace=namespaces
262 "GET /?cmd=capabilities HTTP/1.1" 200 -
262 "GET /?cmd=capabilities HTTP/1.1" 200 -
263 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872
263 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D7f4e523d01f2cc3765ac8934da3d14db775ff872
264 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases
265 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
264 "GET /?cmd=branchmap HTTP/1.1" 200 -
266 "GET /?cmd=branchmap HTTP/1.1" 200 -
265 "GET /?cmd=branchmap HTTP/1.1" 200 -
267 "GET /?cmd=branchmap HTTP/1.1" 200 -
266 "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks
267 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
268 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
268 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524
269 "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=686173686564+5eb5abfefeea63c80dd7553bcc3783f37e0c5524
269 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
270 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases
270 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
271 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks
271
272
272 #endif
273 #endif
273 $ cd ..
274 $ cd ..
274
275
275 clone of serve with repo in root and unserved subrepo (issue2970)
276 clone of serve with repo in root and unserved subrepo (issue2970)
276
277
277 $ hg --cwd test init sub
278 $ hg --cwd test init sub
278 $ echo empty > test/sub/empty
279 $ echo empty > test/sub/empty
279 $ hg --cwd test/sub add empty
280 $ hg --cwd test/sub add empty
280 $ hg --cwd test/sub commit -qm 'add empty'
281 $ hg --cwd test/sub commit -qm 'add empty'
281 $ hg --cwd test/sub tag -r 0 something
282 $ hg --cwd test/sub tag -r 0 something
282 $ echo sub = sub > test/.hgsub
283 $ echo sub = sub > test/.hgsub
283 $ hg --cwd test add .hgsub
284 $ hg --cwd test add .hgsub
284 $ hg --cwd test commit -qm 'add subrepo'
285 $ hg --cwd test commit -qm 'add subrepo'
285 $ hg clone http://localhost:$HGPORT noslash-clone
286 $ hg clone http://localhost:$HGPORT noslash-clone
286 requesting all changes
287 requesting all changes
287 adding changesets
288 adding changesets
288 adding manifests
289 adding manifests
289 adding file changes
290 adding file changes
290 added 3 changesets with 7 changes to 7 files
291 added 3 changesets with 7 changes to 7 files
291 updating to branch default
292 updating to branch default
292 abort: HTTP Error 404: Not Found
293 abort: HTTP Error 404: Not Found
293 [255]
294 [255]
294 $ hg clone http://localhost:$HGPORT/ slash-clone
295 $ hg clone http://localhost:$HGPORT/ slash-clone
295 requesting all changes
296 requesting all changes
296 adding changesets
297 adding changesets
297 adding manifests
298 adding manifests
298 adding file changes
299 adding file changes
299 added 3 changesets with 7 changes to 7 files
300 added 3 changesets with 7 changes to 7 files
300 updating to branch default
301 updating to branch default
301 abort: HTTP Error 404: Not Found
302 abort: HTTP Error 404: Not Found
302 [255]
303 [255]
303
304
304 check error log
305 check error log
305
306
306 $ cat error.log
307 $ cat error.log
@@ -1,669 +1,670 b''
1 $ cat >> $HGRCPATH << EOF
1 $ cat >> $HGRCPATH << EOF
2 > [phases]
2 > [phases]
3 > # public changeset are not obsolete
3 > # public changeset are not obsolete
4 > publish=false
4 > publish=false
5 > [ui]
5 > [ui]
6 > logtemplate="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n"
6 > logtemplate="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n"
7 > EOF
7 > EOF
8 $ mkcommit() {
8 $ mkcommit() {
9 > echo "$1" > "$1"
9 > echo "$1" > "$1"
10 > hg add "$1"
10 > hg add "$1"
11 > hg ci -m "add $1"
11 > hg ci -m "add $1"
12 > }
12 > }
13 $ getid() {
13 $ getid() {
14 > hg id --debug --hidden -ir "desc('$1')"
14 > hg id --debug --hidden -ir "desc('$1')"
15 > }
15 > }
16
16
17 $ cat > debugkeys.py <<EOF
17 $ cat > debugkeys.py <<EOF
18 > def reposetup(ui, repo):
18 > def reposetup(ui, repo):
19 > class debugkeysrepo(repo.__class__):
19 > class debugkeysrepo(repo.__class__):
20 > def listkeys(self, namespace):
20 > def listkeys(self, namespace):
21 > ui.write('listkeys %s\n' % (namespace,))
21 > ui.write('listkeys %s\n' % (namespace,))
22 > return super(debugkeysrepo, self).listkeys(namespace)
22 > return super(debugkeysrepo, self).listkeys(namespace)
23 >
23 >
24 > if repo.local():
24 > if repo.local():
25 > repo.__class__ = debugkeysrepo
25 > repo.__class__ = debugkeysrepo
26 > EOF
26 > EOF
27
27
28 $ hg init tmpa
28 $ hg init tmpa
29 $ cd tmpa
29 $ cd tmpa
30 $ mkcommit kill_me
30 $ mkcommit kill_me
31
31
32 Checking that the feature is properly disabled
32 Checking that the feature is properly disabled
33
33
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 abort: obsolete feature is not enabled on this repo
35 abort: obsolete feature is not enabled on this repo
36 [255]
36 [255]
37
37
38 Enabling it
38 Enabling it
39
39
40 $ cat > ../obs.py << EOF
40 $ cat > ../obs.py << EOF
41 > import mercurial.obsolete
41 > import mercurial.obsolete
42 > mercurial.obsolete._enabled = True
42 > mercurial.obsolete._enabled = True
43 > EOF
43 > EOF
44 $ echo '[extensions]' >> $HGRCPATH
44 $ echo '[extensions]' >> $HGRCPATH
45 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
45 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
46
46
47 Killing a single changeset without replacement
47 Killing a single changeset without replacement
48
48
49 $ hg debugobsolete 0
49 $ hg debugobsolete 0
50 abort: changeset references must be full hexadecimal node identifiers
50 abort: changeset references must be full hexadecimal node identifiers
51 [255]
51 [255]
52 $ hg debugobsolete '00'
52 $ hg debugobsolete '00'
53 abort: changeset references must be full hexadecimal node identifiers
53 abort: changeset references must be full hexadecimal node identifiers
54 [255]
54 [255]
55 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
55 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
56 $ hg debugobsolete
56 $ hg debugobsolete
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'}
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'}
58
58
59 (test that mercurial is not confused)
59 (test that mercurial is not confused)
60
60
61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
62 $ hg tip
62 $ hg tip
63 -1:000000000000 (public) [tip ]
63 -1:000000000000 (public) [tip ]
64 $ hg up --hidden tip --quiet
64 $ hg up --hidden tip --quiet
65 $ cd ..
65 $ cd ..
66
66
67 Killing a single changeset with replacement
67 Killing a single changeset with replacement
68
68
69 $ hg init tmpb
69 $ hg init tmpb
70 $ cd tmpb
70 $ cd tmpb
71 $ mkcommit a
71 $ mkcommit a
72 $ mkcommit b
72 $ mkcommit b
73 $ mkcommit original_c
73 $ mkcommit original_c
74 $ hg up "desc('b')"
74 $ hg up "desc('b')"
75 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
75 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
76 $ mkcommit new_c
76 $ mkcommit new_c
77 created new head
77 created new head
78 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
78 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
79 $ hg debugobsolete --flag 12 `getid original_c` `getid new_c` -d '56 12'
79 $ hg debugobsolete --flag 12 `getid original_c` `getid new_c` -d '56 12'
80 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
80 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
81 2:245bde4270cd add original_c
81 2:245bde4270cd add original_c
82 $ hg debugrevlog -cd
82 $ hg debugrevlog -cd
83 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads
83 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads
84 0 -1 -1 0 59 0 0 0 0 58 58 0 1
84 0 -1 -1 0 59 0 0 0 0 58 58 0 1
85 1 0 -1 59 118 59 59 0 0 58 116 0 1
85 1 0 -1 59 118 59 59 0 0 58 116 0 1
86 2 1 -1 118 204 59 59 59 0 76 192 0 1
86 2 1 -1 118 204 59 59 59 0 76 192 0 1
87 3 1 -1 204 271 204 204 59 0 66 258 0 2
87 3 1 -1 204 271 204 204 59 0 66 258 0 2
88 $ hg debugobsolete
88 $ hg debugobsolete
89 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
89 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
90
90
91 do it again (it read the obsstore before adding new changeset)
91 do it again (it read the obsstore before adding new changeset)
92
92
93 $ hg up '.^'
93 $ hg up '.^'
94 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
94 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
95 $ mkcommit new_2_c
95 $ mkcommit new_2_c
96 created new head
96 created new head
97 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
97 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
98 $ hg debugobsolete
98 $ hg debugobsolete
99 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
99 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
100 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
100 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
101
101
102 Register two markers with a missing node
102 Register two markers with a missing node
103
103
104 $ hg up '.^'
104 $ hg up '.^'
105 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
105 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
106 $ mkcommit new_3_c
106 $ mkcommit new_3_c
107 created new head
107 created new head
108 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
108 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
109 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
109 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
110 $ hg debugobsolete
110 $ hg debugobsolete
111 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
111 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
112 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
112 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
113 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
113 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
114 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
114 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
115
115
116 Refuse pathological nullid successors
116 Refuse pathological nullid successors
117 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
117 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
118 transaction abort!
118 transaction abort!
119 rollback completed
119 rollback completed
120 abort: bad obsolescence marker detected: invalid successors nullid
120 abort: bad obsolescence marker detected: invalid successors nullid
121 [255]
121 [255]
122
122
123 Check that graphlog detect that a changeset is obsolete:
123 Check that graphlog detect that a changeset is obsolete:
124
124
125 $ hg log -G
125 $ hg log -G
126 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
126 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
127 |
127 |
128 o 1:7c3bad9141dc (draft) [ ] add b
128 o 1:7c3bad9141dc (draft) [ ] add b
129 |
129 |
130 o 0:1f0dee641bb7 (draft) [ ] add a
130 o 0:1f0dee641bb7 (draft) [ ] add a
131
131
132
132
133 check that heads does not report them
133 check that heads does not report them
134
134
135 $ hg heads
135 $ hg heads
136 5:5601fb93a350 (draft) [tip ] add new_3_c
136 5:5601fb93a350 (draft) [tip ] add new_3_c
137 $ hg heads --hidden
137 $ hg heads --hidden
138 5:5601fb93a350 (draft) [tip ] add new_3_c
138 5:5601fb93a350 (draft) [tip ] add new_3_c
139 4:ca819180edb9 (draft) [ ] add new_2_c
139 4:ca819180edb9 (draft) [ ] add new_2_c
140 3:cdbce2fbb163 (draft) [ ] add new_c
140 3:cdbce2fbb163 (draft) [ ] add new_c
141 2:245bde4270cd (draft) [ ] add original_c
141 2:245bde4270cd (draft) [ ] add original_c
142
142
143
143
144 check that summary does not report them
144 check that summary does not report them
145
145
146 $ hg init ../sink
146 $ hg init ../sink
147 $ echo '[paths]' >> .hg/hgrc
147 $ echo '[paths]' >> .hg/hgrc
148 $ echo 'default=../sink' >> .hg/hgrc
148 $ echo 'default=../sink' >> .hg/hgrc
149 $ hg summary --remote
149 $ hg summary --remote
150 parent: 5:5601fb93a350 tip
150 parent: 5:5601fb93a350 tip
151 add new_3_c
151 add new_3_c
152 branch: default
152 branch: default
153 commit: (clean)
153 commit: (clean)
154 update: (current)
154 update: (current)
155 remote: 3 outgoing
155 remote: 3 outgoing
156
156
157 $ hg summary --remote --hidden
157 $ hg summary --remote --hidden
158 parent: 5:5601fb93a350 tip
158 parent: 5:5601fb93a350 tip
159 add new_3_c
159 add new_3_c
160 branch: default
160 branch: default
161 commit: (clean)
161 commit: (clean)
162 update: 3 new changesets, 4 branch heads (merge)
162 update: 3 new changesets, 4 branch heads (merge)
163 remote: 3 outgoing
163 remote: 3 outgoing
164
164
165 check that various commands work well with filtering
165 check that various commands work well with filtering
166
166
167 $ hg tip
167 $ hg tip
168 5:5601fb93a350 (draft) [tip ] add new_3_c
168 5:5601fb93a350 (draft) [tip ] add new_3_c
169 $ hg log -r 6
169 $ hg log -r 6
170 abort: unknown revision '6'!
170 abort: unknown revision '6'!
171 [255]
171 [255]
172 $ hg log -r 4
172 $ hg log -r 4
173 abort: unknown revision '4'!
173 abort: unknown revision '4'!
174 [255]
174 [255]
175
175
176 Check that public changeset are not accounted as obsolete:
176 Check that public changeset are not accounted as obsolete:
177
177
178 $ hg --hidden phase --public 2
178 $ hg --hidden phase --public 2
179 $ hg log -G
179 $ hg log -G
180 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
180 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
181 |
181 |
182 | o 2:245bde4270cd (public) [ ] add original_c
182 | o 2:245bde4270cd (public) [ ] add original_c
183 |/
183 |/
184 o 1:7c3bad9141dc (public) [ ] add b
184 o 1:7c3bad9141dc (public) [ ] add b
185 |
185 |
186 o 0:1f0dee641bb7 (public) [ ] add a
186 o 0:1f0dee641bb7 (public) [ ] add a
187
187
188
188
189 And that bumped changeset are detected
189 And that bumped changeset are detected
190 --------------------------------------
190 --------------------------------------
191
191
192 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
192 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
193 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
193 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
194 the public changeset
194 the public changeset
195
195
196 $ hg log --hidden -r 'bumped()'
196 $ hg log --hidden -r 'bumped()'
197 5:5601fb93a350 (draft) [tip ] add new_3_c
197 5:5601fb93a350 (draft) [tip ] add new_3_c
198
198
199 And that we can't push bumped changeset
199 And that we can't push bumped changeset
200
200
201 $ hg push ../tmpa -r 0 --force #(make repo related)
201 $ hg push ../tmpa -r 0 --force #(make repo related)
202 pushing to ../tmpa
202 pushing to ../tmpa
203 searching for changes
203 searching for changes
204 warning: repository is unrelated
204 warning: repository is unrelated
205 adding changesets
205 adding changesets
206 adding manifests
206 adding manifests
207 adding file changes
207 adding file changes
208 added 1 changesets with 1 changes to 1 files (+1 heads)
208 added 1 changesets with 1 changes to 1 files (+1 heads)
209 $ hg push ../tmpa
209 $ hg push ../tmpa
210 pushing to ../tmpa
210 pushing to ../tmpa
211 searching for changes
211 searching for changes
212 abort: push includes bumped changeset: 5601fb93a350!
212 abort: push includes bumped changeset: 5601fb93a350!
213 [255]
213 [255]
214
214
215 Fixing "bumped" situation
215 Fixing "bumped" situation
216 We need to create a clone of 5 and add a special marker with a flag
216 We need to create a clone of 5 and add a special marker with a flag
217
217
218 $ hg up '5^'
218 $ hg up '5^'
219 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
219 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
220 $ hg revert -ar 5
220 $ hg revert -ar 5
221 adding new_3_c
221 adding new_3_c
222 $ hg ci -m 'add n3w_3_c'
222 $ hg ci -m 'add n3w_3_c'
223 created new head
223 created new head
224 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
224 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
225 $ hg log -r 'bumped()'
225 $ hg log -r 'bumped()'
226 $ hg log -G
226 $ hg log -G
227 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
227 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
228 |
228 |
229 | o 2:245bde4270cd (public) [ ] add original_c
229 | o 2:245bde4270cd (public) [ ] add original_c
230 |/
230 |/
231 o 1:7c3bad9141dc (public) [ ] add b
231 o 1:7c3bad9141dc (public) [ ] add b
232 |
232 |
233 o 0:1f0dee641bb7 (public) [ ] add a
233 o 0:1f0dee641bb7 (public) [ ] add a
234
234
235
235
236
236
237
237
238 $ cd ..
238 $ cd ..
239
239
240 Exchange Test
240 Exchange Test
241 ============================
241 ============================
242
242
243 Destination repo does not have any data
243 Destination repo does not have any data
244 ---------------------------------------
244 ---------------------------------------
245
245
246 Simple incoming test
246 Simple incoming test
247
247
248 $ hg init tmpc
248 $ hg init tmpc
249 $ cd tmpc
249 $ cd tmpc
250 $ hg incoming ../tmpb
250 $ hg incoming ../tmpb
251 comparing with ../tmpb
251 comparing with ../tmpb
252 0:1f0dee641bb7 (public) [ ] add a
252 0:1f0dee641bb7 (public) [ ] add a
253 1:7c3bad9141dc (public) [ ] add b
253 1:7c3bad9141dc (public) [ ] add b
254 2:245bde4270cd (public) [ ] add original_c
254 2:245bde4270cd (public) [ ] add original_c
255 6:6f9641995072 (draft) [tip ] add n3w_3_c
255 6:6f9641995072 (draft) [tip ] add n3w_3_c
256
256
257 Try to pull markers
257 Try to pull markers
258 (extinct changeset are excluded but marker are pushed)
258 (extinct changeset are excluded but marker are pushed)
259
259
260 $ hg pull ../tmpb
260 $ hg pull ../tmpb
261 pulling from ../tmpb
261 pulling from ../tmpb
262 requesting all changes
262 requesting all changes
263 adding changesets
263 adding changesets
264 adding manifests
264 adding manifests
265 adding file changes
265 adding file changes
266 added 4 changesets with 4 changes to 4 files (+1 heads)
266 added 4 changesets with 4 changes to 4 files (+1 heads)
267 (run 'hg heads' to see heads, 'hg merge' to merge)
267 (run 'hg heads' to see heads, 'hg merge' to merge)
268 $ hg debugobsolete
268 $ hg debugobsolete
269 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
269 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
270 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
270 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
271 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
271 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
272 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
272 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
273 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
273 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
274
274
275 Rollback//Transaction support
275 Rollback//Transaction support
276
276
277 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
277 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
278 $ hg debugobsolete
278 $ hg debugobsolete
279 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
279 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
280 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
280 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
281 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
281 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
282 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
282 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
283 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
283 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
284 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 {'date': '1340 0', 'user': 'test'}
284 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 {'date': '1340 0', 'user': 'test'}
285 $ hg rollback -n
285 $ hg rollback -n
286 repository tip rolled back to revision 3 (undo debugobsolete)
286 repository tip rolled back to revision 3 (undo debugobsolete)
287 $ hg rollback
287 $ hg rollback
288 repository tip rolled back to revision 3 (undo debugobsolete)
288 repository tip rolled back to revision 3 (undo debugobsolete)
289 $ hg debugobsolete
289 $ hg debugobsolete
290 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
290 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
291 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
291 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
292 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
292 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
293 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
293 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
294 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
294 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
295
295
296 $ cd ..
296 $ cd ..
297
297
298 Try to push markers
298 Try to push markers
299
299
300 $ hg init tmpd
300 $ hg init tmpd
301 $ hg -R tmpb push tmpd
301 $ hg -R tmpb push tmpd
302 pushing to tmpd
302 pushing to tmpd
303 searching for changes
303 searching for changes
304 adding changesets
304 adding changesets
305 adding manifests
305 adding manifests
306 adding file changes
306 adding file changes
307 added 4 changesets with 4 changes to 4 files (+1 heads)
307 added 4 changesets with 4 changes to 4 files (+1 heads)
308 $ hg -R tmpd debugobsolete
308 $ hg -R tmpd debugobsolete
309 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
309 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
310 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
310 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
311 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
311 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
312 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
312 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
313 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
313 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
314
314
315 Check obsolete keys are exchanged only if source has an obsolete store
315 Check obsolete keys are exchanged only if source has an obsolete store
316
316
317 $ hg init empty
317 $ hg init empty
318 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
318 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
319 pushing to tmpd
319 pushing to tmpd
320 listkeys phases
320 no changes found
321 no changes found
321 listkeys phases
322 listkeys phases
322 listkeys bookmarks
323 listkeys bookmarks
323 [1]
324 [1]
324
325
325 clone support
326 clone support
326 (markers are copied and extinct changesets are included to allow hardlinks)
327 (markers are copied and extinct changesets are included to allow hardlinks)
327
328
328 $ hg clone tmpb clone-dest
329 $ hg clone tmpb clone-dest
329 updating to branch default
330 updating to branch default
330 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 $ hg -R clone-dest log -G --hidden
332 $ hg -R clone-dest log -G --hidden
332 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
333 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
333 |
334 |
334 | x 5:5601fb93a350 (draft) [ ] add new_3_c
335 | x 5:5601fb93a350 (draft) [ ] add new_3_c
335 |/
336 |/
336 | x 4:ca819180edb9 (draft) [ ] add new_2_c
337 | x 4:ca819180edb9 (draft) [ ] add new_2_c
337 |/
338 |/
338 | x 3:cdbce2fbb163 (draft) [ ] add new_c
339 | x 3:cdbce2fbb163 (draft) [ ] add new_c
339 |/
340 |/
340 | o 2:245bde4270cd (public) [ ] add original_c
341 | o 2:245bde4270cd (public) [ ] add original_c
341 |/
342 |/
342 o 1:7c3bad9141dc (public) [ ] add b
343 o 1:7c3bad9141dc (public) [ ] add b
343 |
344 |
344 o 0:1f0dee641bb7 (public) [ ] add a
345 o 0:1f0dee641bb7 (public) [ ] add a
345
346
346 $ hg -R clone-dest debugobsolete
347 $ hg -R clone-dest debugobsolete
347 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
348 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
348 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
349 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
349 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
350 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
350 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
351 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
351 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
352 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
352
353
353
354
354 Destination repo have existing data
355 Destination repo have existing data
355 ---------------------------------------
356 ---------------------------------------
356
357
357 On pull
358 On pull
358
359
359 $ hg init tmpe
360 $ hg init tmpe
360 $ cd tmpe
361 $ cd tmpe
361 $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
362 $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
362 $ hg pull ../tmpb
363 $ hg pull ../tmpb
363 pulling from ../tmpb
364 pulling from ../tmpb
364 requesting all changes
365 requesting all changes
365 adding changesets
366 adding changesets
366 adding manifests
367 adding manifests
367 adding file changes
368 adding file changes
368 added 4 changesets with 4 changes to 4 files (+1 heads)
369 added 4 changesets with 4 changes to 4 files (+1 heads)
369 (run 'hg heads' to see heads, 'hg merge' to merge)
370 (run 'hg heads' to see heads, 'hg merge' to merge)
370 $ hg debugobsolete
371 $ hg debugobsolete
371 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
372 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
372 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
373 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
373 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
374 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
374 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
375 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
375 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
376 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
376 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
377 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
377
378
378
379
379 On push
380 On push
380
381
381 $ hg push ../tmpc
382 $ hg push ../tmpc
382 pushing to ../tmpc
383 pushing to ../tmpc
383 searching for changes
384 searching for changes
384 no changes found
385 no changes found
385 [1]
386 [1]
386 $ hg -R ../tmpc debugobsolete
387 $ hg -R ../tmpc debugobsolete
387 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
388 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
388 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
389 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
389 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
390 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
390 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
391 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
391 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
392 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
392 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
393 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
393
394
394 detect outgoing obsolete and unstable
395 detect outgoing obsolete and unstable
395 ---------------------------------------
396 ---------------------------------------
396
397
397
398
398 $ hg log -G
399 $ hg log -G
399 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
400 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
400 |
401 |
401 | o 2:245bde4270cd (public) [ ] add original_c
402 | o 2:245bde4270cd (public) [ ] add original_c
402 |/
403 |/
403 o 1:7c3bad9141dc (public) [ ] add b
404 o 1:7c3bad9141dc (public) [ ] add b
404 |
405 |
405 o 0:1f0dee641bb7 (public) [ ] add a
406 o 0:1f0dee641bb7 (public) [ ] add a
406
407
407 $ hg up 'desc("n3w_3_c")'
408 $ hg up 'desc("n3w_3_c")'
408 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
409 $ mkcommit original_d
410 $ mkcommit original_d
410 $ mkcommit original_e
411 $ mkcommit original_e
411 $ hg debugobsolete `getid original_d` -d '0 0'
412 $ hg debugobsolete `getid original_d` -d '0 0'
412 $ hg log -r 'obsolete()'
413 $ hg log -r 'obsolete()'
413 4:94b33453f93b (draft) [ ] add original_d
414 4:94b33453f93b (draft) [ ] add original_d
414 $ hg log -G -r '::unstable()'
415 $ hg log -G -r '::unstable()'
415 @ 5:cda648ca50f5 (draft) [tip ] add original_e
416 @ 5:cda648ca50f5 (draft) [tip ] add original_e
416 |
417 |
417 x 4:94b33453f93b (draft) [ ] add original_d
418 x 4:94b33453f93b (draft) [ ] add original_d
418 |
419 |
419 o 3:6f9641995072 (draft) [ ] add n3w_3_c
420 o 3:6f9641995072 (draft) [ ] add n3w_3_c
420 |
421 |
421 o 1:7c3bad9141dc (public) [ ] add b
422 o 1:7c3bad9141dc (public) [ ] add b
422 |
423 |
423 o 0:1f0dee641bb7 (public) [ ] add a
424 o 0:1f0dee641bb7 (public) [ ] add a
424
425
425
426
426 refuse to push obsolete changeset
427 refuse to push obsolete changeset
427
428
428 $ hg push ../tmpc/ -r 'desc("original_d")'
429 $ hg push ../tmpc/ -r 'desc("original_d")'
429 pushing to ../tmpc/
430 pushing to ../tmpc/
430 searching for changes
431 searching for changes
431 abort: push includes obsolete changeset: 94b33453f93b!
432 abort: push includes obsolete changeset: 94b33453f93b!
432 [255]
433 [255]
433
434
434 refuse to push unstable changeset
435 refuse to push unstable changeset
435
436
436 $ hg push ../tmpc/
437 $ hg push ../tmpc/
437 pushing to ../tmpc/
438 pushing to ../tmpc/
438 searching for changes
439 searching for changes
439 abort: push includes unstable changeset: cda648ca50f5!
440 abort: push includes unstable changeset: cda648ca50f5!
440 [255]
441 [255]
441
442
442 Test that extinct changeset are properly detected
443 Test that extinct changeset are properly detected
443
444
444 $ hg log -r 'extinct()'
445 $ hg log -r 'extinct()'
445
446
446 Don't try to push extinct changeset
447 Don't try to push extinct changeset
447
448
448 $ hg init ../tmpf
449 $ hg init ../tmpf
449 $ hg out ../tmpf
450 $ hg out ../tmpf
450 comparing with ../tmpf
451 comparing with ../tmpf
451 searching for changes
452 searching for changes
452 0:1f0dee641bb7 (public) [ ] add a
453 0:1f0dee641bb7 (public) [ ] add a
453 1:7c3bad9141dc (public) [ ] add b
454 1:7c3bad9141dc (public) [ ] add b
454 2:245bde4270cd (public) [ ] add original_c
455 2:245bde4270cd (public) [ ] add original_c
455 3:6f9641995072 (draft) [ ] add n3w_3_c
456 3:6f9641995072 (draft) [ ] add n3w_3_c
456 4:94b33453f93b (draft) [ ] add original_d
457 4:94b33453f93b (draft) [ ] add original_d
457 5:cda648ca50f5 (draft) [tip ] add original_e
458 5:cda648ca50f5 (draft) [tip ] add original_e
458 $ hg push ../tmpf -f # -f because be push unstable too
459 $ hg push ../tmpf -f # -f because be push unstable too
459 pushing to ../tmpf
460 pushing to ../tmpf
460 searching for changes
461 searching for changes
461 adding changesets
462 adding changesets
462 adding manifests
463 adding manifests
463 adding file changes
464 adding file changes
464 added 6 changesets with 6 changes to 6 files (+1 heads)
465 added 6 changesets with 6 changes to 6 files (+1 heads)
465
466
466 no warning displayed
467 no warning displayed
467
468
468 $ hg push ../tmpf
469 $ hg push ../tmpf
469 pushing to ../tmpf
470 pushing to ../tmpf
470 searching for changes
471 searching for changes
471 no changes found
472 no changes found
472 [1]
473 [1]
473
474
474 Do not warn about new head when the new head is a successors of a remote one
475 Do not warn about new head when the new head is a successors of a remote one
475
476
476 $ hg log -G
477 $ hg log -G
477 @ 5:cda648ca50f5 (draft) [tip ] add original_e
478 @ 5:cda648ca50f5 (draft) [tip ] add original_e
478 |
479 |
479 x 4:94b33453f93b (draft) [ ] add original_d
480 x 4:94b33453f93b (draft) [ ] add original_d
480 |
481 |
481 o 3:6f9641995072 (draft) [ ] add n3w_3_c
482 o 3:6f9641995072 (draft) [ ] add n3w_3_c
482 |
483 |
483 | o 2:245bde4270cd (public) [ ] add original_c
484 | o 2:245bde4270cd (public) [ ] add original_c
484 |/
485 |/
485 o 1:7c3bad9141dc (public) [ ] add b
486 o 1:7c3bad9141dc (public) [ ] add b
486 |
487 |
487 o 0:1f0dee641bb7 (public) [ ] add a
488 o 0:1f0dee641bb7 (public) [ ] add a
488
489
489 $ hg up -q 'desc(n3w_3_c)'
490 $ hg up -q 'desc(n3w_3_c)'
490 $ mkcommit obsolete_e
491 $ mkcommit obsolete_e
491 created new head
492 created new head
492 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
493 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
493 $ hg outgoing ../tmpf # parasite hg outgoing testin
494 $ hg outgoing ../tmpf # parasite hg outgoing testin
494 comparing with ../tmpf
495 comparing with ../tmpf
495 searching for changes
496 searching for changes
496 6:3de5eca88c00 (draft) [tip ] add obsolete_e
497 6:3de5eca88c00 (draft) [tip ] add obsolete_e
497 $ hg push ../tmpf
498 $ hg push ../tmpf
498 pushing to ../tmpf
499 pushing to ../tmpf
499 searching for changes
500 searching for changes
500 adding changesets
501 adding changesets
501 adding manifests
502 adding manifests
502 adding file changes
503 adding file changes
503 added 1 changesets with 1 changes to 1 files (+1 heads)
504 added 1 changesets with 1 changes to 1 files (+1 heads)
504
505
505 #if serve
506 #if serve
506
507
507 check hgweb does not explode
508 check hgweb does not explode
508 ====================================
509 ====================================
509
510
510 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
511 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
511 adding changesets
512 adding changesets
512 adding manifests
513 adding manifests
513 adding file changes
514 adding file changes
514 added 62 changesets with 63 changes to 9 files (+60 heads)
515 added 62 changesets with 63 changes to 9 files (+60 heads)
515 (run 'hg heads .' to see heads, 'hg merge' to merge)
516 (run 'hg heads .' to see heads, 'hg merge' to merge)
516 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
517 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
517 > do
518 > do
518 > hg debugobsolete $node
519 > hg debugobsolete $node
519 > done
520 > done
520 $ hg up tip
521 $ hg up tip
521 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
522 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
522
523
523 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
524 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
524 $ cat hg.pid >> $DAEMON_PIDS
525 $ cat hg.pid >> $DAEMON_PIDS
525
526
526 check changelog view
527 check changelog view
527
528
528 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'shortlog/'
529 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'shortlog/'
529 200 Script output follows
530 200 Script output follows
530
531
531 check graph view
532 check graph view
532
533
533 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'graph'
534 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'graph'
534 200 Script output follows
535 200 Script output follows
535
536
536 check filelog view
537 check filelog view
537
538
538 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'log/'`hg id --debug --id`/'babar'
539 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'log/'`hg id --debug --id`/'babar'
539 200 Script output follows
540 200 Script output follows
540
541
541 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/68'
542 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/68'
542 200 Script output follows
543 200 Script output follows
543 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/67'
544 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/67'
544 404 Not Found
545 404 Not Found
545 [1]
546 [1]
546
547
547 check that web.view config option:
548 check that web.view config option:
548
549
549 $ "$TESTDIR/killdaemons.py" hg.pid
550 $ "$TESTDIR/killdaemons.py" hg.pid
550 $ cat >> .hg/hgrc << EOF
551 $ cat >> .hg/hgrc << EOF
551 > [web]
552 > [web]
552 > view=all
553 > view=all
553 > EOF
554 > EOF
554 $ wait
555 $ wait
555 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
556 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
556 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/67'
557 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'rev/67'
557 200 Script output follows
558 200 Script output follows
558 $ "$TESTDIR/killdaemons.py" hg.pid
559 $ "$TESTDIR/killdaemons.py" hg.pid
559
560
560 Checking _enable=False warning if obsolete marker exists
561 Checking _enable=False warning if obsolete marker exists
561
562
562 $ echo '[extensions]' >> $HGRCPATH
563 $ echo '[extensions]' >> $HGRCPATH
563 $ echo "obs=!" >> $HGRCPATH
564 $ echo "obs=!" >> $HGRCPATH
564 $ hg log -r tip
565 $ hg log -r tip
565 obsolete feature not enabled but 68 markers found!
566 obsolete feature not enabled but 68 markers found!
566 68:c15e9edfca13 (draft) [tip ] add celestine
567 68:c15e9edfca13 (draft) [tip ] add celestine
567
568
568 reenable for later test
569 reenable for later test
569
570
570 $ echo '[extensions]' >> $HGRCPATH
571 $ echo '[extensions]' >> $HGRCPATH
571 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
572 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
572
573
573 #endif
574 #endif
574
575
575 Test incoming/outcoming with changesets obsoleted remotely, known locally
576 Test incoming/outcoming with changesets obsoleted remotely, known locally
576 ===============================================================================
577 ===============================================================================
577
578
578 This test issue 3805
579 This test issue 3805
579
580
580 $ hg init repo-issue3805
581 $ hg init repo-issue3805
581 $ cd repo-issue3805
582 $ cd repo-issue3805
582 $ echo "foo" > foo
583 $ echo "foo" > foo
583 $ hg ci -Am "A"
584 $ hg ci -Am "A"
584 adding foo
585 adding foo
585 $ hg clone . ../other-issue3805
586 $ hg clone . ../other-issue3805
586 updating to branch default
587 updating to branch default
587 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 $ echo "bar" >> foo
589 $ echo "bar" >> foo
589 $ hg ci --amend
590 $ hg ci --amend
590 $ cd ../other-issue3805
591 $ cd ../other-issue3805
591 $ hg log -G
592 $ hg log -G
592 @ 0:193e9254ce7e (draft) [tip ] A
593 @ 0:193e9254ce7e (draft) [tip ] A
593
594
594 $ hg log -G -R ../repo-issue3805
595 $ hg log -G -R ../repo-issue3805
595 @ 2:3816541e5485 (draft) [tip ] A
596 @ 2:3816541e5485 (draft) [tip ] A
596
597
597 $ hg incoming
598 $ hg incoming
598 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
599 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
599 searching for changes
600 searching for changes
600 2:3816541e5485 (draft) [tip ] A
601 2:3816541e5485 (draft) [tip ] A
601 $ hg incoming --bundle ../issue3805.hg
602 $ hg incoming --bundle ../issue3805.hg
602 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
603 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
603 searching for changes
604 searching for changes
604 2:3816541e5485 (draft) [tip ] A
605 2:3816541e5485 (draft) [tip ] A
605 $ hg outgoing
606 $ hg outgoing
606 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
607 comparing with $TESTTMP/tmpe/repo-issue3805 (glob)
607 searching for changes
608 searching for changes
608 no changes found
609 no changes found
609 [1]
610 [1]
610
611
611 #if serve
612 #if serve
612
613
613 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
614 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
614 $ cat hg.pid >> $DAEMON_PIDS
615 $ cat hg.pid >> $DAEMON_PIDS
615
616
616 $ hg incoming http://localhost:$HGPORT
617 $ hg incoming http://localhost:$HGPORT
617 comparing with http://localhost:$HGPORT/
618 comparing with http://localhost:$HGPORT/
618 searching for changes
619 searching for changes
619 1:3816541e5485 (public) [tip ] A
620 1:3816541e5485 (public) [tip ] A
620 $ hg outgoing http://localhost:$HGPORT
621 $ hg outgoing http://localhost:$HGPORT
621 comparing with http://localhost:$HGPORT/
622 comparing with http://localhost:$HGPORT/
622 searching for changes
623 searching for changes
623 no changes found
624 no changes found
624 [1]
625 [1]
625
626
626 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
627 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
627
628
628 #endif
629 #endif
629
630
630 This test issue 3814
631 This test issue 3814
631
632
632 (nothing to push but locally hidden changeset)
633 (nothing to push but locally hidden changeset)
633
634
634 $ cd ..
635 $ cd ..
635 $ hg init repo-issue3814
636 $ hg init repo-issue3814
636 $ cd repo-issue3805
637 $ cd repo-issue3805
637 $ hg push -r 3816541e5485 ../repo-issue3814
638 $ hg push -r 3816541e5485 ../repo-issue3814
638 pushing to ../repo-issue3814
639 pushing to ../repo-issue3814
639 searching for changes
640 searching for changes
640 adding changesets
641 adding changesets
641 adding manifests
642 adding manifests
642 adding file changes
643 adding file changes
643 added 1 changesets with 1 changes to 1 files
644 added 1 changesets with 1 changes to 1 files
644 $ hg out ../repo-issue3814
645 $ hg out ../repo-issue3814
645 comparing with ../repo-issue3814
646 comparing with ../repo-issue3814
646 searching for changes
647 searching for changes
647 no changes found
648 no changes found
648 [1]
649 [1]
649
650
650 Test that a local tag blocks a changeset from being hidden
651 Test that a local tag blocks a changeset from being hidden
651
652
652 $ hg tag -l visible -r 0 --hidden
653 $ hg tag -l visible -r 0 --hidden
653 $ hg log -G
654 $ hg log -G
654 @ 2:3816541e5485 (draft) [tip ] A
655 @ 2:3816541e5485 (draft) [tip ] A
655
656
656 x 0:193e9254ce7e (draft) [visible ] A
657 x 0:193e9254ce7e (draft) [visible ] A
657
658
658 Test that removing a local tag does not cause some commands to fail
659 Test that removing a local tag does not cause some commands to fail
659
660
660 $ hg tag -l -r tip tiptag
661 $ hg tag -l -r tip tiptag
661 $ hg tags
662 $ hg tags
662 tiptag 2:3816541e5485
663 tiptag 2:3816541e5485
663 tip 2:3816541e5485
664 tip 2:3816541e5485
664 visible 0:193e9254ce7e
665 visible 0:193e9254ce7e
665 $ hg --config extensions.strip= strip -r tip --no-backup
666 $ hg --config extensions.strip= strip -r tip --no-backup
666 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
667 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
667 $ hg tags
668 $ hg tags
668 visible 0:193e9254ce7e
669 visible 0:193e9254ce7e
669 tip 0:193e9254ce7e
670 tip 0:193e9254ce7e
@@ -1,774 +1,775 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo foo > t1
3 $ echo foo > t1
4 $ hg add t1
4 $ hg add t1
5 $ hg commit -m "1"
5 $ hg commit -m "1"
6
6
7 $ cd ..
7 $ cd ..
8 $ hg clone a b
8 $ hg clone a b
9 updating to branch default
9 updating to branch default
10 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
11
11
12 $ cd a
12 $ cd a
13 $ echo foo > t2
13 $ echo foo > t2
14 $ hg add t2
14 $ hg add t2
15 $ hg commit -m "2"
15 $ hg commit -m "2"
16
16
17 $ cd ../b
17 $ cd ../b
18 $ echo foo > t3
18 $ echo foo > t3
19 $ hg add t3
19 $ hg add t3
20 $ hg commit -m "3"
20 $ hg commit -m "3"
21
21
22 $ hg push ../a
22 $ hg push ../a
23 pushing to ../a
23 pushing to ../a
24 searching for changes
24 searching for changes
25 remote has heads on branch 'default' that are not known locally: 1c9246a22a0a
25 remote has heads on branch 'default' that are not known locally: 1c9246a22a0a
26 abort: push creates new remote head 1e108cc5548c!
26 abort: push creates new remote head 1e108cc5548c!
27 (pull and merge or see "hg help push" for details about pushing new heads)
27 (pull and merge or see "hg help push" for details about pushing new heads)
28 [255]
28 [255]
29
29
30 $ hg push --debug ../a
30 $ hg push --debug ../a
31 pushing to ../a
31 pushing to ../a
32 query 1; heads
32 query 1; heads
33 searching for changes
33 searching for changes
34 taking quick initial sample
34 taking quick initial sample
35 searching: 2 queries
35 searching: 2 queries
36 query 2; still undecided: 1, sample size is: 1
36 query 2; still undecided: 1, sample size is: 1
37 2 total queries
37 2 total queries
38 listing keys for "phases"
38 listing keys for "bookmarks"
39 listing keys for "bookmarks"
39 remote has heads on branch 'default' that are not known locally: 1c9246a22a0a
40 remote has heads on branch 'default' that are not known locally: 1c9246a22a0a
40 new remote heads on branch 'default':
41 new remote heads on branch 'default':
41 1e108cc5548c
42 1e108cc5548c
42 abort: push creates new remote head 1e108cc5548c!
43 abort: push creates new remote head 1e108cc5548c!
43 (pull and merge or see "hg help push" for details about pushing new heads)
44 (pull and merge or see "hg help push" for details about pushing new heads)
44 [255]
45 [255]
45
46
46 $ hg pull ../a
47 $ hg pull ../a
47 pulling from ../a
48 pulling from ../a
48 searching for changes
49 searching for changes
49 adding changesets
50 adding changesets
50 adding manifests
51 adding manifests
51 adding file changes
52 adding file changes
52 added 1 changesets with 1 changes to 1 files (+1 heads)
53 added 1 changesets with 1 changes to 1 files (+1 heads)
53 (run 'hg heads' to see heads, 'hg merge' to merge)
54 (run 'hg heads' to see heads, 'hg merge' to merge)
54
55
55 $ hg push ../a
56 $ hg push ../a
56 pushing to ../a
57 pushing to ../a
57 searching for changes
58 searching for changes
58 abort: push creates new remote head 1e108cc5548c!
59 abort: push creates new remote head 1e108cc5548c!
59 (merge or see "hg help push" for details about pushing new heads)
60 (merge or see "hg help push" for details about pushing new heads)
60 [255]
61 [255]
61
62
62 $ hg merge
63 $ hg merge
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 (branch merge, don't forget to commit)
65 (branch merge, don't forget to commit)
65
66
66 $ hg commit -m "4"
67 $ hg commit -m "4"
67 $ hg push ../a
68 $ hg push ../a
68 pushing to ../a
69 pushing to ../a
69 searching for changes
70 searching for changes
70 adding changesets
71 adding changesets
71 adding manifests
72 adding manifests
72 adding file changes
73 adding file changes
73 added 2 changesets with 1 changes to 1 files
74 added 2 changesets with 1 changes to 1 files
74
75
75 $ cd ..
76 $ cd ..
76
77
77 $ hg init c
78 $ hg init c
78 $ cd c
79 $ cd c
79 $ for i in 0 1 2; do
80 $ for i in 0 1 2; do
80 > echo $i >> foo
81 > echo $i >> foo
81 > hg ci -Am $i
82 > hg ci -Am $i
82 > done
83 > done
83 adding foo
84 adding foo
84 $ cd ..
85 $ cd ..
85
86
86 $ hg clone c d
87 $ hg clone c d
87 updating to branch default
88 updating to branch default
88 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
89
90
90 $ cd d
91 $ cd d
91 $ for i in 0 1; do
92 $ for i in 0 1; do
92 > hg co -C $i
93 > hg co -C $i
93 > echo d-$i >> foo
94 > echo d-$i >> foo
94 > hg ci -m d-$i
95 > hg ci -m d-$i
95 > done
96 > done
96 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 created new head
98 created new head
98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 created new head
100 created new head
100
101
101 $ HGMERGE=true hg merge 3
102 $ HGMERGE=true hg merge 3
102 merging foo
103 merging foo
103 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
104 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
104 (branch merge, don't forget to commit)
105 (branch merge, don't forget to commit)
105
106
106 $ hg ci -m c-d
107 $ hg ci -m c-d
107
108
108 $ hg push ../c
109 $ hg push ../c
109 pushing to ../c
110 pushing to ../c
110 searching for changes
111 searching for changes
111 abort: push creates new remote head 6346d66eb9f5!
112 abort: push creates new remote head 6346d66eb9f5!
112 (merge or see "hg help push" for details about pushing new heads)
113 (merge or see "hg help push" for details about pushing new heads)
113 [255]
114 [255]
114
115
115 $ hg push -r 2 ../c
116 $ hg push -r 2 ../c
116 pushing to ../c
117 pushing to ../c
117 searching for changes
118 searching for changes
118 no changes found
119 no changes found
119 [1]
120 [1]
120
121
121 $ hg push -r 3 ../c
122 $ hg push -r 3 ../c
122 pushing to ../c
123 pushing to ../c
123 searching for changes
124 searching for changes
124 abort: push creates new remote head a5dda829a167!
125 abort: push creates new remote head a5dda829a167!
125 (merge or see "hg help push" for details about pushing new heads)
126 (merge or see "hg help push" for details about pushing new heads)
126 [255]
127 [255]
127
128
128 $ hg push -v -r 3 -r 4 ../c
129 $ hg push -v -r 3 -r 4 ../c
129 pushing to ../c
130 pushing to ../c
130 searching for changes
131 searching for changes
131 new remote heads on branch 'default':
132 new remote heads on branch 'default':
132 a5dda829a167
133 a5dda829a167
133 ee8fbc7a0295
134 ee8fbc7a0295
134 abort: push creates new remote head a5dda829a167!
135 abort: push creates new remote head a5dda829a167!
135 (merge or see "hg help push" for details about pushing new heads)
136 (merge or see "hg help push" for details about pushing new heads)
136 [255]
137 [255]
137
138
138 $ hg push -v -f -r 3 -r 4 ../c
139 $ hg push -v -f -r 3 -r 4 ../c
139 pushing to ../c
140 pushing to ../c
140 searching for changes
141 searching for changes
141 2 changesets found
142 2 changesets found
142 adding changesets
143 adding changesets
143 adding manifests
144 adding manifests
144 adding file changes
145 adding file changes
145 added 2 changesets with 2 changes to 1 files (+2 heads)
146 added 2 changesets with 2 changes to 1 files (+2 heads)
146
147
147 $ hg push -r 5 ../c
148 $ hg push -r 5 ../c
148 pushing to ../c
149 pushing to ../c
149 searching for changes
150 searching for changes
150 adding changesets
151 adding changesets
151 adding manifests
152 adding manifests
152 adding file changes
153 adding file changes
153 added 1 changesets with 1 changes to 1 files (-1 heads)
154 added 1 changesets with 1 changes to 1 files (-1 heads)
154
155
155 $ hg in ../c
156 $ hg in ../c
156 comparing with ../c
157 comparing with ../c
157 searching for changes
158 searching for changes
158 no changes found
159 no changes found
159 [1]
160 [1]
160
161
161
162
162 Issue450: push -r warns about remote head creation even if no heads
163 Issue450: push -r warns about remote head creation even if no heads
163 will be created
164 will be created
164
165
165 $ hg init ../e
166 $ hg init ../e
166 $ hg push -r 0 ../e
167 $ hg push -r 0 ../e
167 pushing to ../e
168 pushing to ../e
168 searching for changes
169 searching for changes
169 adding changesets
170 adding changesets
170 adding manifests
171 adding manifests
171 adding file changes
172 adding file changes
172 added 1 changesets with 1 changes to 1 files
173 added 1 changesets with 1 changes to 1 files
173
174
174 $ hg push -r 1 ../e
175 $ hg push -r 1 ../e
175 pushing to ../e
176 pushing to ../e
176 searching for changes
177 searching for changes
177 adding changesets
178 adding changesets
178 adding manifests
179 adding manifests
179 adding file changes
180 adding file changes
180 added 1 changesets with 1 changes to 1 files
181 added 1 changesets with 1 changes to 1 files
181
182
182 $ cd ..
183 $ cd ..
183
184
184
185
185 Issue736: named branches are not considered for detection of
186 Issue736: named branches are not considered for detection of
186 unmerged heads in "hg push"
187 unmerged heads in "hg push"
187
188
188 $ hg init f
189 $ hg init f
189 $ cd f
190 $ cd f
190 $ hg -q branch a
191 $ hg -q branch a
191 $ echo 0 > foo
192 $ echo 0 > foo
192 $ hg -q ci -Am 0
193 $ hg -q ci -Am 0
193 $ echo 1 > foo
194 $ echo 1 > foo
194 $ hg -q ci -m 1
195 $ hg -q ci -m 1
195 $ hg -q up 0
196 $ hg -q up 0
196 $ echo 2 > foo
197 $ echo 2 > foo
197 $ hg -q ci -m 2
198 $ hg -q ci -m 2
198 $ hg -q up 0
199 $ hg -q up 0
199 $ hg -q branch b
200 $ hg -q branch b
200 $ echo 3 > foo
201 $ echo 3 > foo
201 $ hg -q ci -m 3
202 $ hg -q ci -m 3
202 $ cd ..
203 $ cd ..
203
204
204 $ hg -q clone f g
205 $ hg -q clone f g
205 $ cd g
206 $ cd g
206
207
207 Push on existing branch and new branch:
208 Push on existing branch and new branch:
208
209
209 $ hg -q up 1
210 $ hg -q up 1
210 $ echo 4 > foo
211 $ echo 4 > foo
211 $ hg -q ci -m 4
212 $ hg -q ci -m 4
212 $ hg -q up 0
213 $ hg -q up 0
213 $ echo 5 > foo
214 $ echo 5 > foo
214 $ hg -q branch c
215 $ hg -q branch c
215 $ hg -q ci -m 5
216 $ hg -q ci -m 5
216
217
217 $ hg push ../f
218 $ hg push ../f
218 pushing to ../f
219 pushing to ../f
219 searching for changes
220 searching for changes
220 abort: push creates new remote branches: c!
221 abort: push creates new remote branches: c!
221 (use 'hg push --new-branch' to create new remote branches)
222 (use 'hg push --new-branch' to create new remote branches)
222 [255]
223 [255]
223
224
224 $ hg push -r 4 -r 5 ../f
225 $ hg push -r 4 -r 5 ../f
225 pushing to ../f
226 pushing to ../f
226 searching for changes
227 searching for changes
227 abort: push creates new remote branches: c!
228 abort: push creates new remote branches: c!
228 (use 'hg push --new-branch' to create new remote branches)
229 (use 'hg push --new-branch' to create new remote branches)
229 [255]
230 [255]
230
231
231
232
232 Multiple new branches:
233 Multiple new branches:
233
234
234 $ hg -q branch d
235 $ hg -q branch d
235 $ echo 6 > foo
236 $ echo 6 > foo
236 $ hg -q ci -m 6
237 $ hg -q ci -m 6
237
238
238 $ hg push ../f
239 $ hg push ../f
239 pushing to ../f
240 pushing to ../f
240 searching for changes
241 searching for changes
241 abort: push creates new remote branches: c, d!
242 abort: push creates new remote branches: c, d!
242 (use 'hg push --new-branch' to create new remote branches)
243 (use 'hg push --new-branch' to create new remote branches)
243 [255]
244 [255]
244
245
245 $ hg push -r 4 -r 6 ../f
246 $ hg push -r 4 -r 6 ../f
246 pushing to ../f
247 pushing to ../f
247 searching for changes
248 searching for changes
248 abort: push creates new remote branches: c, d!
249 abort: push creates new remote branches: c, d!
249 (use 'hg push --new-branch' to create new remote branches)
250 (use 'hg push --new-branch' to create new remote branches)
250 [255]
251 [255]
251
252
252 $ cd ../g
253 $ cd ../g
253
254
254
255
255 Fail on multiple head push:
256 Fail on multiple head push:
256
257
257 $ hg -q up 1
258 $ hg -q up 1
258 $ echo 7 > foo
259 $ echo 7 > foo
259 $ hg -q ci -m 7
260 $ hg -q ci -m 7
260
261
261 $ hg push -r 4 -r 7 ../f
262 $ hg push -r 4 -r 7 ../f
262 pushing to ../f
263 pushing to ../f
263 searching for changes
264 searching for changes
264 abort: push creates new remote head 0b715ef6ff8f on branch 'a'!
265 abort: push creates new remote head 0b715ef6ff8f on branch 'a'!
265 (merge or see "hg help push" for details about pushing new heads)
266 (merge or see "hg help push" for details about pushing new heads)
266 [255]
267 [255]
267
268
268 Push replacement head on existing branches:
269 Push replacement head on existing branches:
269
270
270 $ hg -q up 3
271 $ hg -q up 3
271 $ echo 8 > foo
272 $ echo 8 > foo
272 $ hg -q ci -m 8
273 $ hg -q ci -m 8
273
274
274 $ hg push -r 7 -r 8 ../f
275 $ hg push -r 7 -r 8 ../f
275 pushing to ../f
276 pushing to ../f
276 searching for changes
277 searching for changes
277 adding changesets
278 adding changesets
278 adding manifests
279 adding manifests
279 adding file changes
280 adding file changes
280 added 2 changesets with 2 changes to 1 files
281 added 2 changesets with 2 changes to 1 files
281
282
282
283
283 Merge of branch a to other branch b followed by unrelated push
284 Merge of branch a to other branch b followed by unrelated push
284 on branch a:
285 on branch a:
285
286
286 $ hg -q up 7
287 $ hg -q up 7
287 $ HGMERGE=true hg -q merge 8
288 $ HGMERGE=true hg -q merge 8
288 $ hg -q ci -m 9
289 $ hg -q ci -m 9
289 $ hg -q up 8
290 $ hg -q up 8
290 $ echo 10 > foo
291 $ echo 10 > foo
291 $ hg -q ci -m 10
292 $ hg -q ci -m 10
292
293
293 $ hg push -r 9 ../f
294 $ hg push -r 9 ../f
294 pushing to ../f
295 pushing to ../f
295 searching for changes
296 searching for changes
296 adding changesets
297 adding changesets
297 adding manifests
298 adding manifests
298 adding file changes
299 adding file changes
299 added 1 changesets with 1 changes to 1 files (-1 heads)
300 added 1 changesets with 1 changes to 1 files (-1 heads)
300
301
301 $ hg push -r 10 ../f
302 $ hg push -r 10 ../f
302 pushing to ../f
303 pushing to ../f
303 searching for changes
304 searching for changes
304 adding changesets
305 adding changesets
305 adding manifests
306 adding manifests
306 adding file changes
307 adding file changes
307 added 1 changesets with 1 changes to 1 files (+1 heads)
308 added 1 changesets with 1 changes to 1 files (+1 heads)
308
309
309
310
310 Cheating the counting algorithm:
311 Cheating the counting algorithm:
311
312
312 $ hg -q up 9
313 $ hg -q up 9
313 $ HGMERGE=true hg -q merge 2
314 $ HGMERGE=true hg -q merge 2
314 $ hg -q ci -m 11
315 $ hg -q ci -m 11
315 $ hg -q up 1
316 $ hg -q up 1
316 $ echo 12 > foo
317 $ echo 12 > foo
317 $ hg -q ci -m 12
318 $ hg -q ci -m 12
318
319
319 $ hg push -r 11 -r 12 ../f
320 $ hg push -r 11 -r 12 ../f
320 pushing to ../f
321 pushing to ../f
321 searching for changes
322 searching for changes
322 adding changesets
323 adding changesets
323 adding manifests
324 adding manifests
324 adding file changes
325 adding file changes
325 added 2 changesets with 2 changes to 1 files
326 added 2 changesets with 2 changes to 1 files
326
327
327
328
328 Failed push of new named branch:
329 Failed push of new named branch:
329
330
330 $ echo 12 > foo
331 $ echo 12 > foo
331 $ hg -q ci -m 12a
332 $ hg -q ci -m 12a
332 [1]
333 [1]
333 $ hg -q up 11
334 $ hg -q up 11
334 $ echo 13 > foo
335 $ echo 13 > foo
335 $ hg -q branch e
336 $ hg -q branch e
336 $ hg -q ci -m 13d
337 $ hg -q ci -m 13d
337
338
338 $ hg push -r 12 -r 13 ../f
339 $ hg push -r 12 -r 13 ../f
339 pushing to ../f
340 pushing to ../f
340 searching for changes
341 searching for changes
341 abort: push creates new remote branches: e!
342 abort: push creates new remote branches: e!
342 (use 'hg push --new-branch' to create new remote branches)
343 (use 'hg push --new-branch' to create new remote branches)
343 [255]
344 [255]
344
345
345
346
346 Using --new-branch to push new named branch:
347 Using --new-branch to push new named branch:
347
348
348 $ hg push --new-branch -r 12 -r 13 ../f
349 $ hg push --new-branch -r 12 -r 13 ../f
349 pushing to ../f
350 pushing to ../f
350 searching for changes
351 searching for changes
351 adding changesets
352 adding changesets
352 adding manifests
353 adding manifests
353 adding file changes
354 adding file changes
354 added 1 changesets with 1 changes to 1 files
355 added 1 changesets with 1 changes to 1 files
355
356
356 Pushing multi headed new branch:
357 Pushing multi headed new branch:
357
358
358 $ echo 14 > foo
359 $ echo 14 > foo
359 $ hg -q branch f
360 $ hg -q branch f
360 $ hg -q ci -m 14
361 $ hg -q ci -m 14
361 $ echo 15 > foo
362 $ echo 15 > foo
362 $ hg -q ci -m 15
363 $ hg -q ci -m 15
363 $ hg -q up 14
364 $ hg -q up 14
364 $ echo 16 > foo
365 $ echo 16 > foo
365 $ hg -q ci -m 16
366 $ hg -q ci -m 16
366 $ hg push --branch f --new-branch ../f
367 $ hg push --branch f --new-branch ../f
367 pushing to ../f
368 pushing to ../f
368 searching for changes
369 searching for changes
369 abort: push creates new branch 'f' with multiple heads
370 abort: push creates new branch 'f' with multiple heads
370 (merge or see "hg help push" for details about pushing new heads)
371 (merge or see "hg help push" for details about pushing new heads)
371 [255]
372 [255]
372 $ hg push --branch f --new-branch --force ../f
373 $ hg push --branch f --new-branch --force ../f
373 pushing to ../f
374 pushing to ../f
374 searching for changes
375 searching for changes
375 adding changesets
376 adding changesets
376 adding manifests
377 adding manifests
377 adding file changes
378 adding file changes
378 added 3 changesets with 3 changes to 1 files (+1 heads)
379 added 3 changesets with 3 changes to 1 files (+1 heads)
379
380
380 Checking prepush logic does not allow silently pushing
381 Checking prepush logic does not allow silently pushing
381 multiple new heads but also doesn't report too many heads:
382 multiple new heads but also doesn't report too many heads:
382
383
383 $ cd ..
384 $ cd ..
384 $ hg init h
385 $ hg init h
385 $ echo init > h/init
386 $ echo init > h/init
386 $ hg -R h ci -Am init
387 $ hg -R h ci -Am init
387 adding init
388 adding init
388 $ echo a > h/a
389 $ echo a > h/a
389 $ hg -R h ci -Am a
390 $ hg -R h ci -Am a
390 adding a
391 adding a
391 $ hg clone h i
392 $ hg clone h i
392 updating to branch default
393 updating to branch default
393 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
394 $ hg -R h up 0
395 $ hg -R h up 0
395 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
396 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
396 $ echo b > h/b
397 $ echo b > h/b
397 $ hg -R h ci -Am b
398 $ hg -R h ci -Am b
398 adding b
399 adding b
399 created new head
400 created new head
400 $ hg -R i up 0
401 $ hg -R i up 0
401 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
402 $ echo c > i/c
403 $ echo c > i/c
403 $ hg -R i ci -Am c
404 $ hg -R i ci -Am c
404 adding c
405 adding c
405 created new head
406 created new head
406
407
407 $ for i in `seq 3`; do hg -R h up -q 0; echo $i > h/b; hg -R h ci -qAm$i; done
408 $ for i in `seq 3`; do hg -R h up -q 0; echo $i > h/b; hg -R h ci -qAm$i; done
408
409
409 $ hg -R i push h
410 $ hg -R i push h
410 pushing to h
411 pushing to h
411 searching for changes
412 searching for changes
412 remote has heads on branch 'default' that are not known locally: 534543e22c29 764f8ec07b96 afe7cc7679f5 ce4212fc8847
413 remote has heads on branch 'default' that are not known locally: 534543e22c29 764f8ec07b96 afe7cc7679f5 ce4212fc8847
413 abort: push creates new remote head 97bd0c84d346!
414 abort: push creates new remote head 97bd0c84d346!
414 (pull and merge or see "hg help push" for details about pushing new heads)
415 (pull and merge or see "hg help push" for details about pushing new heads)
415 [255]
416 [255]
416 $ hg -R h up -q 0; echo x > h/b; hg -R h ci -qAmx
417 $ hg -R h up -q 0; echo x > h/b; hg -R h ci -qAmx
417 $ hg -R i push h
418 $ hg -R i push h
418 pushing to h
419 pushing to h
419 searching for changes
420 searching for changes
420 remote has heads on branch 'default' that are not known locally: 18ddb72c4590 534543e22c29 764f8ec07b96 afe7cc7679f5 and 1 others
421 remote has heads on branch 'default' that are not known locally: 18ddb72c4590 534543e22c29 764f8ec07b96 afe7cc7679f5 and 1 others
421 abort: push creates new remote head 97bd0c84d346!
422 abort: push creates new remote head 97bd0c84d346!
422 (pull and merge or see "hg help push" for details about pushing new heads)
423 (pull and merge or see "hg help push" for details about pushing new heads)
423 [255]
424 [255]
424 $ hg -R i push h -v
425 $ hg -R i push h -v
425 pushing to h
426 pushing to h
426 searching for changes
427 searching for changes
427 remote has heads on branch 'default' that are not known locally: 18ddb72c4590 534543e22c29 764f8ec07b96 afe7cc7679f5 ce4212fc8847
428 remote has heads on branch 'default' that are not known locally: 18ddb72c4590 534543e22c29 764f8ec07b96 afe7cc7679f5 ce4212fc8847
428 new remote heads on branch 'default':
429 new remote heads on branch 'default':
429 97bd0c84d346
430 97bd0c84d346
430 abort: push creates new remote head 97bd0c84d346!
431 abort: push creates new remote head 97bd0c84d346!
431 (pull and merge or see "hg help push" for details about pushing new heads)
432 (pull and merge or see "hg help push" for details about pushing new heads)
432 [255]
433 [255]
433
434
434
435
435 Check prepush logic with merged branches:
436 Check prepush logic with merged branches:
436
437
437 $ hg init j
438 $ hg init j
438 $ hg -R j branch a
439 $ hg -R j branch a
439 marked working directory as branch a
440 marked working directory as branch a
440 (branches are permanent and global, did you want a bookmark?)
441 (branches are permanent and global, did you want a bookmark?)
441 $ echo init > j/foo
442 $ echo init > j/foo
442 $ hg -R j ci -Am init
443 $ hg -R j ci -Am init
443 adding foo
444 adding foo
444 $ hg clone j k
445 $ hg clone j k
445 updating to branch a
446 updating to branch a
446 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 $ echo a1 > j/foo
448 $ echo a1 > j/foo
448 $ hg -R j ci -m a1
449 $ hg -R j ci -m a1
449 $ hg -R k branch b
450 $ hg -R k branch b
450 marked working directory as branch b
451 marked working directory as branch b
451 (branches are permanent and global, did you want a bookmark?)
452 (branches are permanent and global, did you want a bookmark?)
452 $ echo b > k/foo
453 $ echo b > k/foo
453 $ hg -R k ci -m b
454 $ hg -R k ci -m b
454 $ hg -R k up 0
455 $ hg -R k up 0
455 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456
457
457 $ hg -R k merge b
458 $ hg -R k merge b
458 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
459 (branch merge, don't forget to commit)
460 (branch merge, don't forget to commit)
460
461
461 $ hg -R k ci -m merge
462 $ hg -R k ci -m merge
462
463
463 $ hg -R k push -r a j
464 $ hg -R k push -r a j
464 pushing to j
465 pushing to j
465 searching for changes
466 searching for changes
466 abort: push creates new remote branches: b!
467 abort: push creates new remote branches: b!
467 (use 'hg push --new-branch' to create new remote branches)
468 (use 'hg push --new-branch' to create new remote branches)
468 [255]
469 [255]
469
470
470
471
471 Prepush -r should not allow you to sneak in new heads:
472 Prepush -r should not allow you to sneak in new heads:
472
473
473 $ hg init l
474 $ hg init l
474 $ cd l
475 $ cd l
475 $ echo a >> foo
476 $ echo a >> foo
476 $ hg -q add foo
477 $ hg -q add foo
477 $ hg -q branch a
478 $ hg -q branch a
478 $ hg -q ci -ma
479 $ hg -q ci -ma
479 $ hg -q up null
480 $ hg -q up null
480 $ echo a >> foo
481 $ echo a >> foo
481 $ hg -q add foo
482 $ hg -q add foo
482 $ hg -q branch b
483 $ hg -q branch b
483 $ hg -q ci -mb
484 $ hg -q ci -mb
484 $ cd ..
485 $ cd ..
485 $ hg -q clone l m -u a
486 $ hg -q clone l m -u a
486 $ cd m
487 $ cd m
487 $ hg -q merge b
488 $ hg -q merge b
488 $ hg -q ci -mmb
489 $ hg -q ci -mmb
489 $ hg -q up 0
490 $ hg -q up 0
490 $ echo a >> foo
491 $ echo a >> foo
491 $ hg -q ci -ma2
492 $ hg -q ci -ma2
492 $ hg -q up 2
493 $ hg -q up 2
493 $ echo a >> foo
494 $ echo a >> foo
494 $ hg -q branch -f b
495 $ hg -q branch -f b
495 $ hg -q ci -mb2
496 $ hg -q ci -mb2
496 $ hg -q merge 3
497 $ hg -q merge 3
497 $ hg -q ci -mma
498 $ hg -q ci -mma
498
499
499 $ hg push ../l -b b
500 $ hg push ../l -b b
500 pushing to ../l
501 pushing to ../l
501 searching for changes
502 searching for changes
502 abort: push creates new remote head 451211cc22b0 on branch 'a'!
503 abort: push creates new remote head 451211cc22b0 on branch 'a'!
503 (merge or see "hg help push" for details about pushing new heads)
504 (merge or see "hg help push" for details about pushing new heads)
504 [255]
505 [255]
505
506
506 $ cd ..
507 $ cd ..
507
508
508
509
509 Check prepush with new branch head on former topo non-head:
510 Check prepush with new branch head on former topo non-head:
510
511
511 $ hg init n
512 $ hg init n
512 $ cd n
513 $ cd n
513 $ hg branch A
514 $ hg branch A
514 marked working directory as branch A
515 marked working directory as branch A
515 (branches are permanent and global, did you want a bookmark?)
516 (branches are permanent and global, did you want a bookmark?)
516 $ echo a >a
517 $ echo a >a
517 $ hg ci -Ama
518 $ hg ci -Ama
518 adding a
519 adding a
519 $ hg branch B
520 $ hg branch B
520 marked working directory as branch B
521 marked working directory as branch B
521 (branches are permanent and global, did you want a bookmark?)
522 (branches are permanent and global, did you want a bookmark?)
522 $ echo b >b
523 $ echo b >b
523 $ hg ci -Amb
524 $ hg ci -Amb
524 adding b
525 adding b
525
526
526 b is now branch head of B, and a topological head
527 b is now branch head of B, and a topological head
527 a is now branch head of A, but not a topological head
528 a is now branch head of A, but not a topological head
528
529
529 $ hg clone . inner
530 $ hg clone . inner
530 updating to branch B
531 updating to branch B
531 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
532 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
532 $ cd inner
533 $ cd inner
533 $ hg up B
534 $ hg up B
534 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
535 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
535 $ echo b1 >b1
536 $ echo b1 >b1
536 $ hg ci -Amb1
537 $ hg ci -Amb1
537 adding b1
538 adding b1
538
539
539 in the clone b1 is now the head of B
540 in the clone b1 is now the head of B
540
541
541 $ cd ..
542 $ cd ..
542 $ hg up 0
543 $ hg up 0
543 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
544 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
544 $ echo a2 >a2
545 $ echo a2 >a2
545 $ hg ci -Ama2
546 $ hg ci -Ama2
546 adding a2
547 adding a2
547
548
548 a2 is now the new branch head of A, and a new topological head
549 a2 is now the new branch head of A, and a new topological head
549 it replaces a former inner branch head, so it should at most warn about
550 it replaces a former inner branch head, so it should at most warn about
550 A, not B
551 A, not B
551
552
552 glog of local:
553 glog of local:
553
554
554 $ hg log -G --template "{rev}: {branches} {desc}\n"
555 $ hg log -G --template "{rev}: {branches} {desc}\n"
555 @ 2: A a2
556 @ 2: A a2
556 |
557 |
557 | o 1: B b
558 | o 1: B b
558 |/
559 |/
559 o 0: A a
560 o 0: A a
560
561
561 glog of remote:
562 glog of remote:
562
563
563 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
564 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
564 @ 2: B b1
565 @ 2: B b1
565 |
566 |
566 o 1: B b
567 o 1: B b
567 |
568 |
568 o 0: A a
569 o 0: A a
569
570
570 outgoing:
571 outgoing:
571
572
572 $ hg out inner --template "{rev}: {branches} {desc}\n"
573 $ hg out inner --template "{rev}: {branches} {desc}\n"
573 comparing with inner
574 comparing with inner
574 searching for changes
575 searching for changes
575 2: A a2
576 2: A a2
576
577
577 $ hg push inner
578 $ hg push inner
578 pushing to inner
579 pushing to inner
579 searching for changes
580 searching for changes
580 adding changesets
581 adding changesets
581 adding manifests
582 adding manifests
582 adding file changes
583 adding file changes
583 added 1 changesets with 1 changes to 1 files (+1 heads)
584 added 1 changesets with 1 changes to 1 files (+1 heads)
584
585
585 $ cd ..
586 $ cd ..
586
587
587
588
588 Check prepush with new branch head on former topo head:
589 Check prepush with new branch head on former topo head:
589
590
590 $ hg init o
591 $ hg init o
591 $ cd o
592 $ cd o
592 $ hg branch A
593 $ hg branch A
593 marked working directory as branch A
594 marked working directory as branch A
594 (branches are permanent and global, did you want a bookmark?)
595 (branches are permanent and global, did you want a bookmark?)
595 $ echo a >a
596 $ echo a >a
596 $ hg ci -Ama
597 $ hg ci -Ama
597 adding a
598 adding a
598 $ hg branch B
599 $ hg branch B
599 marked working directory as branch B
600 marked working directory as branch B
600 (branches are permanent and global, did you want a bookmark?)
601 (branches are permanent and global, did you want a bookmark?)
601 $ echo b >b
602 $ echo b >b
602 $ hg ci -Amb
603 $ hg ci -Amb
603 adding b
604 adding b
604
605
605 b is now branch head of B, and a topological head
606 b is now branch head of B, and a topological head
606
607
607 $ hg up 0
608 $ hg up 0
608 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
609 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
609 $ echo a1 >a1
610 $ echo a1 >a1
610 $ hg ci -Ama1
611 $ hg ci -Ama1
611 adding a1
612 adding a1
612
613
613 a1 is now branch head of A, and a topological head
614 a1 is now branch head of A, and a topological head
614
615
615 $ hg clone . inner
616 $ hg clone . inner
616 updating to branch A
617 updating to branch A
617 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
618 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
618 $ cd inner
619 $ cd inner
619 $ hg up B
620 $ hg up B
620 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
621 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
621 $ echo b1 >b1
622 $ echo b1 >b1
622 $ hg ci -Amb1
623 $ hg ci -Amb1
623 adding b1
624 adding b1
624
625
625 in the clone b1 is now the head of B
626 in the clone b1 is now the head of B
626
627
627 $ cd ..
628 $ cd ..
628 $ echo a2 >a2
629 $ echo a2 >a2
629 $ hg ci -Ama2
630 $ hg ci -Ama2
630 adding a2
631 adding a2
631
632
632 a2 is now the new branch head of A, and a topological head
633 a2 is now the new branch head of A, and a topological head
633 it replaces a former topological and branch head, so this should not warn
634 it replaces a former topological and branch head, so this should not warn
634
635
635 glog of local:
636 glog of local:
636
637
637 $ hg log -G --template "{rev}: {branches} {desc}\n"
638 $ hg log -G --template "{rev}: {branches} {desc}\n"
638 @ 3: A a2
639 @ 3: A a2
639 |
640 |
640 o 2: A a1
641 o 2: A a1
641 |
642 |
642 | o 1: B b
643 | o 1: B b
643 |/
644 |/
644 o 0: A a
645 o 0: A a
645
646
646 glog of remote:
647 glog of remote:
647
648
648 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
649 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
649 @ 3: B b1
650 @ 3: B b1
650 |
651 |
651 | o 2: A a1
652 | o 2: A a1
652 | |
653 | |
653 o | 1: B b
654 o | 1: B b
654 |/
655 |/
655 o 0: A a
656 o 0: A a
656
657
657 outgoing:
658 outgoing:
658
659
659 $ hg out inner --template "{rev}: {branches} {desc}\n"
660 $ hg out inner --template "{rev}: {branches} {desc}\n"
660 comparing with inner
661 comparing with inner
661 searching for changes
662 searching for changes
662 3: A a2
663 3: A a2
663
664
664 $ hg push inner
665 $ hg push inner
665 pushing to inner
666 pushing to inner
666 searching for changes
667 searching for changes
667 adding changesets
668 adding changesets
668 adding manifests
669 adding manifests
669 adding file changes
670 adding file changes
670 added 1 changesets with 1 changes to 1 files
671 added 1 changesets with 1 changes to 1 files
671
672
672 $ cd ..
673 $ cd ..
673
674
674
675
675 Check prepush with new branch head and new child of former branch head
676 Check prepush with new branch head and new child of former branch head
676 but child is on different branch:
677 but child is on different branch:
677
678
678 $ hg init p
679 $ hg init p
679 $ cd p
680 $ cd p
680 $ hg branch A
681 $ hg branch A
681 marked working directory as branch A
682 marked working directory as branch A
682 (branches are permanent and global, did you want a bookmark?)
683 (branches are permanent and global, did you want a bookmark?)
683 $ echo a0 >a
684 $ echo a0 >a
684 $ hg ci -Ama0
685 $ hg ci -Ama0
685 adding a
686 adding a
686 $ echo a1 >a
687 $ echo a1 >a
687 $ hg ci -ma1
688 $ hg ci -ma1
688 $ hg up null
689 $ hg up null
689 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
690 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
690 $ hg branch B
691 $ hg branch B
691 marked working directory as branch B
692 marked working directory as branch B
692 (branches are permanent and global, did you want a bookmark?)
693 (branches are permanent and global, did you want a bookmark?)
693 $ echo b0 >b
694 $ echo b0 >b
694 $ hg ci -Amb0
695 $ hg ci -Amb0
695 adding b
696 adding b
696 $ echo b1 >b
697 $ echo b1 >b
697 $ hg ci -mb1
698 $ hg ci -mb1
698
699
699 $ hg clone . inner
700 $ hg clone . inner
700 updating to branch B
701 updating to branch B
701 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
702 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
702
703
703 $ hg up A
704 $ hg up A
704 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
705 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
705 $ hg branch -f B
706 $ hg branch -f B
706 marked working directory as branch B
707 marked working directory as branch B
707 (branches are permanent and global, did you want a bookmark?)
708 (branches are permanent and global, did you want a bookmark?)
708 $ echo a3 >a
709 $ echo a3 >a
709 $ hg ci -ma3
710 $ hg ci -ma3
710 created new head
711 created new head
711 $ hg up 3
712 $ hg up 3
712 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
713 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
713 $ hg branch -f A
714 $ hg branch -f A
714 marked working directory as branch A
715 marked working directory as branch A
715 (branches are permanent and global, did you want a bookmark?)
716 (branches are permanent and global, did you want a bookmark?)
716 $ echo b3 >b
717 $ echo b3 >b
717 $ hg ci -mb3
718 $ hg ci -mb3
718 created new head
719 created new head
719
720
720 glog of local:
721 glog of local:
721
722
722 $ hg log -G --template "{rev}: {branches} {desc}\n"
723 $ hg log -G --template "{rev}: {branches} {desc}\n"
723 @ 5: A b3
724 @ 5: A b3
724 |
725 |
725 | o 4: B a3
726 | o 4: B a3
726 | |
727 | |
727 o | 3: B b1
728 o | 3: B b1
728 | |
729 | |
729 o | 2: B b0
730 o | 2: B b0
730 /
731 /
731 o 1: A a1
732 o 1: A a1
732 |
733 |
733 o 0: A a0
734 o 0: A a0
734
735
735 glog of remote:
736 glog of remote:
736
737
737 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
738 $ hg log -G -R inner --template "{rev}: {branches} {desc}\n"
738 @ 3: B b1
739 @ 3: B b1
739 |
740 |
740 o 2: B b0
741 o 2: B b0
741
742
742 o 1: A a1
743 o 1: A a1
743 |
744 |
744 o 0: A a0
745 o 0: A a0
745
746
746 outgoing:
747 outgoing:
747
748
748 $ hg out inner --template "{rev}: {branches} {desc}\n"
749 $ hg out inner --template "{rev}: {branches} {desc}\n"
749 comparing with inner
750 comparing with inner
750 searching for changes
751 searching for changes
751 4: B a3
752 4: B a3
752 5: A b3
753 5: A b3
753
754
754 $ hg push inner
755 $ hg push inner
755 pushing to inner
756 pushing to inner
756 searching for changes
757 searching for changes
757 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
758 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
758 (merge or see "hg help push" for details about pushing new heads)
759 (merge or see "hg help push" for details about pushing new heads)
759 [255]
760 [255]
760
761
761 $ hg push inner -r4 -r5
762 $ hg push inner -r4 -r5
762 pushing to inner
763 pushing to inner
763 searching for changes
764 searching for changes
764 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
765 abort: push creates new remote head 7d0f4fb6cf04 on branch 'A'!
765 (merge or see "hg help push" for details about pushing new heads)
766 (merge or see "hg help push" for details about pushing new heads)
766 [255]
767 [255]
767
768
768 $ hg in inner
769 $ hg in inner
769 comparing with inner
770 comparing with inner
770 searching for changes
771 searching for changes
771 no changes found
772 no changes found
772 [1]
773 [1]
773
774
774 $ cd ..
775 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now