##// END OF EJS Templates
changegroup: move branch cache debug message to proper location...
Gregory Szorc -
r29757:976cd337 default
parent child Browse files
Show More
@@ -1,1049 +1,1048 b''
1 # changegroup.py - Mercurial changegroup manipulation functions
1 # changegroup.py - Mercurial changegroup manipulation functions
2 #
2 #
3 # Copyright 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006 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 __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import os
10 import os
11 import struct
11 import struct
12 import tempfile
12 import tempfile
13 import weakref
13 import weakref
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import (
16 from .node import (
17 hex,
17 hex,
18 nullid,
18 nullid,
19 nullrev,
19 nullrev,
20 short,
20 short,
21 )
21 )
22
22
23 from . import (
23 from . import (
24 branchmap,
24 branchmap,
25 dagutil,
25 dagutil,
26 discovery,
26 discovery,
27 error,
27 error,
28 mdiff,
28 mdiff,
29 phases,
29 phases,
30 util,
30 util,
31 )
31 )
32
32
33 _CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s"
33 _CHANGEGROUPV1_DELTA_HEADER = "20s20s20s20s"
34 _CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s"
34 _CHANGEGROUPV2_DELTA_HEADER = "20s20s20s20s20s"
35 _CHANGEGROUPV3_DELTA_HEADER = ">20s20s20s20s20sH"
35 _CHANGEGROUPV3_DELTA_HEADER = ">20s20s20s20s20sH"
36
36
37 def readexactly(stream, n):
37 def readexactly(stream, n):
38 '''read n bytes from stream.read and abort if less was available'''
38 '''read n bytes from stream.read and abort if less was available'''
39 s = stream.read(n)
39 s = stream.read(n)
40 if len(s) < n:
40 if len(s) < n:
41 raise error.Abort(_("stream ended unexpectedly"
41 raise error.Abort(_("stream ended unexpectedly"
42 " (got %d bytes, expected %d)")
42 " (got %d bytes, expected %d)")
43 % (len(s), n))
43 % (len(s), n))
44 return s
44 return s
45
45
46 def getchunk(stream):
46 def getchunk(stream):
47 """return the next chunk from stream as a string"""
47 """return the next chunk from stream as a string"""
48 d = readexactly(stream, 4)
48 d = readexactly(stream, 4)
49 l = struct.unpack(">l", d)[0]
49 l = struct.unpack(">l", d)[0]
50 if l <= 4:
50 if l <= 4:
51 if l:
51 if l:
52 raise error.Abort(_("invalid chunk length %d") % l)
52 raise error.Abort(_("invalid chunk length %d") % l)
53 return ""
53 return ""
54 return readexactly(stream, l - 4)
54 return readexactly(stream, l - 4)
55
55
56 def chunkheader(length):
56 def chunkheader(length):
57 """return a changegroup chunk header (string)"""
57 """return a changegroup chunk header (string)"""
58 return struct.pack(">l", length + 4)
58 return struct.pack(">l", length + 4)
59
59
60 def closechunk():
60 def closechunk():
61 """return a changegroup chunk header (string) for a zero-length chunk"""
61 """return a changegroup chunk header (string) for a zero-length chunk"""
62 return struct.pack(">l", 0)
62 return struct.pack(">l", 0)
63
63
64 def combineresults(results):
64 def combineresults(results):
65 """logic to combine 0 or more addchangegroup results into one"""
65 """logic to combine 0 or more addchangegroup results into one"""
66 changedheads = 0
66 changedheads = 0
67 result = 1
67 result = 1
68 for ret in results:
68 for ret in results:
69 # If any changegroup result is 0, return 0
69 # If any changegroup result is 0, return 0
70 if ret == 0:
70 if ret == 0:
71 result = 0
71 result = 0
72 break
72 break
73 if ret < -1:
73 if ret < -1:
74 changedheads += ret + 1
74 changedheads += ret + 1
75 elif ret > 1:
75 elif ret > 1:
76 changedheads += ret - 1
76 changedheads += ret - 1
77 if changedheads > 0:
77 if changedheads > 0:
78 result = 1 + changedheads
78 result = 1 + changedheads
79 elif changedheads < 0:
79 elif changedheads < 0:
80 result = -1 + changedheads
80 result = -1 + changedheads
81 return result
81 return result
82
82
83 def writechunks(ui, chunks, filename, vfs=None):
83 def writechunks(ui, chunks, filename, vfs=None):
84 """Write chunks to a file and return its filename.
84 """Write chunks to a file and return its filename.
85
85
86 The stream is assumed to be a bundle file.
86 The stream is assumed to be a bundle file.
87 Existing files will not be overwritten.
87 Existing files will not be overwritten.
88 If no filename is specified, a temporary file is created.
88 If no filename is specified, a temporary file is created.
89 """
89 """
90 fh = None
90 fh = None
91 cleanup = None
91 cleanup = None
92 try:
92 try:
93 if filename:
93 if filename:
94 if vfs:
94 if vfs:
95 fh = vfs.open(filename, "wb")
95 fh = vfs.open(filename, "wb")
96 else:
96 else:
97 fh = open(filename, "wb")
97 fh = open(filename, "wb")
98 else:
98 else:
99 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
99 fd, filename = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg")
100 fh = os.fdopen(fd, "wb")
100 fh = os.fdopen(fd, "wb")
101 cleanup = filename
101 cleanup = filename
102 for c in chunks:
102 for c in chunks:
103 fh.write(c)
103 fh.write(c)
104 cleanup = None
104 cleanup = None
105 return filename
105 return filename
106 finally:
106 finally:
107 if fh is not None:
107 if fh is not None:
108 fh.close()
108 fh.close()
109 if cleanup is not None:
109 if cleanup is not None:
110 if filename and vfs:
110 if filename and vfs:
111 vfs.unlink(cleanup)
111 vfs.unlink(cleanup)
112 else:
112 else:
113 os.unlink(cleanup)
113 os.unlink(cleanup)
114
114
115 class cg1unpacker(object):
115 class cg1unpacker(object):
116 """Unpacker for cg1 changegroup streams.
116 """Unpacker for cg1 changegroup streams.
117
117
118 A changegroup unpacker handles the framing of the revision data in
118 A changegroup unpacker handles the framing of the revision data in
119 the wire format. Most consumers will want to use the apply()
119 the wire format. Most consumers will want to use the apply()
120 method to add the changes from the changegroup to a repository.
120 method to add the changes from the changegroup to a repository.
121
121
122 If you're forwarding a changegroup unmodified to another consumer,
122 If you're forwarding a changegroup unmodified to another consumer,
123 use getchunks(), which returns an iterator of changegroup
123 use getchunks(), which returns an iterator of changegroup
124 chunks. This is mostly useful for cases where you need to know the
124 chunks. This is mostly useful for cases where you need to know the
125 data stream has ended by observing the end of the changegroup.
125 data stream has ended by observing the end of the changegroup.
126
126
127 deltachunk() is useful only if you're applying delta data. Most
127 deltachunk() is useful only if you're applying delta data. Most
128 consumers should prefer apply() instead.
128 consumers should prefer apply() instead.
129
129
130 A few other public methods exist. Those are used only for
130 A few other public methods exist. Those are used only for
131 bundlerepo and some debug commands - their use is discouraged.
131 bundlerepo and some debug commands - their use is discouraged.
132 """
132 """
133 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
133 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
134 deltaheadersize = struct.calcsize(deltaheader)
134 deltaheadersize = struct.calcsize(deltaheader)
135 version = '01'
135 version = '01'
136 _grouplistcount = 1 # One list of files after the manifests
136 _grouplistcount = 1 # One list of files after the manifests
137
137
138 def __init__(self, fh, alg, extras=None):
138 def __init__(self, fh, alg, extras=None):
139 if alg == 'UN':
139 if alg == 'UN':
140 alg = None # get more modern without breaking too much
140 alg = None # get more modern without breaking too much
141 if not alg in util.decompressors:
141 if not alg in util.decompressors:
142 raise error.Abort(_('unknown stream compression type: %s')
142 raise error.Abort(_('unknown stream compression type: %s')
143 % alg)
143 % alg)
144 if alg == 'BZ':
144 if alg == 'BZ':
145 alg = '_truncatedBZ'
145 alg = '_truncatedBZ'
146 self._stream = util.decompressors[alg](fh)
146 self._stream = util.decompressors[alg](fh)
147 self._type = alg
147 self._type = alg
148 self.extras = extras or {}
148 self.extras = extras or {}
149 self.callback = None
149 self.callback = None
150
150
151 # These methods (compressed, read, seek, tell) all appear to only
151 # These methods (compressed, read, seek, tell) all appear to only
152 # be used by bundlerepo, but it's a little hard to tell.
152 # be used by bundlerepo, but it's a little hard to tell.
153 def compressed(self):
153 def compressed(self):
154 return self._type is not None
154 return self._type is not None
155 def read(self, l):
155 def read(self, l):
156 return self._stream.read(l)
156 return self._stream.read(l)
157 def seek(self, pos):
157 def seek(self, pos):
158 return self._stream.seek(pos)
158 return self._stream.seek(pos)
159 def tell(self):
159 def tell(self):
160 return self._stream.tell()
160 return self._stream.tell()
161 def close(self):
161 def close(self):
162 return self._stream.close()
162 return self._stream.close()
163
163
164 def _chunklength(self):
164 def _chunklength(self):
165 d = readexactly(self._stream, 4)
165 d = readexactly(self._stream, 4)
166 l = struct.unpack(">l", d)[0]
166 l = struct.unpack(">l", d)[0]
167 if l <= 4:
167 if l <= 4:
168 if l:
168 if l:
169 raise error.Abort(_("invalid chunk length %d") % l)
169 raise error.Abort(_("invalid chunk length %d") % l)
170 return 0
170 return 0
171 if self.callback:
171 if self.callback:
172 self.callback()
172 self.callback()
173 return l - 4
173 return l - 4
174
174
175 def changelogheader(self):
175 def changelogheader(self):
176 """v10 does not have a changelog header chunk"""
176 """v10 does not have a changelog header chunk"""
177 return {}
177 return {}
178
178
179 def manifestheader(self):
179 def manifestheader(self):
180 """v10 does not have a manifest header chunk"""
180 """v10 does not have a manifest header chunk"""
181 return {}
181 return {}
182
182
183 def filelogheader(self):
183 def filelogheader(self):
184 """return the header of the filelogs chunk, v10 only has the filename"""
184 """return the header of the filelogs chunk, v10 only has the filename"""
185 l = self._chunklength()
185 l = self._chunklength()
186 if not l:
186 if not l:
187 return {}
187 return {}
188 fname = readexactly(self._stream, l)
188 fname = readexactly(self._stream, l)
189 return {'filename': fname}
189 return {'filename': fname}
190
190
191 def _deltaheader(self, headertuple, prevnode):
191 def _deltaheader(self, headertuple, prevnode):
192 node, p1, p2, cs = headertuple
192 node, p1, p2, cs = headertuple
193 if prevnode is None:
193 if prevnode is None:
194 deltabase = p1
194 deltabase = p1
195 else:
195 else:
196 deltabase = prevnode
196 deltabase = prevnode
197 flags = 0
197 flags = 0
198 return node, p1, p2, deltabase, cs, flags
198 return node, p1, p2, deltabase, cs, flags
199
199
200 def deltachunk(self, prevnode):
200 def deltachunk(self, prevnode):
201 l = self._chunklength()
201 l = self._chunklength()
202 if not l:
202 if not l:
203 return {}
203 return {}
204 headerdata = readexactly(self._stream, self.deltaheadersize)
204 headerdata = readexactly(self._stream, self.deltaheadersize)
205 header = struct.unpack(self.deltaheader, headerdata)
205 header = struct.unpack(self.deltaheader, headerdata)
206 delta = readexactly(self._stream, l - self.deltaheadersize)
206 delta = readexactly(self._stream, l - self.deltaheadersize)
207 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
207 node, p1, p2, deltabase, cs, flags = self._deltaheader(header, prevnode)
208 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs,
208 return {'node': node, 'p1': p1, 'p2': p2, 'cs': cs,
209 'deltabase': deltabase, 'delta': delta, 'flags': flags}
209 'deltabase': deltabase, 'delta': delta, 'flags': flags}
210
210
211 def getchunks(self):
211 def getchunks(self):
212 """returns all the chunks contains in the bundle
212 """returns all the chunks contains in the bundle
213
213
214 Used when you need to forward the binary stream to a file or another
214 Used when you need to forward the binary stream to a file or another
215 network API. To do so, it parse the changegroup data, otherwise it will
215 network API. To do so, it parse the changegroup data, otherwise it will
216 block in case of sshrepo because it don't know the end of the stream.
216 block in case of sshrepo because it don't know the end of the stream.
217 """
217 """
218 # an empty chunkgroup is the end of the changegroup
218 # an empty chunkgroup is the end of the changegroup
219 # a changegroup has at least 2 chunkgroups (changelog and manifest).
219 # a changegroup has at least 2 chunkgroups (changelog and manifest).
220 # after that, changegroup versions 1 and 2 have a series of groups
220 # after that, changegroup versions 1 and 2 have a series of groups
221 # with one group per file. changegroup 3 has a series of directory
221 # with one group per file. changegroup 3 has a series of directory
222 # manifests before the files.
222 # manifests before the files.
223 count = 0
223 count = 0
224 emptycount = 0
224 emptycount = 0
225 while emptycount < self._grouplistcount:
225 while emptycount < self._grouplistcount:
226 empty = True
226 empty = True
227 count += 1
227 count += 1
228 while True:
228 while True:
229 chunk = getchunk(self)
229 chunk = getchunk(self)
230 if not chunk:
230 if not chunk:
231 if empty and count > 2:
231 if empty and count > 2:
232 emptycount += 1
232 emptycount += 1
233 break
233 break
234 empty = False
234 empty = False
235 yield chunkheader(len(chunk))
235 yield chunkheader(len(chunk))
236 pos = 0
236 pos = 0
237 while pos < len(chunk):
237 while pos < len(chunk):
238 next = pos + 2**20
238 next = pos + 2**20
239 yield chunk[pos:next]
239 yield chunk[pos:next]
240 pos = next
240 pos = next
241 yield closechunk()
241 yield closechunk()
242
242
243 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
243 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
244 # We know that we'll never have more manifests than we had
244 # We know that we'll never have more manifests than we had
245 # changesets.
245 # changesets.
246 self.callback = prog(_('manifests'), numchanges)
246 self.callback = prog(_('manifests'), numchanges)
247 # no need to check for empty manifest group here:
247 # no need to check for empty manifest group here:
248 # if the result of the merge of 1 and 2 is the same in 3 and 4,
248 # if the result of the merge of 1 and 2 is the same in 3 and 4,
249 # no new manifest will be created and the manifest group will
249 # no new manifest will be created and the manifest group will
250 # be empty during the pull
250 # be empty during the pull
251 self.manifestheader()
251 self.manifestheader()
252 repo.manifest.addgroup(self, revmap, trp)
252 repo.manifest.addgroup(self, revmap, trp)
253 repo.ui.progress(_('manifests'), None)
253 repo.ui.progress(_('manifests'), None)
254 self.callback = None
254 self.callback = None
255
255
256 def apply(self, repo, srctype, url, emptyok=False,
256 def apply(self, repo, srctype, url, emptyok=False,
257 targetphase=phases.draft, expectedtotal=None):
257 targetphase=phases.draft, expectedtotal=None):
258 """Add the changegroup returned by source.read() to this repo.
258 """Add the changegroup returned by source.read() to this repo.
259 srctype is a string like 'push', 'pull', or 'unbundle'. url is
259 srctype is a string like 'push', 'pull', or 'unbundle'. url is
260 the URL of the repo where this changegroup is coming from.
260 the URL of the repo where this changegroup is coming from.
261
261
262 Return an integer summarizing the change to this repo:
262 Return an integer summarizing the change to this repo:
263 - nothing changed or no source: 0
263 - nothing changed or no source: 0
264 - more heads than before: 1+added heads (2..n)
264 - more heads than before: 1+added heads (2..n)
265 - fewer heads than before: -1-removed heads (-2..-n)
265 - fewer heads than before: -1-removed heads (-2..-n)
266 - number of heads stays the same: 1
266 - number of heads stays the same: 1
267 """
267 """
268 repo = repo.unfiltered()
268 repo = repo.unfiltered()
269 def csmap(x):
269 def csmap(x):
270 repo.ui.debug("add changeset %s\n" % short(x))
270 repo.ui.debug("add changeset %s\n" % short(x))
271 return len(cl)
271 return len(cl)
272
272
273 def revmap(x):
273 def revmap(x):
274 return cl.rev(x)
274 return cl.rev(x)
275
275
276 changesets = files = revisions = 0
276 changesets = files = revisions = 0
277
277
278 try:
278 try:
279 with repo.transaction("\n".join([srctype,
279 with repo.transaction("\n".join([srctype,
280 util.hidepassword(url)])) as tr:
280 util.hidepassword(url)])) as tr:
281 # The transaction could have been created before and already
281 # The transaction could have been created before and already
282 # carries source information. In this case we use the top
282 # carries source information. In this case we use the top
283 # level data. We overwrite the argument because we need to use
283 # level data. We overwrite the argument because we need to use
284 # the top level value (if they exist) in this function.
284 # the top level value (if they exist) in this function.
285 srctype = tr.hookargs.setdefault('source', srctype)
285 srctype = tr.hookargs.setdefault('source', srctype)
286 url = tr.hookargs.setdefault('url', url)
286 url = tr.hookargs.setdefault('url', url)
287 repo.hook('prechangegroup', throw=True, **tr.hookargs)
287 repo.hook('prechangegroup', throw=True, **tr.hookargs)
288
288
289 # write changelog data to temp files so concurrent readers
289 # write changelog data to temp files so concurrent readers
290 # will not see an inconsistent view
290 # will not see an inconsistent view
291 cl = repo.changelog
291 cl = repo.changelog
292 cl.delayupdate(tr)
292 cl.delayupdate(tr)
293 oldheads = cl.heads()
293 oldheads = cl.heads()
294
294
295 trp = weakref.proxy(tr)
295 trp = weakref.proxy(tr)
296 # pull off the changeset group
296 # pull off the changeset group
297 repo.ui.status(_("adding changesets\n"))
297 repo.ui.status(_("adding changesets\n"))
298 clstart = len(cl)
298 clstart = len(cl)
299 class prog(object):
299 class prog(object):
300 def __init__(self, step, total):
300 def __init__(self, step, total):
301 self._step = step
301 self._step = step
302 self._total = total
302 self._total = total
303 self._count = 1
303 self._count = 1
304 def __call__(self):
304 def __call__(self):
305 repo.ui.progress(self._step, self._count,
305 repo.ui.progress(self._step, self._count,
306 unit=_('chunks'), total=self._total)
306 unit=_('chunks'), total=self._total)
307 self._count += 1
307 self._count += 1
308 self.callback = prog(_('changesets'), expectedtotal)
308 self.callback = prog(_('changesets'), expectedtotal)
309
309
310 efiles = set()
310 efiles = set()
311 def onchangelog(cl, node):
311 def onchangelog(cl, node):
312 efiles.update(cl.readfiles(node))
312 efiles.update(cl.readfiles(node))
313
313
314 self.changelogheader()
314 self.changelogheader()
315 srccontent = cl.addgroup(self, csmap, trp,
315 srccontent = cl.addgroup(self, csmap, trp,
316 addrevisioncb=onchangelog)
316 addrevisioncb=onchangelog)
317 efiles = len(efiles)
317 efiles = len(efiles)
318
318
319 if not (srccontent or emptyok):
319 if not (srccontent or emptyok):
320 raise error.Abort(_("received changelog group is empty"))
320 raise error.Abort(_("received changelog group is empty"))
321 clend = len(cl)
321 clend = len(cl)
322 changesets = clend - clstart
322 changesets = clend - clstart
323 repo.ui.progress(_('changesets'), None)
323 repo.ui.progress(_('changesets'), None)
324 self.callback = None
324 self.callback = None
325
325
326 # pull off the manifest group
326 # pull off the manifest group
327 repo.ui.status(_("adding manifests\n"))
327 repo.ui.status(_("adding manifests\n"))
328 self._unpackmanifests(repo, revmap, trp, prog, changesets)
328 self._unpackmanifests(repo, revmap, trp, prog, changesets)
329
329
330 needfiles = {}
330 needfiles = {}
331 if repo.ui.configbool('server', 'validate', default=False):
331 if repo.ui.configbool('server', 'validate', default=False):
332 # validate incoming csets have their manifests
332 # validate incoming csets have their manifests
333 for cset in xrange(clstart, clend):
333 for cset in xrange(clstart, clend):
334 mfnode = repo.changelog.read(
334 mfnode = repo.changelog.read(
335 repo.changelog.node(cset))[0]
335 repo.changelog.node(cset))[0]
336 mfest = repo.manifest.readdelta(mfnode)
336 mfest = repo.manifest.readdelta(mfnode)
337 # store file nodes we must see
337 # store file nodes we must see
338 for f, n in mfest.iteritems():
338 for f, n in mfest.iteritems():
339 needfiles.setdefault(f, set()).add(n)
339 needfiles.setdefault(f, set()).add(n)
340
340
341 # process the files
341 # process the files
342 repo.ui.status(_("adding file changes\n"))
342 repo.ui.status(_("adding file changes\n"))
343 newrevs, newfiles = _addchangegroupfiles(
343 newrevs, newfiles = _addchangegroupfiles(
344 repo, self, revmap, trp, efiles, needfiles)
344 repo, self, revmap, trp, efiles, needfiles)
345 revisions += newrevs
345 revisions += newrevs
346 files += newfiles
346 files += newfiles
347
347
348 dh = 0
348 dh = 0
349 if oldheads:
349 if oldheads:
350 heads = cl.heads()
350 heads = cl.heads()
351 dh = len(heads) - len(oldheads)
351 dh = len(heads) - len(oldheads)
352 for h in heads:
352 for h in heads:
353 if h not in oldheads and repo[h].closesbranch():
353 if h not in oldheads and repo[h].closesbranch():
354 dh -= 1
354 dh -= 1
355 htext = ""
355 htext = ""
356 if dh:
356 if dh:
357 htext = _(" (%+d heads)") % dh
357 htext = _(" (%+d heads)") % dh
358
358
359 repo.ui.status(_("added %d changesets"
359 repo.ui.status(_("added %d changesets"
360 " with %d changes to %d files%s\n")
360 " with %d changes to %d files%s\n")
361 % (changesets, revisions, files, htext))
361 % (changesets, revisions, files, htext))
362 repo.invalidatevolatilesets()
362 repo.invalidatevolatilesets()
363
363
364 if changesets > 0:
364 if changesets > 0:
365 if 'node' not in tr.hookargs:
365 if 'node' not in tr.hookargs:
366 tr.hookargs['node'] = hex(cl.node(clstart))
366 tr.hookargs['node'] = hex(cl.node(clstart))
367 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
367 tr.hookargs['node_last'] = hex(cl.node(clend - 1))
368 hookargs = dict(tr.hookargs)
368 hookargs = dict(tr.hookargs)
369 else:
369 else:
370 hookargs = dict(tr.hookargs)
370 hookargs = dict(tr.hookargs)
371 hookargs['node'] = hex(cl.node(clstart))
371 hookargs['node'] = hex(cl.node(clstart))
372 hookargs['node_last'] = hex(cl.node(clend - 1))
372 hookargs['node_last'] = hex(cl.node(clend - 1))
373 repo.hook('pretxnchangegroup', throw=True, **hookargs)
373 repo.hook('pretxnchangegroup', throw=True, **hookargs)
374
374
375 added = [cl.node(r) for r in xrange(clstart, clend)]
375 added = [cl.node(r) for r in xrange(clstart, clend)]
376 publishing = repo.publishing()
376 publishing = repo.publishing()
377 if srctype in ('push', 'serve'):
377 if srctype in ('push', 'serve'):
378 # Old servers can not push the boundary themselves.
378 # Old servers can not push the boundary themselves.
379 # New servers won't push the boundary if changeset already
379 # New servers won't push the boundary if changeset already
380 # exists locally as secret
380 # exists locally as secret
381 #
381 #
382 # We should not use added here but the list of all change in
382 # We should not use added here but the list of all change in
383 # the bundle
383 # the bundle
384 if publishing:
384 if publishing:
385 phases.advanceboundary(repo, tr, phases.public,
385 phases.advanceboundary(repo, tr, phases.public,
386 srccontent)
386 srccontent)
387 else:
387 else:
388 # Those changesets have been pushed from the
388 # Those changesets have been pushed from the
389 # outside, their phases are going to be pushed
389 # outside, their phases are going to be pushed
390 # alongside. Therefor `targetphase` is
390 # alongside. Therefor `targetphase` is
391 # ignored.
391 # ignored.
392 phases.advanceboundary(repo, tr, phases.draft,
392 phases.advanceboundary(repo, tr, phases.draft,
393 srccontent)
393 srccontent)
394 phases.retractboundary(repo, tr, phases.draft, added)
394 phases.retractboundary(repo, tr, phases.draft, added)
395 elif srctype != 'strip':
395 elif srctype != 'strip':
396 # publishing only alter behavior during push
396 # publishing only alter behavior during push
397 #
397 #
398 # strip should not touch boundary at all
398 # strip should not touch boundary at all
399 phases.retractboundary(repo, tr, targetphase, added)
399 phases.retractboundary(repo, tr, targetphase, added)
400
400
401 if changesets > 0:
401 if changesets > 0:
402 if srctype != 'strip':
402 if srctype != 'strip':
403 # During strip, branchcache is invalid but
403 # During strip, branchcache is invalid but
404 # coming call to `destroyed` will repair it.
404 # coming call to `destroyed` will repair it.
405 # In other case we can safely update cache on
405 # In other case we can safely update cache on
406 # disk.
406 # disk.
407 repo.ui.debug('updating the branch cache\n')
407 branchmap.updatecache(repo.filtered('served'))
408 branchmap.updatecache(repo.filtered('served'))
408
409
409 def runhooks():
410 def runhooks():
410 # These hooks run when the lock releases, not when the
411 # These hooks run when the lock releases, not when the
411 # transaction closes. So it's possible for the changelog
412 # transaction closes. So it's possible for the changelog
412 # to have changed since we last saw it.
413 # to have changed since we last saw it.
413 if clstart >= len(repo):
414 if clstart >= len(repo):
414 return
415 return
415
416
416 # forcefully update the on-disk branch cache
417 repo.ui.debug("updating the branch cache\n")
418 repo.hook("changegroup", **hookargs)
417 repo.hook("changegroup", **hookargs)
419
418
420 for n in added:
419 for n in added:
421 args = hookargs.copy()
420 args = hookargs.copy()
422 args['node'] = hex(n)
421 args['node'] = hex(n)
423 del args['node_last']
422 del args['node_last']
424 repo.hook("incoming", **args)
423 repo.hook("incoming", **args)
425
424
426 newheads = [h for h in repo.heads()
425 newheads = [h for h in repo.heads()
427 if h not in oldheads]
426 if h not in oldheads]
428 repo.ui.log("incoming",
427 repo.ui.log("incoming",
429 "%s incoming changes - new heads: %s\n",
428 "%s incoming changes - new heads: %s\n",
430 len(added),
429 len(added),
431 ', '.join([hex(c[:6]) for c in newheads]))
430 ', '.join([hex(c[:6]) for c in newheads]))
432
431
433 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
432 tr.addpostclose('changegroup-runhooks-%020i' % clstart,
434 lambda tr: repo._afterlock(runhooks))
433 lambda tr: repo._afterlock(runhooks))
435 finally:
434 finally:
436 repo.ui.flush()
435 repo.ui.flush()
437 # never return 0 here:
436 # never return 0 here:
438 if dh < 0:
437 if dh < 0:
439 return dh - 1
438 return dh - 1
440 else:
439 else:
441 return dh + 1
440 return dh + 1
442
441
443 class cg2unpacker(cg1unpacker):
442 class cg2unpacker(cg1unpacker):
444 """Unpacker for cg2 streams.
443 """Unpacker for cg2 streams.
445
444
446 cg2 streams add support for generaldelta, so the delta header
445 cg2 streams add support for generaldelta, so the delta header
447 format is slightly different. All other features about the data
446 format is slightly different. All other features about the data
448 remain the same.
447 remain the same.
449 """
448 """
450 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
449 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
451 deltaheadersize = struct.calcsize(deltaheader)
450 deltaheadersize = struct.calcsize(deltaheader)
452 version = '02'
451 version = '02'
453
452
454 def _deltaheader(self, headertuple, prevnode):
453 def _deltaheader(self, headertuple, prevnode):
455 node, p1, p2, deltabase, cs = headertuple
454 node, p1, p2, deltabase, cs = headertuple
456 flags = 0
455 flags = 0
457 return node, p1, p2, deltabase, cs, flags
456 return node, p1, p2, deltabase, cs, flags
458
457
459 class cg3unpacker(cg2unpacker):
458 class cg3unpacker(cg2unpacker):
460 """Unpacker for cg3 streams.
459 """Unpacker for cg3 streams.
461
460
462 cg3 streams add support for exchanging treemanifests and revlog
461 cg3 streams add support for exchanging treemanifests and revlog
463 flags. It adds the revlog flags to the delta header and an empty chunk
462 flags. It adds the revlog flags to the delta header and an empty chunk
464 separating manifests and files.
463 separating manifests and files.
465 """
464 """
466 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
465 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
467 deltaheadersize = struct.calcsize(deltaheader)
466 deltaheadersize = struct.calcsize(deltaheader)
468 version = '03'
467 version = '03'
469 _grouplistcount = 2 # One list of manifests and one list of files
468 _grouplistcount = 2 # One list of manifests and one list of files
470
469
471 def _deltaheader(self, headertuple, prevnode):
470 def _deltaheader(self, headertuple, prevnode):
472 node, p1, p2, deltabase, cs, flags = headertuple
471 node, p1, p2, deltabase, cs, flags = headertuple
473 return node, p1, p2, deltabase, cs, flags
472 return node, p1, p2, deltabase, cs, flags
474
473
475 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
474 def _unpackmanifests(self, repo, revmap, trp, prog, numchanges):
476 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog,
475 super(cg3unpacker, self)._unpackmanifests(repo, revmap, trp, prog,
477 numchanges)
476 numchanges)
478 for chunkdata in iter(self.filelogheader, {}):
477 for chunkdata in iter(self.filelogheader, {}):
479 # If we get here, there are directory manifests in the changegroup
478 # If we get here, there are directory manifests in the changegroup
480 d = chunkdata["filename"]
479 d = chunkdata["filename"]
481 repo.ui.debug("adding %s revisions\n" % d)
480 repo.ui.debug("adding %s revisions\n" % d)
482 dirlog = repo.manifest.dirlog(d)
481 dirlog = repo.manifest.dirlog(d)
483 if not dirlog.addgroup(self, revmap, trp):
482 if not dirlog.addgroup(self, revmap, trp):
484 raise error.Abort(_("received dir revlog group is empty"))
483 raise error.Abort(_("received dir revlog group is empty"))
485
484
486 class headerlessfixup(object):
485 class headerlessfixup(object):
487 def __init__(self, fh, h):
486 def __init__(self, fh, h):
488 self._h = h
487 self._h = h
489 self._fh = fh
488 self._fh = fh
490 def read(self, n):
489 def read(self, n):
491 if self._h:
490 if self._h:
492 d, self._h = self._h[:n], self._h[n:]
491 d, self._h = self._h[:n], self._h[n:]
493 if len(d) < n:
492 if len(d) < n:
494 d += readexactly(self._fh, n - len(d))
493 d += readexactly(self._fh, n - len(d))
495 return d
494 return d
496 return readexactly(self._fh, n)
495 return readexactly(self._fh, n)
497
496
498 class cg1packer(object):
497 class cg1packer(object):
499 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
498 deltaheader = _CHANGEGROUPV1_DELTA_HEADER
500 version = '01'
499 version = '01'
501 def __init__(self, repo, bundlecaps=None):
500 def __init__(self, repo, bundlecaps=None):
502 """Given a source repo, construct a bundler.
501 """Given a source repo, construct a bundler.
503
502
504 bundlecaps is optional and can be used to specify the set of
503 bundlecaps is optional and can be used to specify the set of
505 capabilities which can be used to build the bundle.
504 capabilities which can be used to build the bundle.
506 """
505 """
507 # Set of capabilities we can use to build the bundle.
506 # Set of capabilities we can use to build the bundle.
508 if bundlecaps is None:
507 if bundlecaps is None:
509 bundlecaps = set()
508 bundlecaps = set()
510 self._bundlecaps = bundlecaps
509 self._bundlecaps = bundlecaps
511 # experimental config: bundle.reorder
510 # experimental config: bundle.reorder
512 reorder = repo.ui.config('bundle', 'reorder', 'auto')
511 reorder = repo.ui.config('bundle', 'reorder', 'auto')
513 if reorder == 'auto':
512 if reorder == 'auto':
514 reorder = None
513 reorder = None
515 else:
514 else:
516 reorder = util.parsebool(reorder)
515 reorder = util.parsebool(reorder)
517 self._repo = repo
516 self._repo = repo
518 self._reorder = reorder
517 self._reorder = reorder
519 self._progress = repo.ui.progress
518 self._progress = repo.ui.progress
520 if self._repo.ui.verbose and not self._repo.ui.debugflag:
519 if self._repo.ui.verbose and not self._repo.ui.debugflag:
521 self._verbosenote = self._repo.ui.note
520 self._verbosenote = self._repo.ui.note
522 else:
521 else:
523 self._verbosenote = lambda s: None
522 self._verbosenote = lambda s: None
524
523
525 def close(self):
524 def close(self):
526 return closechunk()
525 return closechunk()
527
526
528 def fileheader(self, fname):
527 def fileheader(self, fname):
529 return chunkheader(len(fname)) + fname
528 return chunkheader(len(fname)) + fname
530
529
531 # Extracted both for clarity and for overriding in extensions.
530 # Extracted both for clarity and for overriding in extensions.
532 def _sortgroup(self, revlog, nodelist, lookup):
531 def _sortgroup(self, revlog, nodelist, lookup):
533 """Sort nodes for change group and turn them into revnums."""
532 """Sort nodes for change group and turn them into revnums."""
534 # for generaldelta revlogs, we linearize the revs; this will both be
533 # for generaldelta revlogs, we linearize the revs; this will both be
535 # much quicker and generate a much smaller bundle
534 # much quicker and generate a much smaller bundle
536 if (revlog._generaldelta and self._reorder is None) or self._reorder:
535 if (revlog._generaldelta and self._reorder is None) or self._reorder:
537 dag = dagutil.revlogdag(revlog)
536 dag = dagutil.revlogdag(revlog)
538 return dag.linearize(set(revlog.rev(n) for n in nodelist))
537 return dag.linearize(set(revlog.rev(n) for n in nodelist))
539 else:
538 else:
540 return sorted([revlog.rev(n) for n in nodelist])
539 return sorted([revlog.rev(n) for n in nodelist])
541
540
542 def group(self, nodelist, revlog, lookup, units=None):
541 def group(self, nodelist, revlog, lookup, units=None):
543 """Calculate a delta group, yielding a sequence of changegroup chunks
542 """Calculate a delta group, yielding a sequence of changegroup chunks
544 (strings).
543 (strings).
545
544
546 Given a list of changeset revs, return a set of deltas and
545 Given a list of changeset revs, return a set of deltas and
547 metadata corresponding to nodes. The first delta is
546 metadata corresponding to nodes. The first delta is
548 first parent(nodelist[0]) -> nodelist[0], the receiver is
547 first parent(nodelist[0]) -> nodelist[0], the receiver is
549 guaranteed to have this parent as it has all history before
548 guaranteed to have this parent as it has all history before
550 these changesets. In the case firstparent is nullrev the
549 these changesets. In the case firstparent is nullrev the
551 changegroup starts with a full revision.
550 changegroup starts with a full revision.
552
551
553 If units is not None, progress detail will be generated, units specifies
552 If units is not None, progress detail will be generated, units specifies
554 the type of revlog that is touched (changelog, manifest, etc.).
553 the type of revlog that is touched (changelog, manifest, etc.).
555 """
554 """
556 # if we don't have any revisions touched by these changesets, bail
555 # if we don't have any revisions touched by these changesets, bail
557 if len(nodelist) == 0:
556 if len(nodelist) == 0:
558 yield self.close()
557 yield self.close()
559 return
558 return
560
559
561 revs = self._sortgroup(revlog, nodelist, lookup)
560 revs = self._sortgroup(revlog, nodelist, lookup)
562
561
563 # add the parent of the first rev
562 # add the parent of the first rev
564 p = revlog.parentrevs(revs[0])[0]
563 p = revlog.parentrevs(revs[0])[0]
565 revs.insert(0, p)
564 revs.insert(0, p)
566
565
567 # build deltas
566 # build deltas
568 total = len(revs) - 1
567 total = len(revs) - 1
569 msgbundling = _('bundling')
568 msgbundling = _('bundling')
570 for r in xrange(len(revs) - 1):
569 for r in xrange(len(revs) - 1):
571 if units is not None:
570 if units is not None:
572 self._progress(msgbundling, r + 1, unit=units, total=total)
571 self._progress(msgbundling, r + 1, unit=units, total=total)
573 prev, curr = revs[r], revs[r + 1]
572 prev, curr = revs[r], revs[r + 1]
574 linknode = lookup(revlog.node(curr))
573 linknode = lookup(revlog.node(curr))
575 for c in self.revchunk(revlog, curr, prev, linknode):
574 for c in self.revchunk(revlog, curr, prev, linknode):
576 yield c
575 yield c
577
576
578 if units is not None:
577 if units is not None:
579 self._progress(msgbundling, None)
578 self._progress(msgbundling, None)
580 yield self.close()
579 yield self.close()
581
580
582 # filter any nodes that claim to be part of the known set
581 # filter any nodes that claim to be part of the known set
583 def prune(self, revlog, missing, commonrevs):
582 def prune(self, revlog, missing, commonrevs):
584 rr, rl = revlog.rev, revlog.linkrev
583 rr, rl = revlog.rev, revlog.linkrev
585 return [n for n in missing if rl(rr(n)) not in commonrevs]
584 return [n for n in missing if rl(rr(n)) not in commonrevs]
586
585
587 def _packmanifests(self, dir, mfnodes, lookuplinknode):
586 def _packmanifests(self, dir, mfnodes, lookuplinknode):
588 """Pack flat manifests into a changegroup stream."""
587 """Pack flat manifests into a changegroup stream."""
589 assert not dir
588 assert not dir
590 for chunk in self.group(mfnodes, self._repo.manifest,
589 for chunk in self.group(mfnodes, self._repo.manifest,
591 lookuplinknode, units=_('manifests')):
590 lookuplinknode, units=_('manifests')):
592 yield chunk
591 yield chunk
593
592
594 def _manifestsdone(self):
593 def _manifestsdone(self):
595 return ''
594 return ''
596
595
597 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
596 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
598 '''yield a sequence of changegroup chunks (strings)'''
597 '''yield a sequence of changegroup chunks (strings)'''
599 repo = self._repo
598 repo = self._repo
600 cl = repo.changelog
599 cl = repo.changelog
601
600
602 clrevorder = {}
601 clrevorder = {}
603 mfs = {} # needed manifests
602 mfs = {} # needed manifests
604 fnodes = {} # needed file nodes
603 fnodes = {} # needed file nodes
605 changedfiles = set()
604 changedfiles = set()
606
605
607 # Callback for the changelog, used to collect changed files and manifest
606 # Callback for the changelog, used to collect changed files and manifest
608 # nodes.
607 # nodes.
609 # Returns the linkrev node (identity in the changelog case).
608 # Returns the linkrev node (identity in the changelog case).
610 def lookupcl(x):
609 def lookupcl(x):
611 c = cl.read(x)
610 c = cl.read(x)
612 clrevorder[x] = len(clrevorder)
611 clrevorder[x] = len(clrevorder)
613 n = c[0]
612 n = c[0]
614 # record the first changeset introducing this manifest version
613 # record the first changeset introducing this manifest version
615 mfs.setdefault(n, x)
614 mfs.setdefault(n, x)
616 # Record a complete list of potentially-changed files in
615 # Record a complete list of potentially-changed files in
617 # this manifest.
616 # this manifest.
618 changedfiles.update(c[3])
617 changedfiles.update(c[3])
619 return x
618 return x
620
619
621 self._verbosenote(_('uncompressed size of bundle content:\n'))
620 self._verbosenote(_('uncompressed size of bundle content:\n'))
622 size = 0
621 size = 0
623 for chunk in self.group(clnodes, cl, lookupcl, units=_('changesets')):
622 for chunk in self.group(clnodes, cl, lookupcl, units=_('changesets')):
624 size += len(chunk)
623 size += len(chunk)
625 yield chunk
624 yield chunk
626 self._verbosenote(_('%8.i (changelog)\n') % size)
625 self._verbosenote(_('%8.i (changelog)\n') % size)
627
626
628 # We need to make sure that the linkrev in the changegroup refers to
627 # We need to make sure that the linkrev in the changegroup refers to
629 # the first changeset that introduced the manifest or file revision.
628 # the first changeset that introduced the manifest or file revision.
630 # The fastpath is usually safer than the slowpath, because the filelogs
629 # The fastpath is usually safer than the slowpath, because the filelogs
631 # are walked in revlog order.
630 # are walked in revlog order.
632 #
631 #
633 # When taking the slowpath with reorder=None and the manifest revlog
632 # When taking the slowpath with reorder=None and the manifest revlog
634 # uses generaldelta, the manifest may be walked in the "wrong" order.
633 # uses generaldelta, the manifest may be walked in the "wrong" order.
635 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
634 # Without 'clrevorder', we would get an incorrect linkrev (see fix in
636 # cc0ff93d0c0c).
635 # cc0ff93d0c0c).
637 #
636 #
638 # When taking the fastpath, we are only vulnerable to reordering
637 # When taking the fastpath, we are only vulnerable to reordering
639 # of the changelog itself. The changelog never uses generaldelta, so
638 # of the changelog itself. The changelog never uses generaldelta, so
640 # it is only reordered when reorder=True. To handle this case, we
639 # it is only reordered when reorder=True. To handle this case, we
641 # simply take the slowpath, which already has the 'clrevorder' logic.
640 # simply take the slowpath, which already has the 'clrevorder' logic.
642 # This was also fixed in cc0ff93d0c0c.
641 # This was also fixed in cc0ff93d0c0c.
643 fastpathlinkrev = fastpathlinkrev and not self._reorder
642 fastpathlinkrev = fastpathlinkrev and not self._reorder
644 # Treemanifests don't work correctly with fastpathlinkrev
643 # Treemanifests don't work correctly with fastpathlinkrev
645 # either, because we don't discover which directory nodes to
644 # either, because we don't discover which directory nodes to
646 # send along with files. This could probably be fixed.
645 # send along with files. This could probably be fixed.
647 fastpathlinkrev = fastpathlinkrev and (
646 fastpathlinkrev = fastpathlinkrev and (
648 'treemanifest' not in repo.requirements)
647 'treemanifest' not in repo.requirements)
649
648
650 for chunk in self.generatemanifests(commonrevs, clrevorder,
649 for chunk in self.generatemanifests(commonrevs, clrevorder,
651 fastpathlinkrev, mfs, fnodes):
650 fastpathlinkrev, mfs, fnodes):
652 yield chunk
651 yield chunk
653 mfs.clear()
652 mfs.clear()
654 clrevs = set(cl.rev(x) for x in clnodes)
653 clrevs = set(cl.rev(x) for x in clnodes)
655
654
656 if not fastpathlinkrev:
655 if not fastpathlinkrev:
657 def linknodes(unused, fname):
656 def linknodes(unused, fname):
658 return fnodes.get(fname, {})
657 return fnodes.get(fname, {})
659 else:
658 else:
660 cln = cl.node
659 cln = cl.node
661 def linknodes(filerevlog, fname):
660 def linknodes(filerevlog, fname):
662 llr = filerevlog.linkrev
661 llr = filerevlog.linkrev
663 fln = filerevlog.node
662 fln = filerevlog.node
664 revs = ((r, llr(r)) for r in filerevlog)
663 revs = ((r, llr(r)) for r in filerevlog)
665 return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs)
664 return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs)
666
665
667 for chunk in self.generatefiles(changedfiles, linknodes, commonrevs,
666 for chunk in self.generatefiles(changedfiles, linknodes, commonrevs,
668 source):
667 source):
669 yield chunk
668 yield chunk
670
669
671 yield self.close()
670 yield self.close()
672
671
673 if clnodes:
672 if clnodes:
674 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
673 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
675
674
676 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
675 def generatemanifests(self, commonrevs, clrevorder, fastpathlinkrev, mfs,
677 fnodes):
676 fnodes):
678 repo = self._repo
677 repo = self._repo
679 dirlog = repo.manifest.dirlog
678 dirlog = repo.manifest.dirlog
680 tmfnodes = {'': mfs}
679 tmfnodes = {'': mfs}
681
680
682 # Callback for the manifest, used to collect linkrevs for filelog
681 # Callback for the manifest, used to collect linkrevs for filelog
683 # revisions.
682 # revisions.
684 # Returns the linkrev node (collected in lookupcl).
683 # Returns the linkrev node (collected in lookupcl).
685 def makelookupmflinknode(dir):
684 def makelookupmflinknode(dir):
686 if fastpathlinkrev:
685 if fastpathlinkrev:
687 assert not dir
686 assert not dir
688 return mfs.__getitem__
687 return mfs.__getitem__
689
688
690 def lookupmflinknode(x):
689 def lookupmflinknode(x):
691 """Callback for looking up the linknode for manifests.
690 """Callback for looking up the linknode for manifests.
692
691
693 Returns the linkrev node for the specified manifest.
692 Returns the linkrev node for the specified manifest.
694
693
695 SIDE EFFECT:
694 SIDE EFFECT:
696
695
697 1) fclnodes gets populated with the list of relevant
696 1) fclnodes gets populated with the list of relevant
698 file nodes if we're not using fastpathlinkrev
697 file nodes if we're not using fastpathlinkrev
699 2) When treemanifests are in use, collects treemanifest nodes
698 2) When treemanifests are in use, collects treemanifest nodes
700 to send
699 to send
701
700
702 Note that this means manifests must be completely sent to
701 Note that this means manifests must be completely sent to
703 the client before you can trust the list of files and
702 the client before you can trust the list of files and
704 treemanifests to send.
703 treemanifests to send.
705 """
704 """
706 clnode = tmfnodes[dir][x]
705 clnode = tmfnodes[dir][x]
707 mdata = dirlog(dir).readshallowfast(x)
706 mdata = dirlog(dir).readshallowfast(x)
708 for p, n, fl in mdata.iterentries():
707 for p, n, fl in mdata.iterentries():
709 if fl == 't': # subdirectory manifest
708 if fl == 't': # subdirectory manifest
710 subdir = dir + p + '/'
709 subdir = dir + p + '/'
711 tmfclnodes = tmfnodes.setdefault(subdir, {})
710 tmfclnodes = tmfnodes.setdefault(subdir, {})
712 tmfclnode = tmfclnodes.setdefault(n, clnode)
711 tmfclnode = tmfclnodes.setdefault(n, clnode)
713 if clrevorder[clnode] < clrevorder[tmfclnode]:
712 if clrevorder[clnode] < clrevorder[tmfclnode]:
714 tmfclnodes[n] = clnode
713 tmfclnodes[n] = clnode
715 else:
714 else:
716 f = dir + p
715 f = dir + p
717 fclnodes = fnodes.setdefault(f, {})
716 fclnodes = fnodes.setdefault(f, {})
718 fclnode = fclnodes.setdefault(n, clnode)
717 fclnode = fclnodes.setdefault(n, clnode)
719 if clrevorder[clnode] < clrevorder[fclnode]:
718 if clrevorder[clnode] < clrevorder[fclnode]:
720 fclnodes[n] = clnode
719 fclnodes[n] = clnode
721 return clnode
720 return clnode
722 return lookupmflinknode
721 return lookupmflinknode
723
722
724 size = 0
723 size = 0
725 while tmfnodes:
724 while tmfnodes:
726 dir = min(tmfnodes)
725 dir = min(tmfnodes)
727 nodes = tmfnodes[dir]
726 nodes = tmfnodes[dir]
728 prunednodes = self.prune(dirlog(dir), nodes, commonrevs)
727 prunednodes = self.prune(dirlog(dir), nodes, commonrevs)
729 if not dir or prunednodes:
728 if not dir or prunednodes:
730 for x in self._packmanifests(dir, prunednodes,
729 for x in self._packmanifests(dir, prunednodes,
731 makelookupmflinknode(dir)):
730 makelookupmflinknode(dir)):
732 size += len(x)
731 size += len(x)
733 yield x
732 yield x
734 del tmfnodes[dir]
733 del tmfnodes[dir]
735 self._verbosenote(_('%8.i (manifests)\n') % size)
734 self._verbosenote(_('%8.i (manifests)\n') % size)
736 yield self._manifestsdone()
735 yield self._manifestsdone()
737
736
738 # The 'source' parameter is useful for extensions
737 # The 'source' parameter is useful for extensions
739 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
738 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
740 repo = self._repo
739 repo = self._repo
741 progress = self._progress
740 progress = self._progress
742 msgbundling = _('bundling')
741 msgbundling = _('bundling')
743
742
744 total = len(changedfiles)
743 total = len(changedfiles)
745 # for progress output
744 # for progress output
746 msgfiles = _('files')
745 msgfiles = _('files')
747 for i, fname in enumerate(sorted(changedfiles)):
746 for i, fname in enumerate(sorted(changedfiles)):
748 filerevlog = repo.file(fname)
747 filerevlog = repo.file(fname)
749 if not filerevlog:
748 if not filerevlog:
750 raise error.Abort(_("empty or missing revlog for %s") % fname)
749 raise error.Abort(_("empty or missing revlog for %s") % fname)
751
750
752 linkrevnodes = linknodes(filerevlog, fname)
751 linkrevnodes = linknodes(filerevlog, fname)
753 # Lookup for filenodes, we collected the linkrev nodes above in the
752 # Lookup for filenodes, we collected the linkrev nodes above in the
754 # fastpath case and with lookupmf in the slowpath case.
753 # fastpath case and with lookupmf in the slowpath case.
755 def lookupfilelog(x):
754 def lookupfilelog(x):
756 return linkrevnodes[x]
755 return linkrevnodes[x]
757
756
758 filenodes = self.prune(filerevlog, linkrevnodes, commonrevs)
757 filenodes = self.prune(filerevlog, linkrevnodes, commonrevs)
759 if filenodes:
758 if filenodes:
760 progress(msgbundling, i + 1, item=fname, unit=msgfiles,
759 progress(msgbundling, i + 1, item=fname, unit=msgfiles,
761 total=total)
760 total=total)
762 h = self.fileheader(fname)
761 h = self.fileheader(fname)
763 size = len(h)
762 size = len(h)
764 yield h
763 yield h
765 for chunk in self.group(filenodes, filerevlog, lookupfilelog):
764 for chunk in self.group(filenodes, filerevlog, lookupfilelog):
766 size += len(chunk)
765 size += len(chunk)
767 yield chunk
766 yield chunk
768 self._verbosenote(_('%8.i %s\n') % (size, fname))
767 self._verbosenote(_('%8.i %s\n') % (size, fname))
769 progress(msgbundling, None)
768 progress(msgbundling, None)
770
769
771 def deltaparent(self, revlog, rev, p1, p2, prev):
770 def deltaparent(self, revlog, rev, p1, p2, prev):
772 return prev
771 return prev
773
772
774 def revchunk(self, revlog, rev, prev, linknode):
773 def revchunk(self, revlog, rev, prev, linknode):
775 node = revlog.node(rev)
774 node = revlog.node(rev)
776 p1, p2 = revlog.parentrevs(rev)
775 p1, p2 = revlog.parentrevs(rev)
777 base = self.deltaparent(revlog, rev, p1, p2, prev)
776 base = self.deltaparent(revlog, rev, p1, p2, prev)
778
777
779 prefix = ''
778 prefix = ''
780 if revlog.iscensored(base) or revlog.iscensored(rev):
779 if revlog.iscensored(base) or revlog.iscensored(rev):
781 try:
780 try:
782 delta = revlog.revision(node)
781 delta = revlog.revision(node)
783 except error.CensoredNodeError as e:
782 except error.CensoredNodeError as e:
784 delta = e.tombstone
783 delta = e.tombstone
785 if base == nullrev:
784 if base == nullrev:
786 prefix = mdiff.trivialdiffheader(len(delta))
785 prefix = mdiff.trivialdiffheader(len(delta))
787 else:
786 else:
788 baselen = revlog.rawsize(base)
787 baselen = revlog.rawsize(base)
789 prefix = mdiff.replacediffheader(baselen, len(delta))
788 prefix = mdiff.replacediffheader(baselen, len(delta))
790 elif base == nullrev:
789 elif base == nullrev:
791 delta = revlog.revision(node)
790 delta = revlog.revision(node)
792 prefix = mdiff.trivialdiffheader(len(delta))
791 prefix = mdiff.trivialdiffheader(len(delta))
793 else:
792 else:
794 delta = revlog.revdiff(base, rev)
793 delta = revlog.revdiff(base, rev)
795 p1n, p2n = revlog.parents(node)
794 p1n, p2n = revlog.parents(node)
796 basenode = revlog.node(base)
795 basenode = revlog.node(base)
797 flags = revlog.flags(rev)
796 flags = revlog.flags(rev)
798 meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags)
797 meta = self.builddeltaheader(node, p1n, p2n, basenode, linknode, flags)
799 meta += prefix
798 meta += prefix
800 l = len(meta) + len(delta)
799 l = len(meta) + len(delta)
801 yield chunkheader(l)
800 yield chunkheader(l)
802 yield meta
801 yield meta
803 yield delta
802 yield delta
804 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
803 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
805 # do nothing with basenode, it is implicitly the previous one in HG10
804 # do nothing with basenode, it is implicitly the previous one in HG10
806 # do nothing with flags, it is implicitly 0 for cg1 and cg2
805 # do nothing with flags, it is implicitly 0 for cg1 and cg2
807 return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
806 return struct.pack(self.deltaheader, node, p1n, p2n, linknode)
808
807
809 class cg2packer(cg1packer):
808 class cg2packer(cg1packer):
810 version = '02'
809 version = '02'
811 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
810 deltaheader = _CHANGEGROUPV2_DELTA_HEADER
812
811
813 def __init__(self, repo, bundlecaps=None):
812 def __init__(self, repo, bundlecaps=None):
814 super(cg2packer, self).__init__(repo, bundlecaps)
813 super(cg2packer, self).__init__(repo, bundlecaps)
815 if self._reorder is None:
814 if self._reorder is None:
816 # Since generaldelta is directly supported by cg2, reordering
815 # Since generaldelta is directly supported by cg2, reordering
817 # generally doesn't help, so we disable it by default (treating
816 # generally doesn't help, so we disable it by default (treating
818 # bundle.reorder=auto just like bundle.reorder=False).
817 # bundle.reorder=auto just like bundle.reorder=False).
819 self._reorder = False
818 self._reorder = False
820
819
821 def deltaparent(self, revlog, rev, p1, p2, prev):
820 def deltaparent(self, revlog, rev, p1, p2, prev):
822 dp = revlog.deltaparent(rev)
821 dp = revlog.deltaparent(rev)
823 # avoid storing full revisions; pick prev in those cases
822 # avoid storing full revisions; pick prev in those cases
824 # also pick prev when we can't be sure remote has dp
823 # also pick prev when we can't be sure remote has dp
825 if dp == nullrev or (dp != p1 and dp != p2 and dp != prev):
824 if dp == nullrev or (dp != p1 and dp != p2 and dp != prev):
826 return prev
825 return prev
827 return dp
826 return dp
828
827
829 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
828 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
830 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
829 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
831 return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode)
830 return struct.pack(self.deltaheader, node, p1n, p2n, basenode, linknode)
832
831
833 class cg3packer(cg2packer):
832 class cg3packer(cg2packer):
834 version = '03'
833 version = '03'
835 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
834 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
836
835
837 def _packmanifests(self, dir, mfnodes, lookuplinknode):
836 def _packmanifests(self, dir, mfnodes, lookuplinknode):
838 if dir:
837 if dir:
839 yield self.fileheader(dir)
838 yield self.fileheader(dir)
840 for chunk in self.group(mfnodes, self._repo.manifest.dirlog(dir),
839 for chunk in self.group(mfnodes, self._repo.manifest.dirlog(dir),
841 lookuplinknode, units=_('manifests')):
840 lookuplinknode, units=_('manifests')):
842 yield chunk
841 yield chunk
843
842
844 def _manifestsdone(self):
843 def _manifestsdone(self):
845 return self.close()
844 return self.close()
846
845
847 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
846 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
848 return struct.pack(
847 return struct.pack(
849 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
848 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
850
849
851 _packermap = {'01': (cg1packer, cg1unpacker),
850 _packermap = {'01': (cg1packer, cg1unpacker),
852 # cg2 adds support for exchanging generaldelta
851 # cg2 adds support for exchanging generaldelta
853 '02': (cg2packer, cg2unpacker),
852 '02': (cg2packer, cg2unpacker),
854 # cg3 adds support for exchanging revlog flags and treemanifests
853 # cg3 adds support for exchanging revlog flags and treemanifests
855 '03': (cg3packer, cg3unpacker),
854 '03': (cg3packer, cg3unpacker),
856 }
855 }
857
856
858 def allsupportedversions(ui):
857 def allsupportedversions(ui):
859 versions = set(_packermap.keys())
858 versions = set(_packermap.keys())
860 versions.discard('03')
859 versions.discard('03')
861 if (ui.configbool('experimental', 'changegroup3') or
860 if (ui.configbool('experimental', 'changegroup3') or
862 ui.configbool('experimental', 'treemanifest')):
861 ui.configbool('experimental', 'treemanifest')):
863 versions.add('03')
862 versions.add('03')
864 return versions
863 return versions
865
864
866 # Changegroup versions that can be applied to the repo
865 # Changegroup versions that can be applied to the repo
867 def supportedincomingversions(repo):
866 def supportedincomingversions(repo):
868 versions = allsupportedversions(repo.ui)
867 versions = allsupportedversions(repo.ui)
869 if 'treemanifest' in repo.requirements:
868 if 'treemanifest' in repo.requirements:
870 versions.add('03')
869 versions.add('03')
871 return versions
870 return versions
872
871
873 # Changegroup versions that can be created from the repo
872 # Changegroup versions that can be created from the repo
874 def supportedoutgoingversions(repo):
873 def supportedoutgoingversions(repo):
875 versions = allsupportedversions(repo.ui)
874 versions = allsupportedversions(repo.ui)
876 if 'treemanifest' in repo.requirements:
875 if 'treemanifest' in repo.requirements:
877 # Versions 01 and 02 support only flat manifests and it's just too
876 # Versions 01 and 02 support only flat manifests and it's just too
878 # expensive to convert between the flat manifest and tree manifest on
877 # expensive to convert between the flat manifest and tree manifest on
879 # the fly. Since tree manifests are hashed differently, all of history
878 # the fly. Since tree manifests are hashed differently, all of history
880 # would have to be converted. Instead, we simply don't even pretend to
879 # would have to be converted. Instead, we simply don't even pretend to
881 # support versions 01 and 02.
880 # support versions 01 and 02.
882 versions.discard('01')
881 versions.discard('01')
883 versions.discard('02')
882 versions.discard('02')
884 versions.add('03')
883 versions.add('03')
885 return versions
884 return versions
886
885
887 def safeversion(repo):
886 def safeversion(repo):
888 # Finds the smallest version that it's safe to assume clients of the repo
887 # Finds the smallest version that it's safe to assume clients of the repo
889 # will support. For example, all hg versions that support generaldelta also
888 # will support. For example, all hg versions that support generaldelta also
890 # support changegroup 02.
889 # support changegroup 02.
891 versions = supportedoutgoingversions(repo)
890 versions = supportedoutgoingversions(repo)
892 if 'generaldelta' in repo.requirements:
891 if 'generaldelta' in repo.requirements:
893 versions.discard('01')
892 versions.discard('01')
894 assert versions
893 assert versions
895 return min(versions)
894 return min(versions)
896
895
897 def getbundler(version, repo, bundlecaps=None):
896 def getbundler(version, repo, bundlecaps=None):
898 assert version in supportedoutgoingversions(repo)
897 assert version in supportedoutgoingversions(repo)
899 return _packermap[version][0](repo, bundlecaps)
898 return _packermap[version][0](repo, bundlecaps)
900
899
901 def getunbundler(version, fh, alg, extras=None):
900 def getunbundler(version, fh, alg, extras=None):
902 return _packermap[version][1](fh, alg, extras=extras)
901 return _packermap[version][1](fh, alg, extras=extras)
903
902
904 def _changegroupinfo(repo, nodes, source):
903 def _changegroupinfo(repo, nodes, source):
905 if repo.ui.verbose or source == 'bundle':
904 if repo.ui.verbose or source == 'bundle':
906 repo.ui.status(_("%d changesets found\n") % len(nodes))
905 repo.ui.status(_("%d changesets found\n") % len(nodes))
907 if repo.ui.debugflag:
906 if repo.ui.debugflag:
908 repo.ui.debug("list of changesets:\n")
907 repo.ui.debug("list of changesets:\n")
909 for node in nodes:
908 for node in nodes:
910 repo.ui.debug("%s\n" % hex(node))
909 repo.ui.debug("%s\n" % hex(node))
911
910
912 def getsubsetraw(repo, outgoing, bundler, source, fastpath=False):
911 def getsubsetraw(repo, outgoing, bundler, source, fastpath=False):
913 repo = repo.unfiltered()
912 repo = repo.unfiltered()
914 commonrevs = outgoing.common
913 commonrevs = outgoing.common
915 csets = outgoing.missing
914 csets = outgoing.missing
916 heads = outgoing.missingheads
915 heads = outgoing.missingheads
917 # We go through the fast path if we get told to, or if all (unfiltered
916 # We go through the fast path if we get told to, or if all (unfiltered
918 # heads have been requested (since we then know there all linkrevs will
917 # heads have been requested (since we then know there all linkrevs will
919 # be pulled by the client).
918 # be pulled by the client).
920 heads.sort()
919 heads.sort()
921 fastpathlinkrev = fastpath or (
920 fastpathlinkrev = fastpath or (
922 repo.filtername is None and heads == sorted(repo.heads()))
921 repo.filtername is None and heads == sorted(repo.heads()))
923
922
924 repo.hook('preoutgoing', throw=True, source=source)
923 repo.hook('preoutgoing', throw=True, source=source)
925 _changegroupinfo(repo, csets, source)
924 _changegroupinfo(repo, csets, source)
926 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
925 return bundler.generate(commonrevs, csets, fastpathlinkrev, source)
927
926
928 def getsubset(repo, outgoing, bundler, source, fastpath=False):
927 def getsubset(repo, outgoing, bundler, source, fastpath=False):
929 gengroup = getsubsetraw(repo, outgoing, bundler, source, fastpath)
928 gengroup = getsubsetraw(repo, outgoing, bundler, source, fastpath)
930 return getunbundler(bundler.version, util.chunkbuffer(gengroup), None,
929 return getunbundler(bundler.version, util.chunkbuffer(gengroup), None,
931 {'clcount': len(outgoing.missing)})
930 {'clcount': len(outgoing.missing)})
932
931
933 def changegroupsubset(repo, roots, heads, source, version='01'):
932 def changegroupsubset(repo, roots, heads, source, version='01'):
934 """Compute a changegroup consisting of all the nodes that are
933 """Compute a changegroup consisting of all the nodes that are
935 descendants of any of the roots and ancestors of any of the heads.
934 descendants of any of the roots and ancestors of any of the heads.
936 Return a chunkbuffer object whose read() method will return
935 Return a chunkbuffer object whose read() method will return
937 successive changegroup chunks.
936 successive changegroup chunks.
938
937
939 It is fairly complex as determining which filenodes and which
938 It is fairly complex as determining which filenodes and which
940 manifest nodes need to be included for the changeset to be complete
939 manifest nodes need to be included for the changeset to be complete
941 is non-trivial.
940 is non-trivial.
942
941
943 Another wrinkle is doing the reverse, figuring out which changeset in
942 Another wrinkle is doing the reverse, figuring out which changeset in
944 the changegroup a particular filenode or manifestnode belongs to.
943 the changegroup a particular filenode or manifestnode belongs to.
945 """
944 """
946 outgoing = discovery.outgoingbetween(repo, roots, heads)
945 outgoing = discovery.outgoingbetween(repo, roots, heads)
947 bundler = getbundler(version, repo)
946 bundler = getbundler(version, repo)
948 return getsubset(repo, outgoing, bundler, source)
947 return getsubset(repo, outgoing, bundler, source)
949
948
950 def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None,
949 def getlocalchangegroupraw(repo, source, outgoing, bundlecaps=None,
951 version='01'):
950 version='01'):
952 """Like getbundle, but taking a discovery.outgoing as an argument.
951 """Like getbundle, but taking a discovery.outgoing as an argument.
953
952
954 This is only implemented for local repos and reuses potentially
953 This is only implemented for local repos and reuses potentially
955 precomputed sets in outgoing. Returns a raw changegroup generator."""
954 precomputed sets in outgoing. Returns a raw changegroup generator."""
956 if not outgoing.missing:
955 if not outgoing.missing:
957 return None
956 return None
958 bundler = getbundler(version, repo, bundlecaps)
957 bundler = getbundler(version, repo, bundlecaps)
959 return getsubsetraw(repo, outgoing, bundler, source)
958 return getsubsetraw(repo, outgoing, bundler, source)
960
959
961 def getlocalchangegroup(repo, source, outgoing, bundlecaps=None,
960 def getlocalchangegroup(repo, source, outgoing, bundlecaps=None,
962 version='01'):
961 version='01'):
963 """Like getbundle, but taking a discovery.outgoing as an argument.
962 """Like getbundle, but taking a discovery.outgoing as an argument.
964
963
965 This is only implemented for local repos and reuses potentially
964 This is only implemented for local repos and reuses potentially
966 precomputed sets in outgoing."""
965 precomputed sets in outgoing."""
967 if not outgoing.missing:
966 if not outgoing.missing:
968 return None
967 return None
969 bundler = getbundler(version, repo, bundlecaps)
968 bundler = getbundler(version, repo, bundlecaps)
970 return getsubset(repo, outgoing, bundler, source)
969 return getsubset(repo, outgoing, bundler, source)
971
970
972 def computeoutgoing(repo, heads, common):
971 def computeoutgoing(repo, heads, common):
973 """Computes which revs are outgoing given a set of common
972 """Computes which revs are outgoing given a set of common
974 and a set of heads.
973 and a set of heads.
975
974
976 This is a separate function so extensions can have access to
975 This is a separate function so extensions can have access to
977 the logic.
976 the logic.
978
977
979 Returns a discovery.outgoing object.
978 Returns a discovery.outgoing object.
980 """
979 """
981 cl = repo.changelog
980 cl = repo.changelog
982 if common:
981 if common:
983 hasnode = cl.hasnode
982 hasnode = cl.hasnode
984 common = [n for n in common if hasnode(n)]
983 common = [n for n in common if hasnode(n)]
985 else:
984 else:
986 common = [nullid]
985 common = [nullid]
987 if not heads:
986 if not heads:
988 heads = cl.heads()
987 heads = cl.heads()
989 return discovery.outgoing(cl, common, heads)
988 return discovery.outgoing(cl, common, heads)
990
989
991 def getchangegroup(repo, source, heads=None, common=None, bundlecaps=None,
990 def getchangegroup(repo, source, heads=None, common=None, bundlecaps=None,
992 version='01'):
991 version='01'):
993 """Like changegroupsubset, but returns the set difference between the
992 """Like changegroupsubset, but returns the set difference between the
994 ancestors of heads and the ancestors common.
993 ancestors of heads and the ancestors common.
995
994
996 If heads is None, use the local heads. If common is None, use [nullid].
995 If heads is None, use the local heads. If common is None, use [nullid].
997
996
998 The nodes in common might not all be known locally due to the way the
997 The nodes in common might not all be known locally due to the way the
999 current discovery protocol works.
998 current discovery protocol works.
1000 """
999 """
1001 outgoing = computeoutgoing(repo, heads, common)
1000 outgoing = computeoutgoing(repo, heads, common)
1002 return getlocalchangegroup(repo, source, outgoing, bundlecaps=bundlecaps,
1001 return getlocalchangegroup(repo, source, outgoing, bundlecaps=bundlecaps,
1003 version=version)
1002 version=version)
1004
1003
1005 def changegroup(repo, basenodes, source):
1004 def changegroup(repo, basenodes, source):
1006 # to avoid a race we use changegroupsubset() (issue1320)
1005 # to avoid a race we use changegroupsubset() (issue1320)
1007 return changegroupsubset(repo, basenodes, repo.heads(), source)
1006 return changegroupsubset(repo, basenodes, repo.heads(), source)
1008
1007
1009 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1008 def _addchangegroupfiles(repo, source, revmap, trp, expectedfiles, needfiles):
1010 revisions = 0
1009 revisions = 0
1011 files = 0
1010 files = 0
1012 for chunkdata in iter(source.filelogheader, {}):
1011 for chunkdata in iter(source.filelogheader, {}):
1013 files += 1
1012 files += 1
1014 f = chunkdata["filename"]
1013 f = chunkdata["filename"]
1015 repo.ui.debug("adding %s revisions\n" % f)
1014 repo.ui.debug("adding %s revisions\n" % f)
1016 repo.ui.progress(_('files'), files, unit=_('files'),
1015 repo.ui.progress(_('files'), files, unit=_('files'),
1017 total=expectedfiles)
1016 total=expectedfiles)
1018 fl = repo.file(f)
1017 fl = repo.file(f)
1019 o = len(fl)
1018 o = len(fl)
1020 try:
1019 try:
1021 if not fl.addgroup(source, revmap, trp):
1020 if not fl.addgroup(source, revmap, trp):
1022 raise error.Abort(_("received file revlog group is empty"))
1021 raise error.Abort(_("received file revlog group is empty"))
1023 except error.CensoredBaseError as e:
1022 except error.CensoredBaseError as e:
1024 raise error.Abort(_("received delta base is censored: %s") % e)
1023 raise error.Abort(_("received delta base is censored: %s") % e)
1025 revisions += len(fl) - o
1024 revisions += len(fl) - o
1026 if f in needfiles:
1025 if f in needfiles:
1027 needs = needfiles[f]
1026 needs = needfiles[f]
1028 for new in xrange(o, len(fl)):
1027 for new in xrange(o, len(fl)):
1029 n = fl.node(new)
1028 n = fl.node(new)
1030 if n in needs:
1029 if n in needs:
1031 needs.remove(n)
1030 needs.remove(n)
1032 else:
1031 else:
1033 raise error.Abort(
1032 raise error.Abort(
1034 _("received spurious file revlog entry"))
1033 _("received spurious file revlog entry"))
1035 if not needs:
1034 if not needs:
1036 del needfiles[f]
1035 del needfiles[f]
1037 repo.ui.progress(_('files'), None)
1036 repo.ui.progress(_('files'), None)
1038
1037
1039 for f, needs in needfiles.iteritems():
1038 for f, needs in needfiles.iteritems():
1040 fl = repo.file(f)
1039 fl = repo.file(f)
1041 for n in needs:
1040 for n in needs:
1042 try:
1041 try:
1043 fl.rev(n)
1042 fl.rev(n)
1044 except error.LookupError:
1043 except error.LookupError:
1045 raise error.Abort(
1044 raise error.Abort(
1046 _('missing file data for %s:%s - run hg verify') %
1045 _('missing file data for %s:%s - run hg verify') %
1047 (f, hex(n)))
1046 (f, hex(n)))
1048
1047
1049 return revisions, files
1048 return revisions, files
@@ -1,2148 +1,2148 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 -n '/\[[ha]/,$p' b/.hg/hgrc | grep -v fakegroups.py
7 > sed -n '/\[[ha]/,$p' 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 "phases"
86 checking for updated bookmarks
86 checking for updated bookmarks
87 listing keys for "bookmarks"
87 listing keys for "bookmarks"
88 listing keys for "bookmarks"
88 listing keys for "bookmarks"
89 3 changesets found
89 3 changesets found
90 list of changesets:
90 list of changesets:
91 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
91 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
92 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
92 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
93 911600dab2ae7a9baff75958b84fe606851ce955
93 911600dab2ae7a9baff75958b84fe606851ce955
94 bundle2-output-bundle: "HG20", 4 parts total
94 bundle2-output-bundle: "HG20", 4 parts total
95 bundle2-output-part: "replycaps" 155 bytes payload
95 bundle2-output-part: "replycaps" 155 bytes payload
96 bundle2-output-part: "check:heads" streamed payload
96 bundle2-output-part: "check:heads" streamed payload
97 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
97 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
98 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
98 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
99 bundle2-input-bundle: with-transaction
99 bundle2-input-bundle: with-transaction
100 bundle2-input-part: "replycaps" supported
100 bundle2-input-part: "replycaps" supported
101 bundle2-input-part: total payload size 155
101 bundle2-input-part: total payload size 155
102 bundle2-input-part: "check:heads" supported
102 bundle2-input-part: "check:heads" supported
103 bundle2-input-part: total payload size 20
103 bundle2-input-part: total payload size 20
104 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
104 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
105 adding changesets
105 adding changesets
106 add changeset ef1ea85a6374
106 add changeset ef1ea85a6374
107 add changeset f9cafe1212c8
107 add changeset f9cafe1212c8
108 add changeset 911600dab2ae
108 add changeset 911600dab2ae
109 adding manifests
109 adding manifests
110 adding file changes
110 adding file changes
111 adding foo/Bar/file.txt revisions
111 adding foo/Bar/file.txt revisions
112 adding foo/file.txt revisions
112 adding foo/file.txt revisions
113 adding quux/file.py revisions
113 adding quux/file.py revisions
114 added 3 changesets with 3 changes to 3 files
114 added 3 changesets with 3 changes to 3 files
115 updating the branch cache
115 bundle2-input-part: total payload size 1606
116 bundle2-input-part: total payload size 1606
116 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
117 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
117 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
118 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
118 bundle2-input-bundle: 3 parts total
119 bundle2-input-bundle: 3 parts total
119 updating the branch cache
120 bundle2-output-bundle: "HG20", 2 parts total
120 bundle2-output-bundle: "HG20", 2 parts total
121 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
121 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
122 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
122 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
123 bundle2-input-bundle: with-transaction
123 bundle2-input-bundle: with-transaction
124 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
124 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
125 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
125 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
126 bundle2-input-bundle: 1 parts total
126 bundle2-input-bundle: 1 parts total
127 listing keys for "phases"
127 listing keys for "phases"
128 repository tip rolled back to revision 0 (undo push)
128 repository tip rolled back to revision 0 (undo push)
129 0:6675d58eff77
129 0:6675d58eff77
130
130
131
131
132 $ echo '[hooks]' >> $config
132 $ echo '[hooks]' >> $config
133 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
133 $ echo 'pretxnchangegroup.acl = python:hgext.acl.hook' >> $config
134
134
135 Extension disabled for lack of acl.sources
135 Extension disabled for lack of acl.sources
136
136
137 $ do_push fred
137 $ do_push fred
138 Pushing as user fred
138 Pushing as user fred
139 hgrc = """
139 hgrc = """
140 [hooks]
140 [hooks]
141 pretxnchangegroup.acl = python:hgext.acl.hook
141 pretxnchangegroup.acl = python:hgext.acl.hook
142 """
142 """
143 pushing to ../b
143 pushing to ../b
144 query 1; heads
144 query 1; heads
145 searching for changes
145 searching for changes
146 all remote heads known locally
146 all remote heads known locally
147 listing keys for "phases"
147 listing keys for "phases"
148 checking for updated bookmarks
148 checking for updated bookmarks
149 listing keys for "bookmarks"
149 listing keys for "bookmarks"
150 invalid branchheads cache (served): tip differs
150 invalid branchheads cache (served): tip differs
151 listing keys for "bookmarks"
151 listing keys for "bookmarks"
152 3 changesets found
152 3 changesets found
153 list of changesets:
153 list of changesets:
154 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
154 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
155 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
155 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
156 911600dab2ae7a9baff75958b84fe606851ce955
156 911600dab2ae7a9baff75958b84fe606851ce955
157 bundle2-output-bundle: "HG20", 4 parts total
157 bundle2-output-bundle: "HG20", 4 parts total
158 bundle2-output-part: "replycaps" 155 bytes payload
158 bundle2-output-part: "replycaps" 155 bytes payload
159 bundle2-output-part: "check:heads" streamed payload
159 bundle2-output-part: "check:heads" streamed payload
160 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
160 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
161 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
161 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
162 bundle2-input-bundle: with-transaction
162 bundle2-input-bundle: with-transaction
163 bundle2-input-part: "replycaps" supported
163 bundle2-input-part: "replycaps" supported
164 bundle2-input-part: total payload size 155
164 bundle2-input-part: total payload size 155
165 bundle2-input-part: "check:heads" supported
165 bundle2-input-part: "check:heads" supported
166 bundle2-input-part: total payload size 20
166 bundle2-input-part: total payload size 20
167 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
167 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
168 adding changesets
168 adding changesets
169 add changeset ef1ea85a6374
169 add changeset ef1ea85a6374
170 add changeset f9cafe1212c8
170 add changeset f9cafe1212c8
171 add changeset 911600dab2ae
171 add changeset 911600dab2ae
172 adding manifests
172 adding manifests
173 adding file changes
173 adding file changes
174 adding foo/Bar/file.txt revisions
174 adding foo/Bar/file.txt revisions
175 adding foo/file.txt revisions
175 adding foo/file.txt revisions
176 adding quux/file.py revisions
176 adding quux/file.py revisions
177 added 3 changesets with 3 changes to 3 files
177 added 3 changesets with 3 changes to 3 files
178 calling hook pretxnchangegroup.acl: hgext.acl.hook
178 calling hook pretxnchangegroup.acl: hgext.acl.hook
179 acl: changes have source "push" - skipping
179 acl: changes have source "push" - skipping
180 updating the branch cache
180 bundle2-input-part: total payload size 1606
181 bundle2-input-part: total payload size 1606
181 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
182 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
182 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
183 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
183 bundle2-input-bundle: 3 parts total
184 bundle2-input-bundle: 3 parts total
184 updating the branch cache
185 bundle2-output-bundle: "HG20", 2 parts total
185 bundle2-output-bundle: "HG20", 2 parts total
186 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
186 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
187 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
187 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
188 bundle2-input-bundle: with-transaction
188 bundle2-input-bundle: with-transaction
189 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
189 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
190 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
190 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
191 bundle2-input-bundle: 1 parts total
191 bundle2-input-bundle: 1 parts total
192 listing keys for "phases"
192 listing keys for "phases"
193 repository tip rolled back to revision 0 (undo push)
193 repository tip rolled back to revision 0 (undo push)
194 0:6675d58eff77
194 0:6675d58eff77
195
195
196
196
197 No [acl.allow]/[acl.deny]
197 No [acl.allow]/[acl.deny]
198
198
199 $ echo '[acl]' >> $config
199 $ echo '[acl]' >> $config
200 $ echo 'sources = push' >> $config
200 $ echo 'sources = push' >> $config
201 $ do_push fred
201 $ do_push fred
202 Pushing as user fred
202 Pushing as user fred
203 hgrc = """
203 hgrc = """
204 [hooks]
204 [hooks]
205 pretxnchangegroup.acl = python:hgext.acl.hook
205 pretxnchangegroup.acl = python:hgext.acl.hook
206 [acl]
206 [acl]
207 sources = push
207 sources = push
208 """
208 """
209 pushing to ../b
209 pushing to ../b
210 query 1; heads
210 query 1; heads
211 searching for changes
211 searching for changes
212 all remote heads known locally
212 all remote heads known locally
213 listing keys for "phases"
213 listing keys for "phases"
214 checking for updated bookmarks
214 checking for updated bookmarks
215 listing keys for "bookmarks"
215 listing keys for "bookmarks"
216 invalid branchheads cache (served): tip differs
216 invalid branchheads cache (served): tip differs
217 listing keys for "bookmarks"
217 listing keys for "bookmarks"
218 3 changesets found
218 3 changesets found
219 list of changesets:
219 list of changesets:
220 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
220 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
221 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
221 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
222 911600dab2ae7a9baff75958b84fe606851ce955
222 911600dab2ae7a9baff75958b84fe606851ce955
223 bundle2-output-bundle: "HG20", 4 parts total
223 bundle2-output-bundle: "HG20", 4 parts total
224 bundle2-output-part: "replycaps" 155 bytes payload
224 bundle2-output-part: "replycaps" 155 bytes payload
225 bundle2-output-part: "check:heads" streamed payload
225 bundle2-output-part: "check:heads" streamed payload
226 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
226 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
227 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
227 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
228 bundle2-input-bundle: with-transaction
228 bundle2-input-bundle: with-transaction
229 bundle2-input-part: "replycaps" supported
229 bundle2-input-part: "replycaps" supported
230 bundle2-input-part: total payload size 155
230 bundle2-input-part: total payload size 155
231 bundle2-input-part: "check:heads" supported
231 bundle2-input-part: "check:heads" supported
232 bundle2-input-part: total payload size 20
232 bundle2-input-part: total payload size 20
233 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
233 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
234 adding changesets
234 adding changesets
235 add changeset ef1ea85a6374
235 add changeset ef1ea85a6374
236 add changeset f9cafe1212c8
236 add changeset f9cafe1212c8
237 add changeset 911600dab2ae
237 add changeset 911600dab2ae
238 adding manifests
238 adding manifests
239 adding file changes
239 adding file changes
240 adding foo/Bar/file.txt revisions
240 adding foo/Bar/file.txt revisions
241 adding foo/file.txt revisions
241 adding foo/file.txt revisions
242 adding quux/file.py revisions
242 adding quux/file.py revisions
243 added 3 changesets with 3 changes to 3 files
243 added 3 changesets with 3 changes to 3 files
244 calling hook pretxnchangegroup.acl: hgext.acl.hook
244 calling hook pretxnchangegroup.acl: hgext.acl.hook
245 acl: checking access for user "fred"
245 acl: checking access for user "fred"
246 acl: acl.allow.branches not enabled
246 acl: acl.allow.branches not enabled
247 acl: acl.deny.branches not enabled
247 acl: acl.deny.branches not enabled
248 acl: acl.allow not enabled
248 acl: acl.allow not enabled
249 acl: acl.deny not enabled
249 acl: acl.deny not enabled
250 acl: branch access granted: "ef1ea85a6374" on branch "default"
250 acl: branch access granted: "ef1ea85a6374" on branch "default"
251 acl: path access granted: "ef1ea85a6374"
251 acl: path access granted: "ef1ea85a6374"
252 acl: branch access granted: "f9cafe1212c8" on branch "default"
252 acl: branch access granted: "f9cafe1212c8" on branch "default"
253 acl: path access granted: "f9cafe1212c8"
253 acl: path access granted: "f9cafe1212c8"
254 acl: branch access granted: "911600dab2ae" on branch "default"
254 acl: branch access granted: "911600dab2ae" on branch "default"
255 acl: path access granted: "911600dab2ae"
255 acl: path access granted: "911600dab2ae"
256 updating the branch cache
256 bundle2-input-part: total payload size 1606
257 bundle2-input-part: total payload size 1606
257 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
258 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
258 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
259 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
259 bundle2-input-bundle: 3 parts total
260 bundle2-input-bundle: 3 parts total
260 updating the branch cache
261 bundle2-output-bundle: "HG20", 2 parts total
261 bundle2-output-bundle: "HG20", 2 parts total
262 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
262 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
263 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
263 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
264 bundle2-input-bundle: with-transaction
264 bundle2-input-bundle: with-transaction
265 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
265 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
266 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
266 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
267 bundle2-input-bundle: 1 parts total
267 bundle2-input-bundle: 1 parts total
268 listing keys for "phases"
268 listing keys for "phases"
269 repository tip rolled back to revision 0 (undo push)
269 repository tip rolled back to revision 0 (undo push)
270 0:6675d58eff77
270 0:6675d58eff77
271
271
272
272
273 Empty [acl.allow]
273 Empty [acl.allow]
274
274
275 $ echo '[acl.allow]' >> $config
275 $ echo '[acl.allow]' >> $config
276 $ do_push fred
276 $ do_push fred
277 Pushing as user fred
277 Pushing as user fred
278 hgrc = """
278 hgrc = """
279 [hooks]
279 [hooks]
280 pretxnchangegroup.acl = python:hgext.acl.hook
280 pretxnchangegroup.acl = python:hgext.acl.hook
281 [acl]
281 [acl]
282 sources = push
282 sources = push
283 [acl.allow]
283 [acl.allow]
284 """
284 """
285 pushing to ../b
285 pushing to ../b
286 query 1; heads
286 query 1; heads
287 searching for changes
287 searching for changes
288 all remote heads known locally
288 all remote heads known locally
289 listing keys for "phases"
289 listing keys for "phases"
290 checking for updated bookmarks
290 checking for updated bookmarks
291 listing keys for "bookmarks"
291 listing keys for "bookmarks"
292 invalid branchheads cache (served): tip differs
292 invalid branchheads cache (served): tip differs
293 listing keys for "bookmarks"
293 listing keys for "bookmarks"
294 3 changesets found
294 3 changesets found
295 list of changesets:
295 list of changesets:
296 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
296 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
297 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
297 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
298 911600dab2ae7a9baff75958b84fe606851ce955
298 911600dab2ae7a9baff75958b84fe606851ce955
299 bundle2-output-bundle: "HG20", 4 parts total
299 bundle2-output-bundle: "HG20", 4 parts total
300 bundle2-output-part: "replycaps" 155 bytes payload
300 bundle2-output-part: "replycaps" 155 bytes payload
301 bundle2-output-part: "check:heads" streamed payload
301 bundle2-output-part: "check:heads" streamed payload
302 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
302 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
303 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
303 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
304 bundle2-input-bundle: with-transaction
304 bundle2-input-bundle: with-transaction
305 bundle2-input-part: "replycaps" supported
305 bundle2-input-part: "replycaps" supported
306 bundle2-input-part: total payload size 155
306 bundle2-input-part: total payload size 155
307 bundle2-input-part: "check:heads" supported
307 bundle2-input-part: "check:heads" supported
308 bundle2-input-part: total payload size 20
308 bundle2-input-part: total payload size 20
309 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
309 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
310 adding changesets
310 adding changesets
311 add changeset ef1ea85a6374
311 add changeset ef1ea85a6374
312 add changeset f9cafe1212c8
312 add changeset f9cafe1212c8
313 add changeset 911600dab2ae
313 add changeset 911600dab2ae
314 adding manifests
314 adding manifests
315 adding file changes
315 adding file changes
316 adding foo/Bar/file.txt revisions
316 adding foo/Bar/file.txt revisions
317 adding foo/file.txt revisions
317 adding foo/file.txt revisions
318 adding quux/file.py revisions
318 adding quux/file.py revisions
319 added 3 changesets with 3 changes to 3 files
319 added 3 changesets with 3 changes to 3 files
320 calling hook pretxnchangegroup.acl: hgext.acl.hook
320 calling hook pretxnchangegroup.acl: hgext.acl.hook
321 acl: checking access for user "fred"
321 acl: checking access for user "fred"
322 acl: acl.allow.branches not enabled
322 acl: acl.allow.branches not enabled
323 acl: acl.deny.branches not enabled
323 acl: acl.deny.branches not enabled
324 acl: acl.allow enabled, 0 entries for user fred
324 acl: acl.allow enabled, 0 entries for user fred
325 acl: acl.deny not enabled
325 acl: acl.deny not enabled
326 acl: branch access granted: "ef1ea85a6374" on branch "default"
326 acl: branch access granted: "ef1ea85a6374" on branch "default"
327 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
327 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
328 bundle2-input-part: total payload size 1606
328 bundle2-input-part: total payload size 1606
329 bundle2-input-bundle: 3 parts total
329 bundle2-input-bundle: 3 parts total
330 transaction abort!
330 transaction abort!
331 rollback completed
331 rollback completed
332 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
332 abort: acl: user "fred" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
333 no rollback information available
333 no rollback information available
334 0:6675d58eff77
334 0:6675d58eff77
335
335
336
336
337 fred is allowed inside foo/
337 fred is allowed inside foo/
338
338
339 $ echo 'foo/** = fred' >> $config
339 $ echo 'foo/** = fred' >> $config
340 $ do_push fred
340 $ do_push fred
341 Pushing as user fred
341 Pushing as user fred
342 hgrc = """
342 hgrc = """
343 [hooks]
343 [hooks]
344 pretxnchangegroup.acl = python:hgext.acl.hook
344 pretxnchangegroup.acl = python:hgext.acl.hook
345 [acl]
345 [acl]
346 sources = push
346 sources = push
347 [acl.allow]
347 [acl.allow]
348 foo/** = fred
348 foo/** = fred
349 """
349 """
350 pushing to ../b
350 pushing to ../b
351 query 1; heads
351 query 1; heads
352 searching for changes
352 searching for changes
353 all remote heads known locally
353 all remote heads known locally
354 listing keys for "phases"
354 listing keys for "phases"
355 checking for updated bookmarks
355 checking for updated bookmarks
356 listing keys for "bookmarks"
356 listing keys for "bookmarks"
357 invalid branchheads cache (served): tip differs
357 invalid branchheads cache (served): tip differs
358 listing keys for "bookmarks"
358 listing keys for "bookmarks"
359 3 changesets found
359 3 changesets found
360 list of changesets:
360 list of changesets:
361 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
361 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
362 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
362 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
363 911600dab2ae7a9baff75958b84fe606851ce955
363 911600dab2ae7a9baff75958b84fe606851ce955
364 bundle2-output-bundle: "HG20", 4 parts total
364 bundle2-output-bundle: "HG20", 4 parts total
365 bundle2-output-part: "replycaps" 155 bytes payload
365 bundle2-output-part: "replycaps" 155 bytes payload
366 bundle2-output-part: "check:heads" streamed payload
366 bundle2-output-part: "check:heads" streamed payload
367 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
367 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
368 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
368 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
369 bundle2-input-bundle: with-transaction
369 bundle2-input-bundle: with-transaction
370 bundle2-input-part: "replycaps" supported
370 bundle2-input-part: "replycaps" supported
371 bundle2-input-part: total payload size 155
371 bundle2-input-part: total payload size 155
372 bundle2-input-part: "check:heads" supported
372 bundle2-input-part: "check:heads" supported
373 bundle2-input-part: total payload size 20
373 bundle2-input-part: total payload size 20
374 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
374 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
375 adding changesets
375 adding changesets
376 add changeset ef1ea85a6374
376 add changeset ef1ea85a6374
377 add changeset f9cafe1212c8
377 add changeset f9cafe1212c8
378 add changeset 911600dab2ae
378 add changeset 911600dab2ae
379 adding manifests
379 adding manifests
380 adding file changes
380 adding file changes
381 adding foo/Bar/file.txt revisions
381 adding foo/Bar/file.txt revisions
382 adding foo/file.txt revisions
382 adding foo/file.txt revisions
383 adding quux/file.py revisions
383 adding quux/file.py revisions
384 added 3 changesets with 3 changes to 3 files
384 added 3 changesets with 3 changes to 3 files
385 calling hook pretxnchangegroup.acl: hgext.acl.hook
385 calling hook pretxnchangegroup.acl: hgext.acl.hook
386 acl: checking access for user "fred"
386 acl: checking access for user "fred"
387 acl: acl.allow.branches not enabled
387 acl: acl.allow.branches not enabled
388 acl: acl.deny.branches not enabled
388 acl: acl.deny.branches not enabled
389 acl: acl.allow enabled, 1 entries for user fred
389 acl: acl.allow enabled, 1 entries for user fred
390 acl: acl.deny not enabled
390 acl: acl.deny not enabled
391 acl: branch access granted: "ef1ea85a6374" on branch "default"
391 acl: branch access granted: "ef1ea85a6374" on branch "default"
392 acl: path access granted: "ef1ea85a6374"
392 acl: path access granted: "ef1ea85a6374"
393 acl: branch access granted: "f9cafe1212c8" on branch "default"
393 acl: branch access granted: "f9cafe1212c8" on branch "default"
394 acl: path access granted: "f9cafe1212c8"
394 acl: path access granted: "f9cafe1212c8"
395 acl: branch access granted: "911600dab2ae" on branch "default"
395 acl: branch access granted: "911600dab2ae" on branch "default"
396 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
396 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
397 bundle2-input-part: total payload size 1606
397 bundle2-input-part: total payload size 1606
398 bundle2-input-bundle: 3 parts total
398 bundle2-input-bundle: 3 parts total
399 transaction abort!
399 transaction abort!
400 rollback completed
400 rollback completed
401 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
401 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
402 no rollback information available
402 no rollback information available
403 0:6675d58eff77
403 0:6675d58eff77
404
404
405
405
406 Empty [acl.deny]
406 Empty [acl.deny]
407
407
408 $ echo '[acl.deny]' >> $config
408 $ echo '[acl.deny]' >> $config
409 $ do_push barney
409 $ do_push barney
410 Pushing as user barney
410 Pushing as user barney
411 hgrc = """
411 hgrc = """
412 [hooks]
412 [hooks]
413 pretxnchangegroup.acl = python:hgext.acl.hook
413 pretxnchangegroup.acl = python:hgext.acl.hook
414 [acl]
414 [acl]
415 sources = push
415 sources = push
416 [acl.allow]
416 [acl.allow]
417 foo/** = fred
417 foo/** = fred
418 [acl.deny]
418 [acl.deny]
419 """
419 """
420 pushing to ../b
420 pushing to ../b
421 query 1; heads
421 query 1; heads
422 searching for changes
422 searching for changes
423 all remote heads known locally
423 all remote heads known locally
424 listing keys for "phases"
424 listing keys for "phases"
425 checking for updated bookmarks
425 checking for updated bookmarks
426 listing keys for "bookmarks"
426 listing keys for "bookmarks"
427 invalid branchheads cache (served): tip differs
427 invalid branchheads cache (served): tip differs
428 listing keys for "bookmarks"
428 listing keys for "bookmarks"
429 3 changesets found
429 3 changesets found
430 list of changesets:
430 list of changesets:
431 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
431 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
432 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
432 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
433 911600dab2ae7a9baff75958b84fe606851ce955
433 911600dab2ae7a9baff75958b84fe606851ce955
434 bundle2-output-bundle: "HG20", 4 parts total
434 bundle2-output-bundle: "HG20", 4 parts total
435 bundle2-output-part: "replycaps" 155 bytes payload
435 bundle2-output-part: "replycaps" 155 bytes payload
436 bundle2-output-part: "check:heads" streamed payload
436 bundle2-output-part: "check:heads" streamed payload
437 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
437 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
438 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
438 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
439 bundle2-input-bundle: with-transaction
439 bundle2-input-bundle: with-transaction
440 bundle2-input-part: "replycaps" supported
440 bundle2-input-part: "replycaps" supported
441 bundle2-input-part: total payload size 155
441 bundle2-input-part: total payload size 155
442 bundle2-input-part: "check:heads" supported
442 bundle2-input-part: "check:heads" supported
443 bundle2-input-part: total payload size 20
443 bundle2-input-part: total payload size 20
444 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
444 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
445 adding changesets
445 adding changesets
446 add changeset ef1ea85a6374
446 add changeset ef1ea85a6374
447 add changeset f9cafe1212c8
447 add changeset f9cafe1212c8
448 add changeset 911600dab2ae
448 add changeset 911600dab2ae
449 adding manifests
449 adding manifests
450 adding file changes
450 adding file changes
451 adding foo/Bar/file.txt revisions
451 adding foo/Bar/file.txt revisions
452 adding foo/file.txt revisions
452 adding foo/file.txt revisions
453 adding quux/file.py revisions
453 adding quux/file.py revisions
454 added 3 changesets with 3 changes to 3 files
454 added 3 changesets with 3 changes to 3 files
455 calling hook pretxnchangegroup.acl: hgext.acl.hook
455 calling hook pretxnchangegroup.acl: hgext.acl.hook
456 acl: checking access for user "barney"
456 acl: checking access for user "barney"
457 acl: acl.allow.branches not enabled
457 acl: acl.allow.branches not enabled
458 acl: acl.deny.branches not enabled
458 acl: acl.deny.branches not enabled
459 acl: acl.allow enabled, 0 entries for user barney
459 acl: acl.allow enabled, 0 entries for user barney
460 acl: acl.deny enabled, 0 entries for user barney
460 acl: acl.deny enabled, 0 entries for user barney
461 acl: branch access granted: "ef1ea85a6374" on branch "default"
461 acl: branch access granted: "ef1ea85a6374" on branch "default"
462 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
462 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
463 bundle2-input-part: total payload size 1606
463 bundle2-input-part: total payload size 1606
464 bundle2-input-bundle: 3 parts total
464 bundle2-input-bundle: 3 parts total
465 transaction abort!
465 transaction abort!
466 rollback completed
466 rollback completed
467 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")
468 no rollback information available
468 no rollback information available
469 0:6675d58eff77
469 0:6675d58eff77
470
470
471
471
472 fred is allowed inside foo/, but not foo/bar/ (case matters)
472 fred is allowed inside foo/, but not foo/bar/ (case matters)
473
473
474 $ echo 'foo/bar/** = fred' >> $config
474 $ echo 'foo/bar/** = fred' >> $config
475 $ do_push fred
475 $ do_push fred
476 Pushing as user fred
476 Pushing as user fred
477 hgrc = """
477 hgrc = """
478 [hooks]
478 [hooks]
479 pretxnchangegroup.acl = python:hgext.acl.hook
479 pretxnchangegroup.acl = python:hgext.acl.hook
480 [acl]
480 [acl]
481 sources = push
481 sources = push
482 [acl.allow]
482 [acl.allow]
483 foo/** = fred
483 foo/** = fred
484 [acl.deny]
484 [acl.deny]
485 foo/bar/** = fred
485 foo/bar/** = fred
486 """
486 """
487 pushing to ../b
487 pushing to ../b
488 query 1; heads
488 query 1; heads
489 searching for changes
489 searching for changes
490 all remote heads known locally
490 all remote heads known locally
491 listing keys for "phases"
491 listing keys for "phases"
492 checking for updated bookmarks
492 checking for updated bookmarks
493 listing keys for "bookmarks"
493 listing keys for "bookmarks"
494 invalid branchheads cache (served): tip differs
494 invalid branchheads cache (served): tip differs
495 listing keys for "bookmarks"
495 listing keys for "bookmarks"
496 3 changesets found
496 3 changesets found
497 list of changesets:
497 list of changesets:
498 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
498 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
499 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
499 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
500 911600dab2ae7a9baff75958b84fe606851ce955
500 911600dab2ae7a9baff75958b84fe606851ce955
501 bundle2-output-bundle: "HG20", 4 parts total
501 bundle2-output-bundle: "HG20", 4 parts total
502 bundle2-output-part: "replycaps" 155 bytes payload
502 bundle2-output-part: "replycaps" 155 bytes payload
503 bundle2-output-part: "check:heads" streamed payload
503 bundle2-output-part: "check:heads" streamed payload
504 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
504 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
505 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
505 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
506 bundle2-input-bundle: with-transaction
506 bundle2-input-bundle: with-transaction
507 bundle2-input-part: "replycaps" supported
507 bundle2-input-part: "replycaps" supported
508 bundle2-input-part: total payload size 155
508 bundle2-input-part: total payload size 155
509 bundle2-input-part: "check:heads" supported
509 bundle2-input-part: "check:heads" supported
510 bundle2-input-part: total payload size 20
510 bundle2-input-part: total payload size 20
511 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
511 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
512 adding changesets
512 adding changesets
513 add changeset ef1ea85a6374
513 add changeset ef1ea85a6374
514 add changeset f9cafe1212c8
514 add changeset f9cafe1212c8
515 add changeset 911600dab2ae
515 add changeset 911600dab2ae
516 adding manifests
516 adding manifests
517 adding file changes
517 adding file changes
518 adding foo/Bar/file.txt revisions
518 adding foo/Bar/file.txt revisions
519 adding foo/file.txt revisions
519 adding foo/file.txt revisions
520 adding quux/file.py revisions
520 adding quux/file.py revisions
521 added 3 changesets with 3 changes to 3 files
521 added 3 changesets with 3 changes to 3 files
522 calling hook pretxnchangegroup.acl: hgext.acl.hook
522 calling hook pretxnchangegroup.acl: hgext.acl.hook
523 acl: checking access for user "fred"
523 acl: checking access for user "fred"
524 acl: acl.allow.branches not enabled
524 acl: acl.allow.branches not enabled
525 acl: acl.deny.branches not enabled
525 acl: acl.deny.branches not enabled
526 acl: acl.allow enabled, 1 entries for user fred
526 acl: acl.allow enabled, 1 entries for user fred
527 acl: acl.deny enabled, 1 entries for user fred
527 acl: acl.deny enabled, 1 entries for user fred
528 acl: branch access granted: "ef1ea85a6374" on branch "default"
528 acl: branch access granted: "ef1ea85a6374" on branch "default"
529 acl: path access granted: "ef1ea85a6374"
529 acl: path access granted: "ef1ea85a6374"
530 acl: branch access granted: "f9cafe1212c8" on branch "default"
530 acl: branch access granted: "f9cafe1212c8" on branch "default"
531 acl: path access granted: "f9cafe1212c8"
531 acl: path access granted: "f9cafe1212c8"
532 acl: branch access granted: "911600dab2ae" on branch "default"
532 acl: branch access granted: "911600dab2ae" on branch "default"
533 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
533 error: pretxnchangegroup.acl hook failed: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
534 bundle2-input-part: total payload size 1606
534 bundle2-input-part: total payload size 1606
535 bundle2-input-bundle: 3 parts total
535 bundle2-input-bundle: 3 parts total
536 transaction abort!
536 transaction abort!
537 rollback completed
537 rollback completed
538 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
538 abort: acl: user "fred" not allowed on "quux/file.py" (changeset "911600dab2ae")
539 no rollback information available
539 no rollback information available
540 0:6675d58eff77
540 0:6675d58eff77
541
541
542
542
543 fred is allowed inside foo/, but not foo/Bar/
543 fred is allowed inside foo/, but not foo/Bar/
544
544
545 $ echo 'foo/Bar/** = fred' >> $config
545 $ echo 'foo/Bar/** = fred' >> $config
546 $ do_push fred
546 $ do_push fred
547 Pushing as user fred
547 Pushing as user fred
548 hgrc = """
548 hgrc = """
549 [hooks]
549 [hooks]
550 pretxnchangegroup.acl = python:hgext.acl.hook
550 pretxnchangegroup.acl = python:hgext.acl.hook
551 [acl]
551 [acl]
552 sources = push
552 sources = push
553 [acl.allow]
553 [acl.allow]
554 foo/** = fred
554 foo/** = fred
555 [acl.deny]
555 [acl.deny]
556 foo/bar/** = fred
556 foo/bar/** = fred
557 foo/Bar/** = fred
557 foo/Bar/** = fred
558 """
558 """
559 pushing to ../b
559 pushing to ../b
560 query 1; heads
560 query 1; heads
561 searching for changes
561 searching for changes
562 all remote heads known locally
562 all remote heads known locally
563 listing keys for "phases"
563 listing keys for "phases"
564 checking for updated bookmarks
564 checking for updated bookmarks
565 listing keys for "bookmarks"
565 listing keys for "bookmarks"
566 invalid branchheads cache (served): tip differs
566 invalid branchheads cache (served): tip differs
567 listing keys for "bookmarks"
567 listing keys for "bookmarks"
568 3 changesets found
568 3 changesets found
569 list of changesets:
569 list of changesets:
570 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
570 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
571 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
571 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
572 911600dab2ae7a9baff75958b84fe606851ce955
572 911600dab2ae7a9baff75958b84fe606851ce955
573 bundle2-output-bundle: "HG20", 4 parts total
573 bundle2-output-bundle: "HG20", 4 parts total
574 bundle2-output-part: "replycaps" 155 bytes payload
574 bundle2-output-part: "replycaps" 155 bytes payload
575 bundle2-output-part: "check:heads" streamed payload
575 bundle2-output-part: "check:heads" streamed payload
576 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
576 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
577 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
577 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
578 bundle2-input-bundle: with-transaction
578 bundle2-input-bundle: with-transaction
579 bundle2-input-part: "replycaps" supported
579 bundle2-input-part: "replycaps" supported
580 bundle2-input-part: total payload size 155
580 bundle2-input-part: total payload size 155
581 bundle2-input-part: "check:heads" supported
581 bundle2-input-part: "check:heads" supported
582 bundle2-input-part: total payload size 20
582 bundle2-input-part: total payload size 20
583 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
583 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
584 adding changesets
584 adding changesets
585 add changeset ef1ea85a6374
585 add changeset ef1ea85a6374
586 add changeset f9cafe1212c8
586 add changeset f9cafe1212c8
587 add changeset 911600dab2ae
587 add changeset 911600dab2ae
588 adding manifests
588 adding manifests
589 adding file changes
589 adding file changes
590 adding foo/Bar/file.txt revisions
590 adding foo/Bar/file.txt revisions
591 adding foo/file.txt revisions
591 adding foo/file.txt revisions
592 adding quux/file.py revisions
592 adding quux/file.py revisions
593 added 3 changesets with 3 changes to 3 files
593 added 3 changesets with 3 changes to 3 files
594 calling hook pretxnchangegroup.acl: hgext.acl.hook
594 calling hook pretxnchangegroup.acl: hgext.acl.hook
595 acl: checking access for user "fred"
595 acl: checking access for user "fred"
596 acl: acl.allow.branches not enabled
596 acl: acl.allow.branches not enabled
597 acl: acl.deny.branches not enabled
597 acl: acl.deny.branches not enabled
598 acl: acl.allow enabled, 1 entries for user fred
598 acl: acl.allow enabled, 1 entries for user fred
599 acl: acl.deny enabled, 2 entries for user fred
599 acl: acl.deny enabled, 2 entries for user fred
600 acl: branch access granted: "ef1ea85a6374" on branch "default"
600 acl: branch access granted: "ef1ea85a6374" on branch "default"
601 acl: path access granted: "ef1ea85a6374"
601 acl: path access granted: "ef1ea85a6374"
602 acl: branch access granted: "f9cafe1212c8" on branch "default"
602 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")
603 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
604 bundle2-input-part: total payload size 1606
604 bundle2-input-part: total payload size 1606
605 bundle2-input-bundle: 3 parts total
605 bundle2-input-bundle: 3 parts total
606 transaction abort!
606 transaction abort!
607 rollback completed
607 rollback completed
608 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
608 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
609 no rollback information available
609 no rollback information available
610 0:6675d58eff77
610 0:6675d58eff77
611
611
612
612
613 $ echo 'barney is not mentioned => not allowed anywhere'
613 $ echo 'barney is not mentioned => not allowed anywhere'
614 barney is not mentioned => not allowed anywhere
614 barney is not mentioned => not allowed anywhere
615 $ do_push barney
615 $ do_push barney
616 Pushing as user barney
616 Pushing as user barney
617 hgrc = """
617 hgrc = """
618 [hooks]
618 [hooks]
619 pretxnchangegroup.acl = python:hgext.acl.hook
619 pretxnchangegroup.acl = python:hgext.acl.hook
620 [acl]
620 [acl]
621 sources = push
621 sources = push
622 [acl.allow]
622 [acl.allow]
623 foo/** = fred
623 foo/** = fred
624 [acl.deny]
624 [acl.deny]
625 foo/bar/** = fred
625 foo/bar/** = fred
626 foo/Bar/** = fred
626 foo/Bar/** = fred
627 """
627 """
628 pushing to ../b
628 pushing to ../b
629 query 1; heads
629 query 1; heads
630 searching for changes
630 searching for changes
631 all remote heads known locally
631 all remote heads known locally
632 listing keys for "phases"
632 listing keys for "phases"
633 checking for updated bookmarks
633 checking for updated bookmarks
634 listing keys for "bookmarks"
634 listing keys for "bookmarks"
635 invalid branchheads cache (served): tip differs
635 invalid branchheads cache (served): tip differs
636 listing keys for "bookmarks"
636 listing keys for "bookmarks"
637 3 changesets found
637 3 changesets found
638 list of changesets:
638 list of changesets:
639 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
639 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
640 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
640 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
641 911600dab2ae7a9baff75958b84fe606851ce955
641 911600dab2ae7a9baff75958b84fe606851ce955
642 bundle2-output-bundle: "HG20", 4 parts total
642 bundle2-output-bundle: "HG20", 4 parts total
643 bundle2-output-part: "replycaps" 155 bytes payload
643 bundle2-output-part: "replycaps" 155 bytes payload
644 bundle2-output-part: "check:heads" streamed payload
644 bundle2-output-part: "check:heads" streamed payload
645 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
645 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
646 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
646 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
647 bundle2-input-bundle: with-transaction
647 bundle2-input-bundle: with-transaction
648 bundle2-input-part: "replycaps" supported
648 bundle2-input-part: "replycaps" supported
649 bundle2-input-part: total payload size 155
649 bundle2-input-part: total payload size 155
650 bundle2-input-part: "check:heads" supported
650 bundle2-input-part: "check:heads" supported
651 bundle2-input-part: total payload size 20
651 bundle2-input-part: total payload size 20
652 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
652 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
653 adding changesets
653 adding changesets
654 add changeset ef1ea85a6374
654 add changeset ef1ea85a6374
655 add changeset f9cafe1212c8
655 add changeset f9cafe1212c8
656 add changeset 911600dab2ae
656 add changeset 911600dab2ae
657 adding manifests
657 adding manifests
658 adding file changes
658 adding file changes
659 adding foo/Bar/file.txt revisions
659 adding foo/Bar/file.txt revisions
660 adding foo/file.txt revisions
660 adding foo/file.txt revisions
661 adding quux/file.py revisions
661 adding quux/file.py revisions
662 added 3 changesets with 3 changes to 3 files
662 added 3 changesets with 3 changes to 3 files
663 calling hook pretxnchangegroup.acl: hgext.acl.hook
663 calling hook pretxnchangegroup.acl: hgext.acl.hook
664 acl: checking access for user "barney"
664 acl: checking access for user "barney"
665 acl: acl.allow.branches not enabled
665 acl: acl.allow.branches not enabled
666 acl: acl.deny.branches not enabled
666 acl: acl.deny.branches not enabled
667 acl: acl.allow enabled, 0 entries for user barney
667 acl: acl.allow enabled, 0 entries for user barney
668 acl: acl.deny enabled, 0 entries for user barney
668 acl: acl.deny enabled, 0 entries for user barney
669 acl: branch access granted: "ef1ea85a6374" on branch "default"
669 acl: branch access granted: "ef1ea85a6374" on branch "default"
670 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
670 error: pretxnchangegroup.acl hook failed: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
671 bundle2-input-part: total payload size 1606
671 bundle2-input-part: total payload size 1606
672 bundle2-input-bundle: 3 parts total
672 bundle2-input-bundle: 3 parts total
673 transaction abort!
673 transaction abort!
674 rollback completed
674 rollback completed
675 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
675 abort: acl: user "barney" not allowed on "foo/file.txt" (changeset "ef1ea85a6374")
676 no rollback information available
676 no rollback information available
677 0:6675d58eff77
677 0:6675d58eff77
678
678
679
679
680 barney is allowed everywhere
680 barney is allowed everywhere
681
681
682 $ echo '[acl.allow]' >> $config
682 $ echo '[acl.allow]' >> $config
683 $ echo '** = barney' >> $config
683 $ echo '** = barney' >> $config
684 $ do_push barney
684 $ do_push barney
685 Pushing as user barney
685 Pushing as user barney
686 hgrc = """
686 hgrc = """
687 [hooks]
687 [hooks]
688 pretxnchangegroup.acl = python:hgext.acl.hook
688 pretxnchangegroup.acl = python:hgext.acl.hook
689 [acl]
689 [acl]
690 sources = push
690 sources = push
691 [acl.allow]
691 [acl.allow]
692 foo/** = fred
692 foo/** = fred
693 [acl.deny]
693 [acl.deny]
694 foo/bar/** = fred
694 foo/bar/** = fred
695 foo/Bar/** = fred
695 foo/Bar/** = fred
696 [acl.allow]
696 [acl.allow]
697 ** = barney
697 ** = barney
698 """
698 """
699 pushing to ../b
699 pushing to ../b
700 query 1; heads
700 query 1; heads
701 searching for changes
701 searching for changes
702 all remote heads known locally
702 all remote heads known locally
703 listing keys for "phases"
703 listing keys for "phases"
704 checking for updated bookmarks
704 checking for updated bookmarks
705 listing keys for "bookmarks"
705 listing keys for "bookmarks"
706 invalid branchheads cache (served): tip differs
706 invalid branchheads cache (served): tip differs
707 listing keys for "bookmarks"
707 listing keys for "bookmarks"
708 3 changesets found
708 3 changesets found
709 list of changesets:
709 list of changesets:
710 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
710 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
711 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
711 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
712 911600dab2ae7a9baff75958b84fe606851ce955
712 911600dab2ae7a9baff75958b84fe606851ce955
713 bundle2-output-bundle: "HG20", 4 parts total
713 bundle2-output-bundle: "HG20", 4 parts total
714 bundle2-output-part: "replycaps" 155 bytes payload
714 bundle2-output-part: "replycaps" 155 bytes payload
715 bundle2-output-part: "check:heads" streamed payload
715 bundle2-output-part: "check:heads" streamed payload
716 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
716 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
717 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
717 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
718 bundle2-input-bundle: with-transaction
718 bundle2-input-bundle: with-transaction
719 bundle2-input-part: "replycaps" supported
719 bundle2-input-part: "replycaps" supported
720 bundle2-input-part: total payload size 155
720 bundle2-input-part: total payload size 155
721 bundle2-input-part: "check:heads" supported
721 bundle2-input-part: "check:heads" supported
722 bundle2-input-part: total payload size 20
722 bundle2-input-part: total payload size 20
723 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
723 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
724 adding changesets
724 adding changesets
725 add changeset ef1ea85a6374
725 add changeset ef1ea85a6374
726 add changeset f9cafe1212c8
726 add changeset f9cafe1212c8
727 add changeset 911600dab2ae
727 add changeset 911600dab2ae
728 adding manifests
728 adding manifests
729 adding file changes
729 adding file changes
730 adding foo/Bar/file.txt revisions
730 adding foo/Bar/file.txt revisions
731 adding foo/file.txt revisions
731 adding foo/file.txt revisions
732 adding quux/file.py revisions
732 adding quux/file.py revisions
733 added 3 changesets with 3 changes to 3 files
733 added 3 changesets with 3 changes to 3 files
734 calling hook pretxnchangegroup.acl: hgext.acl.hook
734 calling hook pretxnchangegroup.acl: hgext.acl.hook
735 acl: checking access for user "barney"
735 acl: checking access for user "barney"
736 acl: acl.allow.branches not enabled
736 acl: acl.allow.branches not enabled
737 acl: acl.deny.branches not enabled
737 acl: acl.deny.branches not enabled
738 acl: acl.allow enabled, 1 entries for user barney
738 acl: acl.allow enabled, 1 entries for user barney
739 acl: acl.deny enabled, 0 entries for user barney
739 acl: acl.deny enabled, 0 entries for user barney
740 acl: branch access granted: "ef1ea85a6374" on branch "default"
740 acl: branch access granted: "ef1ea85a6374" on branch "default"
741 acl: path access granted: "ef1ea85a6374"
741 acl: path access granted: "ef1ea85a6374"
742 acl: branch access granted: "f9cafe1212c8" on branch "default"
742 acl: branch access granted: "f9cafe1212c8" on branch "default"
743 acl: path access granted: "f9cafe1212c8"
743 acl: path access granted: "f9cafe1212c8"
744 acl: branch access granted: "911600dab2ae" on branch "default"
744 acl: branch access granted: "911600dab2ae" on branch "default"
745 acl: path access granted: "911600dab2ae"
745 acl: path access granted: "911600dab2ae"
746 updating the branch cache
746 bundle2-input-part: total payload size 1606
747 bundle2-input-part: total payload size 1606
747 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
748 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
748 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
749 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
749 bundle2-input-bundle: 3 parts total
750 bundle2-input-bundle: 3 parts total
750 updating the branch cache
751 bundle2-output-bundle: "HG20", 2 parts total
751 bundle2-output-bundle: "HG20", 2 parts total
752 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
752 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
753 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
753 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
754 bundle2-input-bundle: with-transaction
754 bundle2-input-bundle: with-transaction
755 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
755 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
756 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
756 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
757 bundle2-input-bundle: 1 parts total
757 bundle2-input-bundle: 1 parts total
758 listing keys for "phases"
758 listing keys for "phases"
759 repository tip rolled back to revision 0 (undo push)
759 repository tip rolled back to revision 0 (undo push)
760 0:6675d58eff77
760 0:6675d58eff77
761
761
762
762
763 wilma can change files with a .txt extension
763 wilma can change files with a .txt extension
764
764
765 $ echo '**/*.txt = wilma' >> $config
765 $ echo '**/*.txt = wilma' >> $config
766 $ do_push wilma
766 $ do_push wilma
767 Pushing as user wilma
767 Pushing as user wilma
768 hgrc = """
768 hgrc = """
769 [hooks]
769 [hooks]
770 pretxnchangegroup.acl = python:hgext.acl.hook
770 pretxnchangegroup.acl = python:hgext.acl.hook
771 [acl]
771 [acl]
772 sources = push
772 sources = push
773 [acl.allow]
773 [acl.allow]
774 foo/** = fred
774 foo/** = fred
775 [acl.deny]
775 [acl.deny]
776 foo/bar/** = fred
776 foo/bar/** = fred
777 foo/Bar/** = fred
777 foo/Bar/** = fred
778 [acl.allow]
778 [acl.allow]
779 ** = barney
779 ** = barney
780 **/*.txt = wilma
780 **/*.txt = wilma
781 """
781 """
782 pushing to ../b
782 pushing to ../b
783 query 1; heads
783 query 1; heads
784 searching for changes
784 searching for changes
785 all remote heads known locally
785 all remote heads known locally
786 listing keys for "phases"
786 listing keys for "phases"
787 checking for updated bookmarks
787 checking for updated bookmarks
788 listing keys for "bookmarks"
788 listing keys for "bookmarks"
789 invalid branchheads cache (served): tip differs
789 invalid branchheads cache (served): tip differs
790 listing keys for "bookmarks"
790 listing keys for "bookmarks"
791 3 changesets found
791 3 changesets found
792 list of changesets:
792 list of changesets:
793 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
793 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
794 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
794 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
795 911600dab2ae7a9baff75958b84fe606851ce955
795 911600dab2ae7a9baff75958b84fe606851ce955
796 bundle2-output-bundle: "HG20", 4 parts total
796 bundle2-output-bundle: "HG20", 4 parts total
797 bundle2-output-part: "replycaps" 155 bytes payload
797 bundle2-output-part: "replycaps" 155 bytes payload
798 bundle2-output-part: "check:heads" streamed payload
798 bundle2-output-part: "check:heads" streamed payload
799 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
799 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
800 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
800 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
801 bundle2-input-bundle: with-transaction
801 bundle2-input-bundle: with-transaction
802 bundle2-input-part: "replycaps" supported
802 bundle2-input-part: "replycaps" supported
803 bundle2-input-part: total payload size 155
803 bundle2-input-part: total payload size 155
804 bundle2-input-part: "check:heads" supported
804 bundle2-input-part: "check:heads" supported
805 bundle2-input-part: total payload size 20
805 bundle2-input-part: total payload size 20
806 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
806 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
807 adding changesets
807 adding changesets
808 add changeset ef1ea85a6374
808 add changeset ef1ea85a6374
809 add changeset f9cafe1212c8
809 add changeset f9cafe1212c8
810 add changeset 911600dab2ae
810 add changeset 911600dab2ae
811 adding manifests
811 adding manifests
812 adding file changes
812 adding file changes
813 adding foo/Bar/file.txt revisions
813 adding foo/Bar/file.txt revisions
814 adding foo/file.txt revisions
814 adding foo/file.txt revisions
815 adding quux/file.py revisions
815 adding quux/file.py revisions
816 added 3 changesets with 3 changes to 3 files
816 added 3 changesets with 3 changes to 3 files
817 calling hook pretxnchangegroup.acl: hgext.acl.hook
817 calling hook pretxnchangegroup.acl: hgext.acl.hook
818 acl: checking access for user "wilma"
818 acl: checking access for user "wilma"
819 acl: acl.allow.branches not enabled
819 acl: acl.allow.branches not enabled
820 acl: acl.deny.branches not enabled
820 acl: acl.deny.branches not enabled
821 acl: acl.allow enabled, 1 entries for user wilma
821 acl: acl.allow enabled, 1 entries for user wilma
822 acl: acl.deny enabled, 0 entries for user wilma
822 acl: acl.deny enabled, 0 entries for user wilma
823 acl: branch access granted: "ef1ea85a6374" on branch "default"
823 acl: branch access granted: "ef1ea85a6374" on branch "default"
824 acl: path access granted: "ef1ea85a6374"
824 acl: path access granted: "ef1ea85a6374"
825 acl: branch access granted: "f9cafe1212c8" on branch "default"
825 acl: branch access granted: "f9cafe1212c8" on branch "default"
826 acl: path access granted: "f9cafe1212c8"
826 acl: path access granted: "f9cafe1212c8"
827 acl: branch access granted: "911600dab2ae" on branch "default"
827 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")
828 error: pretxnchangegroup.acl hook failed: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
829 bundle2-input-part: total payload size 1606
829 bundle2-input-part: total payload size 1606
830 bundle2-input-bundle: 3 parts total
830 bundle2-input-bundle: 3 parts total
831 transaction abort!
831 transaction abort!
832 rollback completed
832 rollback completed
833 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
833 abort: acl: user "wilma" not allowed on "quux/file.py" (changeset "911600dab2ae")
834 no rollback information available
834 no rollback information available
835 0:6675d58eff77
835 0:6675d58eff77
836
836
837
837
838 file specified by acl.config does not exist
838 file specified by acl.config does not exist
839
839
840 $ echo '[acl]' >> $config
840 $ echo '[acl]' >> $config
841 $ echo 'config = ../acl.config' >> $config
841 $ echo 'config = ../acl.config' >> $config
842 $ do_push barney
842 $ do_push barney
843 Pushing as user barney
843 Pushing as user barney
844 hgrc = """
844 hgrc = """
845 [hooks]
845 [hooks]
846 pretxnchangegroup.acl = python:hgext.acl.hook
846 pretxnchangegroup.acl = python:hgext.acl.hook
847 [acl]
847 [acl]
848 sources = push
848 sources = push
849 [acl.allow]
849 [acl.allow]
850 foo/** = fred
850 foo/** = fred
851 [acl.deny]
851 [acl.deny]
852 foo/bar/** = fred
852 foo/bar/** = fred
853 foo/Bar/** = fred
853 foo/Bar/** = fred
854 [acl.allow]
854 [acl.allow]
855 ** = barney
855 ** = barney
856 **/*.txt = wilma
856 **/*.txt = wilma
857 [acl]
857 [acl]
858 config = ../acl.config
858 config = ../acl.config
859 """
859 """
860 pushing to ../b
860 pushing to ../b
861 query 1; heads
861 query 1; heads
862 searching for changes
862 searching for changes
863 all remote heads known locally
863 all remote heads known locally
864 listing keys for "phases"
864 listing keys for "phases"
865 checking for updated bookmarks
865 checking for updated bookmarks
866 listing keys for "bookmarks"
866 listing keys for "bookmarks"
867 invalid branchheads cache (served): tip differs
867 invalid branchheads cache (served): tip differs
868 listing keys for "bookmarks"
868 listing keys for "bookmarks"
869 3 changesets found
869 3 changesets found
870 list of changesets:
870 list of changesets:
871 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
871 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
872 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
872 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
873 911600dab2ae7a9baff75958b84fe606851ce955
873 911600dab2ae7a9baff75958b84fe606851ce955
874 bundle2-output-bundle: "HG20", 4 parts total
874 bundle2-output-bundle: "HG20", 4 parts total
875 bundle2-output-part: "replycaps" 155 bytes payload
875 bundle2-output-part: "replycaps" 155 bytes payload
876 bundle2-output-part: "check:heads" streamed payload
876 bundle2-output-part: "check:heads" streamed payload
877 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
877 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
878 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
878 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
879 bundle2-input-bundle: with-transaction
879 bundle2-input-bundle: with-transaction
880 bundle2-input-part: "replycaps" supported
880 bundle2-input-part: "replycaps" supported
881 bundle2-input-part: total payload size 155
881 bundle2-input-part: total payload size 155
882 bundle2-input-part: "check:heads" supported
882 bundle2-input-part: "check:heads" supported
883 bundle2-input-part: total payload size 20
883 bundle2-input-part: total payload size 20
884 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
884 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
885 adding changesets
885 adding changesets
886 add changeset ef1ea85a6374
886 add changeset ef1ea85a6374
887 add changeset f9cafe1212c8
887 add changeset f9cafe1212c8
888 add changeset 911600dab2ae
888 add changeset 911600dab2ae
889 adding manifests
889 adding manifests
890 adding file changes
890 adding file changes
891 adding foo/Bar/file.txt revisions
891 adding foo/Bar/file.txt revisions
892 adding foo/file.txt revisions
892 adding foo/file.txt revisions
893 adding quux/file.py revisions
893 adding quux/file.py revisions
894 added 3 changesets with 3 changes to 3 files
894 added 3 changesets with 3 changes to 3 files
895 calling hook pretxnchangegroup.acl: hgext.acl.hook
895 calling hook pretxnchangegroup.acl: hgext.acl.hook
896 acl: checking access for user "barney"
896 acl: checking access for user "barney"
897 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
897 error: pretxnchangegroup.acl hook raised an exception: [Errno 2] No such file or directory: '../acl.config'
898 bundle2-input-part: total payload size 1606
898 bundle2-input-part: total payload size 1606
899 bundle2-input-bundle: 3 parts total
899 bundle2-input-bundle: 3 parts total
900 transaction abort!
900 transaction abort!
901 rollback completed
901 rollback completed
902 abort: No such file or directory: ../acl.config
902 abort: No such file or directory: ../acl.config
903 no rollback information available
903 no rollback information available
904 0:6675d58eff77
904 0:6675d58eff77
905
905
906
906
907 betty is allowed inside foo/ by a acl.config file
907 betty is allowed inside foo/ by a acl.config file
908
908
909 $ echo '[acl.allow]' >> acl.config
909 $ echo '[acl.allow]' >> acl.config
910 $ echo 'foo/** = betty' >> acl.config
910 $ echo 'foo/** = betty' >> acl.config
911 $ do_push betty
911 $ do_push betty
912 Pushing as user betty
912 Pushing as user betty
913 hgrc = """
913 hgrc = """
914 [hooks]
914 [hooks]
915 pretxnchangegroup.acl = python:hgext.acl.hook
915 pretxnchangegroup.acl = python:hgext.acl.hook
916 [acl]
916 [acl]
917 sources = push
917 sources = push
918 [acl.allow]
918 [acl.allow]
919 foo/** = fred
919 foo/** = fred
920 [acl.deny]
920 [acl.deny]
921 foo/bar/** = fred
921 foo/bar/** = fred
922 foo/Bar/** = fred
922 foo/Bar/** = fred
923 [acl.allow]
923 [acl.allow]
924 ** = barney
924 ** = barney
925 **/*.txt = wilma
925 **/*.txt = wilma
926 [acl]
926 [acl]
927 config = ../acl.config
927 config = ../acl.config
928 """
928 """
929 acl.config = """
929 acl.config = """
930 [acl.allow]
930 [acl.allow]
931 foo/** = betty
931 foo/** = betty
932 """
932 """
933 pushing to ../b
933 pushing to ../b
934 query 1; heads
934 query 1; heads
935 searching for changes
935 searching for changes
936 all remote heads known locally
936 all remote heads known locally
937 listing keys for "phases"
937 listing keys for "phases"
938 checking for updated bookmarks
938 checking for updated bookmarks
939 listing keys for "bookmarks"
939 listing keys for "bookmarks"
940 invalid branchheads cache (served): tip differs
940 invalid branchheads cache (served): tip differs
941 listing keys for "bookmarks"
941 listing keys for "bookmarks"
942 3 changesets found
942 3 changesets found
943 list of changesets:
943 list of changesets:
944 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
944 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
945 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
945 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
946 911600dab2ae7a9baff75958b84fe606851ce955
946 911600dab2ae7a9baff75958b84fe606851ce955
947 bundle2-output-bundle: "HG20", 4 parts total
947 bundle2-output-bundle: "HG20", 4 parts total
948 bundle2-output-part: "replycaps" 155 bytes payload
948 bundle2-output-part: "replycaps" 155 bytes payload
949 bundle2-output-part: "check:heads" streamed payload
949 bundle2-output-part: "check:heads" streamed payload
950 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
950 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
951 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
951 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
952 bundle2-input-bundle: with-transaction
952 bundle2-input-bundle: with-transaction
953 bundle2-input-part: "replycaps" supported
953 bundle2-input-part: "replycaps" supported
954 bundle2-input-part: total payload size 155
954 bundle2-input-part: total payload size 155
955 bundle2-input-part: "check:heads" supported
955 bundle2-input-part: "check:heads" supported
956 bundle2-input-part: total payload size 20
956 bundle2-input-part: total payload size 20
957 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
957 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
958 adding changesets
958 adding changesets
959 add changeset ef1ea85a6374
959 add changeset ef1ea85a6374
960 add changeset f9cafe1212c8
960 add changeset f9cafe1212c8
961 add changeset 911600dab2ae
961 add changeset 911600dab2ae
962 adding manifests
962 adding manifests
963 adding file changes
963 adding file changes
964 adding foo/Bar/file.txt revisions
964 adding foo/Bar/file.txt revisions
965 adding foo/file.txt revisions
965 adding foo/file.txt revisions
966 adding quux/file.py revisions
966 adding quux/file.py revisions
967 added 3 changesets with 3 changes to 3 files
967 added 3 changesets with 3 changes to 3 files
968 calling hook pretxnchangegroup.acl: hgext.acl.hook
968 calling hook pretxnchangegroup.acl: hgext.acl.hook
969 acl: checking access for user "betty"
969 acl: checking access for user "betty"
970 acl: acl.allow.branches not enabled
970 acl: acl.allow.branches not enabled
971 acl: acl.deny.branches not enabled
971 acl: acl.deny.branches not enabled
972 acl: acl.allow enabled, 1 entries for user betty
972 acl: acl.allow enabled, 1 entries for user betty
973 acl: acl.deny enabled, 0 entries for user betty
973 acl: acl.deny enabled, 0 entries for user betty
974 acl: branch access granted: "ef1ea85a6374" on branch "default"
974 acl: branch access granted: "ef1ea85a6374" on branch "default"
975 acl: path access granted: "ef1ea85a6374"
975 acl: path access granted: "ef1ea85a6374"
976 acl: branch access granted: "f9cafe1212c8" on branch "default"
976 acl: branch access granted: "f9cafe1212c8" on branch "default"
977 acl: path access granted: "f9cafe1212c8"
977 acl: path access granted: "f9cafe1212c8"
978 acl: branch access granted: "911600dab2ae" on branch "default"
978 acl: branch access granted: "911600dab2ae" on branch "default"
979 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
979 error: pretxnchangegroup.acl hook failed: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
980 bundle2-input-part: total payload size 1606
980 bundle2-input-part: total payload size 1606
981 bundle2-input-bundle: 3 parts total
981 bundle2-input-bundle: 3 parts total
982 transaction abort!
982 transaction abort!
983 rollback completed
983 rollback completed
984 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
984 abort: acl: user "betty" not allowed on "quux/file.py" (changeset "911600dab2ae")
985 no rollback information available
985 no rollback information available
986 0:6675d58eff77
986 0:6675d58eff77
987
987
988
988
989 acl.config can set only [acl.allow]/[acl.deny]
989 acl.config can set only [acl.allow]/[acl.deny]
990
990
991 $ echo '[hooks]' >> acl.config
991 $ echo '[hooks]' >> acl.config
992 $ echo 'changegroup.acl = false' >> acl.config
992 $ echo 'changegroup.acl = false' >> acl.config
993 $ do_push barney
993 $ do_push barney
994 Pushing as user barney
994 Pushing as user barney
995 hgrc = """
995 hgrc = """
996 [hooks]
996 [hooks]
997 pretxnchangegroup.acl = python:hgext.acl.hook
997 pretxnchangegroup.acl = python:hgext.acl.hook
998 [acl]
998 [acl]
999 sources = push
999 sources = push
1000 [acl.allow]
1000 [acl.allow]
1001 foo/** = fred
1001 foo/** = fred
1002 [acl.deny]
1002 [acl.deny]
1003 foo/bar/** = fred
1003 foo/bar/** = fred
1004 foo/Bar/** = fred
1004 foo/Bar/** = fred
1005 [acl.allow]
1005 [acl.allow]
1006 ** = barney
1006 ** = barney
1007 **/*.txt = wilma
1007 **/*.txt = wilma
1008 [acl]
1008 [acl]
1009 config = ../acl.config
1009 config = ../acl.config
1010 """
1010 """
1011 acl.config = """
1011 acl.config = """
1012 [acl.allow]
1012 [acl.allow]
1013 foo/** = betty
1013 foo/** = betty
1014 [hooks]
1014 [hooks]
1015 changegroup.acl = false
1015 changegroup.acl = false
1016 """
1016 """
1017 pushing to ../b
1017 pushing to ../b
1018 query 1; heads
1018 query 1; heads
1019 searching for changes
1019 searching for changes
1020 all remote heads known locally
1020 all remote heads known locally
1021 listing keys for "phases"
1021 listing keys for "phases"
1022 checking for updated bookmarks
1022 checking for updated bookmarks
1023 listing keys for "bookmarks"
1023 listing keys for "bookmarks"
1024 invalid branchheads cache (served): tip differs
1024 invalid branchheads cache (served): tip differs
1025 listing keys for "bookmarks"
1025 listing keys for "bookmarks"
1026 3 changesets found
1026 3 changesets found
1027 list of changesets:
1027 list of changesets:
1028 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1028 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1029 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1029 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1030 911600dab2ae7a9baff75958b84fe606851ce955
1030 911600dab2ae7a9baff75958b84fe606851ce955
1031 bundle2-output-bundle: "HG20", 4 parts total
1031 bundle2-output-bundle: "HG20", 4 parts total
1032 bundle2-output-part: "replycaps" 155 bytes payload
1032 bundle2-output-part: "replycaps" 155 bytes payload
1033 bundle2-output-part: "check:heads" streamed payload
1033 bundle2-output-part: "check:heads" streamed payload
1034 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1034 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1035 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1035 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1036 bundle2-input-bundle: with-transaction
1036 bundle2-input-bundle: with-transaction
1037 bundle2-input-part: "replycaps" supported
1037 bundle2-input-part: "replycaps" supported
1038 bundle2-input-part: total payload size 155
1038 bundle2-input-part: total payload size 155
1039 bundle2-input-part: "check:heads" supported
1039 bundle2-input-part: "check:heads" supported
1040 bundle2-input-part: total payload size 20
1040 bundle2-input-part: total payload size 20
1041 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1041 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1042 adding changesets
1042 adding changesets
1043 add changeset ef1ea85a6374
1043 add changeset ef1ea85a6374
1044 add changeset f9cafe1212c8
1044 add changeset f9cafe1212c8
1045 add changeset 911600dab2ae
1045 add changeset 911600dab2ae
1046 adding manifests
1046 adding manifests
1047 adding file changes
1047 adding file changes
1048 adding foo/Bar/file.txt revisions
1048 adding foo/Bar/file.txt revisions
1049 adding foo/file.txt revisions
1049 adding foo/file.txt revisions
1050 adding quux/file.py revisions
1050 adding quux/file.py revisions
1051 added 3 changesets with 3 changes to 3 files
1051 added 3 changesets with 3 changes to 3 files
1052 calling hook pretxnchangegroup.acl: hgext.acl.hook
1052 calling hook pretxnchangegroup.acl: hgext.acl.hook
1053 acl: checking access for user "barney"
1053 acl: checking access for user "barney"
1054 acl: acl.allow.branches not enabled
1054 acl: acl.allow.branches not enabled
1055 acl: acl.deny.branches not enabled
1055 acl: acl.deny.branches not enabled
1056 acl: acl.allow enabled, 1 entries for user barney
1056 acl: acl.allow enabled, 1 entries for user barney
1057 acl: acl.deny enabled, 0 entries for user barney
1057 acl: acl.deny enabled, 0 entries for user barney
1058 acl: branch access granted: "ef1ea85a6374" on branch "default"
1058 acl: branch access granted: "ef1ea85a6374" on branch "default"
1059 acl: path access granted: "ef1ea85a6374"
1059 acl: path access granted: "ef1ea85a6374"
1060 acl: branch access granted: "f9cafe1212c8" on branch "default"
1060 acl: branch access granted: "f9cafe1212c8" on branch "default"
1061 acl: path access granted: "f9cafe1212c8"
1061 acl: path access granted: "f9cafe1212c8"
1062 acl: branch access granted: "911600dab2ae" on branch "default"
1062 acl: branch access granted: "911600dab2ae" on branch "default"
1063 acl: path access granted: "911600dab2ae"
1063 acl: path access granted: "911600dab2ae"
1064 updating the branch cache
1064 bundle2-input-part: total payload size 1606
1065 bundle2-input-part: total payload size 1606
1065 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1066 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1066 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1067 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1067 bundle2-input-bundle: 3 parts total
1068 bundle2-input-bundle: 3 parts total
1068 updating the branch cache
1069 bundle2-output-bundle: "HG20", 2 parts total
1069 bundle2-output-bundle: "HG20", 2 parts total
1070 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1070 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1071 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1071 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1072 bundle2-input-bundle: with-transaction
1072 bundle2-input-bundle: with-transaction
1073 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1073 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1074 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1074 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1075 bundle2-input-bundle: 1 parts total
1075 bundle2-input-bundle: 1 parts total
1076 listing keys for "phases"
1076 listing keys for "phases"
1077 repository tip rolled back to revision 0 (undo push)
1077 repository tip rolled back to revision 0 (undo push)
1078 0:6675d58eff77
1078 0:6675d58eff77
1079
1079
1080
1080
1081 asterisk
1081 asterisk
1082
1082
1083 $ init_config
1083 $ init_config
1084
1084
1085 asterisk test
1085 asterisk test
1086
1086
1087 $ echo '[acl.allow]' >> $config
1087 $ echo '[acl.allow]' >> $config
1088 $ echo "** = fred" >> $config
1088 $ echo "** = fred" >> $config
1089
1089
1090 fred is always allowed
1090 fred is always allowed
1091
1091
1092 $ do_push fred
1092 $ do_push fred
1093 Pushing as user fred
1093 Pushing as user fred
1094 hgrc = """
1094 hgrc = """
1095 [hooks]
1095 [hooks]
1096 pretxnchangegroup.acl = python:hgext.acl.hook
1096 pretxnchangegroup.acl = python:hgext.acl.hook
1097 [acl]
1097 [acl]
1098 sources = push
1098 sources = push
1099 [extensions]
1099 [extensions]
1100 [acl.allow]
1100 [acl.allow]
1101 ** = fred
1101 ** = fred
1102 """
1102 """
1103 pushing to ../b
1103 pushing to ../b
1104 query 1; heads
1104 query 1; heads
1105 searching for changes
1105 searching for changes
1106 all remote heads known locally
1106 all remote heads known locally
1107 listing keys for "phases"
1107 listing keys for "phases"
1108 checking for updated bookmarks
1108 checking for updated bookmarks
1109 listing keys for "bookmarks"
1109 listing keys for "bookmarks"
1110 invalid branchheads cache (served): tip differs
1110 invalid branchheads cache (served): tip differs
1111 listing keys for "bookmarks"
1111 listing keys for "bookmarks"
1112 3 changesets found
1112 3 changesets found
1113 list of changesets:
1113 list of changesets:
1114 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1114 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1115 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1115 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1116 911600dab2ae7a9baff75958b84fe606851ce955
1116 911600dab2ae7a9baff75958b84fe606851ce955
1117 bundle2-output-bundle: "HG20", 4 parts total
1117 bundle2-output-bundle: "HG20", 4 parts total
1118 bundle2-output-part: "replycaps" 155 bytes payload
1118 bundle2-output-part: "replycaps" 155 bytes payload
1119 bundle2-output-part: "check:heads" streamed payload
1119 bundle2-output-part: "check:heads" streamed payload
1120 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1120 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1121 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1121 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1122 bundle2-input-bundle: with-transaction
1122 bundle2-input-bundle: with-transaction
1123 bundle2-input-part: "replycaps" supported
1123 bundle2-input-part: "replycaps" supported
1124 bundle2-input-part: total payload size 155
1124 bundle2-input-part: total payload size 155
1125 bundle2-input-part: "check:heads" supported
1125 bundle2-input-part: "check:heads" supported
1126 bundle2-input-part: total payload size 20
1126 bundle2-input-part: total payload size 20
1127 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1127 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1128 adding changesets
1128 adding changesets
1129 add changeset ef1ea85a6374
1129 add changeset ef1ea85a6374
1130 add changeset f9cafe1212c8
1130 add changeset f9cafe1212c8
1131 add changeset 911600dab2ae
1131 add changeset 911600dab2ae
1132 adding manifests
1132 adding manifests
1133 adding file changes
1133 adding file changes
1134 adding foo/Bar/file.txt revisions
1134 adding foo/Bar/file.txt revisions
1135 adding foo/file.txt revisions
1135 adding foo/file.txt revisions
1136 adding quux/file.py revisions
1136 adding quux/file.py revisions
1137 added 3 changesets with 3 changes to 3 files
1137 added 3 changesets with 3 changes to 3 files
1138 calling hook pretxnchangegroup.acl: hgext.acl.hook
1138 calling hook pretxnchangegroup.acl: hgext.acl.hook
1139 acl: checking access for user "fred"
1139 acl: checking access for user "fred"
1140 acl: acl.allow.branches not enabled
1140 acl: acl.allow.branches not enabled
1141 acl: acl.deny.branches not enabled
1141 acl: acl.deny.branches not enabled
1142 acl: acl.allow enabled, 1 entries for user fred
1142 acl: acl.allow enabled, 1 entries for user fred
1143 acl: acl.deny not enabled
1143 acl: acl.deny not enabled
1144 acl: branch access granted: "ef1ea85a6374" on branch "default"
1144 acl: branch access granted: "ef1ea85a6374" on branch "default"
1145 acl: path access granted: "ef1ea85a6374"
1145 acl: path access granted: "ef1ea85a6374"
1146 acl: branch access granted: "f9cafe1212c8" on branch "default"
1146 acl: branch access granted: "f9cafe1212c8" on branch "default"
1147 acl: path access granted: "f9cafe1212c8"
1147 acl: path access granted: "f9cafe1212c8"
1148 acl: branch access granted: "911600dab2ae" on branch "default"
1148 acl: branch access granted: "911600dab2ae" on branch "default"
1149 acl: path access granted: "911600dab2ae"
1149 acl: path access granted: "911600dab2ae"
1150 updating the branch cache
1150 bundle2-input-part: total payload size 1606
1151 bundle2-input-part: total payload size 1606
1151 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1152 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1152 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1153 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1153 bundle2-input-bundle: 3 parts total
1154 bundle2-input-bundle: 3 parts total
1154 updating the branch cache
1155 bundle2-output-bundle: "HG20", 2 parts total
1155 bundle2-output-bundle: "HG20", 2 parts total
1156 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1156 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1157 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1157 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1158 bundle2-input-bundle: with-transaction
1158 bundle2-input-bundle: with-transaction
1159 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1159 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1160 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1160 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1161 bundle2-input-bundle: 1 parts total
1161 bundle2-input-bundle: 1 parts total
1162 listing keys for "phases"
1162 listing keys for "phases"
1163 repository tip rolled back to revision 0 (undo push)
1163 repository tip rolled back to revision 0 (undo push)
1164 0:6675d58eff77
1164 0:6675d58eff77
1165
1165
1166
1166
1167 $ echo '[acl.deny]' >> $config
1167 $ echo '[acl.deny]' >> $config
1168 $ echo "foo/Bar/** = *" >> $config
1168 $ echo "foo/Bar/** = *" >> $config
1169
1169
1170 no one is allowed inside foo/Bar/
1170 no one is allowed inside foo/Bar/
1171
1171
1172 $ do_push fred
1172 $ do_push fred
1173 Pushing as user fred
1173 Pushing as user fred
1174 hgrc = """
1174 hgrc = """
1175 [hooks]
1175 [hooks]
1176 pretxnchangegroup.acl = python:hgext.acl.hook
1176 pretxnchangegroup.acl = python:hgext.acl.hook
1177 [acl]
1177 [acl]
1178 sources = push
1178 sources = push
1179 [extensions]
1179 [extensions]
1180 [acl.allow]
1180 [acl.allow]
1181 ** = fred
1181 ** = fred
1182 [acl.deny]
1182 [acl.deny]
1183 foo/Bar/** = *
1183 foo/Bar/** = *
1184 """
1184 """
1185 pushing to ../b
1185 pushing to ../b
1186 query 1; heads
1186 query 1; heads
1187 searching for changes
1187 searching for changes
1188 all remote heads known locally
1188 all remote heads known locally
1189 listing keys for "phases"
1189 listing keys for "phases"
1190 checking for updated bookmarks
1190 checking for updated bookmarks
1191 listing keys for "bookmarks"
1191 listing keys for "bookmarks"
1192 invalid branchheads cache (served): tip differs
1192 invalid branchheads cache (served): tip differs
1193 listing keys for "bookmarks"
1193 listing keys for "bookmarks"
1194 3 changesets found
1194 3 changesets found
1195 list of changesets:
1195 list of changesets:
1196 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1196 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1197 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1197 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1198 911600dab2ae7a9baff75958b84fe606851ce955
1198 911600dab2ae7a9baff75958b84fe606851ce955
1199 bundle2-output-bundle: "HG20", 4 parts total
1199 bundle2-output-bundle: "HG20", 4 parts total
1200 bundle2-output-part: "replycaps" 155 bytes payload
1200 bundle2-output-part: "replycaps" 155 bytes payload
1201 bundle2-output-part: "check:heads" streamed payload
1201 bundle2-output-part: "check:heads" streamed payload
1202 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1202 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1203 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1203 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1204 bundle2-input-bundle: with-transaction
1204 bundle2-input-bundle: with-transaction
1205 bundle2-input-part: "replycaps" supported
1205 bundle2-input-part: "replycaps" supported
1206 bundle2-input-part: total payload size 155
1206 bundle2-input-part: total payload size 155
1207 bundle2-input-part: "check:heads" supported
1207 bundle2-input-part: "check:heads" supported
1208 bundle2-input-part: total payload size 20
1208 bundle2-input-part: total payload size 20
1209 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1209 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1210 adding changesets
1210 adding changesets
1211 add changeset ef1ea85a6374
1211 add changeset ef1ea85a6374
1212 add changeset f9cafe1212c8
1212 add changeset f9cafe1212c8
1213 add changeset 911600dab2ae
1213 add changeset 911600dab2ae
1214 adding manifests
1214 adding manifests
1215 adding file changes
1215 adding file changes
1216 adding foo/Bar/file.txt revisions
1216 adding foo/Bar/file.txt revisions
1217 adding foo/file.txt revisions
1217 adding foo/file.txt revisions
1218 adding quux/file.py revisions
1218 adding quux/file.py revisions
1219 added 3 changesets with 3 changes to 3 files
1219 added 3 changesets with 3 changes to 3 files
1220 calling hook pretxnchangegroup.acl: hgext.acl.hook
1220 calling hook pretxnchangegroup.acl: hgext.acl.hook
1221 acl: checking access for user "fred"
1221 acl: checking access for user "fred"
1222 acl: acl.allow.branches not enabled
1222 acl: acl.allow.branches not enabled
1223 acl: acl.deny.branches not enabled
1223 acl: acl.deny.branches not enabled
1224 acl: acl.allow enabled, 1 entries for user fred
1224 acl: acl.allow enabled, 1 entries for user fred
1225 acl: acl.deny enabled, 1 entries for user fred
1225 acl: acl.deny enabled, 1 entries for user fred
1226 acl: branch access granted: "ef1ea85a6374" on branch "default"
1226 acl: branch access granted: "ef1ea85a6374" on branch "default"
1227 acl: path access granted: "ef1ea85a6374"
1227 acl: path access granted: "ef1ea85a6374"
1228 acl: branch access granted: "f9cafe1212c8" on branch "default"
1228 acl: branch access granted: "f9cafe1212c8" on branch "default"
1229 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1229 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1230 bundle2-input-part: total payload size 1606
1230 bundle2-input-part: total payload size 1606
1231 bundle2-input-bundle: 3 parts total
1231 bundle2-input-bundle: 3 parts total
1232 transaction abort!
1232 transaction abort!
1233 rollback completed
1233 rollback completed
1234 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1234 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1235 no rollback information available
1235 no rollback information available
1236 0:6675d58eff77
1236 0:6675d58eff77
1237
1237
1238
1238
1239 Groups
1239 Groups
1240
1240
1241 $ init_config
1241 $ init_config
1242
1242
1243 OS-level groups
1243 OS-level groups
1244
1244
1245 $ echo '[acl.allow]' >> $config
1245 $ echo '[acl.allow]' >> $config
1246 $ echo "** = @group1" >> $config
1246 $ echo "** = @group1" >> $config
1247
1247
1248 @group1 is always allowed
1248 @group1 is always allowed
1249
1249
1250 $ do_push fred
1250 $ do_push fred
1251 Pushing as user fred
1251 Pushing as user fred
1252 hgrc = """
1252 hgrc = """
1253 [hooks]
1253 [hooks]
1254 pretxnchangegroup.acl = python:hgext.acl.hook
1254 pretxnchangegroup.acl = python:hgext.acl.hook
1255 [acl]
1255 [acl]
1256 sources = push
1256 sources = push
1257 [extensions]
1257 [extensions]
1258 [acl.allow]
1258 [acl.allow]
1259 ** = @group1
1259 ** = @group1
1260 """
1260 """
1261 pushing to ../b
1261 pushing to ../b
1262 query 1; heads
1262 query 1; heads
1263 searching for changes
1263 searching for changes
1264 all remote heads known locally
1264 all remote heads known locally
1265 listing keys for "phases"
1265 listing keys for "phases"
1266 checking for updated bookmarks
1266 checking for updated bookmarks
1267 listing keys for "bookmarks"
1267 listing keys for "bookmarks"
1268 invalid branchheads cache (served): tip differs
1268 invalid branchheads cache (served): tip differs
1269 listing keys for "bookmarks"
1269 listing keys for "bookmarks"
1270 3 changesets found
1270 3 changesets found
1271 list of changesets:
1271 list of changesets:
1272 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1272 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1273 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1273 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1274 911600dab2ae7a9baff75958b84fe606851ce955
1274 911600dab2ae7a9baff75958b84fe606851ce955
1275 bundle2-output-bundle: "HG20", 4 parts total
1275 bundle2-output-bundle: "HG20", 4 parts total
1276 bundle2-output-part: "replycaps" 155 bytes payload
1276 bundle2-output-part: "replycaps" 155 bytes payload
1277 bundle2-output-part: "check:heads" streamed payload
1277 bundle2-output-part: "check:heads" streamed payload
1278 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1278 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1279 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1279 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1280 bundle2-input-bundle: with-transaction
1280 bundle2-input-bundle: with-transaction
1281 bundle2-input-part: "replycaps" supported
1281 bundle2-input-part: "replycaps" supported
1282 bundle2-input-part: total payload size 155
1282 bundle2-input-part: total payload size 155
1283 bundle2-input-part: "check:heads" supported
1283 bundle2-input-part: "check:heads" supported
1284 bundle2-input-part: total payload size 20
1284 bundle2-input-part: total payload size 20
1285 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1285 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1286 adding changesets
1286 adding changesets
1287 add changeset ef1ea85a6374
1287 add changeset ef1ea85a6374
1288 add changeset f9cafe1212c8
1288 add changeset f9cafe1212c8
1289 add changeset 911600dab2ae
1289 add changeset 911600dab2ae
1290 adding manifests
1290 adding manifests
1291 adding file changes
1291 adding file changes
1292 adding foo/Bar/file.txt revisions
1292 adding foo/Bar/file.txt revisions
1293 adding foo/file.txt revisions
1293 adding foo/file.txt revisions
1294 adding quux/file.py revisions
1294 adding quux/file.py revisions
1295 added 3 changesets with 3 changes to 3 files
1295 added 3 changesets with 3 changes to 3 files
1296 calling hook pretxnchangegroup.acl: hgext.acl.hook
1296 calling hook pretxnchangegroup.acl: hgext.acl.hook
1297 acl: checking access for user "fred"
1297 acl: checking access for user "fred"
1298 acl: acl.allow.branches not enabled
1298 acl: acl.allow.branches not enabled
1299 acl: acl.deny.branches not enabled
1299 acl: acl.deny.branches not enabled
1300 acl: "group1" not defined in [acl.groups]
1300 acl: "group1" not defined in [acl.groups]
1301 acl: acl.allow enabled, 1 entries for user fred
1301 acl: acl.allow enabled, 1 entries for user fred
1302 acl: acl.deny not enabled
1302 acl: acl.deny not enabled
1303 acl: branch access granted: "ef1ea85a6374" on branch "default"
1303 acl: branch access granted: "ef1ea85a6374" on branch "default"
1304 acl: path access granted: "ef1ea85a6374"
1304 acl: path access granted: "ef1ea85a6374"
1305 acl: branch access granted: "f9cafe1212c8" on branch "default"
1305 acl: branch access granted: "f9cafe1212c8" on branch "default"
1306 acl: path access granted: "f9cafe1212c8"
1306 acl: path access granted: "f9cafe1212c8"
1307 acl: branch access granted: "911600dab2ae" on branch "default"
1307 acl: branch access granted: "911600dab2ae" on branch "default"
1308 acl: path access granted: "911600dab2ae"
1308 acl: path access granted: "911600dab2ae"
1309 updating the branch cache
1309 bundle2-input-part: total payload size 1606
1310 bundle2-input-part: total payload size 1606
1310 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1311 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1311 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1312 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1312 bundle2-input-bundle: 3 parts total
1313 bundle2-input-bundle: 3 parts total
1313 updating the branch cache
1314 bundle2-output-bundle: "HG20", 2 parts total
1314 bundle2-output-bundle: "HG20", 2 parts total
1315 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1315 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1316 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1316 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1317 bundle2-input-bundle: with-transaction
1317 bundle2-input-bundle: with-transaction
1318 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1318 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1319 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1319 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1320 bundle2-input-bundle: 1 parts total
1320 bundle2-input-bundle: 1 parts total
1321 listing keys for "phases"
1321 listing keys for "phases"
1322 repository tip rolled back to revision 0 (undo push)
1322 repository tip rolled back to revision 0 (undo push)
1323 0:6675d58eff77
1323 0:6675d58eff77
1324
1324
1325
1325
1326 $ echo '[acl.deny]' >> $config
1326 $ echo '[acl.deny]' >> $config
1327 $ echo "foo/Bar/** = @group1" >> $config
1327 $ echo "foo/Bar/** = @group1" >> $config
1328
1328
1329 @group is allowed inside anything but foo/Bar/
1329 @group is allowed inside anything but foo/Bar/
1330
1330
1331 $ do_push fred
1331 $ do_push fred
1332 Pushing as user fred
1332 Pushing as user fred
1333 hgrc = """
1333 hgrc = """
1334 [hooks]
1334 [hooks]
1335 pretxnchangegroup.acl = python:hgext.acl.hook
1335 pretxnchangegroup.acl = python:hgext.acl.hook
1336 [acl]
1336 [acl]
1337 sources = push
1337 sources = push
1338 [extensions]
1338 [extensions]
1339 [acl.allow]
1339 [acl.allow]
1340 ** = @group1
1340 ** = @group1
1341 [acl.deny]
1341 [acl.deny]
1342 foo/Bar/** = @group1
1342 foo/Bar/** = @group1
1343 """
1343 """
1344 pushing to ../b
1344 pushing to ../b
1345 query 1; heads
1345 query 1; heads
1346 searching for changes
1346 searching for changes
1347 all remote heads known locally
1347 all remote heads known locally
1348 listing keys for "phases"
1348 listing keys for "phases"
1349 checking for updated bookmarks
1349 checking for updated bookmarks
1350 listing keys for "bookmarks"
1350 listing keys for "bookmarks"
1351 invalid branchheads cache (served): tip differs
1351 invalid branchheads cache (served): tip differs
1352 listing keys for "bookmarks"
1352 listing keys for "bookmarks"
1353 3 changesets found
1353 3 changesets found
1354 list of changesets:
1354 list of changesets:
1355 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1355 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1356 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1356 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1357 911600dab2ae7a9baff75958b84fe606851ce955
1357 911600dab2ae7a9baff75958b84fe606851ce955
1358 bundle2-output-bundle: "HG20", 4 parts total
1358 bundle2-output-bundle: "HG20", 4 parts total
1359 bundle2-output-part: "replycaps" 155 bytes payload
1359 bundle2-output-part: "replycaps" 155 bytes payload
1360 bundle2-output-part: "check:heads" streamed payload
1360 bundle2-output-part: "check:heads" streamed payload
1361 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1361 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1362 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1362 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1363 bundle2-input-bundle: with-transaction
1363 bundle2-input-bundle: with-transaction
1364 bundle2-input-part: "replycaps" supported
1364 bundle2-input-part: "replycaps" supported
1365 bundle2-input-part: total payload size 155
1365 bundle2-input-part: total payload size 155
1366 bundle2-input-part: "check:heads" supported
1366 bundle2-input-part: "check:heads" supported
1367 bundle2-input-part: total payload size 20
1367 bundle2-input-part: total payload size 20
1368 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1368 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1369 adding changesets
1369 adding changesets
1370 add changeset ef1ea85a6374
1370 add changeset ef1ea85a6374
1371 add changeset f9cafe1212c8
1371 add changeset f9cafe1212c8
1372 add changeset 911600dab2ae
1372 add changeset 911600dab2ae
1373 adding manifests
1373 adding manifests
1374 adding file changes
1374 adding file changes
1375 adding foo/Bar/file.txt revisions
1375 adding foo/Bar/file.txt revisions
1376 adding foo/file.txt revisions
1376 adding foo/file.txt revisions
1377 adding quux/file.py revisions
1377 adding quux/file.py revisions
1378 added 3 changesets with 3 changes to 3 files
1378 added 3 changesets with 3 changes to 3 files
1379 calling hook pretxnchangegroup.acl: hgext.acl.hook
1379 calling hook pretxnchangegroup.acl: hgext.acl.hook
1380 acl: checking access for user "fred"
1380 acl: checking access for user "fred"
1381 acl: acl.allow.branches not enabled
1381 acl: acl.allow.branches not enabled
1382 acl: acl.deny.branches not enabled
1382 acl: acl.deny.branches not enabled
1383 acl: "group1" not defined in [acl.groups]
1383 acl: "group1" not defined in [acl.groups]
1384 acl: acl.allow enabled, 1 entries for user fred
1384 acl: acl.allow enabled, 1 entries for user fred
1385 acl: "group1" not defined in [acl.groups]
1385 acl: "group1" not defined in [acl.groups]
1386 acl: acl.deny enabled, 1 entries for user fred
1386 acl: acl.deny enabled, 1 entries for user fred
1387 acl: branch access granted: "ef1ea85a6374" on branch "default"
1387 acl: branch access granted: "ef1ea85a6374" on branch "default"
1388 acl: path access granted: "ef1ea85a6374"
1388 acl: path access granted: "ef1ea85a6374"
1389 acl: branch access granted: "f9cafe1212c8" on branch "default"
1389 acl: branch access granted: "f9cafe1212c8" on branch "default"
1390 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1390 error: pretxnchangegroup.acl hook failed: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1391 bundle2-input-part: total payload size 1606
1391 bundle2-input-part: total payload size 1606
1392 bundle2-input-bundle: 3 parts total
1392 bundle2-input-bundle: 3 parts total
1393 transaction abort!
1393 transaction abort!
1394 rollback completed
1394 rollback completed
1395 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1395 abort: acl: user "fred" denied on "foo/Bar/file.txt" (changeset "f9cafe1212c8")
1396 no rollback information available
1396 no rollback information available
1397 0:6675d58eff77
1397 0:6675d58eff77
1398
1398
1399
1399
1400 Invalid group
1400 Invalid group
1401
1401
1402 Disable the fakegroups trick to get real failures
1402 Disable the fakegroups trick to get real failures
1403
1403
1404 $ grep -v fakegroups $config > config.tmp
1404 $ grep -v fakegroups $config > config.tmp
1405 $ mv config.tmp $config
1405 $ mv config.tmp $config
1406 $ echo '[acl.allow]' >> $config
1406 $ echo '[acl.allow]' >> $config
1407 $ echo "** = @unlikelytoexist" >> $config
1407 $ echo "** = @unlikelytoexist" >> $config
1408 $ do_push fred 2>&1 | grep unlikelytoexist
1408 $ do_push fred 2>&1 | grep unlikelytoexist
1409 ** = @unlikelytoexist
1409 ** = @unlikelytoexist
1410 acl: "unlikelytoexist" not defined in [acl.groups]
1410 acl: "unlikelytoexist" not defined in [acl.groups]
1411 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1411 error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
1412 abort: group 'unlikelytoexist' is undefined
1412 abort: group 'unlikelytoexist' is undefined
1413
1413
1414
1414
1415 Branch acl tests setup
1415 Branch acl tests setup
1416
1416
1417 $ init_config
1417 $ init_config
1418 $ cd b
1418 $ cd b
1419 $ hg up
1419 $ hg up
1420 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1420 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1421 $ hg branch foobar
1421 $ hg branch foobar
1422 marked working directory as branch foobar
1422 marked working directory as branch foobar
1423 (branches are permanent and global, did you want a bookmark?)
1423 (branches are permanent and global, did you want a bookmark?)
1424 $ hg commit -m 'create foobar'
1424 $ hg commit -m 'create foobar'
1425 $ echo 'foo contents' > abc.txt
1425 $ echo 'foo contents' > abc.txt
1426 $ hg add abc.txt
1426 $ hg add abc.txt
1427 $ hg commit -m 'foobar contents'
1427 $ hg commit -m 'foobar contents'
1428 $ cd ..
1428 $ cd ..
1429 $ hg --cwd a pull ../b
1429 $ hg --cwd a pull ../b
1430 pulling from ../b
1430 pulling from ../b
1431 searching for changes
1431 searching for changes
1432 adding changesets
1432 adding changesets
1433 adding manifests
1433 adding manifests
1434 adding file changes
1434 adding file changes
1435 added 2 changesets with 1 changes to 1 files (+1 heads)
1435 added 2 changesets with 1 changes to 1 files (+1 heads)
1436 (run 'hg heads' to see heads)
1436 (run 'hg heads' to see heads)
1437
1437
1438 Create additional changeset on foobar branch
1438 Create additional changeset on foobar branch
1439
1439
1440 $ cd a
1440 $ cd a
1441 $ hg up -C foobar
1441 $ hg up -C foobar
1442 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1442 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
1443 $ echo 'foo contents2' > abc.txt
1443 $ echo 'foo contents2' > abc.txt
1444 $ hg commit -m 'foobar contents2'
1444 $ hg commit -m 'foobar contents2'
1445 $ cd ..
1445 $ cd ..
1446
1446
1447
1447
1448 No branch acls specified
1448 No branch acls specified
1449
1449
1450 $ do_push astro
1450 $ do_push astro
1451 Pushing as user astro
1451 Pushing as user astro
1452 hgrc = """
1452 hgrc = """
1453 [hooks]
1453 [hooks]
1454 pretxnchangegroup.acl = python:hgext.acl.hook
1454 pretxnchangegroup.acl = python:hgext.acl.hook
1455 [acl]
1455 [acl]
1456 sources = push
1456 sources = push
1457 [extensions]
1457 [extensions]
1458 """
1458 """
1459 pushing to ../b
1459 pushing to ../b
1460 query 1; heads
1460 query 1; heads
1461 searching for changes
1461 searching for changes
1462 all remote heads known locally
1462 all remote heads known locally
1463 listing keys for "phases"
1463 listing keys for "phases"
1464 checking for updated bookmarks
1464 checking for updated bookmarks
1465 listing keys for "bookmarks"
1465 listing keys for "bookmarks"
1466 listing keys for "bookmarks"
1466 listing keys for "bookmarks"
1467 4 changesets found
1467 4 changesets found
1468 list of changesets:
1468 list of changesets:
1469 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1469 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1470 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1470 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1471 911600dab2ae7a9baff75958b84fe606851ce955
1471 911600dab2ae7a9baff75958b84fe606851ce955
1472 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1472 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1473 bundle2-output-bundle: "HG20", 5 parts total
1473 bundle2-output-bundle: "HG20", 5 parts total
1474 bundle2-output-part: "replycaps" 155 bytes payload
1474 bundle2-output-part: "replycaps" 155 bytes payload
1475 bundle2-output-part: "check:heads" streamed payload
1475 bundle2-output-part: "check:heads" streamed payload
1476 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1476 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1477 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1477 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1478 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1478 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1479 bundle2-input-bundle: with-transaction
1479 bundle2-input-bundle: with-transaction
1480 bundle2-input-part: "replycaps" supported
1480 bundle2-input-part: "replycaps" supported
1481 bundle2-input-part: total payload size 155
1481 bundle2-input-part: total payload size 155
1482 bundle2-input-part: "check:heads" supported
1482 bundle2-input-part: "check:heads" supported
1483 bundle2-input-part: total payload size 20
1483 bundle2-input-part: total payload size 20
1484 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1484 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1485 adding changesets
1485 adding changesets
1486 add changeset ef1ea85a6374
1486 add changeset ef1ea85a6374
1487 add changeset f9cafe1212c8
1487 add changeset f9cafe1212c8
1488 add changeset 911600dab2ae
1488 add changeset 911600dab2ae
1489 add changeset e8fc755d4d82
1489 add changeset e8fc755d4d82
1490 adding manifests
1490 adding manifests
1491 adding file changes
1491 adding file changes
1492 adding abc.txt revisions
1492 adding abc.txt revisions
1493 adding foo/Bar/file.txt revisions
1493 adding foo/Bar/file.txt revisions
1494 adding foo/file.txt revisions
1494 adding foo/file.txt revisions
1495 adding quux/file.py revisions
1495 adding quux/file.py revisions
1496 added 4 changesets with 4 changes to 4 files (+1 heads)
1496 added 4 changesets with 4 changes to 4 files (+1 heads)
1497 calling hook pretxnchangegroup.acl: hgext.acl.hook
1497 calling hook pretxnchangegroup.acl: hgext.acl.hook
1498 acl: checking access for user "astro"
1498 acl: checking access for user "astro"
1499 acl: acl.allow.branches not enabled
1499 acl: acl.allow.branches not enabled
1500 acl: acl.deny.branches not enabled
1500 acl: acl.deny.branches not enabled
1501 acl: acl.allow not enabled
1501 acl: acl.allow not enabled
1502 acl: acl.deny not enabled
1502 acl: acl.deny not enabled
1503 acl: branch access granted: "ef1ea85a6374" on branch "default"
1503 acl: branch access granted: "ef1ea85a6374" on branch "default"
1504 acl: path access granted: "ef1ea85a6374"
1504 acl: path access granted: "ef1ea85a6374"
1505 acl: branch access granted: "f9cafe1212c8" on branch "default"
1505 acl: branch access granted: "f9cafe1212c8" on branch "default"
1506 acl: path access granted: "f9cafe1212c8"
1506 acl: path access granted: "f9cafe1212c8"
1507 acl: branch access granted: "911600dab2ae" on branch "default"
1507 acl: branch access granted: "911600dab2ae" on branch "default"
1508 acl: path access granted: "911600dab2ae"
1508 acl: path access granted: "911600dab2ae"
1509 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1509 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1510 acl: path access granted: "e8fc755d4d82"
1510 acl: path access granted: "e8fc755d4d82"
1511 updating the branch cache
1511 bundle2-input-part: total payload size 2101
1512 bundle2-input-part: total payload size 2101
1512 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1513 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1513 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1514 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1514 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1515 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1515 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1516 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1516 bundle2-input-bundle: 4 parts total
1517 bundle2-input-bundle: 4 parts total
1517 updating the branch cache
1518 bundle2-output-bundle: "HG20", 3 parts total
1518 bundle2-output-bundle: "HG20", 3 parts total
1519 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1519 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1520 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1520 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1521 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1521 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1522 bundle2-input-bundle: with-transaction
1522 bundle2-input-bundle: with-transaction
1523 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1523 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1524 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1524 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1525 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1525 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1526 bundle2-input-bundle: 2 parts total
1526 bundle2-input-bundle: 2 parts total
1527 listing keys for "phases"
1527 listing keys for "phases"
1528 repository tip rolled back to revision 2 (undo push)
1528 repository tip rolled back to revision 2 (undo push)
1529 2:fb35475503ef
1529 2:fb35475503ef
1530
1530
1531
1531
1532 Branch acl deny test
1532 Branch acl deny test
1533
1533
1534 $ echo "[acl.deny.branches]" >> $config
1534 $ echo "[acl.deny.branches]" >> $config
1535 $ echo "foobar = *" >> $config
1535 $ echo "foobar = *" >> $config
1536 $ do_push astro
1536 $ do_push astro
1537 Pushing as user astro
1537 Pushing as user astro
1538 hgrc = """
1538 hgrc = """
1539 [hooks]
1539 [hooks]
1540 pretxnchangegroup.acl = python:hgext.acl.hook
1540 pretxnchangegroup.acl = python:hgext.acl.hook
1541 [acl]
1541 [acl]
1542 sources = push
1542 sources = push
1543 [extensions]
1543 [extensions]
1544 [acl.deny.branches]
1544 [acl.deny.branches]
1545 foobar = *
1545 foobar = *
1546 """
1546 """
1547 pushing to ../b
1547 pushing to ../b
1548 query 1; heads
1548 query 1; heads
1549 searching for changes
1549 searching for changes
1550 all remote heads known locally
1550 all remote heads known locally
1551 listing keys for "phases"
1551 listing keys for "phases"
1552 checking for updated bookmarks
1552 checking for updated bookmarks
1553 listing keys for "bookmarks"
1553 listing keys for "bookmarks"
1554 listing keys for "bookmarks"
1554 listing keys for "bookmarks"
1555 4 changesets found
1555 4 changesets found
1556 list of changesets:
1556 list of changesets:
1557 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1557 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1558 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1558 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1559 911600dab2ae7a9baff75958b84fe606851ce955
1559 911600dab2ae7a9baff75958b84fe606851ce955
1560 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1560 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1561 bundle2-output-bundle: "HG20", 5 parts total
1561 bundle2-output-bundle: "HG20", 5 parts total
1562 bundle2-output-part: "replycaps" 155 bytes payload
1562 bundle2-output-part: "replycaps" 155 bytes payload
1563 bundle2-output-part: "check:heads" streamed payload
1563 bundle2-output-part: "check:heads" streamed payload
1564 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1564 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1565 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1565 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1566 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1566 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1567 bundle2-input-bundle: with-transaction
1567 bundle2-input-bundle: with-transaction
1568 bundle2-input-part: "replycaps" supported
1568 bundle2-input-part: "replycaps" supported
1569 bundle2-input-part: total payload size 155
1569 bundle2-input-part: total payload size 155
1570 bundle2-input-part: "check:heads" supported
1570 bundle2-input-part: "check:heads" supported
1571 bundle2-input-part: total payload size 20
1571 bundle2-input-part: total payload size 20
1572 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1572 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1573 adding changesets
1573 adding changesets
1574 add changeset ef1ea85a6374
1574 add changeset ef1ea85a6374
1575 add changeset f9cafe1212c8
1575 add changeset f9cafe1212c8
1576 add changeset 911600dab2ae
1576 add changeset 911600dab2ae
1577 add changeset e8fc755d4d82
1577 add changeset e8fc755d4d82
1578 adding manifests
1578 adding manifests
1579 adding file changes
1579 adding file changes
1580 adding abc.txt revisions
1580 adding abc.txt revisions
1581 adding foo/Bar/file.txt revisions
1581 adding foo/Bar/file.txt revisions
1582 adding foo/file.txt revisions
1582 adding foo/file.txt revisions
1583 adding quux/file.py revisions
1583 adding quux/file.py revisions
1584 added 4 changesets with 4 changes to 4 files (+1 heads)
1584 added 4 changesets with 4 changes to 4 files (+1 heads)
1585 calling hook pretxnchangegroup.acl: hgext.acl.hook
1585 calling hook pretxnchangegroup.acl: hgext.acl.hook
1586 acl: checking access for user "astro"
1586 acl: checking access for user "astro"
1587 acl: acl.allow.branches not enabled
1587 acl: acl.allow.branches not enabled
1588 acl: acl.deny.branches enabled, 1 entries for user astro
1588 acl: acl.deny.branches enabled, 1 entries for user astro
1589 acl: acl.allow not enabled
1589 acl: acl.allow not enabled
1590 acl: acl.deny not enabled
1590 acl: acl.deny not enabled
1591 acl: branch access granted: "ef1ea85a6374" on branch "default"
1591 acl: branch access granted: "ef1ea85a6374" on branch "default"
1592 acl: path access granted: "ef1ea85a6374"
1592 acl: path access granted: "ef1ea85a6374"
1593 acl: branch access granted: "f9cafe1212c8" on branch "default"
1593 acl: branch access granted: "f9cafe1212c8" on branch "default"
1594 acl: path access granted: "f9cafe1212c8"
1594 acl: path access granted: "f9cafe1212c8"
1595 acl: branch access granted: "911600dab2ae" on branch "default"
1595 acl: branch access granted: "911600dab2ae" on branch "default"
1596 acl: path access granted: "911600dab2ae"
1596 acl: path access granted: "911600dab2ae"
1597 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1597 error: pretxnchangegroup.acl hook failed: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1598 bundle2-input-part: total payload size 2101
1598 bundle2-input-part: total payload size 2101
1599 bundle2-input-bundle: 4 parts total
1599 bundle2-input-bundle: 4 parts total
1600 transaction abort!
1600 transaction abort!
1601 rollback completed
1601 rollback completed
1602 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1602 abort: acl: user "astro" denied on branch "foobar" (changeset "e8fc755d4d82")
1603 no rollback information available
1603 no rollback information available
1604 2:fb35475503ef
1604 2:fb35475503ef
1605
1605
1606
1606
1607 Branch acl empty allow test
1607 Branch acl empty allow test
1608
1608
1609 $ init_config
1609 $ init_config
1610 $ echo "[acl.allow.branches]" >> $config
1610 $ echo "[acl.allow.branches]" >> $config
1611 $ do_push astro
1611 $ do_push astro
1612 Pushing as user astro
1612 Pushing as user astro
1613 hgrc = """
1613 hgrc = """
1614 [hooks]
1614 [hooks]
1615 pretxnchangegroup.acl = python:hgext.acl.hook
1615 pretxnchangegroup.acl = python:hgext.acl.hook
1616 [acl]
1616 [acl]
1617 sources = push
1617 sources = push
1618 [extensions]
1618 [extensions]
1619 [acl.allow.branches]
1619 [acl.allow.branches]
1620 """
1620 """
1621 pushing to ../b
1621 pushing to ../b
1622 query 1; heads
1622 query 1; heads
1623 searching for changes
1623 searching for changes
1624 all remote heads known locally
1624 all remote heads known locally
1625 listing keys for "phases"
1625 listing keys for "phases"
1626 checking for updated bookmarks
1626 checking for updated bookmarks
1627 listing keys for "bookmarks"
1627 listing keys for "bookmarks"
1628 listing keys for "bookmarks"
1628 listing keys for "bookmarks"
1629 4 changesets found
1629 4 changesets found
1630 list of changesets:
1630 list of changesets:
1631 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1631 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1632 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1632 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1633 911600dab2ae7a9baff75958b84fe606851ce955
1633 911600dab2ae7a9baff75958b84fe606851ce955
1634 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1634 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1635 bundle2-output-bundle: "HG20", 5 parts total
1635 bundle2-output-bundle: "HG20", 5 parts total
1636 bundle2-output-part: "replycaps" 155 bytes payload
1636 bundle2-output-part: "replycaps" 155 bytes payload
1637 bundle2-output-part: "check:heads" streamed payload
1637 bundle2-output-part: "check:heads" streamed payload
1638 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1638 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1639 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1639 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1640 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1640 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1641 bundle2-input-bundle: with-transaction
1641 bundle2-input-bundle: with-transaction
1642 bundle2-input-part: "replycaps" supported
1642 bundle2-input-part: "replycaps" supported
1643 bundle2-input-part: total payload size 155
1643 bundle2-input-part: total payload size 155
1644 bundle2-input-part: "check:heads" supported
1644 bundle2-input-part: "check:heads" supported
1645 bundle2-input-part: total payload size 20
1645 bundle2-input-part: total payload size 20
1646 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1646 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1647 adding changesets
1647 adding changesets
1648 add changeset ef1ea85a6374
1648 add changeset ef1ea85a6374
1649 add changeset f9cafe1212c8
1649 add changeset f9cafe1212c8
1650 add changeset 911600dab2ae
1650 add changeset 911600dab2ae
1651 add changeset e8fc755d4d82
1651 add changeset e8fc755d4d82
1652 adding manifests
1652 adding manifests
1653 adding file changes
1653 adding file changes
1654 adding abc.txt revisions
1654 adding abc.txt revisions
1655 adding foo/Bar/file.txt revisions
1655 adding foo/Bar/file.txt revisions
1656 adding foo/file.txt revisions
1656 adding foo/file.txt revisions
1657 adding quux/file.py revisions
1657 adding quux/file.py revisions
1658 added 4 changesets with 4 changes to 4 files (+1 heads)
1658 added 4 changesets with 4 changes to 4 files (+1 heads)
1659 calling hook pretxnchangegroup.acl: hgext.acl.hook
1659 calling hook pretxnchangegroup.acl: hgext.acl.hook
1660 acl: checking access for user "astro"
1660 acl: checking access for user "astro"
1661 acl: acl.allow.branches enabled, 0 entries for user astro
1661 acl: acl.allow.branches enabled, 0 entries for user astro
1662 acl: acl.deny.branches not enabled
1662 acl: acl.deny.branches not enabled
1663 acl: acl.allow not enabled
1663 acl: acl.allow not enabled
1664 acl: acl.deny not enabled
1664 acl: acl.deny not enabled
1665 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1665 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1666 bundle2-input-part: total payload size 2101
1666 bundle2-input-part: total payload size 2101
1667 bundle2-input-bundle: 4 parts total
1667 bundle2-input-bundle: 4 parts total
1668 transaction abort!
1668 transaction abort!
1669 rollback completed
1669 rollback completed
1670 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1670 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1671 no rollback information available
1671 no rollback information available
1672 2:fb35475503ef
1672 2:fb35475503ef
1673
1673
1674
1674
1675 Branch acl allow other
1675 Branch acl allow other
1676
1676
1677 $ init_config
1677 $ init_config
1678 $ echo "[acl.allow.branches]" >> $config
1678 $ echo "[acl.allow.branches]" >> $config
1679 $ echo "* = george" >> $config
1679 $ echo "* = george" >> $config
1680 $ do_push astro
1680 $ do_push astro
1681 Pushing as user astro
1681 Pushing as user astro
1682 hgrc = """
1682 hgrc = """
1683 [hooks]
1683 [hooks]
1684 pretxnchangegroup.acl = python:hgext.acl.hook
1684 pretxnchangegroup.acl = python:hgext.acl.hook
1685 [acl]
1685 [acl]
1686 sources = push
1686 sources = push
1687 [extensions]
1687 [extensions]
1688 [acl.allow.branches]
1688 [acl.allow.branches]
1689 * = george
1689 * = george
1690 """
1690 """
1691 pushing to ../b
1691 pushing to ../b
1692 query 1; heads
1692 query 1; heads
1693 searching for changes
1693 searching for changes
1694 all remote heads known locally
1694 all remote heads known locally
1695 listing keys for "phases"
1695 listing keys for "phases"
1696 checking for updated bookmarks
1696 checking for updated bookmarks
1697 listing keys for "bookmarks"
1697 listing keys for "bookmarks"
1698 listing keys for "bookmarks"
1698 listing keys for "bookmarks"
1699 4 changesets found
1699 4 changesets found
1700 list of changesets:
1700 list of changesets:
1701 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1701 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1702 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1702 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1703 911600dab2ae7a9baff75958b84fe606851ce955
1703 911600dab2ae7a9baff75958b84fe606851ce955
1704 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1704 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1705 bundle2-output-bundle: "HG20", 5 parts total
1705 bundle2-output-bundle: "HG20", 5 parts total
1706 bundle2-output-part: "replycaps" 155 bytes payload
1706 bundle2-output-part: "replycaps" 155 bytes payload
1707 bundle2-output-part: "check:heads" streamed payload
1707 bundle2-output-part: "check:heads" streamed payload
1708 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1708 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1709 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1709 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1710 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1710 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1711 bundle2-input-bundle: with-transaction
1711 bundle2-input-bundle: with-transaction
1712 bundle2-input-part: "replycaps" supported
1712 bundle2-input-part: "replycaps" supported
1713 bundle2-input-part: total payload size 155
1713 bundle2-input-part: total payload size 155
1714 bundle2-input-part: "check:heads" supported
1714 bundle2-input-part: "check:heads" supported
1715 bundle2-input-part: total payload size 20
1715 bundle2-input-part: total payload size 20
1716 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1716 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1717 adding changesets
1717 adding changesets
1718 add changeset ef1ea85a6374
1718 add changeset ef1ea85a6374
1719 add changeset f9cafe1212c8
1719 add changeset f9cafe1212c8
1720 add changeset 911600dab2ae
1720 add changeset 911600dab2ae
1721 add changeset e8fc755d4d82
1721 add changeset e8fc755d4d82
1722 adding manifests
1722 adding manifests
1723 adding file changes
1723 adding file changes
1724 adding abc.txt revisions
1724 adding abc.txt revisions
1725 adding foo/Bar/file.txt revisions
1725 adding foo/Bar/file.txt revisions
1726 adding foo/file.txt revisions
1726 adding foo/file.txt revisions
1727 adding quux/file.py revisions
1727 adding quux/file.py revisions
1728 added 4 changesets with 4 changes to 4 files (+1 heads)
1728 added 4 changesets with 4 changes to 4 files (+1 heads)
1729 calling hook pretxnchangegroup.acl: hgext.acl.hook
1729 calling hook pretxnchangegroup.acl: hgext.acl.hook
1730 acl: checking access for user "astro"
1730 acl: checking access for user "astro"
1731 acl: acl.allow.branches enabled, 0 entries for user astro
1731 acl: acl.allow.branches enabled, 0 entries for user astro
1732 acl: acl.deny.branches not enabled
1732 acl: acl.deny.branches not enabled
1733 acl: acl.allow not enabled
1733 acl: acl.allow not enabled
1734 acl: acl.deny not enabled
1734 acl: acl.deny not enabled
1735 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1735 error: pretxnchangegroup.acl hook failed: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1736 bundle2-input-part: total payload size 2101
1736 bundle2-input-part: total payload size 2101
1737 bundle2-input-bundle: 4 parts total
1737 bundle2-input-bundle: 4 parts total
1738 transaction abort!
1738 transaction abort!
1739 rollback completed
1739 rollback completed
1740 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1740 abort: acl: user "astro" not allowed on branch "default" (changeset "ef1ea85a6374")
1741 no rollback information available
1741 no rollback information available
1742 2:fb35475503ef
1742 2:fb35475503ef
1743
1743
1744 $ do_push george
1744 $ do_push george
1745 Pushing as user george
1745 Pushing as user george
1746 hgrc = """
1746 hgrc = """
1747 [hooks]
1747 [hooks]
1748 pretxnchangegroup.acl = python:hgext.acl.hook
1748 pretxnchangegroup.acl = python:hgext.acl.hook
1749 [acl]
1749 [acl]
1750 sources = push
1750 sources = push
1751 [extensions]
1751 [extensions]
1752 [acl.allow.branches]
1752 [acl.allow.branches]
1753 * = george
1753 * = george
1754 """
1754 """
1755 pushing to ../b
1755 pushing to ../b
1756 query 1; heads
1756 query 1; heads
1757 searching for changes
1757 searching for changes
1758 all remote heads known locally
1758 all remote heads known locally
1759 listing keys for "phases"
1759 listing keys for "phases"
1760 checking for updated bookmarks
1760 checking for updated bookmarks
1761 listing keys for "bookmarks"
1761 listing keys for "bookmarks"
1762 listing keys for "bookmarks"
1762 listing keys for "bookmarks"
1763 4 changesets found
1763 4 changesets found
1764 list of changesets:
1764 list of changesets:
1765 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1765 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1766 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1766 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1767 911600dab2ae7a9baff75958b84fe606851ce955
1767 911600dab2ae7a9baff75958b84fe606851ce955
1768 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1768 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1769 bundle2-output-bundle: "HG20", 5 parts total
1769 bundle2-output-bundle: "HG20", 5 parts total
1770 bundle2-output-part: "replycaps" 155 bytes payload
1770 bundle2-output-part: "replycaps" 155 bytes payload
1771 bundle2-output-part: "check:heads" streamed payload
1771 bundle2-output-part: "check:heads" streamed payload
1772 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1772 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1773 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1773 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1774 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1774 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1775 bundle2-input-bundle: with-transaction
1775 bundle2-input-bundle: with-transaction
1776 bundle2-input-part: "replycaps" supported
1776 bundle2-input-part: "replycaps" supported
1777 bundle2-input-part: total payload size 155
1777 bundle2-input-part: total payload size 155
1778 bundle2-input-part: "check:heads" supported
1778 bundle2-input-part: "check:heads" supported
1779 bundle2-input-part: total payload size 20
1779 bundle2-input-part: total payload size 20
1780 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1780 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1781 adding changesets
1781 adding changesets
1782 add changeset ef1ea85a6374
1782 add changeset ef1ea85a6374
1783 add changeset f9cafe1212c8
1783 add changeset f9cafe1212c8
1784 add changeset 911600dab2ae
1784 add changeset 911600dab2ae
1785 add changeset e8fc755d4d82
1785 add changeset e8fc755d4d82
1786 adding manifests
1786 adding manifests
1787 adding file changes
1787 adding file changes
1788 adding abc.txt revisions
1788 adding abc.txt revisions
1789 adding foo/Bar/file.txt revisions
1789 adding foo/Bar/file.txt revisions
1790 adding foo/file.txt revisions
1790 adding foo/file.txt revisions
1791 adding quux/file.py revisions
1791 adding quux/file.py revisions
1792 added 4 changesets with 4 changes to 4 files (+1 heads)
1792 added 4 changesets with 4 changes to 4 files (+1 heads)
1793 calling hook pretxnchangegroup.acl: hgext.acl.hook
1793 calling hook pretxnchangegroup.acl: hgext.acl.hook
1794 acl: checking access for user "george"
1794 acl: checking access for user "george"
1795 acl: acl.allow.branches enabled, 1 entries for user george
1795 acl: acl.allow.branches enabled, 1 entries for user george
1796 acl: acl.deny.branches not enabled
1796 acl: acl.deny.branches not enabled
1797 acl: acl.allow not enabled
1797 acl: acl.allow not enabled
1798 acl: acl.deny not enabled
1798 acl: acl.deny not enabled
1799 acl: branch access granted: "ef1ea85a6374" on branch "default"
1799 acl: branch access granted: "ef1ea85a6374" on branch "default"
1800 acl: path access granted: "ef1ea85a6374"
1800 acl: path access granted: "ef1ea85a6374"
1801 acl: branch access granted: "f9cafe1212c8" on branch "default"
1801 acl: branch access granted: "f9cafe1212c8" on branch "default"
1802 acl: path access granted: "f9cafe1212c8"
1802 acl: path access granted: "f9cafe1212c8"
1803 acl: branch access granted: "911600dab2ae" on branch "default"
1803 acl: branch access granted: "911600dab2ae" on branch "default"
1804 acl: path access granted: "911600dab2ae"
1804 acl: path access granted: "911600dab2ae"
1805 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1805 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1806 acl: path access granted: "e8fc755d4d82"
1806 acl: path access granted: "e8fc755d4d82"
1807 updating the branch cache
1807 bundle2-input-part: total payload size 2101
1808 bundle2-input-part: total payload size 2101
1808 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1809 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1809 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1810 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1810 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1811 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1811 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1812 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1812 bundle2-input-bundle: 4 parts total
1813 bundle2-input-bundle: 4 parts total
1813 updating the branch cache
1814 bundle2-output-bundle: "HG20", 3 parts total
1814 bundle2-output-bundle: "HG20", 3 parts total
1815 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1815 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1816 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1816 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1817 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1817 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1818 bundle2-input-bundle: with-transaction
1818 bundle2-input-bundle: with-transaction
1819 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1819 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1820 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1820 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1821 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1821 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1822 bundle2-input-bundle: 2 parts total
1822 bundle2-input-bundle: 2 parts total
1823 listing keys for "phases"
1823 listing keys for "phases"
1824 repository tip rolled back to revision 2 (undo push)
1824 repository tip rolled back to revision 2 (undo push)
1825 2:fb35475503ef
1825 2:fb35475503ef
1826
1826
1827
1827
1828 Branch acl conflicting allow
1828 Branch acl conflicting allow
1829 asterisk ends up applying to all branches and allowing george to
1829 asterisk ends up applying to all branches and allowing george to
1830 push foobar into the remote
1830 push foobar into the remote
1831
1831
1832 $ init_config
1832 $ init_config
1833 $ echo "[acl.allow.branches]" >> $config
1833 $ echo "[acl.allow.branches]" >> $config
1834 $ echo "foobar = astro" >> $config
1834 $ echo "foobar = astro" >> $config
1835 $ echo "* = george" >> $config
1835 $ echo "* = george" >> $config
1836 $ do_push george
1836 $ do_push george
1837 Pushing as user george
1837 Pushing as user george
1838 hgrc = """
1838 hgrc = """
1839 [hooks]
1839 [hooks]
1840 pretxnchangegroup.acl = python:hgext.acl.hook
1840 pretxnchangegroup.acl = python:hgext.acl.hook
1841 [acl]
1841 [acl]
1842 sources = push
1842 sources = push
1843 [extensions]
1843 [extensions]
1844 [acl.allow.branches]
1844 [acl.allow.branches]
1845 foobar = astro
1845 foobar = astro
1846 * = george
1846 * = george
1847 """
1847 """
1848 pushing to ../b
1848 pushing to ../b
1849 query 1; heads
1849 query 1; heads
1850 searching for changes
1850 searching for changes
1851 all remote heads known locally
1851 all remote heads known locally
1852 listing keys for "phases"
1852 listing keys for "phases"
1853 checking for updated bookmarks
1853 checking for updated bookmarks
1854 listing keys for "bookmarks"
1854 listing keys for "bookmarks"
1855 listing keys for "bookmarks"
1855 listing keys for "bookmarks"
1856 4 changesets found
1856 4 changesets found
1857 list of changesets:
1857 list of changesets:
1858 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1858 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1859 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1859 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1860 911600dab2ae7a9baff75958b84fe606851ce955
1860 911600dab2ae7a9baff75958b84fe606851ce955
1861 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1861 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1862 bundle2-output-bundle: "HG20", 5 parts total
1862 bundle2-output-bundle: "HG20", 5 parts total
1863 bundle2-output-part: "replycaps" 155 bytes payload
1863 bundle2-output-part: "replycaps" 155 bytes payload
1864 bundle2-output-part: "check:heads" streamed payload
1864 bundle2-output-part: "check:heads" streamed payload
1865 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1865 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1866 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1866 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1867 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1867 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1868 bundle2-input-bundle: with-transaction
1868 bundle2-input-bundle: with-transaction
1869 bundle2-input-part: "replycaps" supported
1869 bundle2-input-part: "replycaps" supported
1870 bundle2-input-part: total payload size 155
1870 bundle2-input-part: total payload size 155
1871 bundle2-input-part: "check:heads" supported
1871 bundle2-input-part: "check:heads" supported
1872 bundle2-input-part: total payload size 20
1872 bundle2-input-part: total payload size 20
1873 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1873 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1874 adding changesets
1874 adding changesets
1875 add changeset ef1ea85a6374
1875 add changeset ef1ea85a6374
1876 add changeset f9cafe1212c8
1876 add changeset f9cafe1212c8
1877 add changeset 911600dab2ae
1877 add changeset 911600dab2ae
1878 add changeset e8fc755d4d82
1878 add changeset e8fc755d4d82
1879 adding manifests
1879 adding manifests
1880 adding file changes
1880 adding file changes
1881 adding abc.txt revisions
1881 adding abc.txt revisions
1882 adding foo/Bar/file.txt revisions
1882 adding foo/Bar/file.txt revisions
1883 adding foo/file.txt revisions
1883 adding foo/file.txt revisions
1884 adding quux/file.py revisions
1884 adding quux/file.py revisions
1885 added 4 changesets with 4 changes to 4 files (+1 heads)
1885 added 4 changesets with 4 changes to 4 files (+1 heads)
1886 calling hook pretxnchangegroup.acl: hgext.acl.hook
1886 calling hook pretxnchangegroup.acl: hgext.acl.hook
1887 acl: checking access for user "george"
1887 acl: checking access for user "george"
1888 acl: acl.allow.branches enabled, 1 entries for user george
1888 acl: acl.allow.branches enabled, 1 entries for user george
1889 acl: acl.deny.branches not enabled
1889 acl: acl.deny.branches not enabled
1890 acl: acl.allow not enabled
1890 acl: acl.allow not enabled
1891 acl: acl.deny not enabled
1891 acl: acl.deny not enabled
1892 acl: branch access granted: "ef1ea85a6374" on branch "default"
1892 acl: branch access granted: "ef1ea85a6374" on branch "default"
1893 acl: path access granted: "ef1ea85a6374"
1893 acl: path access granted: "ef1ea85a6374"
1894 acl: branch access granted: "f9cafe1212c8" on branch "default"
1894 acl: branch access granted: "f9cafe1212c8" on branch "default"
1895 acl: path access granted: "f9cafe1212c8"
1895 acl: path access granted: "f9cafe1212c8"
1896 acl: branch access granted: "911600dab2ae" on branch "default"
1896 acl: branch access granted: "911600dab2ae" on branch "default"
1897 acl: path access granted: "911600dab2ae"
1897 acl: path access granted: "911600dab2ae"
1898 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1898 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
1899 acl: path access granted: "e8fc755d4d82"
1899 acl: path access granted: "e8fc755d4d82"
1900 updating the branch cache
1900 bundle2-input-part: total payload size 2101
1901 bundle2-input-part: total payload size 2101
1901 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1902 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1902 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1903 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
1903 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1904 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
1904 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1905 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
1905 bundle2-input-bundle: 4 parts total
1906 bundle2-input-bundle: 4 parts total
1906 updating the branch cache
1907 bundle2-output-bundle: "HG20", 3 parts total
1907 bundle2-output-bundle: "HG20", 3 parts total
1908 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1908 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
1909 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1909 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1910 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1910 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
1911 bundle2-input-bundle: with-transaction
1911 bundle2-input-bundle: with-transaction
1912 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1912 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
1913 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1913 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1914 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1914 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
1915 bundle2-input-bundle: 2 parts total
1915 bundle2-input-bundle: 2 parts total
1916 listing keys for "phases"
1916 listing keys for "phases"
1917 repository tip rolled back to revision 2 (undo push)
1917 repository tip rolled back to revision 2 (undo push)
1918 2:fb35475503ef
1918 2:fb35475503ef
1919
1919
1920 Branch acl conflicting deny
1920 Branch acl conflicting deny
1921
1921
1922 $ init_config
1922 $ init_config
1923 $ echo "[acl.deny.branches]" >> $config
1923 $ echo "[acl.deny.branches]" >> $config
1924 $ echo "foobar = astro" >> $config
1924 $ echo "foobar = astro" >> $config
1925 $ echo "default = astro" >> $config
1925 $ echo "default = astro" >> $config
1926 $ echo "* = george" >> $config
1926 $ echo "* = george" >> $config
1927 $ do_push george
1927 $ do_push george
1928 Pushing as user george
1928 Pushing as user george
1929 hgrc = """
1929 hgrc = """
1930 [hooks]
1930 [hooks]
1931 pretxnchangegroup.acl = python:hgext.acl.hook
1931 pretxnchangegroup.acl = python:hgext.acl.hook
1932 [acl]
1932 [acl]
1933 sources = push
1933 sources = push
1934 [extensions]
1934 [extensions]
1935 [acl.deny.branches]
1935 [acl.deny.branches]
1936 foobar = astro
1936 foobar = astro
1937 default = astro
1937 default = astro
1938 * = george
1938 * = george
1939 """
1939 """
1940 pushing to ../b
1940 pushing to ../b
1941 query 1; heads
1941 query 1; heads
1942 searching for changes
1942 searching for changes
1943 all remote heads known locally
1943 all remote heads known locally
1944 listing keys for "phases"
1944 listing keys for "phases"
1945 checking for updated bookmarks
1945 checking for updated bookmarks
1946 listing keys for "bookmarks"
1946 listing keys for "bookmarks"
1947 listing keys for "bookmarks"
1947 listing keys for "bookmarks"
1948 4 changesets found
1948 4 changesets found
1949 list of changesets:
1949 list of changesets:
1950 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1950 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
1951 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1951 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
1952 911600dab2ae7a9baff75958b84fe606851ce955
1952 911600dab2ae7a9baff75958b84fe606851ce955
1953 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1953 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
1954 bundle2-output-bundle: "HG20", 5 parts total
1954 bundle2-output-bundle: "HG20", 5 parts total
1955 bundle2-output-part: "replycaps" 155 bytes payload
1955 bundle2-output-part: "replycaps" 155 bytes payload
1956 bundle2-output-part: "check:heads" streamed payload
1956 bundle2-output-part: "check:heads" streamed payload
1957 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1957 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
1958 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1958 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1959 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1959 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
1960 bundle2-input-bundle: with-transaction
1960 bundle2-input-bundle: with-transaction
1961 bundle2-input-part: "replycaps" supported
1961 bundle2-input-part: "replycaps" supported
1962 bundle2-input-part: total payload size 155
1962 bundle2-input-part: total payload size 155
1963 bundle2-input-part: "check:heads" supported
1963 bundle2-input-part: "check:heads" supported
1964 bundle2-input-part: total payload size 20
1964 bundle2-input-part: total payload size 20
1965 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1965 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
1966 adding changesets
1966 adding changesets
1967 add changeset ef1ea85a6374
1967 add changeset ef1ea85a6374
1968 add changeset f9cafe1212c8
1968 add changeset f9cafe1212c8
1969 add changeset 911600dab2ae
1969 add changeset 911600dab2ae
1970 add changeset e8fc755d4d82
1970 add changeset e8fc755d4d82
1971 adding manifests
1971 adding manifests
1972 adding file changes
1972 adding file changes
1973 adding abc.txt revisions
1973 adding abc.txt revisions
1974 adding foo/Bar/file.txt revisions
1974 adding foo/Bar/file.txt revisions
1975 adding foo/file.txt revisions
1975 adding foo/file.txt revisions
1976 adding quux/file.py revisions
1976 adding quux/file.py revisions
1977 added 4 changesets with 4 changes to 4 files (+1 heads)
1977 added 4 changesets with 4 changes to 4 files (+1 heads)
1978 calling hook pretxnchangegroup.acl: hgext.acl.hook
1978 calling hook pretxnchangegroup.acl: hgext.acl.hook
1979 acl: checking access for user "george"
1979 acl: checking access for user "george"
1980 acl: acl.allow.branches not enabled
1980 acl: acl.allow.branches not enabled
1981 acl: acl.deny.branches enabled, 1 entries for user george
1981 acl: acl.deny.branches enabled, 1 entries for user george
1982 acl: acl.allow not enabled
1982 acl: acl.allow not enabled
1983 acl: acl.deny not enabled
1983 acl: acl.deny not enabled
1984 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1984 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1985 bundle2-input-part: total payload size 2101
1985 bundle2-input-part: total payload size 2101
1986 bundle2-input-bundle: 4 parts total
1986 bundle2-input-bundle: 4 parts total
1987 transaction abort!
1987 transaction abort!
1988 rollback completed
1988 rollback completed
1989 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1989 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
1990 no rollback information available
1990 no rollback information available
1991 2:fb35475503ef
1991 2:fb35475503ef
1992
1992
1993 User 'astro' must not be denied
1993 User 'astro' must not be denied
1994
1994
1995 $ init_config
1995 $ init_config
1996 $ echo "[acl.deny.branches]" >> $config
1996 $ echo "[acl.deny.branches]" >> $config
1997 $ echo "default = !astro" >> $config
1997 $ echo "default = !astro" >> $config
1998 $ do_push astro
1998 $ do_push astro
1999 Pushing as user astro
1999 Pushing as user astro
2000 hgrc = """
2000 hgrc = """
2001 [hooks]
2001 [hooks]
2002 pretxnchangegroup.acl = python:hgext.acl.hook
2002 pretxnchangegroup.acl = python:hgext.acl.hook
2003 [acl]
2003 [acl]
2004 sources = push
2004 sources = push
2005 [extensions]
2005 [extensions]
2006 [acl.deny.branches]
2006 [acl.deny.branches]
2007 default = !astro
2007 default = !astro
2008 """
2008 """
2009 pushing to ../b
2009 pushing to ../b
2010 query 1; heads
2010 query 1; heads
2011 searching for changes
2011 searching for changes
2012 all remote heads known locally
2012 all remote heads known locally
2013 listing keys for "phases"
2013 listing keys for "phases"
2014 checking for updated bookmarks
2014 checking for updated bookmarks
2015 listing keys for "bookmarks"
2015 listing keys for "bookmarks"
2016 listing keys for "bookmarks"
2016 listing keys for "bookmarks"
2017 4 changesets found
2017 4 changesets found
2018 list of changesets:
2018 list of changesets:
2019 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2019 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2020 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2020 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2021 911600dab2ae7a9baff75958b84fe606851ce955
2021 911600dab2ae7a9baff75958b84fe606851ce955
2022 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2022 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2023 bundle2-output-bundle: "HG20", 5 parts total
2023 bundle2-output-bundle: "HG20", 5 parts total
2024 bundle2-output-part: "replycaps" 155 bytes payload
2024 bundle2-output-part: "replycaps" 155 bytes payload
2025 bundle2-output-part: "check:heads" streamed payload
2025 bundle2-output-part: "check:heads" streamed payload
2026 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2026 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2027 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2027 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2028 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2028 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2029 bundle2-input-bundle: with-transaction
2029 bundle2-input-bundle: with-transaction
2030 bundle2-input-part: "replycaps" supported
2030 bundle2-input-part: "replycaps" supported
2031 bundle2-input-part: total payload size 155
2031 bundle2-input-part: total payload size 155
2032 bundle2-input-part: "check:heads" supported
2032 bundle2-input-part: "check:heads" supported
2033 bundle2-input-part: total payload size 20
2033 bundle2-input-part: total payload size 20
2034 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2034 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2035 adding changesets
2035 adding changesets
2036 add changeset ef1ea85a6374
2036 add changeset ef1ea85a6374
2037 add changeset f9cafe1212c8
2037 add changeset f9cafe1212c8
2038 add changeset 911600dab2ae
2038 add changeset 911600dab2ae
2039 add changeset e8fc755d4d82
2039 add changeset e8fc755d4d82
2040 adding manifests
2040 adding manifests
2041 adding file changes
2041 adding file changes
2042 adding abc.txt revisions
2042 adding abc.txt revisions
2043 adding foo/Bar/file.txt revisions
2043 adding foo/Bar/file.txt revisions
2044 adding foo/file.txt revisions
2044 adding foo/file.txt revisions
2045 adding quux/file.py revisions
2045 adding quux/file.py revisions
2046 added 4 changesets with 4 changes to 4 files (+1 heads)
2046 added 4 changesets with 4 changes to 4 files (+1 heads)
2047 calling hook pretxnchangegroup.acl: hgext.acl.hook
2047 calling hook pretxnchangegroup.acl: hgext.acl.hook
2048 acl: checking access for user "astro"
2048 acl: checking access for user "astro"
2049 acl: acl.allow.branches not enabled
2049 acl: acl.allow.branches not enabled
2050 acl: acl.deny.branches enabled, 0 entries for user astro
2050 acl: acl.deny.branches enabled, 0 entries for user astro
2051 acl: acl.allow not enabled
2051 acl: acl.allow not enabled
2052 acl: acl.deny not enabled
2052 acl: acl.deny not enabled
2053 acl: branch access granted: "ef1ea85a6374" on branch "default"
2053 acl: branch access granted: "ef1ea85a6374" on branch "default"
2054 acl: path access granted: "ef1ea85a6374"
2054 acl: path access granted: "ef1ea85a6374"
2055 acl: branch access granted: "f9cafe1212c8" on branch "default"
2055 acl: branch access granted: "f9cafe1212c8" on branch "default"
2056 acl: path access granted: "f9cafe1212c8"
2056 acl: path access granted: "f9cafe1212c8"
2057 acl: branch access granted: "911600dab2ae" on branch "default"
2057 acl: branch access granted: "911600dab2ae" on branch "default"
2058 acl: path access granted: "911600dab2ae"
2058 acl: path access granted: "911600dab2ae"
2059 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2059 acl: branch access granted: "e8fc755d4d82" on branch "foobar"
2060 acl: path access granted: "e8fc755d4d82"
2060 acl: path access granted: "e8fc755d4d82"
2061 updating the branch cache
2061 bundle2-input-part: total payload size 2101
2062 bundle2-input-part: total payload size 2101
2062 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
2063 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
2063 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
2064 pushing key for "phases:911600dab2ae7a9baff75958b84fe606851ce955"
2064 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
2065 bundle2-input-part: "pushkey" (params: 4 mandatory) supported
2065 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
2066 pushing key for "phases:e8fc755d4d8217ee5b0c2bb41558c40d43b92c01"
2066 bundle2-input-bundle: 4 parts total
2067 bundle2-input-bundle: 4 parts total
2067 updating the branch cache
2068 bundle2-output-bundle: "HG20", 3 parts total
2068 bundle2-output-bundle: "HG20", 3 parts total
2069 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2069 bundle2-output-part: "reply:changegroup" (advisory) (params: 0 advisory) empty payload
2070 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
2070 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
2071 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
2071 bundle2-output-part: "reply:pushkey" (params: 0 advisory) empty payload
2072 bundle2-input-bundle: with-transaction
2072 bundle2-input-bundle: with-transaction
2073 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2073 bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
2074 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
2074 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
2075 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
2075 bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
2076 bundle2-input-bundle: 2 parts total
2076 bundle2-input-bundle: 2 parts total
2077 listing keys for "phases"
2077 listing keys for "phases"
2078 repository tip rolled back to revision 2 (undo push)
2078 repository tip rolled back to revision 2 (undo push)
2079 2:fb35475503ef
2079 2:fb35475503ef
2080
2080
2081
2081
2082 Non-astro users must be denied
2082 Non-astro users must be denied
2083
2083
2084 $ do_push george
2084 $ do_push george
2085 Pushing as user george
2085 Pushing as user george
2086 hgrc = """
2086 hgrc = """
2087 [hooks]
2087 [hooks]
2088 pretxnchangegroup.acl = python:hgext.acl.hook
2088 pretxnchangegroup.acl = python:hgext.acl.hook
2089 [acl]
2089 [acl]
2090 sources = push
2090 sources = push
2091 [extensions]
2091 [extensions]
2092 [acl.deny.branches]
2092 [acl.deny.branches]
2093 default = !astro
2093 default = !astro
2094 """
2094 """
2095 pushing to ../b
2095 pushing to ../b
2096 query 1; heads
2096 query 1; heads
2097 searching for changes
2097 searching for changes
2098 all remote heads known locally
2098 all remote heads known locally
2099 listing keys for "phases"
2099 listing keys for "phases"
2100 checking for updated bookmarks
2100 checking for updated bookmarks
2101 listing keys for "bookmarks"
2101 listing keys for "bookmarks"
2102 listing keys for "bookmarks"
2102 listing keys for "bookmarks"
2103 4 changesets found
2103 4 changesets found
2104 list of changesets:
2104 list of changesets:
2105 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2105 ef1ea85a6374b77d6da9dcda9541f498f2d17df7
2106 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2106 f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
2107 911600dab2ae7a9baff75958b84fe606851ce955
2107 911600dab2ae7a9baff75958b84fe606851ce955
2108 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2108 e8fc755d4d8217ee5b0c2bb41558c40d43b92c01
2109 bundle2-output-bundle: "HG20", 5 parts total
2109 bundle2-output-bundle: "HG20", 5 parts total
2110 bundle2-output-part: "replycaps" 155 bytes payload
2110 bundle2-output-part: "replycaps" 155 bytes payload
2111 bundle2-output-part: "check:heads" streamed payload
2111 bundle2-output-part: "check:heads" streamed payload
2112 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2112 bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
2113 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2113 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2114 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2114 bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
2115 bundle2-input-bundle: with-transaction
2115 bundle2-input-bundle: with-transaction
2116 bundle2-input-part: "replycaps" supported
2116 bundle2-input-part: "replycaps" supported
2117 bundle2-input-part: total payload size 155
2117 bundle2-input-part: total payload size 155
2118 bundle2-input-part: "check:heads" supported
2118 bundle2-input-part: "check:heads" supported
2119 bundle2-input-part: total payload size 20
2119 bundle2-input-part: total payload size 20
2120 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2120 bundle2-input-part: "changegroup" (params: 1 mandatory) supported
2121 adding changesets
2121 adding changesets
2122 add changeset ef1ea85a6374
2122 add changeset ef1ea85a6374
2123 add changeset f9cafe1212c8
2123 add changeset f9cafe1212c8
2124 add changeset 911600dab2ae
2124 add changeset 911600dab2ae
2125 add changeset e8fc755d4d82
2125 add changeset e8fc755d4d82
2126 adding manifests
2126 adding manifests
2127 adding file changes
2127 adding file changes
2128 adding abc.txt revisions
2128 adding abc.txt revisions
2129 adding foo/Bar/file.txt revisions
2129 adding foo/Bar/file.txt revisions
2130 adding foo/file.txt revisions
2130 adding foo/file.txt revisions
2131 adding quux/file.py revisions
2131 adding quux/file.py revisions
2132 added 4 changesets with 4 changes to 4 files (+1 heads)
2132 added 4 changesets with 4 changes to 4 files (+1 heads)
2133 calling hook pretxnchangegroup.acl: hgext.acl.hook
2133 calling hook pretxnchangegroup.acl: hgext.acl.hook
2134 acl: checking access for user "george"
2134 acl: checking access for user "george"
2135 acl: acl.allow.branches not enabled
2135 acl: acl.allow.branches not enabled
2136 acl: acl.deny.branches enabled, 1 entries for user george
2136 acl: acl.deny.branches enabled, 1 entries for user george
2137 acl: acl.allow not enabled
2137 acl: acl.allow not enabled
2138 acl: acl.deny not enabled
2138 acl: acl.deny not enabled
2139 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2139 error: pretxnchangegroup.acl hook failed: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2140 bundle2-input-part: total payload size 2101
2140 bundle2-input-part: total payload size 2101
2141 bundle2-input-bundle: 4 parts total
2141 bundle2-input-bundle: 4 parts total
2142 transaction abort!
2142 transaction abort!
2143 rollback completed
2143 rollback completed
2144 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2144 abort: acl: user "george" denied on branch "default" (changeset "ef1ea85a6374")
2145 no rollback information available
2145 no rollback information available
2146 2:fb35475503ef
2146 2:fb35475503ef
2147
2147
2148
2148
@@ -1,154 +1,154 b''
1 Test changesets filtering during exchanges (some tests are still in
1 Test changesets filtering during exchanges (some tests are still in
2 test-obsolete.t)
2 test-obsolete.t)
3
3
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [experimental]
5 > [experimental]
6 > evolution=createmarkers
6 > evolution=createmarkers
7 > EOF
7 > EOF
8
8
9 Push does not corrupt remote
9 Push does not corrupt remote
10 ----------------------------
10 ----------------------------
11
11
12 Create a DAG where a changeset reuses a revision from a file first used in an
12 Create a DAG where a changeset reuses a revision from a file first used in an
13 extinct changeset.
13 extinct changeset.
14
14
15 $ hg init local
15 $ hg init local
16 $ cd local
16 $ cd local
17 $ echo 'base' > base
17 $ echo 'base' > base
18 $ hg commit -Am base
18 $ hg commit -Am base
19 adding base
19 adding base
20 $ echo 'A' > A
20 $ echo 'A' > A
21 $ hg commit -Am A
21 $ hg commit -Am A
22 adding A
22 adding A
23 $ hg up 0
23 $ hg up 0
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 $ hg revert -ar 1
25 $ hg revert -ar 1
26 adding A
26 adding A
27 $ hg commit -Am "A'"
27 $ hg commit -Am "A'"
28 created new head
28 created new head
29 $ hg log -G --template='{desc} {node}'
29 $ hg log -G --template='{desc} {node}'
30 @ A' f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
30 @ A' f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
31 |
31 |
32 | o A 9d73aac1b2ed7d53835eaeec212ed41ea47da53a
32 | o A 9d73aac1b2ed7d53835eaeec212ed41ea47da53a
33 |/
33 |/
34 o base d20a80d4def38df63a4b330b7fb688f3d4cae1e3
34 o base d20a80d4def38df63a4b330b7fb688f3d4cae1e3
35
35
36 $ hg debugobsolete 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
36 $ hg debugobsolete 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
37
37
38 Push it. The bundle should not refer to the extinct changeset.
38 Push it. The bundle should not refer to the extinct changeset.
39
39
40 $ hg init ../other
40 $ hg init ../other
41 $ hg push ../other
41 $ hg push ../other
42 pushing to ../other
42 pushing to ../other
43 searching for changes
43 searching for changes
44 adding changesets
44 adding changesets
45 adding manifests
45 adding manifests
46 adding file changes
46 adding file changes
47 added 2 changesets with 2 changes to 2 files
47 added 2 changesets with 2 changes to 2 files
48 $ hg -R ../other verify
48 $ hg -R ../other verify
49 checking changesets
49 checking changesets
50 checking manifests
50 checking manifests
51 crosschecking files in changesets and manifests
51 crosschecking files in changesets and manifests
52 checking files
52 checking files
53 2 files, 2 changesets, 2 total revisions
53 2 files, 2 changesets, 2 total revisions
54
54
55 Adding a changeset going extinct locally
55 Adding a changeset going extinct locally
56 ------------------------------------------
56 ------------------------------------------
57
57
58 Pull a changeset that will immediatly goes extinct (because you already have a
58 Pull a changeset that will immediatly goes extinct (because you already have a
59 marker to obsolete him)
59 marker to obsolete him)
60 (test resolution of issue3788)
60 (test resolution of issue3788)
61
61
62 $ hg phase --draft --force f89bcc95eba5
62 $ hg phase --draft --force f89bcc95eba5
63 $ hg phase -R ../other --draft --force f89bcc95eba5
63 $ hg phase -R ../other --draft --force f89bcc95eba5
64 $ hg commit --amend -m "A''"
64 $ hg commit --amend -m "A''"
65 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
65 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
66 $ hg pull ../other
66 $ hg pull ../other
67 pulling from ../other
67 pulling from ../other
68 searching for changes
68 searching for changes
69 adding changesets
69 adding changesets
70 adding manifests
70 adding manifests
71 adding file changes
71 adding file changes
72 added 1 changesets with 0 changes to 1 files (+1 heads)
72 added 1 changesets with 0 changes to 1 files (+1 heads)
73 (run 'hg heads' to see heads, 'hg merge' to merge)
73 (run 'hg heads' to see heads, 'hg merge' to merge)
74
74
75 check that bundle is not affected
75 check that bundle is not affected
76
76
77 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5.hg
77 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5.hg
78 1 changesets found
78 1 changesets found
79 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
79 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
80 $ hg unbundle ../f89bcc95eba5.hg
80 $ hg unbundle ../f89bcc95eba5.hg
81 adding changesets
81 adding changesets
82 adding manifests
82 adding manifests
83 adding file changes
83 adding file changes
84 added 1 changesets with 0 changes to 1 files (+1 heads)
84 added 1 changesets with 0 changes to 1 files (+1 heads)
85 (run 'hg heads' to see heads)
85 (run 'hg heads' to see heads)
86 $ cd ..
86 $ cd ..
87
87
88 pull does not fetch excessive changesets when common node is hidden (issue4982)
88 pull does not fetch excessive changesets when common node is hidden (issue4982)
89 -------------------------------------------------------------------------------
89 -------------------------------------------------------------------------------
90
90
91 initial repo with server and client matching
91 initial repo with server and client matching
92
92
93 $ hg init pull-hidden-common
93 $ hg init pull-hidden-common
94 $ cd pull-hidden-common
94 $ cd pull-hidden-common
95 $ touch foo
95 $ touch foo
96 $ hg -q commit -A -m initial
96 $ hg -q commit -A -m initial
97 $ echo 1 > foo
97 $ echo 1 > foo
98 $ hg commit -m 1
98 $ hg commit -m 1
99 $ echo 2a > foo
99 $ echo 2a > foo
100 $ hg commit -m 2a
100 $ hg commit -m 2a
101 $ cd ..
101 $ cd ..
102 $ hg clone --pull pull-hidden-common pull-hidden-common-client
102 $ hg clone --pull pull-hidden-common pull-hidden-common-client
103 requesting all changes
103 requesting all changes
104 adding changesets
104 adding changesets
105 adding manifests
105 adding manifests
106 adding file changes
106 adding file changes
107 added 3 changesets with 3 changes to 1 files
107 added 3 changesets with 3 changes to 1 files
108 updating to branch default
108 updating to branch default
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110
110
111 server obsoletes the old head
111 server obsoletes the old head
112
112
113 $ cd pull-hidden-common
113 $ cd pull-hidden-common
114 $ hg -q up -r 1
114 $ hg -q up -r 1
115 $ echo 2b > foo
115 $ echo 2b > foo
116 $ hg -q commit -m 2b
116 $ hg -q commit -m 2b
117 $ hg debugobsolete 6a29ed9c68defff1a139e5c6fa9696fb1a75783d bec0734cd68e84477ba7fc1d13e6cff53ab70129
117 $ hg debugobsolete 6a29ed9c68defff1a139e5c6fa9696fb1a75783d bec0734cd68e84477ba7fc1d13e6cff53ab70129
118 $ cd ..
118 $ cd ..
119
119
120 client only pulls down 1 changeset
120 client only pulls down 1 changeset
121
121
122 $ cd pull-hidden-common-client
122 $ cd pull-hidden-common-client
123 $ hg pull --debug
123 $ hg pull --debug
124 pulling from $TESTTMP/pull-hidden-common (glob)
124 pulling from $TESTTMP/pull-hidden-common (glob)
125 query 1; heads
125 query 1; heads
126 searching for changes
126 searching for changes
127 taking quick initial sample
127 taking quick initial sample
128 query 2; still undecided: 2, sample size is: 2
128 query 2; still undecided: 2, sample size is: 2
129 2 total queries
129 2 total queries
130 1 changesets found
130 1 changesets found
131 list of changesets:
131 list of changesets:
132 bec0734cd68e84477ba7fc1d13e6cff53ab70129
132 bec0734cd68e84477ba7fc1d13e6cff53ab70129
133 listing keys for "phases"
133 listing keys for "phases"
134 listing keys for "bookmarks"
134 listing keys for "bookmarks"
135 bundle2-output-bundle: "HG20", 3 parts total
135 bundle2-output-bundle: "HG20", 3 parts total
136 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
136 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
137 bundle2-output-part: "listkeys" (params: 1 mandatory) 58 bytes payload
137 bundle2-output-part: "listkeys" (params: 1 mandatory) 58 bytes payload
138 bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
138 bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
139 bundle2-input-bundle: with-transaction
139 bundle2-input-bundle: with-transaction
140 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
140 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
141 adding changesets
141 adding changesets
142 add changeset bec0734cd68e
142 add changeset bec0734cd68e
143 adding manifests
143 adding manifests
144 adding file changes
144 adding file changes
145 adding foo revisions
145 adding foo revisions
146 added 1 changesets with 1 changes to 1 files (+1 heads)
146 added 1 changesets with 1 changes to 1 files (+1 heads)
147 updating the branch cache
147 bundle2-input-part: total payload size 474
148 bundle2-input-part: total payload size 474
148 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
149 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
149 bundle2-input-part: total payload size 58
150 bundle2-input-part: total payload size 58
150 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
151 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
151 bundle2-input-bundle: 2 parts total
152 bundle2-input-bundle: 2 parts total
152 checking for updated bookmarks
153 checking for updated bookmarks
153 updating the branch cache
154 (run 'hg heads' to see heads, 'hg merge' to merge)
154 (run 'hg heads' to see heads, 'hg merge' to merge)
@@ -1,360 +1,359 b''
1 $ cat >> $HGRCPATH <<EOF
1 $ cat >> $HGRCPATH <<EOF
2 > [format]
2 > [format]
3 > usegeneraldelta=yes
3 > usegeneraldelta=yes
4 > [extensions]
4 > [extensions]
5 > rebase=
5 > rebase=
6 >
6 >
7 > [phases]
7 > [phases]
8 > publish=False
8 > publish=False
9 >
9 >
10 > [alias]
10 > [alias]
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
12 > EOF
12 > EOF
13
13
14 $ hg init a
14 $ hg init a
15 $ cd a
15 $ cd a
16 $ echo c1 >common
16 $ echo c1 >common
17 $ hg add common
17 $ hg add common
18 $ hg ci -m C1
18 $ hg ci -m C1
19
19
20 $ echo c2 >>common
20 $ echo c2 >>common
21 $ hg ci -m C2
21 $ hg ci -m C2
22
22
23 $ echo c3 >>common
23 $ echo c3 >>common
24 $ hg ci -m C3
24 $ hg ci -m C3
25
25
26 $ hg up -q -C 1
26 $ hg up -q -C 1
27
27
28 $ echo l1 >>extra
28 $ echo l1 >>extra
29 $ hg add extra
29 $ hg add extra
30 $ hg ci -m L1
30 $ hg ci -m L1
31 created new head
31 created new head
32
32
33 $ sed -e 's/c2/l2/' common > common.new
33 $ sed -e 's/c2/l2/' common > common.new
34 $ mv common.new common
34 $ mv common.new common
35 $ hg ci -m L2
35 $ hg ci -m L2
36
36
37 $ echo l3 >> extra2
37 $ echo l3 >> extra2
38 $ hg add extra2
38 $ hg add extra2
39 $ hg ci -m L3
39 $ hg ci -m L3
40 $ hg bookmark mybook
40 $ hg bookmark mybook
41
41
42 $ hg phase --force --secret 4
42 $ hg phase --force --secret 4
43
43
44 $ hg tglog
44 $ hg tglog
45 @ 5:secret 'L3' mybook
45 @ 5:secret 'L3' mybook
46 |
46 |
47 o 4:secret 'L2'
47 o 4:secret 'L2'
48 |
48 |
49 o 3:draft 'L1'
49 o 3:draft 'L1'
50 |
50 |
51 | o 2:draft 'C3'
51 | o 2:draft 'C3'
52 |/
52 |/
53 o 1:draft 'C2'
53 o 1:draft 'C2'
54 |
54 |
55 o 0:draft 'C1'
55 o 0:draft 'C1'
56
56
57 Try to call --continue:
57 Try to call --continue:
58
58
59 $ hg rebase --continue
59 $ hg rebase --continue
60 abort: no rebase in progress
60 abort: no rebase in progress
61 [255]
61 [255]
62
62
63 Conflicting rebase:
63 Conflicting rebase:
64
64
65 $ hg rebase -s 3 -d 2
65 $ hg rebase -s 3 -d 2
66 rebasing 3:3163e20567cc "L1"
66 rebasing 3:3163e20567cc "L1"
67 rebasing 4:46f0b057b5c0 "L2"
67 rebasing 4:46f0b057b5c0 "L2"
68 merging common
68 merging common
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 unresolved conflicts (see hg resolve, then hg rebase --continue)
71 [1]
71 [1]
72
72
73 Try to continue without solving the conflict:
73 Try to continue without solving the conflict:
74
74
75 $ hg rebase --continue
75 $ hg rebase --continue
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
76 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
77 rebasing 4:46f0b057b5c0 "L2"
77 rebasing 4:46f0b057b5c0 "L2"
78 abort: unresolved merge conflicts (see "hg help resolve")
78 abort: unresolved merge conflicts (see "hg help resolve")
79 [255]
79 [255]
80
80
81 Conclude rebase:
81 Conclude rebase:
82
82
83 $ echo 'resolved merge' >common
83 $ echo 'resolved merge' >common
84 $ hg resolve -m common
84 $ hg resolve -m common
85 (no more unresolved files)
85 (no more unresolved files)
86 continue: hg rebase --continue
86 continue: hg rebase --continue
87 $ hg rebase --continue
87 $ hg rebase --continue
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
88 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
89 rebasing 4:46f0b057b5c0 "L2"
89 rebasing 4:46f0b057b5c0 "L2"
90 rebasing 5:8029388f38dc "L3" (mybook)
90 rebasing 5:8029388f38dc "L3" (mybook)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
91 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-backup.hg (glob)
92
92
93 $ hg tglog
93 $ hg tglog
94 @ 5:secret 'L3' mybook
94 @ 5:secret 'L3' mybook
95 |
95 |
96 o 4:secret 'L2'
96 o 4:secret 'L2'
97 |
97 |
98 o 3:draft 'L1'
98 o 3:draft 'L1'
99 |
99 |
100 o 2:draft 'C3'
100 o 2:draft 'C3'
101 |
101 |
102 o 1:draft 'C2'
102 o 1:draft 'C2'
103 |
103 |
104 o 0:draft 'C1'
104 o 0:draft 'C1'
105
105
106 Check correctness:
106 Check correctness:
107
107
108 $ hg cat -r 0 common
108 $ hg cat -r 0 common
109 c1
109 c1
110
110
111 $ hg cat -r 1 common
111 $ hg cat -r 1 common
112 c1
112 c1
113 c2
113 c2
114
114
115 $ hg cat -r 2 common
115 $ hg cat -r 2 common
116 c1
116 c1
117 c2
117 c2
118 c3
118 c3
119
119
120 $ hg cat -r 3 common
120 $ hg cat -r 3 common
121 c1
121 c1
122 c2
122 c2
123 c3
123 c3
124
124
125 $ hg cat -r 4 common
125 $ hg cat -r 4 common
126 resolved merge
126 resolved merge
127
127
128 $ hg cat -r 5 common
128 $ hg cat -r 5 common
129 resolved merge
129 resolved merge
130
130
131 Bookmark stays active after --continue
131 Bookmark stays active after --continue
132 $ hg bookmarks
132 $ hg bookmarks
133 * mybook 5:d67b21408fc0
133 * mybook 5:d67b21408fc0
134
134
135 $ cd ..
135 $ cd ..
136
136
137 Check that the right ancestors is used while rebasing a merge (issue4041)
137 Check that the right ancestors is used while rebasing a merge (issue4041)
138
138
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
139 $ hg clone "$TESTDIR/bundles/issue4041.hg" issue4041
140 requesting all changes
140 requesting all changes
141 adding changesets
141 adding changesets
142 adding manifests
142 adding manifests
143 adding file changes
143 adding file changes
144 added 11 changesets with 8 changes to 3 files (+1 heads)
144 added 11 changesets with 8 changes to 3 files (+1 heads)
145 updating to branch default
145 updating to branch default
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
146 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
147 $ cd issue4041
147 $ cd issue4041
148 $ hg log -G
148 $ hg log -G
149 o changeset: 10:2f2496ddf49d
149 o changeset: 10:2f2496ddf49d
150 |\ branch: f1
150 |\ branch: f1
151 | | tag: tip
151 | | tag: tip
152 | | parent: 7:4c9fbe56a16f
152 | | parent: 7:4c9fbe56a16f
153 | | parent: 9:e31216eec445
153 | | parent: 9:e31216eec445
154 | | user: szhang
154 | | user: szhang
155 | | date: Thu Sep 05 12:59:39 2013 -0400
155 | | date: Thu Sep 05 12:59:39 2013 -0400
156 | | summary: merge
156 | | summary: merge
157 | |
157 | |
158 | o changeset: 9:e31216eec445
158 | o changeset: 9:e31216eec445
159 | | branch: f1
159 | | branch: f1
160 | | user: szhang
160 | | user: szhang
161 | | date: Thu Sep 05 12:59:10 2013 -0400
161 | | date: Thu Sep 05 12:59:10 2013 -0400
162 | | summary: more changes to f1
162 | | summary: more changes to f1
163 | |
163 | |
164 | o changeset: 8:8e4e2c1a07ae
164 | o changeset: 8:8e4e2c1a07ae
165 | |\ branch: f1
165 | |\ branch: f1
166 | | | parent: 2:4bc80088dc6b
166 | | | parent: 2:4bc80088dc6b
167 | | | parent: 6:400110238667
167 | | | parent: 6:400110238667
168 | | | user: szhang
168 | | | user: szhang
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
169 | | | date: Thu Sep 05 12:57:59 2013 -0400
170 | | | summary: bad merge
170 | | | summary: bad merge
171 | | |
171 | | |
172 o | | changeset: 7:4c9fbe56a16f
172 o | | changeset: 7:4c9fbe56a16f
173 |/ / branch: f1
173 |/ / branch: f1
174 | | parent: 2:4bc80088dc6b
174 | | parent: 2:4bc80088dc6b
175 | | user: szhang
175 | | user: szhang
176 | | date: Thu Sep 05 12:54:00 2013 -0400
176 | | date: Thu Sep 05 12:54:00 2013 -0400
177 | | summary: changed f1
177 | | summary: changed f1
178 | |
178 | |
179 | o changeset: 6:400110238667
179 | o changeset: 6:400110238667
180 | | branch: f2
180 | | branch: f2
181 | | parent: 4:12e8ec6bb010
181 | | parent: 4:12e8ec6bb010
182 | | user: szhang
182 | | user: szhang
183 | | date: Tue Sep 03 13:58:02 2013 -0400
183 | | date: Tue Sep 03 13:58:02 2013 -0400
184 | | summary: changed f2 on f2
184 | | summary: changed f2 on f2
185 | |
185 | |
186 | | @ changeset: 5:d79e2059b5c0
186 | | @ changeset: 5:d79e2059b5c0
187 | | | parent: 3:8a951942e016
187 | | | parent: 3:8a951942e016
188 | | | user: szhang
188 | | | user: szhang
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
189 | | | date: Tue Sep 03 13:57:39 2013 -0400
190 | | | summary: changed f2 on default
190 | | | summary: changed f2 on default
191 | | |
191 | | |
192 | o | changeset: 4:12e8ec6bb010
192 | o | changeset: 4:12e8ec6bb010
193 | |/ branch: f2
193 | |/ branch: f2
194 | | user: szhang
194 | | user: szhang
195 | | date: Tue Sep 03 13:57:18 2013 -0400
195 | | date: Tue Sep 03 13:57:18 2013 -0400
196 | | summary: created f2 branch
196 | | summary: created f2 branch
197 | |
197 | |
198 | o changeset: 3:8a951942e016
198 | o changeset: 3:8a951942e016
199 | | parent: 0:24797d4f68de
199 | | parent: 0:24797d4f68de
200 | | user: szhang
200 | | user: szhang
201 | | date: Tue Sep 03 13:57:11 2013 -0400
201 | | date: Tue Sep 03 13:57:11 2013 -0400
202 | | summary: added f2.txt
202 | | summary: added f2.txt
203 | |
203 | |
204 o | changeset: 2:4bc80088dc6b
204 o | changeset: 2:4bc80088dc6b
205 | | branch: f1
205 | | branch: f1
206 | | user: szhang
206 | | user: szhang
207 | | date: Tue Sep 03 13:56:20 2013 -0400
207 | | date: Tue Sep 03 13:56:20 2013 -0400
208 | | summary: added f1.txt
208 | | summary: added f1.txt
209 | |
209 | |
210 o | changeset: 1:ef53c9e6b608
210 o | changeset: 1:ef53c9e6b608
211 |/ branch: f1
211 |/ branch: f1
212 | user: szhang
212 | user: szhang
213 | date: Tue Sep 03 13:55:26 2013 -0400
213 | date: Tue Sep 03 13:55:26 2013 -0400
214 | summary: created f1 branch
214 | summary: created f1 branch
215 |
215 |
216 o changeset: 0:24797d4f68de
216 o changeset: 0:24797d4f68de
217 user: szhang
217 user: szhang
218 date: Tue Sep 03 13:55:08 2013 -0400
218 date: Tue Sep 03 13:55:08 2013 -0400
219 summary: added default.txt
219 summary: added default.txt
220
220
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
221 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
222 rebase onto 2 starting from e31216eec445
222 rebase onto 2 starting from e31216eec445
223 ignoring null merge rebase of 3
223 ignoring null merge rebase of 3
224 ignoring null merge rebase of 4
224 ignoring null merge rebase of 4
225 ignoring null merge rebase of 6
225 ignoring null merge rebase of 6
226 ignoring null merge rebase of 8
226 ignoring null merge rebase of 8
227 rebasing 9:e31216eec445 "more changes to f1"
227 rebasing 9:e31216eec445 "more changes to f1"
228 future parents are 2 and -1
228 future parents are 2 and -1
229 rebase status stored
229 rebase status stored
230 update to 2:4bc80088dc6b
230 update to 2:4bc80088dc6b
231 resolving manifests
231 resolving manifests
232 branchmerge: False, force: True, partial: False
232 branchmerge: False, force: True, partial: False
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
233 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
234 f2.txt: other deleted -> r
234 f2.txt: other deleted -> r
235 removing f2.txt
235 removing f2.txt
236 f1.txt: remote created -> g
236 f1.txt: remote created -> g
237 getting f1.txt
237 getting f1.txt
238 merge against 9:e31216eec445
238 merge against 9:e31216eec445
239 detach base 8:8e4e2c1a07ae
239 detach base 8:8e4e2c1a07ae
240 searching for copies back to rev 3
240 searching for copies back to rev 3
241 resolving manifests
241 resolving manifests
242 branchmerge: True, force: True, partial: False
242 branchmerge: True, force: True, partial: False
243 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
243 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
244 f1.txt: remote is newer -> g
244 f1.txt: remote is newer -> g
245 getting f1.txt
245 getting f1.txt
246 committing files:
246 committing files:
247 f1.txt
247 f1.txt
248 committing manifest
248 committing manifest
249 committing changelog
249 committing changelog
250 rebased as 19c888675e13
250 rebased as 19c888675e13
251 rebasing 10:2f2496ddf49d "merge" (tip)
251 rebasing 10:2f2496ddf49d "merge" (tip)
252 future parents are 11 and 7
252 future parents are 11 and 7
253 rebase status stored
253 rebase status stored
254 already in target
254 already in target
255 merge against 10:2f2496ddf49d
255 merge against 10:2f2496ddf49d
256 detach base 9:e31216eec445
256 detach base 9:e31216eec445
257 searching for copies back to rev 3
257 searching for copies back to rev 3
258 resolving manifests
258 resolving manifests
259 branchmerge: True, force: True, partial: False
259 branchmerge: True, force: True, partial: False
260 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
260 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
261 f1.txt: remote is newer -> g
261 f1.txt: remote is newer -> g
262 getting f1.txt
262 getting f1.txt
263 committing files:
263 committing files:
264 f1.txt
264 f1.txt
265 committing manifest
265 committing manifest
266 committing changelog
266 committing changelog
267 rebased as 2a7f09cac94c
267 rebased as 2a7f09cac94c
268 rebase merging completed
268 rebase merging completed
269 update back to initial working directory parent
269 update back to initial working directory parent
270 resolving manifests
270 resolving manifests
271 branchmerge: False, force: False, partial: False
271 branchmerge: False, force: False, partial: False
272 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
272 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
273 f1.txt: other deleted -> r
273 f1.txt: other deleted -> r
274 removing f1.txt
274 removing f1.txt
275 f2.txt: remote created -> g
275 f2.txt: remote created -> g
276 getting f2.txt
276 getting f2.txt
277 2 changesets found
277 2 changesets found
278 list of changesets:
278 list of changesets:
279 e31216eec445e44352c5f01588856059466a24c9
279 e31216eec445e44352c5f01588856059466a24c9
280 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
280 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
281 bundle2-output-bundle: "HG20", (1 params) 1 parts total
281 bundle2-output-bundle: "HG20", (1 params) 1 parts total
282 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
282 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
283 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
283 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
284 3 changesets found
284 3 changesets found
285 list of changesets:
285 list of changesets:
286 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
286 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
287 19c888675e133ab5dff84516926a65672eaf04d9
287 19c888675e133ab5dff84516926a65672eaf04d9
288 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
288 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
289 bundle2-output-bundle: "HG20", 1 parts total
289 bundle2-output-bundle: "HG20", 1 parts total
290 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
290 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
291 adding branch
291 adding branch
292 bundle2-input-bundle: with-transaction
292 bundle2-input-bundle: with-transaction
293 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
293 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
294 adding changesets
294 adding changesets
295 add changeset 4c9fbe56a16f
295 add changeset 4c9fbe56a16f
296 add changeset 19c888675e13
296 add changeset 19c888675e13
297 add changeset 2a7f09cac94c
297 add changeset 2a7f09cac94c
298 adding manifests
298 adding manifests
299 adding file changes
299 adding file changes
300 adding f1.txt revisions
300 adding f1.txt revisions
301 added 2 changesets with 2 changes to 1 files
301 added 2 changesets with 2 changes to 1 files
302 bundle2-input-part: total payload size 1713
302 bundle2-input-part: total payload size 1713
303 bundle2-input-bundle: 0 parts total
303 bundle2-input-bundle: 0 parts total
304 invalid branchheads cache (served): tip differs
304 invalid branchheads cache (served): tip differs
305 history modification detected - truncating revision branch cache to revision 9
305 history modification detected - truncating revision branch cache to revision 9
306 rebase completed
306 rebase completed
307 updating the branch cache
308 truncating cache/rbc-revs-v1 to 72
307 truncating cache/rbc-revs-v1 to 72
309
308
310 Test minimization of merge conflicts
309 Test minimization of merge conflicts
311 $ hg up -q null
310 $ hg up -q null
312 $ echo a > a
311 $ echo a > a
313 $ hg add a
312 $ hg add a
314 $ hg commit -q -m 'a'
313 $ hg commit -q -m 'a'
315 $ echo b >> a
314 $ echo b >> a
316 $ hg commit -q -m 'ab'
315 $ hg commit -q -m 'ab'
317 $ hg bookmark ab
316 $ hg bookmark ab
318 $ hg up -q '.^'
317 $ hg up -q '.^'
319 $ echo b >> a
318 $ echo b >> a
320 $ echo c >> a
319 $ echo c >> a
321 $ hg commit -q -m 'abc'
320 $ hg commit -q -m 'abc'
322 $ hg rebase -s 7bc217434fc1 -d ab --keep
321 $ hg rebase -s 7bc217434fc1 -d ab --keep
323 rebasing 13:7bc217434fc1 "abc" (tip)
322 rebasing 13:7bc217434fc1 "abc" (tip)
324 merging a
323 merging a
325 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
324 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
326 unresolved conflicts (see hg resolve, then hg rebase --continue)
325 unresolved conflicts (see hg resolve, then hg rebase --continue)
327 [1]
326 [1]
328 $ hg diff
327 $ hg diff
329 diff -r 328e4ab1f7cc a
328 diff -r 328e4ab1f7cc a
330 --- a/a Thu Jan 01 00:00:00 1970 +0000
329 --- a/a Thu Jan 01 00:00:00 1970 +0000
331 +++ b/a * (glob)
330 +++ b/a * (glob)
332 @@ -1,2 +1,6 @@
331 @@ -1,2 +1,6 @@
333 a
332 a
334 b
333 b
335 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
334 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
336 +=======
335 +=======
337 +c
336 +c
338 +>>>>>>> source: 7bc217434fc1 - test: abc
337 +>>>>>>> source: 7bc217434fc1 - test: abc
339 $ hg rebase --abort
338 $ hg rebase --abort
340 rebase aborted
339 rebase aborted
341 $ hg up -q -C 7bc217434fc1
340 $ hg up -q -C 7bc217434fc1
342 $ hg rebase -s . -d ab --keep -t internal:merge3
341 $ hg rebase -s . -d ab --keep -t internal:merge3
343 rebasing 13:7bc217434fc1 "abc" (tip)
342 rebasing 13:7bc217434fc1 "abc" (tip)
344 merging a
343 merging a
345 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
344 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
346 unresolved conflicts (see hg resolve, then hg rebase --continue)
345 unresolved conflicts (see hg resolve, then hg rebase --continue)
347 [1]
346 [1]
348 $ hg diff
347 $ hg diff
349 diff -r 328e4ab1f7cc a
348 diff -r 328e4ab1f7cc a
350 --- a/a Thu Jan 01 00:00:00 1970 +0000
349 --- a/a Thu Jan 01 00:00:00 1970 +0000
351 +++ b/a * (glob)
350 +++ b/a * (glob)
352 @@ -1,2 +1,8 @@
351 @@ -1,2 +1,8 @@
353 a
352 a
354 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
353 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
355 b
354 b
356 +||||||| base
355 +||||||| base
357 +=======
356 +=======
358 +b
357 +b
359 +c
358 +c
360 +>>>>>>> source: 7bc217434fc1 - test: abc
359 +>>>>>>> source: 7bc217434fc1 - test: abc
General Comments 0
You need to be logged in to leave comments. Login now