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