##// END OF EJS Templates
py3: fix formatting of branchmap log messages with repo.filtername=None...
Martin von Zweigbergk -
r42805:c7d236b5 default
parent child Browse files
Show More
@@ -1,673 +1,676
1 1 # branchmap.py - logic to computes, maintain and stores branchmap for local repo
2 2 #
3 3 # Copyright 2005-2007 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 struct
11 11
12 12 from .node import (
13 13 bin,
14 14 hex,
15 15 nullid,
16 16 nullrev,
17 17 )
18 18 from . import (
19 19 encoding,
20 20 error,
21 21 pycompat,
22 22 scmutil,
23 23 util,
24 24 )
25 25 from .utils import (
26 26 repoviewutil,
27 27 stringutil,
28 28 )
29 29
30 30 subsettable = repoviewutil. subsettable
31 31
32 32 calcsize = struct.calcsize
33 33 pack_into = struct.pack_into
34 34 unpack_from = struct.unpack_from
35 35
36 36
37 37 class BranchMapCache(object):
38 38 """mapping of filtered views of repo with their branchcache"""
39 39 def __init__(self):
40 40 self._per_filter = {}
41 41
42 42 def __getitem__(self, repo):
43 43 self.updatecache(repo)
44 44 return self._per_filter[repo.filtername]
45 45
46 46 def updatecache(self, repo):
47 47 """Update the cache for the given filtered view on a repository"""
48 48 # This can trigger updates for the caches for subsets of the filtered
49 49 # view, e.g. when there is no cache for this filtered view or the cache
50 50 # is stale.
51 51
52 52 cl = repo.changelog
53 53 filtername = repo.filtername
54 54 bcache = self._per_filter.get(filtername)
55 55 if bcache is None or not bcache.validfor(repo):
56 56 # cache object missing or cache object stale? Read from disk
57 57 bcache = branchcache.fromfile(repo)
58 58
59 59 revs = []
60 60 if bcache is None:
61 61 # no (fresh) cache available anymore, perhaps we can re-use
62 62 # the cache for a subset, then extend that to add info on missing
63 63 # revisions.
64 64 subsetname = subsettable.get(filtername)
65 65 if subsetname is not None:
66 66 subset = repo.filtered(subsetname)
67 67 bcache = self[subset].copy()
68 68 extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
69 69 revs.extend(r for r in extrarevs if r <= bcache.tiprev)
70 70 else:
71 71 # nothing to fall back on, start empty.
72 72 bcache = branchcache()
73 73
74 74 revs.extend(cl.revs(start=bcache.tiprev + 1))
75 75 if revs:
76 76 bcache.update(repo, revs)
77 77
78 78 assert bcache.validfor(repo), filtername
79 79 self._per_filter[repo.filtername] = bcache
80 80
81 81 def replace(self, repo, remotebranchmap):
82 82 """Replace the branchmap cache for a repo with a branch mapping.
83 83
84 84 This is likely only called during clone with a branch map from a
85 85 remote.
86 86
87 87 """
88 88 cl = repo.changelog
89 89 clrev = cl.rev
90 90 clbranchinfo = cl.branchinfo
91 91 rbheads = []
92 92 closed = []
93 93 for bheads in remotebranchmap.itervalues():
94 94 rbheads += bheads
95 95 for h in bheads:
96 96 r = clrev(h)
97 97 b, c = clbranchinfo(r)
98 98 if c:
99 99 closed.append(h)
100 100
101 101 if rbheads:
102 102 rtiprev = max((int(clrev(node)) for node in rbheads))
103 103 cache = branchcache(
104 104 remotebranchmap, repo[rtiprev].node(), rtiprev,
105 105 closednodes=closed)
106 106
107 107 # Try to stick it as low as possible
108 108 # filter above served are unlikely to be fetch from a clone
109 109 for candidate in ('base', 'immutable', 'served'):
110 110 rview = repo.filtered(candidate)
111 111 if cache.validfor(rview):
112 112 self._per_filter[candidate] = cache
113 113 cache.write(rview)
114 114 return
115 115
116 116 def clear(self):
117 117 self._per_filter.clear()
118 118
119 119 def _unknownnode(node):
120 120 """ raises ValueError when branchcache found a node which does not exists
121 121 """
122 122 raise ValueError(r'node %s does not exist' % pycompat.sysstr(hex(node)))
123 123
124 def _branchcachedesc(repo):
125 if repo.filtername is not None:
126 return 'branch cache (%s)' % repo.filtername
127 else:
128 return 'branch cache'
129
124 130 class branchcache(object):
125 131 """A dict like object that hold branches heads cache.
126 132
127 133 This cache is used to avoid costly computations to determine all the
128 134 branch heads of a repo.
129 135
130 136 The cache is serialized on disk in the following format:
131 137
132 138 <tip hex node> <tip rev number> [optional filtered repo hex hash]
133 139 <branch head hex node> <open/closed state> <branch name>
134 140 <branch head hex node> <open/closed state> <branch name>
135 141 ...
136 142
137 143 The first line is used to check if the cache is still valid. If the
138 144 branch cache is for a filtered repo view, an optional third hash is
139 145 included that hashes the hashes of all filtered revisions.
140 146
141 147 The open/closed state is represented by a single letter 'o' or 'c'.
142 148 This field can be used to avoid changelog reads when determining if a
143 149 branch head closes a branch or not.
144 150 """
145 151
146 152 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
147 153 filteredhash=None, closednodes=None, hasnode=None):
148 154 """ hasnode is a function which can be used to verify whether changelog
149 155 has a given node or not. If it's not provided, we assume that every node
150 156 we have exists in changelog """
151 157 self.tipnode = tipnode
152 158 self.tiprev = tiprev
153 159 self.filteredhash = filteredhash
154 160 # closednodes is a set of nodes that close their branch. If the branch
155 161 # cache has been updated, it may contain nodes that are no longer
156 162 # heads.
157 163 if closednodes is None:
158 164 self._closednodes = set()
159 165 else:
160 166 self._closednodes = closednodes
161 167 self._entries = dict(entries)
162 168 # whether closed nodes are verified or not
163 169 self._closedverified = False
164 170 # branches for which nodes are verified
165 171 self._verifiedbranches = set()
166 172 self._hasnode = hasnode
167 173 if self._hasnode is None:
168 174 self._hasnode = lambda x: True
169 175
170 176 def _verifyclosed(self):
171 177 """ verify the closed nodes we have """
172 178 if self._closedverified:
173 179 return
174 180 for node in self._closednodes:
175 181 if not self._hasnode(node):
176 182 _unknownnode(node)
177 183
178 184 self._closedverified = True
179 185
180 186 def _verifybranch(self, branch):
181 187 """ verify head nodes for the given branch. """
182 188 if branch not in self._entries or branch in self._verifiedbranches:
183 189 return
184 190 for n in self._entries[branch]:
185 191 if not self._hasnode(n):
186 192 _unknownnode(n)
187 193
188 194 self._verifiedbranches.add(branch)
189 195
190 196 def _verifyall(self):
191 197 """ verifies nodes of all the branches """
192 198 needverification = set(self._entries.keys()) - self._verifiedbranches
193 199 for b in needverification:
194 200 self._verifybranch(b)
195 201
196 202 def __iter__(self):
197 203 return iter(self._entries)
198 204
199 205 def __setitem__(self, key, value):
200 206 self._entries[key] = value
201 207
202 208 def __getitem__(self, key):
203 209 self._verifybranch(key)
204 210 return self._entries[key]
205 211
206 212 def __contains__(self, key):
207 213 self._verifybranch(key)
208 214 return key in self._entries
209 215
210 216 def iteritems(self):
211 217 for k, v in self._entries.iteritems():
212 218 self._verifybranch(k)
213 219 yield k, v
214 220
215 221 def hasbranch(self, label):
216 222 """ checks whether a branch of this name exists or not """
217 223 self._verifybranch(label)
218 224 return label in self._entries
219 225
220 226 @classmethod
221 227 def fromfile(cls, repo):
222 228 f = None
223 229 try:
224 230 f = repo.cachevfs(cls._filename(repo))
225 231 lineiter = iter(f)
226 232 cachekey = next(lineiter).rstrip('\n').split(" ", 2)
227 233 last, lrev = cachekey[:2]
228 234 last, lrev = bin(last), int(lrev)
229 235 filteredhash = None
230 236 hasnode = repo.changelog.hasnode
231 237 if len(cachekey) > 2:
232 238 filteredhash = bin(cachekey[2])
233 239 bcache = cls(tipnode=last, tiprev=lrev, filteredhash=filteredhash,
234 240 hasnode=hasnode)
235 241 if not bcache.validfor(repo):
236 242 # invalidate the cache
237 243 raise ValueError(r'tip differs')
238 244 bcache.load(repo, lineiter)
239 245 except (IOError, OSError):
240 246 return None
241 247
242 248 except Exception as inst:
243 249 if repo.ui.debugflag:
244 msg = 'invalid branchheads cache'
245 if repo.filtername is not None:
246 msg += ' (%s)' % repo.filtername
247 msg += ': %s\n'
248 repo.ui.debug(msg % pycompat.bytestr(inst))
250 msg = 'invalid %s: %s\n'
251 repo.ui.debug(msg % (_branchcachedesc(repo),
252 pycompat.bytestr(inst)))
249 253 bcache = None
250 254
251 255 finally:
252 256 if f:
253 257 f.close()
254 258
255 259 return bcache
256 260
257 261 def load(self, repo, lineiter):
258 262 """ fully loads the branchcache by reading from the file using the line
259 263 iterator passed"""
260 264 for line in lineiter:
261 265 line = line.rstrip('\n')
262 266 if not line:
263 267 continue
264 268 node, state, label = line.split(" ", 2)
265 269 if state not in 'oc':
266 270 raise ValueError(r'invalid branch state')
267 271 label = encoding.tolocal(label.strip())
268 272 node = bin(node)
269 273 self._entries.setdefault(label, []).append(node)
270 274 if state == 'c':
271 275 self._closednodes.add(node)
272 276
273 277 @staticmethod
274 278 def _filename(repo):
275 279 """name of a branchcache file for a given repo or repoview"""
276 280 filename = "branch2"
277 281 if repo.filtername:
278 282 filename = '%s-%s' % (filename, repo.filtername)
279 283 return filename
280 284
281 285 def validfor(self, repo):
282 286 """Is the cache content valid regarding a repo
283 287
284 288 - False when cached tipnode is unknown or if we detect a strip.
285 289 - True when cache is up to date or a subset of current repo."""
286 290 try:
287 291 return ((self.tipnode == repo.changelog.node(self.tiprev))
288 292 and (self.filteredhash ==
289 293 scmutil.filteredhash(repo, self.tiprev)))
290 294 except IndexError:
291 295 return False
292 296
293 297 def _branchtip(self, heads):
294 298 '''Return tuple with last open head in heads and false,
295 299 otherwise return last closed head and true.'''
296 300 tip = heads[-1]
297 301 closed = True
298 302 for h in reversed(heads):
299 303 if h not in self._closednodes:
300 304 tip = h
301 305 closed = False
302 306 break
303 307 return tip, closed
304 308
305 309 def branchtip(self, branch):
306 310 '''Return the tipmost open head on branch head, otherwise return the
307 311 tipmost closed head on branch.
308 312 Raise KeyError for unknown branch.'''
309 313 return self._branchtip(self[branch])[0]
310 314
311 315 def iteropen(self, nodes):
312 316 return (n for n in nodes if n not in self._closednodes)
313 317
314 318 def branchheads(self, branch, closed=False):
315 319 self._verifybranch(branch)
316 320 heads = self._entries[branch]
317 321 if not closed:
318 322 heads = list(self.iteropen(heads))
319 323 return heads
320 324
321 325 def iterbranches(self):
322 326 for bn, heads in self.iteritems():
323 327 yield (bn, heads) + self._branchtip(heads)
324 328
325 329 def iterheads(self):
326 330 """ returns all the heads """
327 331 self._verifyall()
328 332 return self._entries.itervalues()
329 333
330 334 def copy(self):
331 335 """return an deep copy of the branchcache object"""
332 336 return type(self)(
333 337 self._entries, self.tipnode, self.tiprev, self.filteredhash,
334 338 self._closednodes)
335 339
336 340 def write(self, repo):
337 341 try:
338 342 f = repo.cachevfs(self._filename(repo), "w", atomictemp=True)
339 343 cachekey = [hex(self.tipnode), '%d' % self.tiprev]
340 344 if self.filteredhash is not None:
341 345 cachekey.append(hex(self.filteredhash))
342 346 f.write(" ".join(cachekey) + '\n')
343 347 nodecount = 0
344 348 for label, nodes in sorted(self._entries.iteritems()):
345 349 label = encoding.fromlocal(label)
346 350 for node in nodes:
347 351 nodecount += 1
348 352 if node in self._closednodes:
349 353 state = 'c'
350 354 else:
351 355 state = 'o'
352 356 f.write("%s %s %s\n" % (hex(node), state, label))
353 357 f.close()
354 repo.ui.log('branchcache',
355 'wrote %s branch cache with %d labels and %d nodes\n',
356 repo.filtername, len(self._entries), nodecount)
358 repo.ui.log('branchcache', 'wrote %s with %d labels and %d nodes\n',
359 _branchcachedesc(repo), len(self._entries), nodecount)
357 360 except (IOError, OSError, error.Abort) as inst:
358 361 # Abort may be raised by read only opener, so log and continue
359 362 repo.ui.debug("couldn't write branch cache: %s\n" %
360 363 stringutil.forcebytestr(inst))
361 364
362 365 def update(self, repo, revgen):
363 366 """Given a branchhead cache, self, that may have extra nodes or be
364 367 missing heads, and a generator of nodes that are strictly a superset of
365 368 heads missing, this function updates self to be correct.
366 369 """
367 370 starttime = util.timer()
368 371 cl = repo.changelog
369 372 # collect new branch entries
370 373 newbranches = {}
371 374 getbranchinfo = repo.revbranchcache().branchinfo
372 375 for r in revgen:
373 376 branch, closesbranch = getbranchinfo(r)
374 377 newbranches.setdefault(branch, []).append(r)
375 378 if closesbranch:
376 379 self._closednodes.add(cl.node(r))
377 380
378 381 # fetch current topological heads to speed up filtering
379 382 topoheads = set(cl.headrevs())
380 383
381 384 # new tip revision which we found after iterating items from new
382 385 # branches
383 386 ntiprev = self.tiprev
384 387
385 388 # if older branchheads are reachable from new ones, they aren't
386 389 # really branchheads. Note checking parents is insufficient:
387 390 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
388 391 for branch, newheadrevs in newbranches.iteritems():
389 392 bheads = self._entries.setdefault(branch, [])
390 393 bheadset = set(cl.rev(node) for node in bheads)
391 394
392 395 # This have been tested True on all internal usage of this function.
393 396 # run it again in case of doubt
394 397 # assert not (set(bheadrevs) & set(newheadrevs))
395 398 bheadset.update(newheadrevs)
396 399
397 400 # This prunes out two kinds of heads - heads that are superseded by
398 401 # a head in newheadrevs, and newheadrevs that are not heads because
399 402 # an existing head is their descendant.
400 403 uncertain = bheadset - topoheads
401 404 if uncertain:
402 405 floorrev = min(uncertain)
403 406 ancestors = set(cl.ancestors(newheadrevs, floorrev))
404 407 bheadset -= ancestors
405 408 bheadrevs = sorted(bheadset)
406 409 self[branch] = [cl.node(rev) for rev in bheadrevs]
407 410 tiprev = bheadrevs[-1]
408 411 if tiprev > ntiprev:
409 412 ntiprev = tiprev
410 413
411 414 if ntiprev > self.tiprev:
412 415 self.tiprev = ntiprev
413 416 self.tipnode = cl.node(ntiprev)
414 417
415 418 if not self.validfor(repo):
416 419 # cache key are not valid anymore
417 420 self.tipnode = nullid
418 421 self.tiprev = nullrev
419 422 for heads in self.iterheads():
420 423 tiprev = max(cl.rev(node) for node in heads)
421 424 if tiprev > self.tiprev:
422 425 self.tipnode = cl.node(tiprev)
423 426 self.tiprev = tiprev
424 427 self.filteredhash = scmutil.filteredhash(repo, self.tiprev)
425 428
426 429 duration = util.timer() - starttime
427 repo.ui.log('branchcache', 'updated %s branch cache in %.4f seconds\n',
428 repo.filtername or b'None', duration)
430 repo.ui.log('branchcache', 'updated %s in %.4f seconds\n',
431 _branchcachedesc(repo), duration)
429 432
430 433 self.write(repo)
431 434
432 435
433 436 class remotebranchcache(branchcache):
434 437 """Branchmap info for a remote connection, should not write locally"""
435 438 def write(self, repo):
436 439 pass
437 440
438 441
439 442 # Revision branch info cache
440 443
441 444 _rbcversion = '-v1'
442 445 _rbcnames = 'rbc-names' + _rbcversion
443 446 _rbcrevs = 'rbc-revs' + _rbcversion
444 447 # [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
445 448 _rbcrecfmt = '>4sI'
446 449 _rbcrecsize = calcsize(_rbcrecfmt)
447 450 _rbcnodelen = 4
448 451 _rbcbranchidxmask = 0x7fffffff
449 452 _rbccloseflag = 0x80000000
450 453
451 454 class revbranchcache(object):
452 455 """Persistent cache, mapping from revision number to branch name and close.
453 456 This is a low level cache, independent of filtering.
454 457
455 458 Branch names are stored in rbc-names in internal encoding separated by 0.
456 459 rbc-names is append-only, and each branch name is only stored once and will
457 460 thus have a unique index.
458 461
459 462 The branch info for each revision is stored in rbc-revs as constant size
460 463 records. The whole file is read into memory, but it is only 'parsed' on
461 464 demand. The file is usually append-only but will be truncated if repo
462 465 modification is detected.
463 466 The record for each revision contains the first 4 bytes of the
464 467 corresponding node hash, and the record is only used if it still matches.
465 468 Even a completely trashed rbc-revs fill thus still give the right result
466 469 while converging towards full recovery ... assuming no incorrectly matching
467 470 node hashes.
468 471 The record also contains 4 bytes where 31 bits contains the index of the
469 472 branch and the last bit indicate that it is a branch close commit.
470 473 The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
471 474 and will grow with it but be 1/8th of its size.
472 475 """
473 476
474 477 def __init__(self, repo, readonly=True):
475 478 assert repo.filtername is None
476 479 self._repo = repo
477 480 self._names = [] # branch names in local encoding with static index
478 481 self._rbcrevs = bytearray()
479 482 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
480 483 try:
481 484 bndata = repo.cachevfs.read(_rbcnames)
482 485 self._rbcsnameslen = len(bndata) # for verification before writing
483 486 if bndata:
484 487 self._names = [encoding.tolocal(bn)
485 488 for bn in bndata.split('\0')]
486 489 except (IOError, OSError):
487 490 if readonly:
488 491 # don't try to use cache - fall back to the slow path
489 492 self.branchinfo = self._branchinfo
490 493
491 494 if self._names:
492 495 try:
493 496 data = repo.cachevfs.read(_rbcrevs)
494 497 self._rbcrevs[:] = data
495 498 except (IOError, OSError) as inst:
496 499 repo.ui.debug("couldn't read revision branch cache: %s\n" %
497 500 stringutil.forcebytestr(inst))
498 501 # remember number of good records on disk
499 502 self._rbcrevslen = min(len(self._rbcrevs) // _rbcrecsize,
500 503 len(repo.changelog))
501 504 if self._rbcrevslen == 0:
502 505 self._names = []
503 506 self._rbcnamescount = len(self._names) # number of names read at
504 507 # _rbcsnameslen
505 508
506 509 def _clear(self):
507 510 self._rbcsnameslen = 0
508 511 del self._names[:]
509 512 self._rbcnamescount = 0
510 513 self._rbcrevslen = len(self._repo.changelog)
511 514 self._rbcrevs = bytearray(self._rbcrevslen * _rbcrecsize)
512 515 util.clearcachedproperty(self, '_namesreverse')
513 516
514 517 @util.propertycache
515 518 def _namesreverse(self):
516 519 return dict((b, r) for r, b in enumerate(self._names))
517 520
518 521 def branchinfo(self, rev):
519 522 """Return branch name and close flag for rev, using and updating
520 523 persistent cache."""
521 524 changelog = self._repo.changelog
522 525 rbcrevidx = rev * _rbcrecsize
523 526
524 527 # avoid negative index, changelog.read(nullrev) is fast without cache
525 528 if rev == nullrev:
526 529 return changelog.branchinfo(rev)
527 530
528 531 # if requested rev isn't allocated, grow and cache the rev info
529 532 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
530 533 return self._branchinfo(rev)
531 534
532 535 # fast path: extract data from cache, use it if node is matching
533 536 reponode = changelog.node(rev)[:_rbcnodelen]
534 537 cachenode, branchidx = unpack_from(
535 538 _rbcrecfmt, util.buffer(self._rbcrevs), rbcrevidx)
536 539 close = bool(branchidx & _rbccloseflag)
537 540 if close:
538 541 branchidx &= _rbcbranchidxmask
539 542 if cachenode == '\0\0\0\0':
540 543 pass
541 544 elif cachenode == reponode:
542 545 try:
543 546 return self._names[branchidx], close
544 547 except IndexError:
545 548 # recover from invalid reference to unknown branch
546 549 self._repo.ui.debug("referenced branch names not found"
547 550 " - rebuilding revision branch cache from scratch\n")
548 551 self._clear()
549 552 else:
550 553 # rev/node map has changed, invalidate the cache from here up
551 554 self._repo.ui.debug("history modification detected - truncating "
552 555 "revision branch cache to revision %d\n" % rev)
553 556 truncate = rbcrevidx + _rbcrecsize
554 557 del self._rbcrevs[truncate:]
555 558 self._rbcrevslen = min(self._rbcrevslen, truncate)
556 559
557 560 # fall back to slow path and make sure it will be written to disk
558 561 return self._branchinfo(rev)
559 562
560 563 def _branchinfo(self, rev):
561 564 """Retrieve branch info from changelog and update _rbcrevs"""
562 565 changelog = self._repo.changelog
563 566 b, close = changelog.branchinfo(rev)
564 567 if b in self._namesreverse:
565 568 branchidx = self._namesreverse[b]
566 569 else:
567 570 branchidx = len(self._names)
568 571 self._names.append(b)
569 572 self._namesreverse[b] = branchidx
570 573 reponode = changelog.node(rev)
571 574 if close:
572 575 branchidx |= _rbccloseflag
573 576 self._setcachedata(rev, reponode, branchidx)
574 577 return b, close
575 578
576 579 def setdata(self, branch, rev, node, close):
577 580 """add new data information to the cache"""
578 581 if branch in self._namesreverse:
579 582 branchidx = self._namesreverse[branch]
580 583 else:
581 584 branchidx = len(self._names)
582 585 self._names.append(branch)
583 586 self._namesreverse[branch] = branchidx
584 587 if close:
585 588 branchidx |= _rbccloseflag
586 589 self._setcachedata(rev, node, branchidx)
587 590 # If no cache data were readable (non exists, bad permission, etc)
588 591 # the cache was bypassing itself by setting:
589 592 #
590 593 # self.branchinfo = self._branchinfo
591 594 #
592 595 # Since we now have data in the cache, we need to drop this bypassing.
593 596 if r'branchinfo' in vars(self):
594 597 del self.branchinfo
595 598
596 599 def _setcachedata(self, rev, node, branchidx):
597 600 """Writes the node's branch data to the in-memory cache data."""
598 601 if rev == nullrev:
599 602 return
600 603 rbcrevidx = rev * _rbcrecsize
601 604 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
602 605 self._rbcrevs.extend('\0' *
603 606 (len(self._repo.changelog) * _rbcrecsize -
604 607 len(self._rbcrevs)))
605 608 pack_into(_rbcrecfmt, self._rbcrevs, rbcrevidx, node, branchidx)
606 609 self._rbcrevslen = min(self._rbcrevslen, rev)
607 610
608 611 tr = self._repo.currenttransaction()
609 612 if tr:
610 613 tr.addfinalize('write-revbranchcache', self.write)
611 614
612 615 def write(self, tr=None):
613 616 """Save branch cache if it is dirty."""
614 617 repo = self._repo
615 618 wlock = None
616 619 step = ''
617 620 try:
618 621 # write the new names
619 622 if self._rbcnamescount < len(self._names):
620 623 wlock = repo.wlock(wait=False)
621 624 step = ' names'
622 625 self._writenames(repo)
623 626
624 627 # write the new revs
625 628 start = self._rbcrevslen * _rbcrecsize
626 629 if start != len(self._rbcrevs):
627 630 step = ''
628 631 if wlock is None:
629 632 wlock = repo.wlock(wait=False)
630 633 self._writerevs(repo, start)
631 634
632 635 except (IOError, OSError, error.Abort, error.LockError) as inst:
633 636 repo.ui.debug("couldn't write revision branch cache%s: %s\n"
634 637 % (step, stringutil.forcebytestr(inst)))
635 638 finally:
636 639 if wlock is not None:
637 640 wlock.release()
638 641
639 642 def _writenames(self, repo):
640 643 """ write the new branch names to revbranchcache """
641 644 if self._rbcnamescount != 0:
642 645 f = repo.cachevfs.open(_rbcnames, 'ab')
643 646 if f.tell() == self._rbcsnameslen:
644 647 f.write('\0')
645 648 else:
646 649 f.close()
647 650 repo.ui.debug("%s changed - rewriting it\n" % _rbcnames)
648 651 self._rbcnamescount = 0
649 652 self._rbcrevslen = 0
650 653 if self._rbcnamescount == 0:
651 654 # before rewriting names, make sure references are removed
652 655 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
653 656 f = repo.cachevfs.open(_rbcnames, 'wb')
654 657 f.write('\0'.join(encoding.fromlocal(b)
655 658 for b in self._names[self._rbcnamescount:]))
656 659 self._rbcsnameslen = f.tell()
657 660 f.close()
658 661 self._rbcnamescount = len(self._names)
659 662
660 663 def _writerevs(self, repo, start):
661 664 """ write the new revs to revbranchcache """
662 665 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
663 666 with repo.cachevfs.open(_rbcrevs, 'ab') as f:
664 667 if f.tell() != start:
665 668 repo.ui.debug("truncating cache/%s to %d\n" % (_rbcrevs, start))
666 669 f.seek(start)
667 670 if f.tell() != start:
668 671 start = 0
669 672 f.seek(start)
670 673 f.truncate()
671 674 end = revs * _rbcrecsize
672 675 f.write(self._rbcrevs[start:end])
673 676 self._rbcrevslen = revs
@@ -1,484 +1,484
1 1 setup
2 2
3 3 $ cat > myextension.py <<EOF
4 4 > from mercurial import error, registrar
5 5 > cmdtable = {}
6 6 > command = registrar.command(cmdtable)
7 7 > @command(b'crash', [], b'hg crash')
8 8 > def crash(ui, *args, **kwargs):
9 9 > raise Exception("oops")
10 10 > @command(b'abortcmd', [], b'hg abortcmd')
11 11 > def abort(ui, *args, **kwargs):
12 12 > raise error.Abort(b"oops")
13 13 > EOF
14 14 $ abspath=`pwd`/myextension.py
15 15
16 16 $ cat >> $HGRCPATH <<EOF
17 17 > [extensions]
18 18 > blackbox=
19 19 > mock=$TESTDIR/mockblackbox.py
20 20 > mq=
21 21 > myextension=$TESTTMP/myextension.py
22 22 > [alias]
23 23 > confuse = log --limit 3
24 24 > so-confusing = confuse --style compact
25 25 > [blackbox]
26 26 > track = backupbundle, branchcache, command, commandalias, commandexception,
27 27 > commandfinish, debug, exthook, incoming, pythonhook, tagscache
28 28 > EOF
29 29
30 30 $ hg init blackboxtest
31 31 $ cd blackboxtest
32 32
33 33 command, exit codes, and duration
34 34
35 35 $ echo a > a
36 36 $ hg add a
37 37 $ hg blackbox --config blackbox.dirty=True
38 38 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob)
39 39 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a
40 40 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob)
41 41 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob)
42 42
43 43 failure exit code
44 44 $ rm ./.hg/blackbox.log
45 45 $ hg add non-existent
46 46 non-existent: $ENOENT$
47 47 [1]
48 48 $ hg blackbox
49 49 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent
50 50 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent exited 1 after * seconds (glob)
51 51 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
52 52
53 53 abort exit code
54 54 $ rm ./.hg/blackbox.log
55 55 $ hg abortcmd 2> /dev/null
56 56 [255]
57 57 $ hg blackbox -l 2
58 58 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abortcmd exited 255 after * seconds (glob)
59 59 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
60 60
61 61 unhandled exception
62 62 $ rm ./.hg/blackbox.log
63 63 $ hg crash 2> /dev/null
64 64 [1]
65 65 $ hg blackbox -l 2
66 66 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> crash exited 1 after * seconds (glob)
67 67 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
68 68
69 69 alias expansion is logged
70 70 $ rm ./.hg/blackbox.log
71 71 $ hg confuse
72 72 $ hg blackbox
73 73 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse
74 74 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
75 75 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse exited 0 after * seconds (glob)
76 76 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
77 77
78 78 recursive aliases work correctly
79 79 $ rm ./.hg/blackbox.log
80 80 $ hg so-confusing
81 81 $ hg blackbox
82 82 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing
83 83 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'so-confusing' expands to 'confuse --style compact'
84 84 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
85 85 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing exited 0 after * seconds (glob)
86 86 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
87 87
88 88 custom date format
89 89 $ rm ./.hg/blackbox.log
90 90 $ hg --config blackbox.date-format='%Y-%m-%d @ %H:%M:%S' \
91 91 > --config devel.default-date='1334347993 0' --traceback status
92 92 A a
93 93 $ hg blackbox
94 94 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status (glob)
95 95 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status exited 0 after * seconds (glob)
96 96 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
97 97
98 98 incoming change tracking
99 99
100 100 create two heads to verify that we only see one change in the log later
101 101 $ hg commit -ma
102 102 $ hg up null
103 103 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
104 104 $ echo b > b
105 105 $ hg commit -Amb
106 106 adding b
107 107 created new head
108 108
109 109 clone, commit, pull
110 110 $ hg clone . ../blackboxtest2
111 111 updating to branch default
112 112 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 113 $ echo c > c
114 114 $ hg commit -Amc
115 115 adding c
116 116 $ cd ../blackboxtest2
117 117 $ hg pull
118 118 pulling from $TESTTMP/blackboxtest
119 119 searching for changes
120 120 adding changesets
121 121 adding manifests
122 122 adding file changes
123 123 added 1 changesets with 1 changes to 1 files
124 124 new changesets d02f48003e62
125 125 (run 'hg update' to get a working copy)
126 126 $ hg blackbox -l 6
127 127 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull
128 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated served branch cache in * seconds (glob)
129 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote served branch cache with 1 labels and 2 nodes
128 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated branch cache (served) in * seconds (glob)
129 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote branch cache (served) with 1 labels and 2 nodes
130 130 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> 1 incoming changes - new heads: d02f48003e62
131 131 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull exited 0 after * seconds (glob)
132 132 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
133 133
134 134 we must not cause a failure if we cannot write to the log
135 135
136 136 $ hg rollback
137 137 repository tip rolled back to revision 1 (undo pull)
138 138
139 139 $ mv .hg/blackbox.log .hg/blackbox.log-
140 140 $ mkdir .hg/blackbox.log
141 141 $ hg --debug incoming
142 142 warning: cannot write to blackbox.log: * (glob)
143 143 comparing with $TESTTMP/blackboxtest
144 144 query 1; heads
145 145 searching for changes
146 146 all local heads known remotely
147 147 changeset: 2:d02f48003e62c24e2659d97d30f2a83abe5d5d51
148 148 tag: tip
149 149 phase: draft
150 150 parent: 1:6563da9dcf87b1949716e38ff3e3dfaa3198eb06
151 151 parent: -1:0000000000000000000000000000000000000000
152 152 manifest: 2:ab9d46b053ebf45b7996f2922b9893ff4b63d892
153 153 user: test
154 154 date: Thu Jan 01 00:00:00 1970 +0000
155 155 files+: c
156 156 extra: branch=default
157 157 description:
158 158 c
159 159
160 160
161 161 $ hg pull
162 162 pulling from $TESTTMP/blackboxtest
163 163 searching for changes
164 164 adding changesets
165 165 adding manifests
166 166 adding file changes
167 167 added 1 changesets with 1 changes to 1 files
168 168 new changesets d02f48003e62
169 169 (run 'hg update' to get a working copy)
170 170
171 171 a failure reading from the log is fatal
172 172
173 173 $ hg blackbox -l 3
174 174 abort: *$TESTTMP/blackboxtest2/.hg/blackbox.log* (glob)
175 175 [255]
176 176
177 177 $ rmdir .hg/blackbox.log
178 178 $ mv .hg/blackbox.log- .hg/blackbox.log
179 179
180 180 backup bundles get logged
181 181
182 182 $ touch d
183 183 $ hg commit -Amd
184 184 adding d
185 185 created new head
186 186 $ hg strip tip
187 187 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
188 188 saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/*-backup.hg (glob)
189 189 $ hg blackbox -l 6
190 190 1970/01/01 00:00:00 bob @73f6ee326b27d820b0472f1a825e3a50f3dc489b (5000)> strip tip
191 191 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/73f6ee326b27-7612e004-backup.hg
192 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated base branch cache in * seconds (glob)
193 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote base branch cache with 1 labels and 2 nodes
192 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated branch cache (base) in * seconds (glob)
193 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote branch cache (base) with 1 labels and 2 nodes
194 194 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> strip tip exited 0 after * seconds (glob)
195 195 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
196 196
197 197 extension and python hooks - use the eol extension for a pythonhook
198 198
199 199 $ echo '[extensions]' >> .hg/hgrc
200 200 $ echo 'eol=' >> .hg/hgrc
201 201 $ echo '[hooks]' >> .hg/hgrc
202 202 $ echo 'update = echo hooked' >> .hg/hgrc
203 203 $ hg update
204 204 The fsmonitor extension is incompatible with the eol extension and has been disabled. (fsmonitor !)
205 205 hooked
206 206 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
207 207 updated to "d02f48003e62: c"
208 208 1 other heads for branch "default"
209 209 $ cat >> .hg/hgrc <<EOF
210 210 > [extensions]
211 211 > # disable eol, because it is not needed for subsequent tests
212 212 > # (in addition, keeping it requires extra care for fsmonitor)
213 213 > eol=!
214 214 > EOF
215 215 $ hg blackbox -l 5
216 216 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> update (no-chg !)
217 217 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob)
218 218 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> exthook-update: echo hooked finished in * seconds (glob)
219 219 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> update exited 0 after * seconds (glob)
220 220 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> serve --cmdserver chgunix --address $TESTTMP.chgsock/server.* --daemon-postexec 'chdir:/' (glob) (chg !)
221 221 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> blackbox -l 5
222 222
223 223 log rotation
224 224
225 225 $ echo '[blackbox]' >> .hg/hgrc
226 226 $ echo 'maxsize = 20 b' >> .hg/hgrc
227 227 $ echo 'maxfiles = 3' >> .hg/hgrc
228 228 $ hg status
229 229 $ hg status
230 230 $ hg status
231 231 $ hg tip -q
232 232 2:d02f48003e62
233 233 $ ls .hg/blackbox.log*
234 234 .hg/blackbox.log
235 235 .hg/blackbox.log.1
236 236 .hg/blackbox.log.2
237 237 $ cd ..
238 238
239 239 $ hg init blackboxtest3
240 240 $ cd blackboxtest3
241 241 $ hg blackbox
242 242 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest3 exited 0 after * seconds (glob)
243 243 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
244 244 $ mv .hg/blackbox.log .hg/blackbox.log-
245 245 $ mkdir .hg/blackbox.log
246 246 $ sed -e 's/\(.*test1.*\)/#\1/; s#\(.*commit2.*\)#os.rmdir(".hg/blackbox.log")\
247 247 > os.rename(".hg/blackbox.log-", ".hg/blackbox.log")\
248 248 > \1#' $TESTDIR/test-dispatch.py > ../test-dispatch.py
249 249 $ "$PYTHON" $TESTDIR/blackbox-readonly-dispatch.py
250 250 running: --debug add foo
251 251 warning: cannot write to blackbox.log: Is a directory (no-windows !)
252 252 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
253 253 adding foo
254 254 result: 0
255 255 running: --debug commit -m commit1 -d 2000-01-01 foo
256 256 warning: cannot write to blackbox.log: Is a directory (no-windows !)
257 257 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
258 258 committing files:
259 259 foo
260 260 committing manifest
261 261 committing changelog
262 262 updating the branch cache
263 263 committed changeset 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
264 264 result: 0
265 265 running: --debug commit -m commit2 -d 2000-01-02 foo
266 266 committing files:
267 267 foo
268 268 committing manifest
269 269 committing changelog
270 270 updating the branch cache
271 271 committed changeset 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
272 272 result: 0
273 273 running: --debug log -r 0
274 274 changeset: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
275 275 phase: draft
276 276 parent: -1:0000000000000000000000000000000000000000
277 277 parent: -1:0000000000000000000000000000000000000000
278 278 manifest: 0:9091aa5df980aea60860a2e39c95182e68d1ddec
279 279 user: test
280 280 date: Sat Jan 01 00:00:00 2000 +0000
281 281 files+: foo
282 282 extra: branch=default
283 283 description:
284 284 commit1
285 285
286 286
287 287 result: 0
288 288 running: --debug log -r tip
289 289 changeset: 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
290 290 tag: tip
291 291 phase: draft
292 292 parent: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
293 293 parent: -1:0000000000000000000000000000000000000000
294 294 manifest: 1:895aa9b7886f89dd017a6d62524e1f9180b04df9
295 295 user: test
296 296 date: Sun Jan 02 00:00:00 2000 +0000
297 297 files: foo
298 298 extra: branch=default
299 299 description:
300 300 commit2
301 301
302 302
303 303 result: 0
304 304 $ hg blackbox
305 305 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updating the branch cache
306 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updated served branch cache in * seconds (glob)
307 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> wrote served branch cache with 1 labels and 1 nodes
306 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updated branch cache (served) in * seconds (glob)
307 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> wrote branch cache (served) with 1 labels and 1 nodes
308 308 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug commit -m commit2 -d 2000-01-02 foo exited 0 after *.?? seconds (glob)
309 309 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0
310 310 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> writing .hg/cache/tags2-visible with 0 tags
311 311 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0 exited 0 after *.?? seconds (glob)
312 312 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip
313 313 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip exited 0 after *.?? seconds (glob)
314 314 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> blackbox
315 315
316 316 Test log recursion from dirty status check
317 317
318 318 $ cat > ../r.py <<EOF
319 319 > from mercurial import context, error, extensions
320 320 > x=[False]
321 321 > def status(orig, *args, **opts):
322 322 > args[0].repo().ui.log(b"broken", b"recursion?")
323 323 > return orig(*args, **opts)
324 324 > def reposetup(ui, repo):
325 325 > extensions.wrapfunction(context.basectx, 'status', status)
326 326 > EOF
327 327 $ hg id --config extensions.x=../r.py --config blackbox.dirty=True
328 328 45589e459b2e tip
329 329
330 330 cleanup
331 331 $ cd ..
332 332
333 333 Test missing log directory, which shouldn't be created automatically
334 334
335 335 $ cat <<'EOF' > closeremove.py
336 336 > def reposetup(ui, repo):
337 337 > class rmrepo(repo.__class__):
338 338 > def close(self):
339 339 > super(rmrepo, self).close()
340 340 > self.ui.debug(b'removing %s\n' % self.vfs.base)
341 341 > self.vfs.rmtree()
342 342 > repo.__class__ = rmrepo
343 343 > EOF
344 344
345 345 $ hg init gone
346 346 $ cd gone
347 347 $ cat <<'EOF' > .hg/hgrc
348 348 > [extensions]
349 349 > closeremove = ../closeremove.py
350 350 > EOF
351 351 $ hg log --debug
352 352 removing $TESTTMP/gone/.hg
353 353 warning: cannot write to blackbox.log: $ENOENT$ (no-windows !)
354 354 warning: cannot write to blackbox.log: $TESTTMP/gone/.hg/blackbox.log: $ENOTDIR$ (windows !)
355 355 $ cd ..
356 356
357 357 blackbox should disable itself if track is empty
358 358
359 359 $ hg --config blackbox.track= init nothing_tracked
360 360 $ cd nothing_tracked
361 361 $ cat >> .hg/hgrc << EOF
362 362 > [blackbox]
363 363 > track =
364 364 > EOF
365 365 $ hg blackbox
366 366 $ cd $TESTTMP
367 367
368 368 a '*' entry in blackbox.track is interpreted as log everything
369 369
370 370 $ hg --config blackbox.track='*' \
371 371 > --config blackbox.logsource=True \
372 372 > init track_star
373 373 $ cd track_star
374 374 $ cat >> .hg/hgrc << EOF
375 375 > [blackbox]
376 376 > logsource = True
377 377 > track = *
378 378 > EOF
379 379 (only look for entries with specific logged sources, otherwise this test is
380 380 pretty brittle)
381 381 $ hg blackbox | egrep '\[command(finish)?\]'
382 382 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [commandfinish]> --config *blackbox.track=* --config *blackbox.logsource=True* init track_star exited 0 after * seconds (glob)
383 383 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000) [command]> blackbox
384 384 $ cd $TESTTMP
385 385
386 386 #if chg
387 387
388 388 when using chg, blackbox.log should get rotated correctly
389 389
390 390 $ cat > $TESTTMP/noop.py << EOF
391 391 > from __future__ import absolute_import
392 392 > import time
393 393 > from mercurial import registrar, scmutil
394 394 > cmdtable = {}
395 395 > command = registrar.command(cmdtable)
396 396 > @command('noop')
397 397 > def noop(ui, repo):
398 398 > pass
399 399 > EOF
400 400
401 401 $ hg init blackbox-chg
402 402 $ cd blackbox-chg
403 403
404 404 $ cat > .hg/hgrc << EOF
405 405 > [blackbox]
406 406 > maxsize = 500B
407 407 > [extensions]
408 408 > # extension change forces chg to restart
409 409 > noop=$TESTTMP/noop.py
410 410 > EOF
411 411
412 412 $ "$PYTHON" -c 'print("a" * 400)' > .hg/blackbox.log
413 413 $ chg noop
414 414 $ chg noop
415 415 $ chg noop
416 416 $ chg noop
417 417 $ chg noop
418 418
419 419 $ cat > showsize.py << 'EOF'
420 420 > import os
421 421 > import sys
422 422 > limit = 500
423 423 > for p in sys.argv[1:]:
424 424 > size = os.stat(p).st_size
425 425 > if size >= limit:
426 426 > desc = '>='
427 427 > else:
428 428 > desc = '<'
429 429 > print('%s: %s %d' % (p, desc, limit))
430 430 > EOF
431 431
432 432 $ "$PYTHON" showsize.py .hg/blackbox*
433 433 .hg/blackbox.log: < 500
434 434 .hg/blackbox.log.1: >= 500
435 435 .hg/blackbox.log.2: >= 500
436 436
437 437 $ cd ..
438 438
439 439 With chg, blackbox should not create the log file if the repo is gone
440 440
441 441 $ hg init repo1
442 442 $ hg --config extensions.a=! -R repo1 log
443 443 $ rm -rf $TESTTMP/repo1
444 444 $ hg --config extensions.a=! init repo1
445 445
446 446 #endif
447 447
448 448 blackbox should work if repo.ui.log is not called (issue5518)
449 449
450 450 $ cat > $TESTTMP/raise.py << EOF
451 451 > from __future__ import absolute_import
452 452 > from mercurial import registrar, scmutil
453 453 > cmdtable = {}
454 454 > command = registrar.command(cmdtable)
455 455 > @command(b'raise')
456 456 > def raisecmd(*args):
457 457 > raise RuntimeError('raise')
458 458 > EOF
459 459
460 460 $ cat >> $HGRCPATH << EOF
461 461 > [blackbox]
462 462 > track = commandexception
463 463 > [extensions]
464 464 > raise=$TESTTMP/raise.py
465 465 > EOF
466 466
467 467 $ hg init $TESTTMP/blackbox-exception-only
468 468 $ cd $TESTTMP/blackbox-exception-only
469 469
470 470 #if chg
471 471 (chg exits 255 because it fails to receive an exit code)
472 472 $ hg raise 2>/dev/null
473 473 [255]
474 474 #else
475 475 (hg exits 1 because Python default exit code for uncaught exception is 1)
476 476 $ hg raise 2>/dev/null
477 477 [1]
478 478 #endif
479 479
480 480 $ head -1 .hg/blackbox.log
481 481 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> ** Unknown exception encountered with possibly-broken third-party extension mock
482 482 $ tail -2 .hg/blackbox.log
483 483 RuntimeError: raise
484 484
@@ -1,423 +1,423
1 1 Testing changing branch on commits
2 2 ==================================
3 3
4 4 Setup
5 5
6 6 $ cat >> $HGRCPATH << EOF
7 7 > [alias]
8 8 > glog = log -G -T "{rev}:{node|short} {desc}\n{branch} ({bookmarks})"
9 9 > [experimental]
10 10 > evolution = createmarkers
11 11 > [extensions]
12 12 > rebase=
13 13 > EOF
14 14
15 15 $ hg init repo
16 16 $ cd repo
17 17 $ for ch in a b c d e; do echo foo >> $ch; hg ci -Aqm "Added "$ch; done
18 18 $ hg glog
19 19 @ 4:aa98ab95a928 Added e
20 20 | default ()
21 21 o 3:62615734edd5 Added d
22 22 | default ()
23 23 o 2:28ad74487de9 Added c
24 24 | default ()
25 25 o 1:29becc82797a Added b
26 26 | default ()
27 27 o 0:18d04c59bb5d Added a
28 28 default ()
29 29
30 30 $ hg branches
31 31 default 4:aa98ab95a928
32 32
33 33 Try without passing a new branch name
34 34
35 35 $ hg branch -r .
36 36 abort: no branch name specified for the revisions
37 37 [255]
38 38
39 39 Setting an invalid branch name
40 40
41 41 $ hg branch -r . a:b
42 42 abort: ':' cannot be used in a name
43 43 [255]
44 44 $ hg branch -r . tip
45 45 abort: the name 'tip' is reserved
46 46 [255]
47 47 $ hg branch -r . 1234
48 48 abort: cannot use an integer as a name
49 49 [255]
50 50
51 51 Change on non-linear set of commits
52 52
53 53 $ hg branch -r 2 -r 4 foo
54 54 abort: cannot change branch of non-linear revisions
55 55 [255]
56 56
57 57 Change in middle of the stack (linear commits)
58 58
59 59 $ hg branch -r 1::3 foo
60 60 abort: cannot change branch of changeset with children
61 61 [255]
62 62
63 63 Change with dirty working directory
64 64
65 65 $ echo bar > a
66 66 $ hg branch -r . foo
67 67 abort: uncommitted changes
68 68 [255]
69 69
70 70 $ hg revert --all
71 71 reverting a
72 72
73 73 Change on empty revision set
74 74
75 75 $ hg branch -r 'draft() - all()' foo
76 76 abort: empty revision set
77 77 [255]
78 78
79 79 Changing branch on linear set of commits from head
80 80
81 81 Without obsmarkers
82 82
83 83 $ hg branch -r 3:4 foo --config experimental.evolution=!
84 84 changed branch on 2 changesets
85 85 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/62615734edd5-e86bd13a-branch-change.hg
86 86 $ hg glog
87 87 @ 4:3938acfb5c0f Added e
88 88 | foo ()
89 89 o 3:9435da006bdc Added d
90 90 | foo ()
91 91 o 2:28ad74487de9 Added c
92 92 | default ()
93 93 o 1:29becc82797a Added b
94 94 | default ()
95 95 o 0:18d04c59bb5d Added a
96 96 default ()
97 97
98 98 $ hg branches
99 99 foo 4:3938acfb5c0f
100 100 default 2:28ad74487de9 (inactive)
101 101
102 102 With obsmarkers
103 103
104 104 $ hg branch -r 3::4 bar
105 105 changed branch on 2 changesets
106 106 $ hg glog
107 107 @ 6:7c1991464886 Added e
108 108 | bar ()
109 109 o 5:1ea05e93925f Added d
110 110 | bar ()
111 111 o 2:28ad74487de9 Added c
112 112 | default ()
113 113 o 1:29becc82797a Added b
114 114 | default ()
115 115 o 0:18d04c59bb5d Added a
116 116 default ()
117 117
118 118 $ hg branches
119 119 bar 6:7c1991464886
120 120 default 2:28ad74487de9 (inactive)
121 121
122 122 Change branch name to an existing branch
123 123
124 124 $ hg branch -r . default
125 125 abort: a branch of the same name already exists
126 126 [255]
127 127
128 128 Changing on a branch head which is not topological head
129 129
130 130 $ hg branch -r 2 stable
131 131 abort: cannot change branch of changeset with children
132 132 [255]
133 133
134 134 Enabling the allowunstable config and trying to change branch on a branch head
135 135 which is not a topological head
136 136
137 137 $ echo "[experimental]" >> .hg/hgrc
138 138 $ echo "evolution.allowunstable=yes" >> .hg/hgrc
139 139 $ hg branch -r 2 foo
140 140 changed branch on 1 changesets
141 141 2 new orphan changesets
142 142
143 143 Changing branch of an obsoleted changeset
144 144
145 145 $ hg branch -r 4 foobar
146 146 abort: hidden revision '4' was rewritten as: 7c1991464886!
147 147 (use --hidden to access hidden revisions)
148 148 [255]
149 149
150 150 $ hg branch -r 4 --hidden foobar
151 151 abort: cannot change branch of a obsolete changeset
152 152 [255]
153 153
154 154 Make sure bookmark movement is correct
155 155
156 156 $ hg bookmark b1
157 157 $ hg glog -r '.^::'
158 158 @ 6:7c1991464886 Added e
159 159 | bar (b1)
160 160 * 5:1ea05e93925f Added d
161 161 | bar ()
162 162 ~
163 163
164 164 $ hg branch -r '(.^)::' wat --debug
165 165 changing branch of '1ea05e93925f806d875a2163f9b76764be644636' from 'bar' to 'wat'
166 166 committing files:
167 167 d
168 168 committing manifest
169 169 committing changelog
170 170 new node id is 343660ccab7400da637bd6a211d07f413536d718
171 171 changing branch of '7c19914648869f5b02fc7fed31ddee9783fdd680' from 'bar' to 'wat'
172 172 committing files:
173 173 e
174 174 committing manifest
175 175 committing changelog
176 176 new node id is de1404b45a69f8cc6437d7679033ee33e9efb4ba
177 177 moving bookmarks ['b1'] from 7c19914648869f5b02fc7fed31ddee9783fdd680 to de1404b45a69f8cc6437d7679033ee33e9efb4ba
178 178 resolving manifests
179 179 branchmerge: False, force: False, partial: False
180 180 ancestor: 7c1991464886, local: 7c1991464886+, remote: de1404b45a69
181 181 starting 4 threads for background file closing (?)
182 182 changed branch on 2 changesets
183 183 updating the branch cache
184 invalid branchheads cache (served): tip differs
184 invalid branch cache (served): tip differs
185 185
186 186 $ hg glog -r '(.^)::'
187 187 @ 9:de1404b45a69 Added e
188 188 | wat (b1)
189 189 * 8:343660ccab74 Added d
190 190 | wat ()
191 191 ~
192 192
193 193 Make sure phase handling is correct
194 194
195 195 $ echo foo >> bar
196 196 $ hg ci -Aqm "added bar" --secret
197 197 1 new orphan changesets
198 198 $ hg glog -r .
199 199 @ 10:8ad1294c1660 added bar
200 200 | wat (b1)
201 201 ~
202 202 $ hg branch -r . secret
203 203 changed branch on 1 changesets
204 204 $ hg phase -r .
205 205 11: secret
206 206
207 207 $ hg branches
208 208 secret 11:38a9b2d53f98
209 209 foo 7:8a4729a5e2b8
210 210 wat 9:de1404b45a69 (inactive)
211 211 default 2:28ad74487de9 (inactive)
212 212 $ hg branch
213 213 secret
214 214
215 215 Changing branch of another head, different from one on which we are
216 216
217 217 $ hg glog
218 218 @ 11:38a9b2d53f98 added bar
219 219 | secret (b1)
220 220 * 9:de1404b45a69 Added e
221 221 | wat ()
222 222 * 8:343660ccab74 Added d
223 223 | wat ()
224 224 | o 7:8a4729a5e2b8 Added c
225 225 | | foo ()
226 226 x | 2:28ad74487de9 Added c
227 227 |/ default ()
228 228 o 1:29becc82797a Added b
229 229 | default ()
230 230 o 0:18d04c59bb5d Added a
231 231 default ()
232 232
233 233 $ hg branch
234 234 secret
235 235
236 236 $ hg branch -r 7 foobar
237 237 changed branch on 1 changesets
238 238
239 239 The current branch must be preserved
240 240 $ hg branch
241 241 secret
242 242
243 243 Changing branch on multiple heads at once
244 244
245 245 $ hg rebase -s 8 -d 12 --keepbranches -q
246 246
247 247 $ hg rebase -s 14 -d 1 --keepbranches -q
248 248
249 249 $ hg branch -r 0: stable
250 250 changed branch on 6 changesets
251 251 $ hg glog
252 252 @ 23:6a5ddbcfb870 added bar
253 253 | stable (b1)
254 254 o 22:baedc6e98a67 Added e
255 255 | stable ()
256 256 | o 21:99ac7bf8aad1 Added d
257 257 | | stable ()
258 258 | o 20:0ecb4d39c4bd Added c
259 259 |/ stable ()
260 260 o 19:fd45b986b109 Added b
261 261 | stable ()
262 262 o 18:204d2769eca2 Added a
263 263 stable ()
264 264
265 265 $ hg branches
266 266 stable 23:6a5ddbcfb870
267 267
268 268 $ hg branch
269 269 stable
270 270
271 271 Changing to same branch is no-op
272 272
273 273 $ hg branch -r 19::21 stable
274 274 changed branch on 0 changesets
275 275
276 276 Changing branch name to existing branch name if the branch of parent of root of
277 277 revs is same as the new branch name
278 278
279 279 $ hg branch -r 20::21 bugfix
280 280 changed branch on 2 changesets
281 281 $ hg glog
282 282 o 25:714defe1cf34 Added d
283 283 | bugfix ()
284 284 o 24:98394def28fc Added c
285 285 | bugfix ()
286 286 | @ 23:6a5ddbcfb870 added bar
287 287 | | stable (b1)
288 288 | o 22:baedc6e98a67 Added e
289 289 |/ stable ()
290 290 o 19:fd45b986b109 Added b
291 291 | stable ()
292 292 o 18:204d2769eca2 Added a
293 293 stable ()
294 294
295 295 $ hg branch -r 24:25 stable
296 296 changed branch on 2 changesets
297 297 $ hg glog
298 298 o 27:4ec342341562 Added d
299 299 | stable ()
300 300 o 26:83f48859c2de Added c
301 301 | stable ()
302 302 | @ 23:6a5ddbcfb870 added bar
303 303 | | stable (b1)
304 304 | o 22:baedc6e98a67 Added e
305 305 |/ stable ()
306 306 o 19:fd45b986b109 Added b
307 307 | stable ()
308 308 o 18:204d2769eca2 Added a
309 309 stable ()
310 310
311 311 Changing branch of a merge commit
312 312
313 313 $ hg branch -q ghi
314 314 $ echo f > f
315 315 $ hg ci -qAm 'Added f'
316 316 $ hg up -q 27
317 317 $ hg branch -q jkl
318 318 $ echo g > g
319 319 $ hg ci -qAm 'Added g'
320 320 $ hg glog -r 'heads(:)'
321 321 @ 29:6bc1c6c2c9da Added g
322 322 | jkl ()
323 323 ~
324 324 o 28:2f1019bd29d2 Added f
325 325 | ghi (b1)
326 326 ~
327 327
328 328 $ hg branch -q default
329 329 $ hg merge -r 28
330 330 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
331 331 (branch merge, don't forget to commit)
332 332 $ hg branch -r . abcd
333 333 abort: outstanding uncommitted merge
334 334 [255]
335 335
336 336 $ hg ci -m "Merge commit"
337 337 $ hg glog -r 'parents(.)::'
338 338 @ 30:4d56e6b1eb6b Merge commit
339 339 |\ default ()
340 340 | o 29:6bc1c6c2c9da Added g
341 341 | | jkl ()
342 342 | ~
343 343 o 28:2f1019bd29d2 Added f
344 344 | ghi (b1)
345 345 ~
346 346
347 347 $ hg branch -r . ghi
348 348 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
349 349 changed branch on 1 changesets
350 350 $ hg branch -r . jkl
351 351 changed branch on 1 changesets
352 352 $ hg branch -r . default
353 353 changed branch on 1 changesets
354 354 $ hg branch -r . stable
355 355 abort: a branch of the same name already exists
356 356 [255]
357 357
358 358 Changing branch on public changeset
359 359
360 360 $ hg phase -r . -p
361 361 $ hg branch -r . def
362 362 abort: cannot change branch of public changesets
363 363 (see 'hg help phases' for details)
364 364 [255]
365 365
366 366 Merge commit with conflicts, with evolution and without
367 367
368 368 $ mklozenge() {
369 369 > echo foo > a
370 370 > hg ci -qAm foo
371 371 > echo bar > a
372 372 > hg ci -qm bar
373 373 > hg up -q '.^'
374 374 > echo baz > a
375 375 > hg ci -qm baz
376 376 > hg merge -q -t :local
377 377 > echo neither > a
378 378 > hg ci -qm neither
379 379 > }
380 380
381 381 $ cd ..
382 382 $ hg init merge-with-evolution
383 383 $ cd merge-with-evolution
384 384 $ mklozenge
385 385
386 386 $ hg branch -r '(.^)::' abc
387 387 changed branch on 2 changesets
388 388 $ hg glog
389 389 @ 5:c07fa8b34d54 neither
390 390 |\ abc ()
391 391 | o 4:f2aa51777cc9 baz
392 392 | | abc ()
393 393 o | 1:2e33c4f0856b bar
394 394 |/ default ()
395 395 o 0:91cfb6004abf foo
396 396 default ()
397 397 $ hg cat a
398 398 neither
399 399
400 400 $ cd ..
401 401 $ hg init merge-without-evolution
402 402 $ cd merge-without-evolution
403 403 $ mklozenge
404 404 $ cat > .hg/hgrc << EOF
405 405 > [experimental]
406 406 > evolution = no
407 407 > evolution.allowunstable = no
408 408 > EOF
409 409
410 410 $ hg branch -r '(.^)::' abc
411 411 changed branch on 2 changesets
412 412 saved backup bundle to $TESTTMP/merge-without-evolution/.hg/strip-backup/9a3a2af368f4-8db1a361-branch-change.hg
413 413 $ hg glog
414 414 @ 3:c07fa8b34d54 neither
415 415 |\ abc ()
416 416 | o 2:f2aa51777cc9 baz
417 417 | | abc ()
418 418 o | 1:2e33c4f0856b bar
419 419 |/ default ()
420 420 o 0:91cfb6004abf foo
421 421 default ()
422 422 $ hg cat a
423 423 neither
@@ -1,431 +1,431
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > rebase=
4 4 > drawdag=$TESTDIR/drawdag.py
5 5 >
6 6 > [phases]
7 7 > publish=False
8 8 >
9 9 > [alias]
10 10 > tglog = log -G --template "{rev}:{phase} '{desc}' {branches} {bookmarks}\n"
11 11 > EOF
12 12
13 13 $ hg init a
14 14 $ cd a
15 15 $ echo c1 >common
16 16 $ hg add common
17 17 $ hg ci -m C1
18 18
19 19 $ echo c2 >>common
20 20 $ hg ci -m C2
21 21
22 22 $ echo c3 >>common
23 23 $ hg ci -m C3
24 24
25 25 $ hg up -q -C 1
26 26
27 27 $ echo l1 >>extra
28 28 $ hg add extra
29 29 $ hg ci -m L1
30 30 created new head
31 31
32 32 $ sed -e 's/c2/l2/' common > common.new
33 33 $ mv common.new common
34 34 $ hg ci -m L2
35 35
36 36 $ echo l3 >> extra2
37 37 $ hg add extra2
38 38 $ hg ci -m L3
39 39 $ hg bookmark mybook
40 40
41 41 $ hg phase --force --secret 4
42 42
43 43 $ hg tglog
44 44 @ 5:secret 'L3' mybook
45 45 |
46 46 o 4:secret 'L2'
47 47 |
48 48 o 3:draft 'L1'
49 49 |
50 50 | o 2:draft 'C3'
51 51 |/
52 52 o 1:draft 'C2'
53 53 |
54 54 o 0:draft 'C1'
55 55
56 56 Try to call --continue:
57 57
58 58 $ hg rebase --continue
59 59 abort: no rebase in progress
60 60 [255]
61 61
62 62 Conflicting rebase:
63 63
64 64 $ hg rebase -s 3 -d 2
65 65 rebasing 3:3163e20567cc "L1"
66 66 rebasing 4:46f0b057b5c0 "L2"
67 67 merging common
68 68 warning: conflicts while merging common! (edit, then use 'hg resolve --mark')
69 69 unresolved conflicts (see hg resolve, then hg rebase --continue)
70 70 [1]
71 71
72 72 $ hg status --config commands.status.verbose=1
73 73 M common
74 74 ? common.orig
75 75 # The repository is in an unfinished *rebase* state.
76 76
77 77 # Unresolved merge conflicts:
78 78 #
79 79 # common
80 80 #
81 81 # To mark files as resolved: hg resolve --mark FILE
82 82
83 83 # To continue: hg rebase --continue
84 84 # To abort: hg rebase --abort
85 85 # To stop: hg rebase --stop
86 86
87 87
88 88 Try to continue without solving the conflict:
89 89
90 90 $ hg rebase --continue
91 91 abort: unresolved merge conflicts (see 'hg help resolve')
92 92 [255]
93 93
94 94 Conclude rebase:
95 95
96 96 $ echo 'resolved merge' >common
97 97 $ hg resolve -m common
98 98 (no more unresolved files)
99 99 continue: hg rebase --continue
100 100 $ hg rebase --continue
101 101 already rebased 3:3163e20567cc "L1" as 3e046f2ecedb
102 102 rebasing 4:46f0b057b5c0 "L2"
103 103 rebasing 5:8029388f38dc "L3" (mybook)
104 104 saved backup bundle to $TESTTMP/a/.hg/strip-backup/3163e20567cc-5ca4656e-rebase.hg
105 105
106 106 $ hg tglog
107 107 @ 5:secret 'L3' mybook
108 108 |
109 109 o 4:secret 'L2'
110 110 |
111 111 o 3:draft 'L1'
112 112 |
113 113 o 2:draft 'C3'
114 114 |
115 115 o 1:draft 'C2'
116 116 |
117 117 o 0:draft 'C1'
118 118
119 119 Check correctness:
120 120
121 121 $ hg cat -r 0 common
122 122 c1
123 123
124 124 $ hg cat -r 1 common
125 125 c1
126 126 c2
127 127
128 128 $ hg cat -r 2 common
129 129 c1
130 130 c2
131 131 c3
132 132
133 133 $ hg cat -r 3 common
134 134 c1
135 135 c2
136 136 c3
137 137
138 138 $ hg cat -r 4 common
139 139 resolved merge
140 140
141 141 $ hg cat -r 5 common
142 142 resolved merge
143 143
144 144 Bookmark stays active after --continue
145 145 $ hg bookmarks
146 146 * mybook 5:d67b21408fc0
147 147
148 148 $ cd ..
149 149
150 150 Check that the right ancestors is used while rebasing a merge (issue4041)
151 151
152 152 $ hg init issue4041
153 153 $ cd issue4041
154 154 $ hg unbundle "$TESTDIR/bundles/issue4041.hg"
155 155 adding changesets
156 156 adding manifests
157 157 adding file changes
158 158 added 11 changesets with 8 changes to 3 files (+1 heads)
159 159 new changesets 24797d4f68de:2f2496ddf49d (11 drafts)
160 160 (run 'hg heads' to see heads)
161 161 $ hg up default
162 162 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
163 163 $ hg log -G
164 164 o changeset: 10:2f2496ddf49d
165 165 |\ branch: f1
166 166 | | tag: tip
167 167 | | parent: 7:4c9fbe56a16f
168 168 | | parent: 9:e31216eec445
169 169 | | user: szhang
170 170 | | date: Thu Sep 05 12:59:39 2013 -0400
171 171 | | summary: merge
172 172 | |
173 173 | o changeset: 9:e31216eec445
174 174 | | branch: f1
175 175 | | user: szhang
176 176 | | date: Thu Sep 05 12:59:10 2013 -0400
177 177 | | summary: more changes to f1
178 178 | |
179 179 | o changeset: 8:8e4e2c1a07ae
180 180 | |\ branch: f1
181 181 | | | parent: 2:4bc80088dc6b
182 182 | | | parent: 6:400110238667
183 183 | | | user: szhang
184 184 | | | date: Thu Sep 05 12:57:59 2013 -0400
185 185 | | | summary: bad merge
186 186 | | |
187 187 o | | changeset: 7:4c9fbe56a16f
188 188 |/ / branch: f1
189 189 | | parent: 2:4bc80088dc6b
190 190 | | user: szhang
191 191 | | date: Thu Sep 05 12:54:00 2013 -0400
192 192 | | summary: changed f1
193 193 | |
194 194 | o changeset: 6:400110238667
195 195 | | branch: f2
196 196 | | parent: 4:12e8ec6bb010
197 197 | | user: szhang
198 198 | | date: Tue Sep 03 13:58:02 2013 -0400
199 199 | | summary: changed f2 on f2
200 200 | |
201 201 | | @ changeset: 5:d79e2059b5c0
202 202 | | | parent: 3:8a951942e016
203 203 | | | user: szhang
204 204 | | | date: Tue Sep 03 13:57:39 2013 -0400
205 205 | | | summary: changed f2 on default
206 206 | | |
207 207 | o | changeset: 4:12e8ec6bb010
208 208 | |/ branch: f2
209 209 | | user: szhang
210 210 | | date: Tue Sep 03 13:57:18 2013 -0400
211 211 | | summary: created f2 branch
212 212 | |
213 213 | o changeset: 3:8a951942e016
214 214 | | parent: 0:24797d4f68de
215 215 | | user: szhang
216 216 | | date: Tue Sep 03 13:57:11 2013 -0400
217 217 | | summary: added f2.txt
218 218 | |
219 219 o | changeset: 2:4bc80088dc6b
220 220 | | branch: f1
221 221 | | user: szhang
222 222 | | date: Tue Sep 03 13:56:20 2013 -0400
223 223 | | summary: added f1.txt
224 224 | |
225 225 o | changeset: 1:ef53c9e6b608
226 226 |/ branch: f1
227 227 | user: szhang
228 228 | date: Tue Sep 03 13:55:26 2013 -0400
229 229 | summary: created f1 branch
230 230 |
231 231 o changeset: 0:24797d4f68de
232 232 user: szhang
233 233 date: Tue Sep 03 13:55:08 2013 -0400
234 234 summary: added default.txt
235 235
236 236 $ hg rebase -s9 -d2 --debug # use debug to really check merge base used
237 237 rebase onto 4bc80088dc6b starting from e31216eec445
238 238 rebasing on disk
239 239 rebase status stored
240 240 rebasing 9:e31216eec445 "more changes to f1"
241 241 future parents are 2 and -1
242 242 update to 2:4bc80088dc6b
243 243 resolving manifests
244 244 branchmerge: False, force: True, partial: False
245 245 ancestor: d79e2059b5c0+, local: d79e2059b5c0+, remote: 4bc80088dc6b
246 246 f2.txt: other deleted -> r
247 247 removing f2.txt
248 248 f1.txt: remote created -> g
249 249 getting f1.txt
250 250 merge against 9:e31216eec445
251 251 detach base 8:8e4e2c1a07ae
252 252 resolving manifests
253 253 branchmerge: True, force: True, partial: False
254 254 ancestor: 8e4e2c1a07ae, local: 4bc80088dc6b+, remote: e31216eec445
255 255 f1.txt: remote is newer -> g
256 256 getting f1.txt
257 257 committing files:
258 258 f1.txt
259 259 committing manifest
260 260 committing changelog
261 261 updating the branch cache
262 262 rebased as 19c888675e13
263 263 rebase status stored
264 264 rebasing 10:2f2496ddf49d "merge" (tip)
265 265 future parents are 11 and 7
266 266 already in destination
267 267 merge against 10:2f2496ddf49d
268 268 detach base 9:e31216eec445
269 269 resolving manifests
270 270 branchmerge: True, force: True, partial: False
271 271 ancestor: e31216eec445, local: 19c888675e13+, remote: 2f2496ddf49d
272 272 f1.txt: remote is newer -> g
273 273 getting f1.txt
274 274 committing files:
275 275 f1.txt
276 276 committing manifest
277 277 committing changelog
278 278 updating the branch cache
279 279 rebased as 2a7f09cac94c
280 280 rebase status stored
281 281 rebase merging completed
282 282 update back to initial working directory parent
283 283 resolving manifests
284 284 branchmerge: False, force: False, partial: False
285 285 ancestor: 2a7f09cac94c, local: 2a7f09cac94c+, remote: d79e2059b5c0
286 286 f1.txt: other deleted -> r
287 287 removing f1.txt
288 288 f2.txt: remote created -> g
289 289 getting f2.txt
290 290 2 changesets found
291 291 list of changesets:
292 292 e31216eec445e44352c5f01588856059466a24c9
293 293 2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
294 294 bundle2-output-bundle: "HG20", (1 params) 3 parts total
295 295 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
296 296 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
297 297 bundle2-output-part: "phase-heads" 24 bytes payload
298 298 saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-rebase.hg
299 299 3 changesets found
300 300 list of changesets:
301 301 4c9fbe56a16f30c0d5dcc40ec1a97bbe3325209c
302 302 19c888675e133ab5dff84516926a65672eaf04d9
303 303 2a7f09cac94c7f4b73ebd5cd1a62d3b2e8e336bf
304 304 bundle2-output-bundle: "HG20", 3 parts total
305 305 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
306 306 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
307 307 bundle2-output-part: "phase-heads" 24 bytes payload
308 308 adding branch
309 309 bundle2-input-bundle: with-transaction
310 310 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
311 311 adding changesets
312 312 add changeset 4c9fbe56a16f
313 313 add changeset 19c888675e13
314 314 add changeset 2a7f09cac94c
315 315 adding manifests
316 316 adding file changes
317 317 adding f1.txt revisions
318 318 added 2 changesets with 2 changes to 1 files
319 319 bundle2-input-part: total payload size 1686
320 320 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
321 321 bundle2-input-part: total payload size 74
322 322 truncating cache/rbc-revs-v1 to 56
323 323 bundle2-input-part: "phase-heads" supported
324 324 bundle2-input-part: total payload size 24
325 325 bundle2-input-bundle: 2 parts total
326 326 updating the branch cache
327 invalid branchheads cache (served): tip differs
328 invalid branchheads cache (served.hidden): tip differs
327 invalid branch cache (served): tip differs
328 invalid branch cache (served.hidden): tip differs
329 329 rebase completed
330 330
331 331 Test minimization of merge conflicts
332 332 $ hg up -q null
333 333 $ echo a > a
334 334 $ hg add a
335 335 $ hg commit -q -m 'a'
336 336 $ echo b >> a
337 337 $ hg commit -q -m 'ab'
338 338 $ hg bookmark ab
339 339 $ hg up -q '.^'
340 340 $ echo b >> a
341 341 $ echo c >> a
342 342 $ hg commit -q -m 'abc'
343 343 $ hg rebase -s 7bc217434fc1 -d ab --keep
344 344 rebasing 13:7bc217434fc1 "abc" (tip)
345 345 merging a
346 346 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
347 347 unresolved conflicts (see hg resolve, then hg rebase --continue)
348 348 [1]
349 349 $ hg diff
350 350 diff -r 328e4ab1f7cc a
351 351 --- a/a Thu Jan 01 00:00:00 1970 +0000
352 352 +++ b/a * (glob)
353 353 @@ -1,2 +1,6 @@
354 354 a
355 355 b
356 356 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
357 357 +=======
358 358 +c
359 359 +>>>>>>> source: 7bc217434fc1 - test: abc
360 360 $ hg rebase --abort
361 361 rebase aborted
362 362 $ hg up -q -C 7bc217434fc1
363 363 $ hg rebase -s . -d ab --keep -t internal:merge3
364 364 rebasing 13:7bc217434fc1 "abc" (tip)
365 365 merging a
366 366 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
367 367 unresolved conflicts (see hg resolve, then hg rebase --continue)
368 368 [1]
369 369 $ hg diff
370 370 diff -r 328e4ab1f7cc a
371 371 --- a/a Thu Jan 01 00:00:00 1970 +0000
372 372 +++ b/a * (glob)
373 373 @@ -1,2 +1,8 @@
374 374 a
375 375 +<<<<<<< dest: 328e4ab1f7cc ab - test: ab
376 376 b
377 377 +||||||| base
378 378 +=======
379 379 +b
380 380 +c
381 381 +>>>>>>> source: 7bc217434fc1 - test: abc
382 382
383 383 Test rebase with obsstore turned on and off (issue5606)
384 384
385 385 $ cd $TESTTMP
386 386 $ hg init b
387 387 $ cd b
388 388 $ hg debugdrawdag <<'EOS'
389 389 > D
390 390 > |
391 391 > C
392 392 > |
393 393 > B E
394 394 > |/
395 395 > A
396 396 > EOS
397 397
398 398 $ hg update E -q
399 399 $ echo 3 > B
400 400 $ hg commit --amend -m E -A B -q
401 401 $ hg rebase -r B+D -d . --config experimental.evolution=true
402 402 rebasing 1:112478962961 "B" (B)
403 403 merging B
404 404 warning: conflicts while merging B! (edit, then use 'hg resolve --mark')
405 405 unresolved conflicts (see hg resolve, then hg rebase --continue)
406 406 [1]
407 407
408 408 $ echo 4 > B
409 409 $ hg resolve -m
410 410 (no more unresolved files)
411 411 continue: hg rebase --continue
412 412 $ hg rebase --continue --config experimental.evolution=none
413 413 rebasing 1:112478962961 "B" (B)
414 414 rebasing 3:f585351a92f8 "D" (D)
415 415 warning: orphaned descendants detected, not stripping 112478962961
416 416 saved backup bundle to $TESTTMP/b/.hg/strip-backup/f585351a92f8-e536a9e4-rebase.hg
417 417
418 418 $ rm .hg/localtags
419 419 $ hg tglog
420 420 o 5:draft 'D'
421 421 |
422 422 o 4:draft 'B'
423 423 |
424 424 @ 3:draft 'E'
425 425 |
426 426 | o 2:draft 'C'
427 427 | |
428 428 | o 1:draft 'B'
429 429 |/
430 430 o 0:draft 'A'
431 431
@@ -1,1354 +1,1354
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "strip=" >> $HGRCPATH
3 3 $ echo "drawdag=$TESTDIR/drawdag.py" >> $HGRCPATH
4 4
5 5 $ restore() {
6 6 > hg unbundle -q .hg/strip-backup/*
7 7 > rm .hg/strip-backup/*
8 8 > }
9 9 $ teststrip() {
10 10 > hg up -C $1
11 11 > echo % before update $1, strip $2
12 12 > hg parents
13 13 > hg --traceback strip $2
14 14 > echo % after update $1, strip $2
15 15 > hg parents
16 16 > restore
17 17 > }
18 18
19 19 $ hg init test
20 20 $ cd test
21 21
22 22 $ echo foo > bar
23 23 $ hg ci -Ama
24 24 adding bar
25 25
26 26 $ echo more >> bar
27 27 $ hg ci -Amb
28 28
29 29 $ echo blah >> bar
30 30 $ hg ci -Amc
31 31
32 32 $ hg up 1
33 33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ echo blah >> bar
35 35 $ hg ci -Amd
36 36 created new head
37 37
38 38 $ echo final >> bar
39 39 $ hg ci -Ame
40 40
41 41 $ hg log
42 42 changeset: 4:443431ffac4f
43 43 tag: tip
44 44 user: test
45 45 date: Thu Jan 01 00:00:00 1970 +0000
46 46 summary: e
47 47
48 48 changeset: 3:65bd5f99a4a3
49 49 parent: 1:ef3a871183d7
50 50 user: test
51 51 date: Thu Jan 01 00:00:00 1970 +0000
52 52 summary: d
53 53
54 54 changeset: 2:264128213d29
55 55 user: test
56 56 date: Thu Jan 01 00:00:00 1970 +0000
57 57 summary: c
58 58
59 59 changeset: 1:ef3a871183d7
60 60 user: test
61 61 date: Thu Jan 01 00:00:00 1970 +0000
62 62 summary: b
63 63
64 64 changeset: 0:9ab35a2d17cb
65 65 user: test
66 66 date: Thu Jan 01 00:00:00 1970 +0000
67 67 summary: a
68 68
69 69
70 70 $ teststrip 4 4
71 71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 72 % before update 4, strip 4
73 73 changeset: 4:443431ffac4f
74 74 tag: tip
75 75 user: test
76 76 date: Thu Jan 01 00:00:00 1970 +0000
77 77 summary: e
78 78
79 79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 80 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
81 81 % after update 4, strip 4
82 82 changeset: 3:65bd5f99a4a3
83 83 tag: tip
84 84 parent: 1:ef3a871183d7
85 85 user: test
86 86 date: Thu Jan 01 00:00:00 1970 +0000
87 87 summary: d
88 88
89 89 $ teststrip 4 3
90 90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 % before update 4, strip 3
92 92 changeset: 4:443431ffac4f
93 93 tag: tip
94 94 user: test
95 95 date: Thu Jan 01 00:00:00 1970 +0000
96 96 summary: e
97 97
98 98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 99 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
100 100 % after update 4, strip 3
101 101 changeset: 1:ef3a871183d7
102 102 user: test
103 103 date: Thu Jan 01 00:00:00 1970 +0000
104 104 summary: b
105 105
106 106 $ teststrip 1 4
107 107 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 108 % before update 1, strip 4
109 109 changeset: 1:ef3a871183d7
110 110 user: test
111 111 date: Thu Jan 01 00:00:00 1970 +0000
112 112 summary: b
113 113
114 114 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
115 115 % after update 1, strip 4
116 116 changeset: 1:ef3a871183d7
117 117 user: test
118 118 date: Thu Jan 01 00:00:00 1970 +0000
119 119 summary: b
120 120
121 121 $ teststrip 4 2
122 122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 123 % before update 4, strip 2
124 124 changeset: 4:443431ffac4f
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: e
129 129
130 130 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
131 131 % after update 4, strip 2
132 132 changeset: 3:443431ffac4f
133 133 tag: tip
134 134 user: test
135 135 date: Thu Jan 01 00:00:00 1970 +0000
136 136 summary: e
137 137
138 138 $ teststrip 4 1
139 139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 140 % before update 4, strip 1
141 141 changeset: 4:264128213d29
142 142 tag: tip
143 143 parent: 1:ef3a871183d7
144 144 user: test
145 145 date: Thu Jan 01 00:00:00 1970 +0000
146 146 summary: c
147 147
148 148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 149 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
150 150 % after update 4, strip 1
151 151 changeset: 0:9ab35a2d17cb
152 152 tag: tip
153 153 user: test
154 154 date: Thu Jan 01 00:00:00 1970 +0000
155 155 summary: a
156 156
157 157 $ teststrip null 4
158 158 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
159 159 % before update null, strip 4
160 160 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
161 161 % after update null, strip 4
162 162
163 163 $ hg log
164 164 changeset: 4:264128213d29
165 165 tag: tip
166 166 parent: 1:ef3a871183d7
167 167 user: test
168 168 date: Thu Jan 01 00:00:00 1970 +0000
169 169 summary: c
170 170
171 171 changeset: 3:443431ffac4f
172 172 user: test
173 173 date: Thu Jan 01 00:00:00 1970 +0000
174 174 summary: e
175 175
176 176 changeset: 2:65bd5f99a4a3
177 177 user: test
178 178 date: Thu Jan 01 00:00:00 1970 +0000
179 179 summary: d
180 180
181 181 changeset: 1:ef3a871183d7
182 182 user: test
183 183 date: Thu Jan 01 00:00:00 1970 +0000
184 184 summary: b
185 185
186 186 changeset: 0:9ab35a2d17cb
187 187 user: test
188 188 date: Thu Jan 01 00:00:00 1970 +0000
189 189 summary: a
190 190
191 191 $ hg up -C 4
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 $ hg parents
194 194 changeset: 4:264128213d29
195 195 tag: tip
196 196 parent: 1:ef3a871183d7
197 197 user: test
198 198 date: Thu Jan 01 00:00:00 1970 +0000
199 199 summary: c
200 200
201 201
202 202 $ hg --traceback strip 4
203 203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 204 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg
205 205 $ hg parents
206 206 changeset: 1:ef3a871183d7
207 207 user: test
208 208 date: Thu Jan 01 00:00:00 1970 +0000
209 209 summary: b
210 210
211 211 $ hg debugbundle .hg/strip-backup/*
212 212 Stream params: {Compression: BZ}
213 213 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
214 214 264128213d290d868c54642d13aeaa3675551a78
215 215 cache:rev-branch-cache -- {} (mandatory: False)
216 216 phase-heads -- {} (mandatory: True)
217 217 264128213d290d868c54642d13aeaa3675551a78 draft
218 218 $ hg unbundle .hg/strip-backup/*
219 219 adding changesets
220 220 adding manifests
221 221 adding file changes
222 222 added 1 changesets with 0 changes to 1 files (+1 heads)
223 223 new changesets 264128213d29 (1 drafts)
224 224 (run 'hg heads' to see heads, 'hg merge' to merge)
225 225 $ rm .hg/strip-backup/*
226 226 $ hg log --graph
227 227 o changeset: 4:264128213d29
228 228 | tag: tip
229 229 | parent: 1:ef3a871183d7
230 230 | user: test
231 231 | date: Thu Jan 01 00:00:00 1970 +0000
232 232 | summary: c
233 233 |
234 234 | o changeset: 3:443431ffac4f
235 235 | | user: test
236 236 | | date: Thu Jan 01 00:00:00 1970 +0000
237 237 | | summary: e
238 238 | |
239 239 | o changeset: 2:65bd5f99a4a3
240 240 |/ user: test
241 241 | date: Thu Jan 01 00:00:00 1970 +0000
242 242 | summary: d
243 243 |
244 244 @ changeset: 1:ef3a871183d7
245 245 | user: test
246 246 | date: Thu Jan 01 00:00:00 1970 +0000
247 247 | summary: b
248 248 |
249 249 o changeset: 0:9ab35a2d17cb
250 250 user: test
251 251 date: Thu Jan 01 00:00:00 1970 +0000
252 252 summary: a
253 253
254 254 $ hg up -C 2
255 255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 256 $ hg merge 4
257 257 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 258 (branch merge, don't forget to commit)
259 259
260 260 before strip of merge parent
261 261
262 262 $ hg parents
263 263 changeset: 2:65bd5f99a4a3
264 264 user: test
265 265 date: Thu Jan 01 00:00:00 1970 +0000
266 266 summary: d
267 267
268 268 changeset: 4:264128213d29
269 269 tag: tip
270 270 parent: 1:ef3a871183d7
271 271 user: test
272 272 date: Thu Jan 01 00:00:00 1970 +0000
273 273 summary: c
274 274
275 275 ##strip not allowed with merge in progress
276 276 $ hg strip 4
277 277 abort: outstanding uncommitted merge
278 278 (use 'hg commit' or 'hg merge --abort')
279 279 [255]
280 280 ##strip allowed --force with merge in progress
281 281 $ hg strip 4 --force
282 282 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
283 283 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
284 284
285 285 after strip of merge parent
286 286
287 287 $ hg parents
288 288 changeset: 1:ef3a871183d7
289 289 user: test
290 290 date: Thu Jan 01 00:00:00 1970 +0000
291 291 summary: b
292 292
293 293 $ restore
294 294
295 295 $ hg up
296 296 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
297 297 updated to "264128213d29: c"
298 298 1 other heads for branch "default"
299 299 $ hg log -G
300 300 @ changeset: 4:264128213d29
301 301 | tag: tip
302 302 | parent: 1:ef3a871183d7
303 303 | user: test
304 304 | date: Thu Jan 01 00:00:00 1970 +0000
305 305 | summary: c
306 306 |
307 307 | o changeset: 3:443431ffac4f
308 308 | | user: test
309 309 | | date: Thu Jan 01 00:00:00 1970 +0000
310 310 | | summary: e
311 311 | |
312 312 | o changeset: 2:65bd5f99a4a3
313 313 |/ user: test
314 314 | date: Thu Jan 01 00:00:00 1970 +0000
315 315 | summary: d
316 316 |
317 317 o changeset: 1:ef3a871183d7
318 318 | user: test
319 319 | date: Thu Jan 01 00:00:00 1970 +0000
320 320 | summary: b
321 321 |
322 322 o changeset: 0:9ab35a2d17cb
323 323 user: test
324 324 date: Thu Jan 01 00:00:00 1970 +0000
325 325 summary: a
326 326
327 327
328 328 2 is parent of 3, only one strip should happen
329 329
330 330 $ hg strip "roots(2)" 3
331 331 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
332 332 $ hg log -G
333 333 @ changeset: 2:264128213d29
334 334 | tag: tip
335 335 | user: test
336 336 | date: Thu Jan 01 00:00:00 1970 +0000
337 337 | summary: c
338 338 |
339 339 o changeset: 1:ef3a871183d7
340 340 | user: test
341 341 | date: Thu Jan 01 00:00:00 1970 +0000
342 342 | summary: b
343 343 |
344 344 o changeset: 0:9ab35a2d17cb
345 345 user: test
346 346 date: Thu Jan 01 00:00:00 1970 +0000
347 347 summary: a
348 348
349 349 $ restore
350 350 $ hg log -G
351 351 o changeset: 4:443431ffac4f
352 352 | tag: tip
353 353 | user: test
354 354 | date: Thu Jan 01 00:00:00 1970 +0000
355 355 | summary: e
356 356 |
357 357 o changeset: 3:65bd5f99a4a3
358 358 | parent: 1:ef3a871183d7
359 359 | user: test
360 360 | date: Thu Jan 01 00:00:00 1970 +0000
361 361 | summary: d
362 362 |
363 363 | @ changeset: 2:264128213d29
364 364 |/ user: test
365 365 | date: Thu Jan 01 00:00:00 1970 +0000
366 366 | summary: c
367 367 |
368 368 o changeset: 1:ef3a871183d7
369 369 | user: test
370 370 | date: Thu Jan 01 00:00:00 1970 +0000
371 371 | summary: b
372 372 |
373 373 o changeset: 0:9ab35a2d17cb
374 374 user: test
375 375 date: Thu Jan 01 00:00:00 1970 +0000
376 376 summary: a
377 377
378 378 Failed hook while applying "saveheads" bundle.
379 379
380 380 $ hg strip 2 --config hooks.pretxnchangegroup.bad=false
381 381 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
382 382 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
383 383 transaction abort!
384 384 rollback completed
385 385 strip failed, backup bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
386 386 strip failed, unrecovered changes stored in '$TESTTMP/test/.hg/strip-backup/*-temp.hg' (glob)
387 387 (fix the problem, then recover the changesets with "hg unbundle '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)
388 388 abort: pretxnchangegroup.bad hook exited with status 1
389 389 [255]
390 390 $ restore
391 391 $ hg log -G
392 392 o changeset: 4:443431ffac4f
393 393 | tag: tip
394 394 | user: test
395 395 | date: Thu Jan 01 00:00:00 1970 +0000
396 396 | summary: e
397 397 |
398 398 o changeset: 3:65bd5f99a4a3
399 399 | parent: 1:ef3a871183d7
400 400 | user: test
401 401 | date: Thu Jan 01 00:00:00 1970 +0000
402 402 | summary: d
403 403 |
404 404 | o changeset: 2:264128213d29
405 405 |/ user: test
406 406 | date: Thu Jan 01 00:00:00 1970 +0000
407 407 | summary: c
408 408 |
409 409 @ changeset: 1:ef3a871183d7
410 410 | user: test
411 411 | date: Thu Jan 01 00:00:00 1970 +0000
412 412 | summary: b
413 413 |
414 414 o changeset: 0:9ab35a2d17cb
415 415 user: test
416 416 date: Thu Jan 01 00:00:00 1970 +0000
417 417 summary: a
418 418
419 419
420 420 2 different branches: 2 strips
421 421
422 422 $ hg strip 2 4
423 423 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
424 424 $ hg log -G
425 425 o changeset: 2:65bd5f99a4a3
426 426 | tag: tip
427 427 | user: test
428 428 | date: Thu Jan 01 00:00:00 1970 +0000
429 429 | summary: d
430 430 |
431 431 @ changeset: 1:ef3a871183d7
432 432 | user: test
433 433 | date: Thu Jan 01 00:00:00 1970 +0000
434 434 | summary: b
435 435 |
436 436 o changeset: 0:9ab35a2d17cb
437 437 user: test
438 438 date: Thu Jan 01 00:00:00 1970 +0000
439 439 summary: a
440 440
441 441 $ restore
442 442
443 443 2 different branches and a common ancestor: 1 strip
444 444
445 445 $ hg strip 1 "2|4"
446 446 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
447 447 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
448 448 $ restore
449 449
450 450 verify fncache is kept up-to-date
451 451
452 452 $ touch a
453 453 $ hg ci -qAm a
454 454 #if repofncache
455 455 $ cat .hg/store/fncache | sort
456 456 data/a.i
457 457 data/bar.i
458 458 #endif
459 459
460 460 $ hg strip tip
461 461 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
462 462 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
463 463 #if repofncache
464 464 $ cat .hg/store/fncache
465 465 data/bar.i
466 466 #endif
467 467
468 468 stripping an empty revset
469 469
470 470 $ hg strip "1 and not 1"
471 471 abort: empty revision set
472 472 [255]
473 473
474 474 remove branchy history for qimport tests
475 475
476 476 $ hg strip 3
477 477 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
478 478
479 479
480 480 strip of applied mq should cleanup status file
481 481
482 482 $ echo "mq=" >> $HGRCPATH
483 483 $ hg up -C 3
484 484 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
485 485 $ echo fooagain >> bar
486 486 $ hg ci -mf
487 487 $ hg qimport -r tip:2
488 488
489 489 applied patches before strip
490 490
491 491 $ hg qapplied
492 492 d
493 493 e
494 494 f
495 495
496 496 stripping revision in queue
497 497
498 498 $ hg strip 3
499 499 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
500 500 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
501 501
502 502 applied patches after stripping rev in queue
503 503
504 504 $ hg qapplied
505 505 d
506 506
507 507 stripping ancestor of queue
508 508
509 509 $ hg strip 1
510 510 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
511 511 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
512 512
513 513 applied patches after stripping ancestor of queue
514 514
515 515 $ hg qapplied
516 516
517 517 Verify strip protects against stripping wc parent when there are uncommitted mods
518 518
519 519 $ echo b > b
520 520 $ echo bb > bar
521 521 $ hg add b
522 522 $ hg ci -m 'b'
523 523 $ hg log --graph
524 524 @ changeset: 1:76dcf9fab855
525 525 | tag: tip
526 526 | user: test
527 527 | date: Thu Jan 01 00:00:00 1970 +0000
528 528 | summary: b
529 529 |
530 530 o changeset: 0:9ab35a2d17cb
531 531 user: test
532 532 date: Thu Jan 01 00:00:00 1970 +0000
533 533 summary: a
534 534
535 535 $ hg up 0
536 536 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
537 537 $ echo c > bar
538 538 $ hg up -t false
539 539 merging bar
540 540 merging bar failed!
541 541 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
542 542 use 'hg resolve' to retry unresolved file merges
543 543 [1]
544 544 $ hg sum
545 545 parent: 1:76dcf9fab855 tip
546 546 b
547 547 branch: default
548 548 commit: 1 modified, 1 unknown, 1 unresolved
549 549 update: (current)
550 550 phases: 2 draft
551 551 mq: 3 unapplied
552 552
553 553 $ echo c > b
554 554 $ hg strip tip
555 555 abort: uncommitted changes
556 556 [255]
557 557 $ hg strip tip --keep
558 558 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
559 559 $ hg log --graph
560 560 @ changeset: 0:9ab35a2d17cb
561 561 tag: tip
562 562 user: test
563 563 date: Thu Jan 01 00:00:00 1970 +0000
564 564 summary: a
565 565
566 566 $ hg status
567 567 M bar
568 568 ? b
569 569 ? bar.orig
570 570
571 571 $ rm bar.orig
572 572 $ hg sum
573 573 parent: 0:9ab35a2d17cb tip
574 574 a
575 575 branch: default
576 576 commit: 1 modified, 1 unknown
577 577 update: (current)
578 578 phases: 1 draft
579 579 mq: 3 unapplied
580 580
581 581 Strip adds, removes, modifies with --keep
582 582
583 583 $ touch b
584 584 $ hg add b
585 585 $ hg commit -mb
586 586 $ touch c
587 587
588 588 ... with a clean working dir
589 589
590 590 $ hg add c
591 591 $ hg rm bar
592 592 $ hg commit -mc
593 593 $ hg status
594 594 $ hg strip --keep tip
595 595 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
596 596 $ hg status
597 597 ! bar
598 598 ? c
599 599
600 600 ... with a dirty working dir
601 601
602 602 $ hg add c
603 603 $ hg rm bar
604 604 $ hg commit -mc
605 605 $ hg status
606 606 $ echo b > b
607 607 $ echo d > d
608 608 $ hg strip --keep tip
609 609 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
610 610 $ hg status
611 611 M b
612 612 ! bar
613 613 ? c
614 614 ? d
615 615
616 616 ... after updating the dirstate
617 617 $ hg add c
618 618 $ hg commit -mc
619 619 $ hg rm c
620 620 $ hg commit -mc
621 621 $ hg strip --keep '.^' -q
622 622 $ cd ..
623 623
624 624 stripping many nodes on a complex graph (issue3299)
625 625
626 626 $ hg init issue3299
627 627 $ cd issue3299
628 628 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
629 629 $ hg strip 'not ancestors(x)'
630 630 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
631 631
632 632 test hg strip -B bookmark
633 633
634 634 $ cd ..
635 635 $ hg init bookmarks
636 636 $ cd bookmarks
637 637 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
638 638 $ hg bookmark -r 'a' 'todelete'
639 639 $ hg bookmark -r 'b' 'B'
640 640 $ hg bookmark -r 'b' 'nostrip'
641 641 $ hg bookmark -r 'c' 'delete'
642 642 $ hg bookmark -r 'd' 'multipledelete1'
643 643 $ hg bookmark -r 'e' 'multipledelete2'
644 644 $ hg bookmark -r 'f' 'singlenode1'
645 645 $ hg bookmark -r 'f' 'singlenode2'
646 646 $ hg up -C todelete
647 647 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
648 648 (activating bookmark todelete)
649 649 $ hg strip -B nostrip
650 650 bookmark 'nostrip' deleted
651 651 abort: empty revision set
652 652 [255]
653 653 $ hg strip -B todelete
654 654 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
655 655 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
656 656 bookmark 'todelete' deleted
657 657 $ hg id -ir dcbb326fdec2
658 658 abort: unknown revision 'dcbb326fdec2'!
659 659 [255]
660 660 $ hg id -ir d62d843c9a01
661 661 d62d843c9a01
662 662 $ hg bookmarks
663 663 B 9:ff43616e5d0f
664 664 delete 6:2702dd0c91e7
665 665 multipledelete1 11:e46a4836065c
666 666 multipledelete2 12:b4594d867745
667 667 singlenode1 13:43227190fef8
668 668 singlenode2 13:43227190fef8
669 669 $ hg strip -B multipledelete1 -B multipledelete2
670 670 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg
671 671 bookmark 'multipledelete1' deleted
672 672 bookmark 'multipledelete2' deleted
673 673 $ hg id -ir e46a4836065c
674 674 abort: unknown revision 'e46a4836065c'!
675 675 [255]
676 676 $ hg id -ir b4594d867745
677 677 abort: unknown revision 'b4594d867745'!
678 678 [255]
679 679 $ hg strip -B singlenode1 -B singlenode2
680 680 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg
681 681 bookmark 'singlenode1' deleted
682 682 bookmark 'singlenode2' deleted
683 683 $ hg id -ir 43227190fef8
684 684 abort: unknown revision '43227190fef8'!
685 685 [255]
686 686 $ hg strip -B unknownbookmark
687 687 abort: bookmark 'unknownbookmark' not found
688 688 [255]
689 689 $ hg strip -B unknownbookmark1 -B unknownbookmark2
690 690 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
691 691 [255]
692 692 $ hg strip -B delete -B unknownbookmark
693 693 abort: bookmark 'unknownbookmark' not found
694 694 [255]
695 695 $ hg strip -B delete
696 696 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
697 697 bookmark 'delete' deleted
698 698 $ hg id -ir 6:2702dd0c91e7
699 699 abort: unknown revision '2702dd0c91e7'!
700 700 [255]
701 701 $ hg update B
702 702 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
703 703 (activating bookmark B)
704 704 $ echo a > a
705 705 $ hg add a
706 706 $ hg strip -B B
707 707 abort: uncommitted changes
708 708 [255]
709 709 $ hg bookmarks
710 710 * B 6:ff43616e5d0f
711 711
712 712 Make sure no one adds back a -b option:
713 713
714 714 $ hg strip -b tip
715 715 hg strip: option -b not recognized
716 716 hg strip [-k] [-f] [-B bookmark] [-r] REV...
717 717
718 718 strip changesets and all their descendants from the repository
719 719
720 720 (use 'hg help -e strip' to show help for the strip extension)
721 721
722 722 options ([+] can be repeated):
723 723
724 724 -r --rev REV [+] strip specified revision (optional, can specify
725 725 revisions without this option)
726 726 -f --force force removal of changesets, discard uncommitted
727 727 changes (no backup)
728 728 --no-backup do not save backup bundle
729 729 -k --keep do not modify working directory during strip
730 730 -B --bookmark BOOKMARK [+] remove revs only reachable from given bookmark
731 731 --mq operate on patch repository
732 732
733 733 (use 'hg strip -h' to show more help)
734 734 [255]
735 735
736 736 $ cd ..
737 737
738 738 Verify bundles don't get overwritten:
739 739
740 740 $ hg init doublebundle
741 741 $ cd doublebundle
742 742 $ touch a
743 743 $ hg commit -Aqm a
744 744 $ touch b
745 745 $ hg commit -Aqm b
746 746 $ hg strip -r 0
747 747 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
748 748 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg
749 749 $ ls .hg/strip-backup
750 750 3903775176ed-e68910bd-backup.hg
751 751 #if repobundlerepo
752 752 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
753 753 $ hg strip -r 0
754 754 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg
755 755 $ ls .hg/strip-backup
756 756 3903775176ed-54390173-backup.hg
757 757 3903775176ed-e68910bd-backup.hg
758 758 #endif
759 759 $ cd ..
760 760
761 761 Test that we only bundle the stripped changesets (issue4736)
762 762 ------------------------------------------------------------
763 763
764 764 initialization (previous repo is empty anyway)
765 765
766 766 $ hg init issue4736
767 767 $ cd issue4736
768 768 $ echo a > a
769 769 $ hg add a
770 770 $ hg commit -m commitA
771 771 $ echo b > b
772 772 $ hg add b
773 773 $ hg commit -m commitB
774 774 $ echo c > c
775 775 $ hg add c
776 776 $ hg commit -m commitC
777 777 $ hg up 'desc(commitB)'
778 778 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
779 779 $ echo d > d
780 780 $ hg add d
781 781 $ hg commit -m commitD
782 782 created new head
783 783 $ hg up 'desc(commitC)'
784 784 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
785 785 $ hg merge 'desc(commitD)'
786 786 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
787 787 (branch merge, don't forget to commit)
788 788 $ hg ci -m 'mergeCD'
789 789 $ hg log -G
790 790 @ changeset: 4:d8db9d137221
791 791 |\ tag: tip
792 792 | | parent: 2:5c51d8d6557d
793 793 | | parent: 3:6625a5168474
794 794 | | user: test
795 795 | | date: Thu Jan 01 00:00:00 1970 +0000
796 796 | | summary: mergeCD
797 797 | |
798 798 | o changeset: 3:6625a5168474
799 799 | | parent: 1:eca11cf91c71
800 800 | | user: test
801 801 | | date: Thu Jan 01 00:00:00 1970 +0000
802 802 | | summary: commitD
803 803 | |
804 804 o | changeset: 2:5c51d8d6557d
805 805 |/ user: test
806 806 | date: Thu Jan 01 00:00:00 1970 +0000
807 807 | summary: commitC
808 808 |
809 809 o changeset: 1:eca11cf91c71
810 810 | user: test
811 811 | date: Thu Jan 01 00:00:00 1970 +0000
812 812 | summary: commitB
813 813 |
814 814 o changeset: 0:105141ef12d0
815 815 user: test
816 816 date: Thu Jan 01 00:00:00 1970 +0000
817 817 summary: commitA
818 818
819 819
820 820 Check bundle behavior:
821 821
822 822 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
823 823 2 changesets found
824 824 #if repobundlerepo
825 825 $ hg log -r 'bundle()' -R ../issue4736.hg
826 826 changeset: 3:6625a5168474
827 827 parent: 1:eca11cf91c71
828 828 user: test
829 829 date: Thu Jan 01 00:00:00 1970 +0000
830 830 summary: commitD
831 831
832 832 changeset: 4:d8db9d137221
833 833 tag: tip
834 834 parent: 2:5c51d8d6557d
835 835 parent: 3:6625a5168474
836 836 user: test
837 837 date: Thu Jan 01 00:00:00 1970 +0000
838 838 summary: mergeCD
839 839
840 840 #endif
841 841
842 842 check strip behavior
843 843
844 844 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
845 845 resolving manifests
846 846 branchmerge: False, force: True, partial: False
847 847 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
848 848 c: other deleted -> r
849 849 removing c
850 850 d: other deleted -> r
851 851 removing d
852 852 starting 4 threads for background file closing (?)
853 853 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
854 854 2 changesets found
855 855 list of changesets:
856 856 6625a516847449b6f0fa3737b9ba56e9f0f3032c
857 857 d8db9d1372214336d2b5570f20ee468d2c72fa8b
858 858 bundle2-output-bundle: "HG20", (1 params) 3 parts total
859 859 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
860 860 bundle2-output-part: "cache:rev-branch-cache" (advisory) streamed payload
861 861 bundle2-output-part: "phase-heads" 24 bytes payload
862 862 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg
863 863 updating the branch cache
864 invalid branchheads cache (served): tip differs
864 invalid branch cache (served): tip differs
865 865 $ hg log -G
866 866 o changeset: 2:5c51d8d6557d
867 867 | tag: tip
868 868 | user: test
869 869 | date: Thu Jan 01 00:00:00 1970 +0000
870 870 | summary: commitC
871 871 |
872 872 @ changeset: 1:eca11cf91c71
873 873 | user: test
874 874 | date: Thu Jan 01 00:00:00 1970 +0000
875 875 | summary: commitB
876 876 |
877 877 o changeset: 0:105141ef12d0
878 878 user: test
879 879 date: Thu Jan 01 00:00:00 1970 +0000
880 880 summary: commitA
881 881
882 882
883 883 strip backup content
884 884
885 885 #if repobundlerepo
886 886 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
887 887 changeset: 3:6625a5168474
888 888 parent: 1:eca11cf91c71
889 889 user: test
890 890 date: Thu Jan 01 00:00:00 1970 +0000
891 891 summary: commitD
892 892
893 893 changeset: 4:d8db9d137221
894 894 tag: tip
895 895 parent: 2:5c51d8d6557d
896 896 parent: 3:6625a5168474
897 897 user: test
898 898 date: Thu Jan 01 00:00:00 1970 +0000
899 899 summary: mergeCD
900 900
901 901
902 902 #endif
903 903
904 904 Check that the phase cache is properly invalidated after a strip with bookmark.
905 905
906 906 $ cat > ../stripstalephasecache.py << EOF
907 907 > from mercurial import extensions, localrepo
908 908 > def transactioncallback(orig, repo, desc, *args, **kwargs):
909 909 > def test(transaction):
910 910 > # observe cache inconsistency
911 911 > try:
912 912 > [repo.changelog.node(r) for r in repo.revs(b"not public()")]
913 913 > except IndexError:
914 914 > repo.ui.status(b"Index error!\n")
915 915 > transaction = orig(repo, desc, *args, **kwargs)
916 916 > # warm up the phase cache
917 917 > list(repo.revs(b"not public()"))
918 918 > if desc != b'strip':
919 919 > transaction.addpostclose(b"phase invalidation test", test)
920 920 > return transaction
921 921 > def extsetup(ui):
922 922 > extensions.wrapfunction(localrepo.localrepository, b"transaction",
923 923 > transactioncallback)
924 924 > EOF
925 925 $ hg up -C 2
926 926 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
927 927 $ echo k > k
928 928 $ hg add k
929 929 $ hg commit -m commitK
930 930 $ echo l > l
931 931 $ hg add l
932 932 $ hg commit -m commitL
933 933 $ hg book -r tip blah
934 934 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
935 935 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
936 936 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg
937 937 $ hg up -C 1
938 938 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
939 939
940 940 Error during post-close callback of the strip transaction
941 941 (They should be gracefully handled and reported)
942 942
943 943 $ cat > ../crashstrip.py << EOF
944 944 > from mercurial import error
945 945 > def reposetup(ui, repo):
946 946 > class crashstriprepo(repo.__class__):
947 947 > def transaction(self, desc, *args, **kwargs):
948 948 > tr = super(crashstriprepo, self).transaction(desc, *args, **kwargs)
949 949 > if desc == b'strip':
950 950 > def crash(tra): raise error.Abort(b'boom')
951 951 > tr.addpostclose(b'crash', crash)
952 952 > return tr
953 953 > repo.__class__ = crashstriprepo
954 954 > EOF
955 955 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
956 956 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg
957 957 strip failed, backup bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg'
958 958 abort: boom
959 959 [255]
960 960
961 961 test stripping a working directory parent doesn't switch named branches
962 962
963 963 $ hg log -G
964 964 @ changeset: 1:eca11cf91c71
965 965 | tag: tip
966 966 | user: test
967 967 | date: Thu Jan 01 00:00:00 1970 +0000
968 968 | summary: commitB
969 969 |
970 970 o changeset: 0:105141ef12d0
971 971 user: test
972 972 date: Thu Jan 01 00:00:00 1970 +0000
973 973 summary: commitA
974 974
975 975
976 976 $ hg branch new-branch
977 977 marked working directory as branch new-branch
978 978 (branches are permanent and global, did you want a bookmark?)
979 979 $ hg ci -m "start new branch"
980 980 $ echo 'foo' > foo.txt
981 981 $ hg ci -Aqm foo
982 982 $ hg up default
983 983 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
984 984 $ echo 'bar' > bar.txt
985 985 $ hg ci -Aqm bar
986 986 $ hg up new-branch
987 987 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
988 988 $ hg merge default
989 989 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
990 990 (branch merge, don't forget to commit)
991 991 $ hg log -G
992 992 @ changeset: 4:35358f982181
993 993 | tag: tip
994 994 | parent: 1:eca11cf91c71
995 995 | user: test
996 996 | date: Thu Jan 01 00:00:00 1970 +0000
997 997 | summary: bar
998 998 |
999 999 | @ changeset: 3:f62c6c09b707
1000 1000 | | branch: new-branch
1001 1001 | | user: test
1002 1002 | | date: Thu Jan 01 00:00:00 1970 +0000
1003 1003 | | summary: foo
1004 1004 | |
1005 1005 | o changeset: 2:b1d33a8cadd9
1006 1006 |/ branch: new-branch
1007 1007 | user: test
1008 1008 | date: Thu Jan 01 00:00:00 1970 +0000
1009 1009 | summary: start new branch
1010 1010 |
1011 1011 o changeset: 1:eca11cf91c71
1012 1012 | user: test
1013 1013 | date: Thu Jan 01 00:00:00 1970 +0000
1014 1014 | summary: commitB
1015 1015 |
1016 1016 o changeset: 0:105141ef12d0
1017 1017 user: test
1018 1018 date: Thu Jan 01 00:00:00 1970 +0000
1019 1019 summary: commitA
1020 1020
1021 1021
1022 1022 $ hg strip --force -r 35358f982181
1023 1023 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1024 1024 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-50d992d4-backup.hg
1025 1025 $ hg log -G
1026 1026 @ changeset: 3:f62c6c09b707
1027 1027 | branch: new-branch
1028 1028 | tag: tip
1029 1029 | user: test
1030 1030 | date: Thu Jan 01 00:00:00 1970 +0000
1031 1031 | summary: foo
1032 1032 |
1033 1033 o changeset: 2:b1d33a8cadd9
1034 1034 | branch: new-branch
1035 1035 | user: test
1036 1036 | date: Thu Jan 01 00:00:00 1970 +0000
1037 1037 | summary: start new branch
1038 1038 |
1039 1039 o changeset: 1:eca11cf91c71
1040 1040 | user: test
1041 1041 | date: Thu Jan 01 00:00:00 1970 +0000
1042 1042 | summary: commitB
1043 1043 |
1044 1044 o changeset: 0:105141ef12d0
1045 1045 user: test
1046 1046 date: Thu Jan 01 00:00:00 1970 +0000
1047 1047 summary: commitA
1048 1048
1049 1049
1050 1050 $ hg up default
1051 1051 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1052 1052 $ echo 'bar' > bar.txt
1053 1053 $ hg ci -Aqm bar
1054 1054 $ hg up new-branch
1055 1055 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1056 1056 $ hg merge default
1057 1057 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1058 1058 (branch merge, don't forget to commit)
1059 1059 $ hg ci -m merge
1060 1060 $ hg log -G
1061 1061 @ changeset: 5:4cf5e92caec2
1062 1062 |\ branch: new-branch
1063 1063 | | tag: tip
1064 1064 | | parent: 3:f62c6c09b707
1065 1065 | | parent: 4:35358f982181
1066 1066 | | user: test
1067 1067 | | date: Thu Jan 01 00:00:00 1970 +0000
1068 1068 | | summary: merge
1069 1069 | |
1070 1070 | o changeset: 4:35358f982181
1071 1071 | | parent: 1:eca11cf91c71
1072 1072 | | user: test
1073 1073 | | date: Thu Jan 01 00:00:00 1970 +0000
1074 1074 | | summary: bar
1075 1075 | |
1076 1076 o | changeset: 3:f62c6c09b707
1077 1077 | | branch: new-branch
1078 1078 | | user: test
1079 1079 | | date: Thu Jan 01 00:00:00 1970 +0000
1080 1080 | | summary: foo
1081 1081 | |
1082 1082 o | changeset: 2:b1d33a8cadd9
1083 1083 |/ branch: new-branch
1084 1084 | user: test
1085 1085 | date: Thu Jan 01 00:00:00 1970 +0000
1086 1086 | summary: start new branch
1087 1087 |
1088 1088 o changeset: 1:eca11cf91c71
1089 1089 | user: test
1090 1090 | date: Thu Jan 01 00:00:00 1970 +0000
1091 1091 | summary: commitB
1092 1092 |
1093 1093 o changeset: 0:105141ef12d0
1094 1094 user: test
1095 1095 date: Thu Jan 01 00:00:00 1970 +0000
1096 1096 summary: commitA
1097 1097
1098 1098
1099 1099 $ hg strip -r 35358f982181
1100 1100 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1101 1101 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1102 1102 $ hg log -G
1103 1103 @ changeset: 3:f62c6c09b707
1104 1104 | branch: new-branch
1105 1105 | tag: tip
1106 1106 | user: test
1107 1107 | date: Thu Jan 01 00:00:00 1970 +0000
1108 1108 | summary: foo
1109 1109 |
1110 1110 o changeset: 2:b1d33a8cadd9
1111 1111 | branch: new-branch
1112 1112 | user: test
1113 1113 | date: Thu Jan 01 00:00:00 1970 +0000
1114 1114 | summary: start new branch
1115 1115 |
1116 1116 o changeset: 1:eca11cf91c71
1117 1117 | user: test
1118 1118 | date: Thu Jan 01 00:00:00 1970 +0000
1119 1119 | summary: commitB
1120 1120 |
1121 1121 o changeset: 0:105141ef12d0
1122 1122 user: test
1123 1123 date: Thu Jan 01 00:00:00 1970 +0000
1124 1124 summary: commitA
1125 1125
1126 1126
1127 1127 $ hg unbundle -u $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1128 1128 adding changesets
1129 1129 adding manifests
1130 1130 adding file changes
1131 1131 added 2 changesets with 1 changes to 1 files
1132 1132 new changesets 35358f982181:4cf5e92caec2 (2 drafts)
1133 1133 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1134 1134
1135 1135 $ hg strip -k -r 35358f982181
1136 1136 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1137 1137 $ hg log -G
1138 1138 @ changeset: 3:f62c6c09b707
1139 1139 | branch: new-branch
1140 1140 | tag: tip
1141 1141 | user: test
1142 1142 | date: Thu Jan 01 00:00:00 1970 +0000
1143 1143 | summary: foo
1144 1144 |
1145 1145 o changeset: 2:b1d33a8cadd9
1146 1146 | branch: new-branch
1147 1147 | user: test
1148 1148 | date: Thu Jan 01 00:00:00 1970 +0000
1149 1149 | summary: start new branch
1150 1150 |
1151 1151 o changeset: 1:eca11cf91c71
1152 1152 | user: test
1153 1153 | date: Thu Jan 01 00:00:00 1970 +0000
1154 1154 | summary: commitB
1155 1155 |
1156 1156 o changeset: 0:105141ef12d0
1157 1157 user: test
1158 1158 date: Thu Jan 01 00:00:00 1970 +0000
1159 1159 summary: commitA
1160 1160
1161 1161 $ hg diff
1162 1162 diff -r f62c6c09b707 bar.txt
1163 1163 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1164 1164 +++ b/bar.txt Thu Jan 01 00:00:00 1970 +0000
1165 1165 @@ -0,0 +1,1 @@
1166 1166 +bar
1167 1167
1168 1168 Use delayedstrip to strip inside a transaction
1169 1169
1170 1170 $ cd $TESTTMP
1171 1171 $ hg init delayedstrip
1172 1172 $ cd delayedstrip
1173 1173 $ hg debugdrawdag <<'EOS'
1174 1174 > D
1175 1175 > |
1176 1176 > C F H # Commit on top of "I",
1177 1177 > | |/| # Strip B+D+I+E+G+H+Z
1178 1178 > I B E G
1179 1179 > \|/
1180 1180 > A Z
1181 1181 > EOS
1182 1182 $ cp -R . ../scmutilcleanup
1183 1183
1184 1184 $ hg up -C I
1185 1185 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1186 1186 $ echo 3 >> I
1187 1187 $ cat > $TESTTMP/delayedstrip.py <<EOF
1188 1188 > from __future__ import absolute_import
1189 1189 > from mercurial import commands, registrar, repair
1190 1190 > cmdtable = {}
1191 1191 > command = registrar.command(cmdtable)
1192 1192 > @command(b'testdelayedstrip')
1193 1193 > def testdelayedstrip(ui, repo):
1194 1194 > def getnodes(expr):
1195 1195 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1196 1196 > with repo.wlock():
1197 1197 > with repo.lock():
1198 1198 > with repo.transaction(b'delayedstrip'):
1199 1199 > repair.delayedstrip(ui, repo, getnodes(b'B+I+Z+D+E'), b'J')
1200 1200 > repair.delayedstrip(ui, repo, getnodes(b'G+H+Z'), b'I')
1201 1201 > commands.commit(ui, repo, message=b'J', date=b'0 0')
1202 1202 > EOF
1203 1203 $ hg testdelayedstrip --config extensions.t=$TESTTMP/delayedstrip.py
1204 1204 warning: orphaned descendants detected, not stripping 08ebfeb61bac, 112478962961, 7fb047a69f22
1205 1205 saved backup bundle to $TESTTMP/delayedstrip/.hg/strip-backup/f585351a92f8-17475721-I.hg
1206 1206
1207 1207 $ hg log -G -T '{rev}:{node|short} {desc}' -r 'sort(all(), topo)'
1208 1208 @ 6:2f2d51af6205 J
1209 1209 |
1210 1210 o 3:08ebfeb61bac I
1211 1211 |
1212 1212 | o 5:64a8289d2492 F
1213 1213 | |
1214 1214 | o 2:7fb047a69f22 E
1215 1215 |/
1216 1216 | o 4:26805aba1e60 C
1217 1217 | |
1218 1218 | o 1:112478962961 B
1219 1219 |/
1220 1220 o 0:426bada5c675 A
1221 1221
1222 1222 Test high-level scmutil.cleanupnodes API
1223 1223
1224 1224 $ cd $TESTTMP/scmutilcleanup
1225 1225 $ hg debugdrawdag <<'EOS'
1226 1226 > D2 F2 G2 # D2, F2, G2 are replacements for D, F, G
1227 1227 > | | |
1228 1228 > C H G
1229 1229 > EOS
1230 1230 $ for i in B C D F G I Z; do
1231 1231 > hg bookmark -i -r $i b-$i
1232 1232 > done
1233 1233 $ hg bookmark -i -r E 'b-F@divergent1'
1234 1234 $ hg bookmark -i -r H 'b-F@divergent2'
1235 1235 $ hg bookmark -i -r G 'b-F@divergent3'
1236 1236 $ cp -R . ../scmutilcleanup.obsstore
1237 1237
1238 1238 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
1239 1239 > from mercurial import registrar, scmutil
1240 1240 > cmdtable = {}
1241 1241 > command = registrar.command(cmdtable)
1242 1242 > @command(b'testnodescleanup')
1243 1243 > def testnodescleanup(ui, repo):
1244 1244 > def nodes(expr):
1245 1245 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1246 1246 > def node(expr):
1247 1247 > return nodes(expr)[0]
1248 1248 > with repo.wlock():
1249 1249 > with repo.lock():
1250 1250 > with repo.transaction(b'delayedstrip'):
1251 1251 > mapping = {node(b'F'): [node(b'F2')],
1252 1252 > node(b'D'): [node(b'D2')],
1253 1253 > node(b'G'): [node(b'G2')]}
1254 1254 > scmutil.cleanupnodes(repo, mapping, b'replace')
1255 1255 > scmutil.cleanupnodes(repo, nodes(b'((B::)+I+Z)-D2-obsolete()'),
1256 1256 > b'replace')
1257 1257 > EOF
1258 1258 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1259 1259 warning: orphaned descendants detected, not stripping 112478962961, 1fc8102cda62, 26805aba1e60
1260 1260 saved backup bundle to $TESTTMP/scmutilcleanup/.hg/strip-backup/f585351a92f8-73fb7c03-replace.hg
1261 1261
1262 1262 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1263 1263 o 8:1473d4b996d1 G2 b-F@divergent3 b-G
1264 1264 |
1265 1265 | o 7:d11b3456a873 F2 b-F
1266 1266 | |
1267 1267 | o 5:5cb05ba470a7 H
1268 1268 |/|
1269 1269 | o 3:7fb047a69f22 E b-F@divergent1
1270 1270 | |
1271 1271 | | o 6:7c78f703e465 D2 b-D
1272 1272 | | |
1273 1273 | | o 4:26805aba1e60 C
1274 1274 | | |
1275 1275 | | o 2:112478962961 B
1276 1276 | |/
1277 1277 o | 1:1fc8102cda62 G
1278 1278 /
1279 1279 o 0:426bada5c675 A b-B b-C b-I
1280 1280
1281 1281 $ hg bookmark
1282 1282 b-B 0:426bada5c675
1283 1283 b-C 0:426bada5c675
1284 1284 b-D 6:7c78f703e465
1285 1285 b-F 7:d11b3456a873
1286 1286 b-F@divergent1 3:7fb047a69f22
1287 1287 b-F@divergent3 8:1473d4b996d1
1288 1288 b-G 8:1473d4b996d1
1289 1289 b-I 0:426bada5c675
1290 1290 b-Z -1:000000000000
1291 1291
1292 1292 Test the above using obsstore "by the way". Not directly related to strip, but
1293 1293 we have reusable code here
1294 1294
1295 1295 $ cd $TESTTMP/scmutilcleanup.obsstore
1296 1296 $ cat >> .hg/hgrc <<EOF
1297 1297 > [experimental]
1298 1298 > evolution=true
1299 1299 > evolution.track-operation=1
1300 1300 > EOF
1301 1301
1302 1302 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1303 1303 4 new orphan changesets
1304 1304
1305 1305 $ rm .hg/localtags
1306 1306 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1307 1307 * 12:1473d4b996d1 G2 b-F@divergent3 b-G
1308 1308 |
1309 1309 | * 11:d11b3456a873 F2 b-F
1310 1310 | |
1311 1311 | * 8:5cb05ba470a7 H
1312 1312 |/|
1313 1313 | o 4:7fb047a69f22 E b-F@divergent1
1314 1314 | |
1315 1315 | | * 10:7c78f703e465 D2 b-D
1316 1316 | | |
1317 1317 | | x 6:26805aba1e60 C
1318 1318 | | |
1319 1319 | | x 3:112478962961 B
1320 1320 | |/
1321 1321 x | 1:1fc8102cda62 G
1322 1322 /
1323 1323 o 0:426bada5c675 A b-B b-C b-I
1324 1324
1325 1325 $ hg debugobsolete
1326 1326 1fc8102cda6204549f031015641606ccf5513ec3 1473d4b996d1d1b121de6b39fab6a04fbf9d873e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1327 1327 64a8289d249234b9886244d379f15e6b650b28e3 d11b3456a873daec7c7bc53e5622e8df6d741bd2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1328 1328 f585351a92f85104bff7c284233c338b10eb1df7 7c78f703e465d73102cc8780667ce269c5208a40 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'replace', 'user': 'test'}
1329 1329 48b9aae0607f43ff110d84e6883c151942add5ab 0 {0000000000000000000000000000000000000000} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1330 1330 112478962961147124edd43549aedd1a335e44bf 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1331 1331 08ebfeb61bac6e3f12079de774d285a0d6689eba 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1332 1332 26805aba1e600a82e93661149f2313866a221a7b 0 {112478962961147124edd43549aedd1a335e44bf} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1333 1333 $ cd ..
1334 1334
1335 1335 Test that obsmarkers are restored even when not using generaldelta
1336 1336
1337 1337 $ hg --config format.usegeneraldelta=no init issue5678
1338 1338 $ cd issue5678
1339 1339 $ cat >> .hg/hgrc <<EOF
1340 1340 > [experimental]
1341 1341 > evolution=true
1342 1342 > EOF
1343 1343 $ echo a > a
1344 1344 $ hg ci -Aqm a
1345 1345 $ hg ci --amend -m a2
1346 1346 $ hg debugobsolete
1347 1347 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1348 1348 $ hg strip .
1349 1349 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1350 1350 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/489bac576828-bef27e14-backup.hg
1351 1351 $ hg unbundle -q .hg/strip-backup/*
1352 1352 $ hg debugobsolete
1353 1353 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1354 1354 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now