##// END OF EJS Templates
export: show 'Date' header in a format that also is readable for humans...
Mads Kiilerich -
r18648:76b69ccc default
parent child Browse files
Show More
@@ -1,2017 +1,2018 b''
1 1 # cmdutil.py - help for command processing in mercurial
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 node import hex, nullid, nullrev, short
9 9 from i18n import _
10 10 import os, sys, errno, re, tempfile
11 11 import util, scmutil, templater, patch, error, templatekw, revlog, copies
12 12 import match as matchmod
13 13 import subrepo, context, repair, graphmod, revset, phases, obsolete
14 14 import changelog
15 15 import bookmarks
16 16 import lock as lockmod
17 17
18 18 def parsealiases(cmd):
19 19 return cmd.lstrip("^").split("|")
20 20
21 21 def findpossible(cmd, table, strict=False):
22 22 """
23 23 Return cmd -> (aliases, command table entry)
24 24 for each matching command.
25 25 Return debug commands (or their aliases) only if no normal command matches.
26 26 """
27 27 choice = {}
28 28 debugchoice = {}
29 29
30 30 if cmd in table:
31 31 # short-circuit exact matches, "log" alias beats "^log|history"
32 32 keys = [cmd]
33 33 else:
34 34 keys = table.keys()
35 35
36 36 for e in keys:
37 37 aliases = parsealiases(e)
38 38 found = None
39 39 if cmd in aliases:
40 40 found = cmd
41 41 elif not strict:
42 42 for a in aliases:
43 43 if a.startswith(cmd):
44 44 found = a
45 45 break
46 46 if found is not None:
47 47 if aliases[0].startswith("debug") or found.startswith("debug"):
48 48 debugchoice[found] = (aliases, table[e])
49 49 else:
50 50 choice[found] = (aliases, table[e])
51 51
52 52 if not choice and debugchoice:
53 53 choice = debugchoice
54 54
55 55 return choice
56 56
57 57 def findcmd(cmd, table, strict=True):
58 58 """Return (aliases, command table entry) for command string."""
59 59 choice = findpossible(cmd, table, strict)
60 60
61 61 if cmd in choice:
62 62 return choice[cmd]
63 63
64 64 if len(choice) > 1:
65 65 clist = choice.keys()
66 66 clist.sort()
67 67 raise error.AmbiguousCommand(cmd, clist)
68 68
69 69 if choice:
70 70 return choice.values()[0]
71 71
72 72 raise error.UnknownCommand(cmd)
73 73
74 74 def findrepo(p):
75 75 while not os.path.isdir(os.path.join(p, ".hg")):
76 76 oldp, p = p, os.path.dirname(p)
77 77 if p == oldp:
78 78 return None
79 79
80 80 return p
81 81
82 82 def bailifchanged(repo):
83 83 if repo.dirstate.p2() != nullid:
84 84 raise util.Abort(_('outstanding uncommitted merge'))
85 85 modified, added, removed, deleted = repo.status()[:4]
86 86 if modified or added or removed or deleted:
87 87 raise util.Abort(_("outstanding uncommitted changes"))
88 88 ctx = repo[None]
89 89 for s in sorted(ctx.substate):
90 90 if ctx.sub(s).dirty():
91 91 raise util.Abort(_("uncommitted changes in subrepo %s") % s)
92 92
93 93 def logmessage(ui, opts):
94 94 """ get the log message according to -m and -l option """
95 95 message = opts.get('message')
96 96 logfile = opts.get('logfile')
97 97
98 98 if message and logfile:
99 99 raise util.Abort(_('options --message and --logfile are mutually '
100 100 'exclusive'))
101 101 if not message and logfile:
102 102 try:
103 103 if logfile == '-':
104 104 message = ui.fin.read()
105 105 else:
106 106 message = '\n'.join(util.readfile(logfile).splitlines())
107 107 except IOError, inst:
108 108 raise util.Abort(_("can't read commit message '%s': %s") %
109 109 (logfile, inst.strerror))
110 110 return message
111 111
112 112 def loglimit(opts):
113 113 """get the log limit according to option -l/--limit"""
114 114 limit = opts.get('limit')
115 115 if limit:
116 116 try:
117 117 limit = int(limit)
118 118 except ValueError:
119 119 raise util.Abort(_('limit must be a positive integer'))
120 120 if limit <= 0:
121 121 raise util.Abort(_('limit must be positive'))
122 122 else:
123 123 limit = None
124 124 return limit
125 125
126 126 def makefilename(repo, pat, node, desc=None,
127 127 total=None, seqno=None, revwidth=None, pathname=None):
128 128 node_expander = {
129 129 'H': lambda: hex(node),
130 130 'R': lambda: str(repo.changelog.rev(node)),
131 131 'h': lambda: short(node),
132 132 'm': lambda: re.sub('[^\w]', '_', str(desc))
133 133 }
134 134 expander = {
135 135 '%': lambda: '%',
136 136 'b': lambda: os.path.basename(repo.root),
137 137 }
138 138
139 139 try:
140 140 if node:
141 141 expander.update(node_expander)
142 142 if node:
143 143 expander['r'] = (lambda:
144 144 str(repo.changelog.rev(node)).zfill(revwidth or 0))
145 145 if total is not None:
146 146 expander['N'] = lambda: str(total)
147 147 if seqno is not None:
148 148 expander['n'] = lambda: str(seqno)
149 149 if total is not None and seqno is not None:
150 150 expander['n'] = lambda: str(seqno).zfill(len(str(total)))
151 151 if pathname is not None:
152 152 expander['s'] = lambda: os.path.basename(pathname)
153 153 expander['d'] = lambda: os.path.dirname(pathname) or '.'
154 154 expander['p'] = lambda: pathname
155 155
156 156 newname = []
157 157 patlen = len(pat)
158 158 i = 0
159 159 while i < patlen:
160 160 c = pat[i]
161 161 if c == '%':
162 162 i += 1
163 163 c = pat[i]
164 164 c = expander[c]()
165 165 newname.append(c)
166 166 i += 1
167 167 return ''.join(newname)
168 168 except KeyError, inst:
169 169 raise util.Abort(_("invalid format spec '%%%s' in output filename") %
170 170 inst.args[0])
171 171
172 172 def makefileobj(repo, pat, node=None, desc=None, total=None,
173 173 seqno=None, revwidth=None, mode='wb', modemap={},
174 174 pathname=None):
175 175
176 176 writable = mode not in ('r', 'rb')
177 177
178 178 if not pat or pat == '-':
179 179 fp = writable and repo.ui.fout or repo.ui.fin
180 180 if util.safehasattr(fp, 'fileno'):
181 181 return os.fdopen(os.dup(fp.fileno()), mode)
182 182 else:
183 183 # if this fp can't be duped properly, return
184 184 # a dummy object that can be closed
185 185 class wrappedfileobj(object):
186 186 noop = lambda x: None
187 187 def __init__(self, f):
188 188 self.f = f
189 189 def __getattr__(self, attr):
190 190 if attr == 'close':
191 191 return self.noop
192 192 else:
193 193 return getattr(self.f, attr)
194 194
195 195 return wrappedfileobj(fp)
196 196 if util.safehasattr(pat, 'write') and writable:
197 197 return pat
198 198 if util.safehasattr(pat, 'read') and 'r' in mode:
199 199 return pat
200 200 fn = makefilename(repo, pat, node, desc, total, seqno, revwidth, pathname)
201 201 mode = modemap.get(fn, mode)
202 202 if mode == 'wb':
203 203 modemap[fn] = 'ab'
204 204 return open(fn, mode)
205 205
206 206 def openrevlog(repo, cmd, file_, opts):
207 207 """opens the changelog, manifest, a filelog or a given revlog"""
208 208 cl = opts['changelog']
209 209 mf = opts['manifest']
210 210 msg = None
211 211 if cl and mf:
212 212 msg = _('cannot specify --changelog and --manifest at the same time')
213 213 elif cl or mf:
214 214 if file_:
215 215 msg = _('cannot specify filename with --changelog or --manifest')
216 216 elif not repo:
217 217 msg = _('cannot specify --changelog or --manifest '
218 218 'without a repository')
219 219 if msg:
220 220 raise util.Abort(msg)
221 221
222 222 r = None
223 223 if repo:
224 224 if cl:
225 225 r = repo.changelog
226 226 elif mf:
227 227 r = repo.manifest
228 228 elif file_:
229 229 filelog = repo.file(file_)
230 230 if len(filelog):
231 231 r = filelog
232 232 if not r:
233 233 if not file_:
234 234 raise error.CommandError(cmd, _('invalid arguments'))
235 235 if not os.path.isfile(file_):
236 236 raise util.Abort(_("revlog '%s' not found") % file_)
237 237 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
238 238 file_[:-2] + ".i")
239 239 return r
240 240
241 241 def copy(ui, repo, pats, opts, rename=False):
242 242 # called with the repo lock held
243 243 #
244 244 # hgsep => pathname that uses "/" to separate directories
245 245 # ossep => pathname that uses os.sep to separate directories
246 246 cwd = repo.getcwd()
247 247 targets = {}
248 248 after = opts.get("after")
249 249 dryrun = opts.get("dry_run")
250 250 wctx = repo[None]
251 251
252 252 def walkpat(pat):
253 253 srcs = []
254 254 badstates = after and '?' or '?r'
255 255 m = scmutil.match(repo[None], [pat], opts, globbed=True)
256 256 for abs in repo.walk(m):
257 257 state = repo.dirstate[abs]
258 258 rel = m.rel(abs)
259 259 exact = m.exact(abs)
260 260 if state in badstates:
261 261 if exact and state == '?':
262 262 ui.warn(_('%s: not copying - file is not managed\n') % rel)
263 263 if exact and state == 'r':
264 264 ui.warn(_('%s: not copying - file has been marked for'
265 265 ' remove\n') % rel)
266 266 continue
267 267 # abs: hgsep
268 268 # rel: ossep
269 269 srcs.append((abs, rel, exact))
270 270 return srcs
271 271
272 272 # abssrc: hgsep
273 273 # relsrc: ossep
274 274 # otarget: ossep
275 275 def copyfile(abssrc, relsrc, otarget, exact):
276 276 abstarget = scmutil.canonpath(repo.root, cwd, otarget)
277 277 if '/' in abstarget:
278 278 # We cannot normalize abstarget itself, this would prevent
279 279 # case only renames, like a => A.
280 280 abspath, absname = abstarget.rsplit('/', 1)
281 281 abstarget = repo.dirstate.normalize(abspath) + '/' + absname
282 282 reltarget = repo.pathto(abstarget, cwd)
283 283 target = repo.wjoin(abstarget)
284 284 src = repo.wjoin(abssrc)
285 285 state = repo.dirstate[abstarget]
286 286
287 287 scmutil.checkportable(ui, abstarget)
288 288
289 289 # check for collisions
290 290 prevsrc = targets.get(abstarget)
291 291 if prevsrc is not None:
292 292 ui.warn(_('%s: not overwriting - %s collides with %s\n') %
293 293 (reltarget, repo.pathto(abssrc, cwd),
294 294 repo.pathto(prevsrc, cwd)))
295 295 return
296 296
297 297 # check for overwrites
298 298 exists = os.path.lexists(target)
299 299 samefile = False
300 300 if exists and abssrc != abstarget:
301 301 if (repo.dirstate.normalize(abssrc) ==
302 302 repo.dirstate.normalize(abstarget)):
303 303 if not rename:
304 304 ui.warn(_("%s: can't copy - same file\n") % reltarget)
305 305 return
306 306 exists = False
307 307 samefile = True
308 308
309 309 if not after and exists or after and state in 'mn':
310 310 if not opts['force']:
311 311 ui.warn(_('%s: not overwriting - file exists\n') %
312 312 reltarget)
313 313 return
314 314
315 315 if after:
316 316 if not exists:
317 317 if rename:
318 318 ui.warn(_('%s: not recording move - %s does not exist\n') %
319 319 (relsrc, reltarget))
320 320 else:
321 321 ui.warn(_('%s: not recording copy - %s does not exist\n') %
322 322 (relsrc, reltarget))
323 323 return
324 324 elif not dryrun:
325 325 try:
326 326 if exists:
327 327 os.unlink(target)
328 328 targetdir = os.path.dirname(target) or '.'
329 329 if not os.path.isdir(targetdir):
330 330 os.makedirs(targetdir)
331 331 if samefile:
332 332 tmp = target + "~hgrename"
333 333 os.rename(src, tmp)
334 334 os.rename(tmp, target)
335 335 else:
336 336 util.copyfile(src, target)
337 337 srcexists = True
338 338 except IOError, inst:
339 339 if inst.errno == errno.ENOENT:
340 340 ui.warn(_('%s: deleted in working copy\n') % relsrc)
341 341 srcexists = False
342 342 else:
343 343 ui.warn(_('%s: cannot copy - %s\n') %
344 344 (relsrc, inst.strerror))
345 345 return True # report a failure
346 346
347 347 if ui.verbose or not exact:
348 348 if rename:
349 349 ui.status(_('moving %s to %s\n') % (relsrc, reltarget))
350 350 else:
351 351 ui.status(_('copying %s to %s\n') % (relsrc, reltarget))
352 352
353 353 targets[abstarget] = abssrc
354 354
355 355 # fix up dirstate
356 356 scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
357 357 dryrun=dryrun, cwd=cwd)
358 358 if rename and not dryrun:
359 359 if not after and srcexists and not samefile:
360 360 util.unlinkpath(repo.wjoin(abssrc))
361 361 wctx.forget([abssrc])
362 362
363 363 # pat: ossep
364 364 # dest ossep
365 365 # srcs: list of (hgsep, hgsep, ossep, bool)
366 366 # return: function that takes hgsep and returns ossep
367 367 def targetpathfn(pat, dest, srcs):
368 368 if os.path.isdir(pat):
369 369 abspfx = scmutil.canonpath(repo.root, cwd, pat)
370 370 abspfx = util.localpath(abspfx)
371 371 if destdirexists:
372 372 striplen = len(os.path.split(abspfx)[0])
373 373 else:
374 374 striplen = len(abspfx)
375 375 if striplen:
376 376 striplen += len(os.sep)
377 377 res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
378 378 elif destdirexists:
379 379 res = lambda p: os.path.join(dest,
380 380 os.path.basename(util.localpath(p)))
381 381 else:
382 382 res = lambda p: dest
383 383 return res
384 384
385 385 # pat: ossep
386 386 # dest ossep
387 387 # srcs: list of (hgsep, hgsep, ossep, bool)
388 388 # return: function that takes hgsep and returns ossep
389 389 def targetpathafterfn(pat, dest, srcs):
390 390 if matchmod.patkind(pat):
391 391 # a mercurial pattern
392 392 res = lambda p: os.path.join(dest,
393 393 os.path.basename(util.localpath(p)))
394 394 else:
395 395 abspfx = scmutil.canonpath(repo.root, cwd, pat)
396 396 if len(abspfx) < len(srcs[0][0]):
397 397 # A directory. Either the target path contains the last
398 398 # component of the source path or it does not.
399 399 def evalpath(striplen):
400 400 score = 0
401 401 for s in srcs:
402 402 t = os.path.join(dest, util.localpath(s[0])[striplen:])
403 403 if os.path.lexists(t):
404 404 score += 1
405 405 return score
406 406
407 407 abspfx = util.localpath(abspfx)
408 408 striplen = len(abspfx)
409 409 if striplen:
410 410 striplen += len(os.sep)
411 411 if os.path.isdir(os.path.join(dest, os.path.split(abspfx)[1])):
412 412 score = evalpath(striplen)
413 413 striplen1 = len(os.path.split(abspfx)[0])
414 414 if striplen1:
415 415 striplen1 += len(os.sep)
416 416 if evalpath(striplen1) > score:
417 417 striplen = striplen1
418 418 res = lambda p: os.path.join(dest,
419 419 util.localpath(p)[striplen:])
420 420 else:
421 421 # a file
422 422 if destdirexists:
423 423 res = lambda p: os.path.join(dest,
424 424 os.path.basename(util.localpath(p)))
425 425 else:
426 426 res = lambda p: dest
427 427 return res
428 428
429 429
430 430 pats = scmutil.expandpats(pats)
431 431 if not pats:
432 432 raise util.Abort(_('no source or destination specified'))
433 433 if len(pats) == 1:
434 434 raise util.Abort(_('no destination specified'))
435 435 dest = pats.pop()
436 436 destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
437 437 if not destdirexists:
438 438 if len(pats) > 1 or matchmod.patkind(pats[0]):
439 439 raise util.Abort(_('with multiple sources, destination must be an '
440 440 'existing directory'))
441 441 if util.endswithsep(dest):
442 442 raise util.Abort(_('destination %s is not a directory') % dest)
443 443
444 444 tfn = targetpathfn
445 445 if after:
446 446 tfn = targetpathafterfn
447 447 copylist = []
448 448 for pat in pats:
449 449 srcs = walkpat(pat)
450 450 if not srcs:
451 451 continue
452 452 copylist.append((tfn(pat, dest, srcs), srcs))
453 453 if not copylist:
454 454 raise util.Abort(_('no files to copy'))
455 455
456 456 errors = 0
457 457 for targetpath, srcs in copylist:
458 458 for abssrc, relsrc, exact in srcs:
459 459 if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
460 460 errors += 1
461 461
462 462 if errors:
463 463 ui.warn(_('(consider using --after)\n'))
464 464
465 465 return errors != 0
466 466
467 467 def service(opts, parentfn=None, initfn=None, runfn=None, logfile=None,
468 468 runargs=None, appendpid=False):
469 469 '''Run a command as a service.'''
470 470
471 471 if opts['daemon'] and not opts['daemon_pipefds']:
472 472 # Signal child process startup with file removal
473 473 lockfd, lockpath = tempfile.mkstemp(prefix='hg-service-')
474 474 os.close(lockfd)
475 475 try:
476 476 if not runargs:
477 477 runargs = util.hgcmd() + sys.argv[1:]
478 478 runargs.append('--daemon-pipefds=%s' % lockpath)
479 479 # Don't pass --cwd to the child process, because we've already
480 480 # changed directory.
481 481 for i in xrange(1, len(runargs)):
482 482 if runargs[i].startswith('--cwd='):
483 483 del runargs[i]
484 484 break
485 485 elif runargs[i].startswith('--cwd'):
486 486 del runargs[i:i + 2]
487 487 break
488 488 def condfn():
489 489 return not os.path.exists(lockpath)
490 490 pid = util.rundetached(runargs, condfn)
491 491 if pid < 0:
492 492 raise util.Abort(_('child process failed to start'))
493 493 finally:
494 494 try:
495 495 os.unlink(lockpath)
496 496 except OSError, e:
497 497 if e.errno != errno.ENOENT:
498 498 raise
499 499 if parentfn:
500 500 return parentfn(pid)
501 501 else:
502 502 return
503 503
504 504 if initfn:
505 505 initfn()
506 506
507 507 if opts['pid_file']:
508 508 mode = appendpid and 'a' or 'w'
509 509 fp = open(opts['pid_file'], mode)
510 510 fp.write(str(os.getpid()) + '\n')
511 511 fp.close()
512 512
513 513 if opts['daemon_pipefds']:
514 514 lockpath = opts['daemon_pipefds']
515 515 try:
516 516 os.setsid()
517 517 except AttributeError:
518 518 pass
519 519 os.unlink(lockpath)
520 520 util.hidewindow()
521 521 sys.stdout.flush()
522 522 sys.stderr.flush()
523 523
524 524 nullfd = os.open(os.devnull, os.O_RDWR)
525 525 logfilefd = nullfd
526 526 if logfile:
527 527 logfilefd = os.open(logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND)
528 528 os.dup2(nullfd, 0)
529 529 os.dup2(logfilefd, 1)
530 530 os.dup2(logfilefd, 2)
531 531 if nullfd not in (0, 1, 2):
532 532 os.close(nullfd)
533 533 if logfile and logfilefd not in (0, 1, 2):
534 534 os.close(logfilefd)
535 535
536 536 if runfn:
537 537 return runfn()
538 538
539 539 def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False,
540 540 opts=None):
541 541 '''export changesets as hg patches.'''
542 542
543 543 total = len(revs)
544 544 revwidth = max([len(str(rev)) for rev in revs])
545 545 filemode = {}
546 546
547 547 def single(rev, seqno, fp):
548 548 ctx = repo[rev]
549 549 node = ctx.node()
550 550 parents = [p.node() for p in ctx.parents() if p]
551 551 branch = ctx.branch()
552 552 if switch_parent:
553 553 parents.reverse()
554 554 prev = (parents and parents[0]) or nullid
555 555
556 556 shouldclose = False
557 557 if not fp and len(template) > 0:
558 558 desc_lines = ctx.description().rstrip().split('\n')
559 559 desc = desc_lines[0] #Commit always has a first line.
560 560 fp = makefileobj(repo, template, node, desc=desc, total=total,
561 561 seqno=seqno, revwidth=revwidth, mode='wb',
562 562 modemap=filemode)
563 563 if fp != template:
564 564 shouldclose = True
565 565 if fp and fp != sys.stdout and util.safehasattr(fp, 'name'):
566 566 repo.ui.note("%s\n" % fp.name)
567 567
568 568 if not fp:
569 569 write = repo.ui.write
570 570 else:
571 571 def write(s, **kw):
572 572 fp.write(s)
573 573
574 574
575 575 write("# HG changeset patch\n")
576 576 write("# User %s\n" % ctx.user())
577 577 write("# Date %d %d\n" % ctx.date())
578 write("# %s\n" % util.datestr(ctx.date()))
578 579 if branch and branch != 'default':
579 580 write("# Branch %s\n" % branch)
580 581 write("# Node ID %s\n" % hex(node))
581 582 write("# Parent %s\n" % hex(prev))
582 583 if len(parents) > 1:
583 584 write("# Parent %s\n" % hex(parents[1]))
584 585 write(ctx.description().rstrip())
585 586 write("\n\n")
586 587
587 588 for chunk, label in patch.diffui(repo, prev, node, opts=opts):
588 589 write(chunk, label=label)
589 590
590 591 if shouldclose:
591 592 fp.close()
592 593
593 594 for seqno, rev in enumerate(revs):
594 595 single(rev, seqno + 1, fp)
595 596
596 597 def diffordiffstat(ui, repo, diffopts, node1, node2, match,
597 598 changes=None, stat=False, fp=None, prefix='',
598 599 listsubrepos=False):
599 600 '''show diff or diffstat.'''
600 601 if fp is None:
601 602 write = ui.write
602 603 else:
603 604 def write(s, **kw):
604 605 fp.write(s)
605 606
606 607 if stat:
607 608 diffopts = diffopts.copy(context=0)
608 609 width = 80
609 610 if not ui.plain():
610 611 width = ui.termwidth()
611 612 chunks = patch.diff(repo, node1, node2, match, changes, diffopts,
612 613 prefix=prefix)
613 614 for chunk, label in patch.diffstatui(util.iterlines(chunks),
614 615 width=width,
615 616 git=diffopts.git):
616 617 write(chunk, label=label)
617 618 else:
618 619 for chunk, label in patch.diffui(repo, node1, node2, match,
619 620 changes, diffopts, prefix=prefix):
620 621 write(chunk, label=label)
621 622
622 623 if listsubrepos:
623 624 ctx1 = repo[node1]
624 625 ctx2 = repo[node2]
625 626 for subpath, sub in subrepo.itersubrepos(ctx1, ctx2):
626 627 tempnode2 = node2
627 628 try:
628 629 if node2 is not None:
629 630 tempnode2 = ctx2.substate[subpath][1]
630 631 except KeyError:
631 632 # A subrepo that existed in node1 was deleted between node1 and
632 633 # node2 (inclusive). Thus, ctx2's substate won't contain that
633 634 # subpath. The best we can do is to ignore it.
634 635 tempnode2 = None
635 636 submatch = matchmod.narrowmatcher(subpath, match)
636 637 sub.diff(ui, diffopts, tempnode2, submatch, changes=changes,
637 638 stat=stat, fp=fp, prefix=prefix)
638 639
639 640 class changeset_printer(object):
640 641 '''show changeset information when templating not requested.'''
641 642
642 643 def __init__(self, ui, repo, patch, diffopts, buffered):
643 644 self.ui = ui
644 645 self.repo = repo
645 646 self.buffered = buffered
646 647 self.patch = patch
647 648 self.diffopts = diffopts
648 649 self.header = {}
649 650 self.hunk = {}
650 651 self.lastheader = None
651 652 self.footer = None
652 653
653 654 def flush(self, rev):
654 655 if rev in self.header:
655 656 h = self.header[rev]
656 657 if h != self.lastheader:
657 658 self.lastheader = h
658 659 self.ui.write(h)
659 660 del self.header[rev]
660 661 if rev in self.hunk:
661 662 self.ui.write(self.hunk[rev])
662 663 del self.hunk[rev]
663 664 return 1
664 665 return 0
665 666
666 667 def close(self):
667 668 if self.footer:
668 669 self.ui.write(self.footer)
669 670
670 671 def show(self, ctx, copies=None, matchfn=None, **props):
671 672 if self.buffered:
672 673 self.ui.pushbuffer()
673 674 self._show(ctx, copies, matchfn, props)
674 675 self.hunk[ctx.rev()] = self.ui.popbuffer(labeled=True)
675 676 else:
676 677 self._show(ctx, copies, matchfn, props)
677 678
678 679 def _show(self, ctx, copies, matchfn, props):
679 680 '''show a single changeset or file revision'''
680 681 changenode = ctx.node()
681 682 rev = ctx.rev()
682 683
683 684 if self.ui.quiet:
684 685 self.ui.write("%d:%s\n" % (rev, short(changenode)),
685 686 label='log.node')
686 687 return
687 688
688 689 log = self.repo.changelog
689 690 date = util.datestr(ctx.date())
690 691
691 692 hexfunc = self.ui.debugflag and hex or short
692 693
693 694 parents = [(p, hexfunc(log.node(p)))
694 695 for p in self._meaningful_parentrevs(log, rev)]
695 696
696 697 # i18n: column positioning for "hg log"
697 698 self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
698 699 label='log.changeset changeset.%s' % ctx.phasestr())
699 700
700 701 branch = ctx.branch()
701 702 # don't show the default branch name
702 703 if branch != 'default':
703 704 # i18n: column positioning for "hg log"
704 705 self.ui.write(_("branch: %s\n") % branch,
705 706 label='log.branch')
706 707 for bookmark in self.repo.nodebookmarks(changenode):
707 708 # i18n: column positioning for "hg log"
708 709 self.ui.write(_("bookmark: %s\n") % bookmark,
709 710 label='log.bookmark')
710 711 for tag in self.repo.nodetags(changenode):
711 712 # i18n: column positioning for "hg log"
712 713 self.ui.write(_("tag: %s\n") % tag,
713 714 label='log.tag')
714 715 if self.ui.debugflag and ctx.phase():
715 716 # i18n: column positioning for "hg log"
716 717 self.ui.write(_("phase: %s\n") % _(ctx.phasestr()),
717 718 label='log.phase')
718 719 for parent in parents:
719 720 # i18n: column positioning for "hg log"
720 721 self.ui.write(_("parent: %d:%s\n") % parent,
721 722 label='log.parent changeset.%s' % ctx.phasestr())
722 723
723 724 if self.ui.debugflag:
724 725 mnode = ctx.manifestnode()
725 726 # i18n: column positioning for "hg log"
726 727 self.ui.write(_("manifest: %d:%s\n") %
727 728 (self.repo.manifest.rev(mnode), hex(mnode)),
728 729 label='ui.debug log.manifest')
729 730 # i18n: column positioning for "hg log"
730 731 self.ui.write(_("user: %s\n") % ctx.user(),
731 732 label='log.user')
732 733 # i18n: column positioning for "hg log"
733 734 self.ui.write(_("date: %s\n") % date,
734 735 label='log.date')
735 736
736 737 if self.ui.debugflag:
737 738 files = self.repo.status(log.parents(changenode)[0], changenode)[:3]
738 739 for key, value in zip([# i18n: column positioning for "hg log"
739 740 _("files:"),
740 741 # i18n: column positioning for "hg log"
741 742 _("files+:"),
742 743 # i18n: column positioning for "hg log"
743 744 _("files-:")], files):
744 745 if value:
745 746 self.ui.write("%-12s %s\n" % (key, " ".join(value)),
746 747 label='ui.debug log.files')
747 748 elif ctx.files() and self.ui.verbose:
748 749 # i18n: column positioning for "hg log"
749 750 self.ui.write(_("files: %s\n") % " ".join(ctx.files()),
750 751 label='ui.note log.files')
751 752 if copies and self.ui.verbose:
752 753 copies = ['%s (%s)' % c for c in copies]
753 754 # i18n: column positioning for "hg log"
754 755 self.ui.write(_("copies: %s\n") % ' '.join(copies),
755 756 label='ui.note log.copies')
756 757
757 758 extra = ctx.extra()
758 759 if extra and self.ui.debugflag:
759 760 for key, value in sorted(extra.items()):
760 761 # i18n: column positioning for "hg log"
761 762 self.ui.write(_("extra: %s=%s\n")
762 763 % (key, value.encode('string_escape')),
763 764 label='ui.debug log.extra')
764 765
765 766 description = ctx.description().strip()
766 767 if description:
767 768 if self.ui.verbose:
768 769 self.ui.write(_("description:\n"),
769 770 label='ui.note log.description')
770 771 self.ui.write(description,
771 772 label='ui.note log.description')
772 773 self.ui.write("\n\n")
773 774 else:
774 775 # i18n: column positioning for "hg log"
775 776 self.ui.write(_("summary: %s\n") %
776 777 description.splitlines()[0],
777 778 label='log.summary')
778 779 self.ui.write("\n")
779 780
780 781 self.showpatch(changenode, matchfn)
781 782
782 783 def showpatch(self, node, matchfn):
783 784 if not matchfn:
784 785 matchfn = self.patch
785 786 if matchfn:
786 787 stat = self.diffopts.get('stat')
787 788 diff = self.diffopts.get('patch')
788 789 diffopts = patch.diffopts(self.ui, self.diffopts)
789 790 prev = self.repo.changelog.parents(node)[0]
790 791 if stat:
791 792 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
792 793 match=matchfn, stat=True)
793 794 if diff:
794 795 if stat:
795 796 self.ui.write("\n")
796 797 diffordiffstat(self.ui, self.repo, diffopts, prev, node,
797 798 match=matchfn, stat=False)
798 799 self.ui.write("\n")
799 800
800 801 def _meaningful_parentrevs(self, log, rev):
801 802 """Return list of meaningful (or all if debug) parentrevs for rev.
802 803
803 804 For merges (two non-nullrev revisions) both parents are meaningful.
804 805 Otherwise the first parent revision is considered meaningful if it
805 806 is not the preceding revision.
806 807 """
807 808 parents = log.parentrevs(rev)
808 809 if not self.ui.debugflag and parents[1] == nullrev:
809 810 if parents[0] >= rev - 1:
810 811 parents = []
811 812 else:
812 813 parents = [parents[0]]
813 814 return parents
814 815
815 816
816 817 class changeset_templater(changeset_printer):
817 818 '''format changeset information.'''
818 819
819 820 def __init__(self, ui, repo, patch, diffopts, mapfile, buffered):
820 821 changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
821 822 formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
822 823 defaulttempl = {
823 824 'parent': '{rev}:{node|formatnode} ',
824 825 'manifest': '{rev}:{node|formatnode}',
825 826 'file_copy': '{name} ({source})',
826 827 'extra': '{key}={value|stringescape}'
827 828 }
828 829 # filecopy is preserved for compatibility reasons
829 830 defaulttempl['filecopy'] = defaulttempl['file_copy']
830 831 self.t = templater.templater(mapfile, {'formatnode': formatnode},
831 832 cache=defaulttempl)
832 833 self.cache = {}
833 834
834 835 def use_template(self, t):
835 836 '''set template string to use'''
836 837 self.t.cache['changeset'] = t
837 838
838 839 def _meaningful_parentrevs(self, ctx):
839 840 """Return list of meaningful (or all if debug) parentrevs for rev.
840 841 """
841 842 parents = ctx.parents()
842 843 if len(parents) > 1:
843 844 return parents
844 845 if self.ui.debugflag:
845 846 return [parents[0], self.repo['null']]
846 847 if parents[0].rev() >= ctx.rev() - 1:
847 848 return []
848 849 return parents
849 850
850 851 def _show(self, ctx, copies, matchfn, props):
851 852 '''show a single changeset or file revision'''
852 853
853 854 showlist = templatekw.showlist
854 855
855 856 # showparents() behaviour depends on ui trace level which
856 857 # causes unexpected behaviours at templating level and makes
857 858 # it harder to extract it in a standalone function. Its
858 859 # behaviour cannot be changed so leave it here for now.
859 860 def showparents(**args):
860 861 ctx = args['ctx']
861 862 parents = [[('rev', p.rev()), ('node', p.hex())]
862 863 for p in self._meaningful_parentrevs(ctx)]
863 864 return showlist('parent', parents, **args)
864 865
865 866 props = props.copy()
866 867 props.update(templatekw.keywords)
867 868 props['parents'] = showparents
868 869 props['templ'] = self.t
869 870 props['ctx'] = ctx
870 871 props['repo'] = self.repo
871 872 props['revcache'] = {'copies': copies}
872 873 props['cache'] = self.cache
873 874
874 875 # find correct templates for current mode
875 876
876 877 tmplmodes = [
877 878 (True, None),
878 879 (self.ui.verbose, 'verbose'),
879 880 (self.ui.quiet, 'quiet'),
880 881 (self.ui.debugflag, 'debug'),
881 882 ]
882 883
883 884 types = {'header': '', 'footer':'', 'changeset': 'changeset'}
884 885 for mode, postfix in tmplmodes:
885 886 for type in types:
886 887 cur = postfix and ('%s_%s' % (type, postfix)) or type
887 888 if mode and cur in self.t:
888 889 types[type] = cur
889 890
890 891 try:
891 892
892 893 # write header
893 894 if types['header']:
894 895 h = templater.stringify(self.t(types['header'], **props))
895 896 if self.buffered:
896 897 self.header[ctx.rev()] = h
897 898 else:
898 899 if self.lastheader != h:
899 900 self.lastheader = h
900 901 self.ui.write(h)
901 902
902 903 # write changeset metadata, then patch if requested
903 904 key = types['changeset']
904 905 self.ui.write(templater.stringify(self.t(key, **props)))
905 906 self.showpatch(ctx.node(), matchfn)
906 907
907 908 if types['footer']:
908 909 if not self.footer:
909 910 self.footer = templater.stringify(self.t(types['footer'],
910 911 **props))
911 912
912 913 except KeyError, inst:
913 914 msg = _("%s: no key named '%s'")
914 915 raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
915 916 except SyntaxError, inst:
916 917 raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
917 918
918 919 def show_changeset(ui, repo, opts, buffered=False):
919 920 """show one changeset using template or regular display.
920 921
921 922 Display format will be the first non-empty hit of:
922 923 1. option 'template'
923 924 2. option 'style'
924 925 3. [ui] setting 'logtemplate'
925 926 4. [ui] setting 'style'
926 927 If all of these values are either the unset or the empty string,
927 928 regular display via changeset_printer() is done.
928 929 """
929 930 # options
930 931 patch = False
931 932 if opts.get('patch') or opts.get('stat'):
932 933 patch = scmutil.matchall(repo)
933 934
934 935 tmpl = opts.get('template')
935 936 style = None
936 937 if tmpl:
937 938 tmpl = templater.parsestring(tmpl, quoted=False)
938 939 else:
939 940 style = opts.get('style')
940 941
941 942 # ui settings
942 943 if not (tmpl or style):
943 944 tmpl = ui.config('ui', 'logtemplate')
944 945 if tmpl:
945 946 try:
946 947 tmpl = templater.parsestring(tmpl)
947 948 except SyntaxError:
948 949 tmpl = templater.parsestring(tmpl, quoted=False)
949 950 else:
950 951 style = util.expandpath(ui.config('ui', 'style', ''))
951 952
952 953 if not (tmpl or style):
953 954 return changeset_printer(ui, repo, patch, opts, buffered)
954 955
955 956 mapfile = None
956 957 if style and not tmpl:
957 958 mapfile = style
958 959 if not os.path.split(mapfile)[0]:
959 960 mapname = (templater.templatepath('map-cmdline.' + mapfile)
960 961 or templater.templatepath(mapfile))
961 962 if mapname:
962 963 mapfile = mapname
963 964
964 965 try:
965 966 t = changeset_templater(ui, repo, patch, opts, mapfile, buffered)
966 967 except SyntaxError, inst:
967 968 raise util.Abort(inst.args[0])
968 969 if tmpl:
969 970 t.use_template(tmpl)
970 971 return t
971 972
972 973 def finddate(ui, repo, date):
973 974 """Find the tipmost changeset that matches the given date spec"""
974 975
975 976 df = util.matchdate(date)
976 977 m = scmutil.matchall(repo)
977 978 results = {}
978 979
979 980 def prep(ctx, fns):
980 981 d = ctx.date()
981 982 if df(d[0]):
982 983 results[ctx.rev()] = d
983 984
984 985 for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
985 986 rev = ctx.rev()
986 987 if rev in results:
987 988 ui.status(_("found revision %s from %s\n") %
988 989 (rev, util.datestr(results[rev])))
989 990 return str(rev)
990 991
991 992 raise util.Abort(_("revision matching date not found"))
992 993
993 994 def increasingwindows(start, end, windowsize=8, sizelimit=512):
994 995 if start < end:
995 996 while start < end:
996 997 yield start, min(windowsize, end - start)
997 998 start += windowsize
998 999 if windowsize < sizelimit:
999 1000 windowsize *= 2
1000 1001 else:
1001 1002 while start > end:
1002 1003 yield start, min(windowsize, start - end - 1)
1003 1004 start -= windowsize
1004 1005 if windowsize < sizelimit:
1005 1006 windowsize *= 2
1006 1007
1007 1008 def walkchangerevs(repo, match, opts, prepare):
1008 1009 '''Iterate over files and the revs in which they changed.
1009 1010
1010 1011 Callers most commonly need to iterate backwards over the history
1011 1012 in which they are interested. Doing so has awful (quadratic-looking)
1012 1013 performance, so we use iterators in a "windowed" way.
1013 1014
1014 1015 We walk a window of revisions in the desired order. Within the
1015 1016 window, we first walk forwards to gather data, then in the desired
1016 1017 order (usually backwards) to display it.
1017 1018
1018 1019 This function returns an iterator yielding contexts. Before
1019 1020 yielding each context, the iterator will first call the prepare
1020 1021 function on each context in the window in forward order.'''
1021 1022
1022 1023 follow = opts.get('follow') or opts.get('follow_first')
1023 1024
1024 1025 if not len(repo):
1025 1026 return []
1026 1027 if opts.get('rev'):
1027 1028 revs = scmutil.revrange(repo, opts.get('rev'))
1028 1029 elif follow:
1029 1030 revs = repo.revs('reverse(:.)')
1030 1031 else:
1031 1032 revs = list(repo)
1032 1033 revs.reverse()
1033 1034 if not revs:
1034 1035 return []
1035 1036 wanted = set()
1036 1037 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1037 1038 fncache = {}
1038 1039 change = repo.changectx
1039 1040
1040 1041 # First step is to fill wanted, the set of revisions that we want to yield.
1041 1042 # When it does not induce extra cost, we also fill fncache for revisions in
1042 1043 # wanted: a cache of filenames that were changed (ctx.files()) and that
1043 1044 # match the file filtering conditions.
1044 1045
1045 1046 if not slowpath and not match.files():
1046 1047 # No files, no patterns. Display all revs.
1047 1048 wanted = set(revs)
1048 1049 copies = []
1049 1050
1050 1051 if not slowpath and match.files():
1051 1052 # We only have to read through the filelog to find wanted revisions
1052 1053
1053 1054 minrev, maxrev = min(revs), max(revs)
1054 1055 def filerevgen(filelog, last):
1055 1056 """
1056 1057 Only files, no patterns. Check the history of each file.
1057 1058
1058 1059 Examines filelog entries within minrev, maxrev linkrev range
1059 1060 Returns an iterator yielding (linkrev, parentlinkrevs, copied)
1060 1061 tuples in backwards order
1061 1062 """
1062 1063 cl_count = len(repo)
1063 1064 revs = []
1064 1065 for j in xrange(0, last + 1):
1065 1066 linkrev = filelog.linkrev(j)
1066 1067 if linkrev < minrev:
1067 1068 continue
1068 1069 # only yield rev for which we have the changelog, it can
1069 1070 # happen while doing "hg log" during a pull or commit
1070 1071 if linkrev >= cl_count:
1071 1072 break
1072 1073
1073 1074 parentlinkrevs = []
1074 1075 for p in filelog.parentrevs(j):
1075 1076 if p != nullrev:
1076 1077 parentlinkrevs.append(filelog.linkrev(p))
1077 1078 n = filelog.node(j)
1078 1079 revs.append((linkrev, parentlinkrevs,
1079 1080 follow and filelog.renamed(n)))
1080 1081
1081 1082 return reversed(revs)
1082 1083 def iterfiles():
1083 1084 pctx = repo['.']
1084 1085 for filename in match.files():
1085 1086 if follow:
1086 1087 if filename not in pctx:
1087 1088 raise util.Abort(_('cannot follow file not in parent '
1088 1089 'revision: "%s"') % filename)
1089 1090 yield filename, pctx[filename].filenode()
1090 1091 else:
1091 1092 yield filename, None
1092 1093 for filename_node in copies:
1093 1094 yield filename_node
1094 1095 for file_, node in iterfiles():
1095 1096 filelog = repo.file(file_)
1096 1097 if not len(filelog):
1097 1098 if node is None:
1098 1099 # A zero count may be a directory or deleted file, so
1099 1100 # try to find matching entries on the slow path.
1100 1101 if follow:
1101 1102 raise util.Abort(
1102 1103 _('cannot follow nonexistent file: "%s"') % file_)
1103 1104 slowpath = True
1104 1105 break
1105 1106 else:
1106 1107 continue
1107 1108
1108 1109 if node is None:
1109 1110 last = len(filelog) - 1
1110 1111 else:
1111 1112 last = filelog.rev(node)
1112 1113
1113 1114
1114 1115 # keep track of all ancestors of the file
1115 1116 ancestors = set([filelog.linkrev(last)])
1116 1117
1117 1118 # iterate from latest to oldest revision
1118 1119 for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
1119 1120 if not follow:
1120 1121 if rev > maxrev:
1121 1122 continue
1122 1123 else:
1123 1124 # Note that last might not be the first interesting
1124 1125 # rev to us:
1125 1126 # if the file has been changed after maxrev, we'll
1126 1127 # have linkrev(last) > maxrev, and we still need
1127 1128 # to explore the file graph
1128 1129 if rev not in ancestors:
1129 1130 continue
1130 1131 # XXX insert 1327 fix here
1131 1132 if flparentlinkrevs:
1132 1133 ancestors.update(flparentlinkrevs)
1133 1134
1134 1135 fncache.setdefault(rev, []).append(file_)
1135 1136 wanted.add(rev)
1136 1137 if copied:
1137 1138 copies.append(copied)
1138 1139
1139 1140 # We decided to fall back to the slowpath because at least one
1140 1141 # of the paths was not a file. Check to see if at least one of them
1141 1142 # existed in history, otherwise simply return
1142 1143 if slowpath:
1143 1144 for path in match.files():
1144 1145 if path == '.' or path in repo.store:
1145 1146 break
1146 1147 else:
1147 1148 return []
1148 1149
1149 1150 if slowpath:
1150 1151 # We have to read the changelog to match filenames against
1151 1152 # changed files
1152 1153
1153 1154 if follow:
1154 1155 raise util.Abort(_('can only follow copies/renames for explicit '
1155 1156 'filenames'))
1156 1157
1157 1158 # The slow path checks files modified in every changeset.
1158 1159 for i in sorted(revs):
1159 1160 ctx = change(i)
1160 1161 matches = filter(match, ctx.files())
1161 1162 if matches:
1162 1163 fncache[i] = matches
1163 1164 wanted.add(i)
1164 1165
1165 1166 class followfilter(object):
1166 1167 def __init__(self, onlyfirst=False):
1167 1168 self.startrev = nullrev
1168 1169 self.roots = set()
1169 1170 self.onlyfirst = onlyfirst
1170 1171
1171 1172 def match(self, rev):
1172 1173 def realparents(rev):
1173 1174 if self.onlyfirst:
1174 1175 return repo.changelog.parentrevs(rev)[0:1]
1175 1176 else:
1176 1177 return filter(lambda x: x != nullrev,
1177 1178 repo.changelog.parentrevs(rev))
1178 1179
1179 1180 if self.startrev == nullrev:
1180 1181 self.startrev = rev
1181 1182 return True
1182 1183
1183 1184 if rev > self.startrev:
1184 1185 # forward: all descendants
1185 1186 if not self.roots:
1186 1187 self.roots.add(self.startrev)
1187 1188 for parent in realparents(rev):
1188 1189 if parent in self.roots:
1189 1190 self.roots.add(rev)
1190 1191 return True
1191 1192 else:
1192 1193 # backwards: all parents
1193 1194 if not self.roots:
1194 1195 self.roots.update(realparents(self.startrev))
1195 1196 if rev in self.roots:
1196 1197 self.roots.remove(rev)
1197 1198 self.roots.update(realparents(rev))
1198 1199 return True
1199 1200
1200 1201 return False
1201 1202
1202 1203 # it might be worthwhile to do this in the iterator if the rev range
1203 1204 # is descending and the prune args are all within that range
1204 1205 for rev in opts.get('prune', ()):
1205 1206 rev = repo[rev].rev()
1206 1207 ff = followfilter()
1207 1208 stop = min(revs[0], revs[-1])
1208 1209 for x in xrange(rev, stop - 1, -1):
1209 1210 if ff.match(x):
1210 1211 wanted.discard(x)
1211 1212
1212 1213 # Now that wanted is correctly initialized, we can iterate over the
1213 1214 # revision range, yielding only revisions in wanted.
1214 1215 def iterate():
1215 1216 if follow and not match.files():
1216 1217 ff = followfilter(onlyfirst=opts.get('follow_first'))
1217 1218 def want(rev):
1218 1219 return ff.match(rev) and rev in wanted
1219 1220 else:
1220 1221 def want(rev):
1221 1222 return rev in wanted
1222 1223
1223 1224 for i, window in increasingwindows(0, len(revs)):
1224 1225 nrevs = [rev for rev in revs[i:i + window] if want(rev)]
1225 1226 for rev in sorted(nrevs):
1226 1227 fns = fncache.get(rev)
1227 1228 ctx = change(rev)
1228 1229 if not fns:
1229 1230 def fns_generator():
1230 1231 for f in ctx.files():
1231 1232 if match(f):
1232 1233 yield f
1233 1234 fns = fns_generator()
1234 1235 prepare(ctx, fns)
1235 1236 for rev in nrevs:
1236 1237 yield change(rev)
1237 1238 return iterate()
1238 1239
1239 1240 def _makegraphfilematcher(repo, pats, followfirst):
1240 1241 # When displaying a revision with --patch --follow FILE, we have
1241 1242 # to know which file of the revision must be diffed. With
1242 1243 # --follow, we want the names of the ancestors of FILE in the
1243 1244 # revision, stored in "fcache". "fcache" is populated by
1244 1245 # reproducing the graph traversal already done by --follow revset
1245 1246 # and relating linkrevs to file names (which is not "correct" but
1246 1247 # good enough).
1247 1248 fcache = {}
1248 1249 fcacheready = [False]
1249 1250 pctx = repo['.']
1250 1251 wctx = repo[None]
1251 1252
1252 1253 def populate():
1253 1254 for fn in pats:
1254 1255 for i in ((pctx[fn],), pctx[fn].ancestors(followfirst=followfirst)):
1255 1256 for c in i:
1256 1257 fcache.setdefault(c.linkrev(), set()).add(c.path())
1257 1258
1258 1259 def filematcher(rev):
1259 1260 if not fcacheready[0]:
1260 1261 # Lazy initialization
1261 1262 fcacheready[0] = True
1262 1263 populate()
1263 1264 return scmutil.match(wctx, fcache.get(rev, []), default='path')
1264 1265
1265 1266 return filematcher
1266 1267
1267 1268 def _makegraphlogrevset(repo, pats, opts, revs):
1268 1269 """Return (expr, filematcher) where expr is a revset string built
1269 1270 from log options and file patterns or None. If --stat or --patch
1270 1271 are not passed filematcher is None. Otherwise it is a callable
1271 1272 taking a revision number and returning a match objects filtering
1272 1273 the files to be detailed when displaying the revision.
1273 1274 """
1274 1275 opt2revset = {
1275 1276 'no_merges': ('not merge()', None),
1276 1277 'only_merges': ('merge()', None),
1277 1278 '_ancestors': ('ancestors(%(val)s)', None),
1278 1279 '_fancestors': ('_firstancestors(%(val)s)', None),
1279 1280 '_descendants': ('descendants(%(val)s)', None),
1280 1281 '_fdescendants': ('_firstdescendants(%(val)s)', None),
1281 1282 '_matchfiles': ('_matchfiles(%(val)s)', None),
1282 1283 'date': ('date(%(val)r)', None),
1283 1284 'branch': ('branch(%(val)r)', ' or '),
1284 1285 '_patslog': ('filelog(%(val)r)', ' or '),
1285 1286 '_patsfollow': ('follow(%(val)r)', ' or '),
1286 1287 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
1287 1288 'keyword': ('keyword(%(val)r)', ' or '),
1288 1289 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
1289 1290 'user': ('user(%(val)r)', ' or '),
1290 1291 }
1291 1292
1292 1293 opts = dict(opts)
1293 1294 # follow or not follow?
1294 1295 follow = opts.get('follow') or opts.get('follow_first')
1295 1296 followfirst = opts.get('follow_first') and 1 or 0
1296 1297 # --follow with FILE behaviour depends on revs...
1297 1298 startrev = revs[0]
1298 1299 followdescendants = (len(revs) > 1 and revs[0] < revs[1]) and 1 or 0
1299 1300
1300 1301 # branch and only_branch are really aliases and must be handled at
1301 1302 # the same time
1302 1303 opts['branch'] = opts.get('branch', []) + opts.get('only_branch', [])
1303 1304 opts['branch'] = [repo.lookupbranch(b) for b in opts['branch']]
1304 1305 # pats/include/exclude are passed to match.match() directly in
1305 1306 # _matchfiles() revset but walkchangerevs() builds its matcher with
1306 1307 # scmutil.match(). The difference is input pats are globbed on
1307 1308 # platforms without shell expansion (windows).
1308 1309 pctx = repo[None]
1309 1310 match, pats = scmutil.matchandpats(pctx, pats, opts)
1310 1311 slowpath = match.anypats() or (match.files() and opts.get('removed'))
1311 1312 if not slowpath:
1312 1313 for f in match.files():
1313 1314 if follow and f not in pctx:
1314 1315 raise util.Abort(_('cannot follow file not in parent '
1315 1316 'revision: "%s"') % f)
1316 1317 filelog = repo.file(f)
1317 1318 if not len(filelog):
1318 1319 # A zero count may be a directory or deleted file, so
1319 1320 # try to find matching entries on the slow path.
1320 1321 if follow:
1321 1322 raise util.Abort(
1322 1323 _('cannot follow nonexistent file: "%s"') % f)
1323 1324 slowpath = True
1324 1325
1325 1326 # We decided to fall back to the slowpath because at least one
1326 1327 # of the paths was not a file. Check to see if at least one of them
1327 1328 # existed in history - in that case, we'll continue down the
1328 1329 # slowpath; otherwise, we can turn off the slowpath
1329 1330 if slowpath:
1330 1331 for path in match.files():
1331 1332 if path == '.' or path in repo.store:
1332 1333 break
1333 1334 else:
1334 1335 slowpath = False
1335 1336
1336 1337 if slowpath:
1337 1338 # See walkchangerevs() slow path.
1338 1339 #
1339 1340 if follow:
1340 1341 raise util.Abort(_('can only follow copies/renames for explicit '
1341 1342 'filenames'))
1342 1343 # pats/include/exclude cannot be represented as separate
1343 1344 # revset expressions as their filtering logic applies at file
1344 1345 # level. For instance "-I a -X a" matches a revision touching
1345 1346 # "a" and "b" while "file(a) and not file(b)" does
1346 1347 # not. Besides, filesets are evaluated against the working
1347 1348 # directory.
1348 1349 matchargs = ['r:', 'd:relpath']
1349 1350 for p in pats:
1350 1351 matchargs.append('p:' + p)
1351 1352 for p in opts.get('include', []):
1352 1353 matchargs.append('i:' + p)
1353 1354 for p in opts.get('exclude', []):
1354 1355 matchargs.append('x:' + p)
1355 1356 matchargs = ','.join(('%r' % p) for p in matchargs)
1356 1357 opts['_matchfiles'] = matchargs
1357 1358 else:
1358 1359 if follow:
1359 1360 fpats = ('_patsfollow', '_patsfollowfirst')
1360 1361 fnopats = (('_ancestors', '_fancestors'),
1361 1362 ('_descendants', '_fdescendants'))
1362 1363 if pats:
1363 1364 # follow() revset interprets its file argument as a
1364 1365 # manifest entry, so use match.files(), not pats.
1365 1366 opts[fpats[followfirst]] = list(match.files())
1366 1367 else:
1367 1368 opts[fnopats[followdescendants][followfirst]] = str(startrev)
1368 1369 else:
1369 1370 opts['_patslog'] = list(pats)
1370 1371
1371 1372 filematcher = None
1372 1373 if opts.get('patch') or opts.get('stat'):
1373 1374 if follow:
1374 1375 filematcher = _makegraphfilematcher(repo, pats, followfirst)
1375 1376 else:
1376 1377 filematcher = lambda rev: match
1377 1378
1378 1379 expr = []
1379 1380 for op, val in opts.iteritems():
1380 1381 if not val:
1381 1382 continue
1382 1383 if op not in opt2revset:
1383 1384 continue
1384 1385 revop, andor = opt2revset[op]
1385 1386 if '%(val)' not in revop:
1386 1387 expr.append(revop)
1387 1388 else:
1388 1389 if not isinstance(val, list):
1389 1390 e = revop % {'val': val}
1390 1391 else:
1391 1392 e = '(' + andor.join((revop % {'val': v}) for v in val) + ')'
1392 1393 expr.append(e)
1393 1394
1394 1395 if expr:
1395 1396 expr = '(' + ' and '.join(expr) + ')'
1396 1397 else:
1397 1398 expr = None
1398 1399 return expr, filematcher
1399 1400
1400 1401 def getgraphlogrevs(repo, pats, opts):
1401 1402 """Return (revs, expr, filematcher) where revs is an iterable of
1402 1403 revision numbers, expr is a revset string built from log options
1403 1404 and file patterns or None, and used to filter 'revs'. If --stat or
1404 1405 --patch are not passed filematcher is None. Otherwise it is a
1405 1406 callable taking a revision number and returning a match objects
1406 1407 filtering the files to be detailed when displaying the revision.
1407 1408 """
1408 1409 if not len(repo):
1409 1410 return [], None, None
1410 1411 limit = loglimit(opts)
1411 1412 # Default --rev value depends on --follow but --follow behaviour
1412 1413 # depends on revisions resolved from --rev...
1413 1414 follow = opts.get('follow') or opts.get('follow_first')
1414 1415 possiblyunsorted = False # whether revs might need sorting
1415 1416 if opts.get('rev'):
1416 1417 revs = scmutil.revrange(repo, opts['rev'])
1417 1418 # Don't sort here because _makegraphlogrevset might depend on the
1418 1419 # order of revs
1419 1420 possiblyunsorted = True
1420 1421 else:
1421 1422 if follow and len(repo) > 0:
1422 1423 revs = repo.revs('reverse(:.)')
1423 1424 else:
1424 1425 revs = list(repo.changelog)
1425 1426 revs.reverse()
1426 1427 if not revs:
1427 1428 return [], None, None
1428 1429 expr, filematcher = _makegraphlogrevset(repo, pats, opts, revs)
1429 1430 if possiblyunsorted:
1430 1431 revs.sort(reverse=True)
1431 1432 if expr:
1432 1433 # Revset matchers often operate faster on revisions in changelog
1433 1434 # order, because most filters deal with the changelog.
1434 1435 revs.reverse()
1435 1436 matcher = revset.match(repo.ui, expr)
1436 1437 # Revset matches can reorder revisions. "A or B" typically returns
1437 1438 # returns the revision matching A then the revision matching B. Sort
1438 1439 # again to fix that.
1439 1440 revs = matcher(repo, revs)
1440 1441 revs.sort(reverse=True)
1441 1442 if limit is not None:
1442 1443 revs = revs[:limit]
1443 1444
1444 1445 return revs, expr, filematcher
1445 1446
1446 1447 def displaygraph(ui, dag, displayer, showparents, edgefn, getrenamed=None,
1447 1448 filematcher=None):
1448 1449 seen, state = [], graphmod.asciistate()
1449 1450 for rev, type, ctx, parents in dag:
1450 1451 char = 'o'
1451 1452 if ctx.node() in showparents:
1452 1453 char = '@'
1453 1454 elif ctx.obsolete():
1454 1455 char = 'x'
1455 1456 copies = None
1456 1457 if getrenamed and ctx.rev():
1457 1458 copies = []
1458 1459 for fn in ctx.files():
1459 1460 rename = getrenamed(fn, ctx.rev())
1460 1461 if rename:
1461 1462 copies.append((fn, rename[0]))
1462 1463 revmatchfn = None
1463 1464 if filematcher is not None:
1464 1465 revmatchfn = filematcher(ctx.rev())
1465 1466 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
1466 1467 lines = displayer.hunk.pop(rev).split('\n')
1467 1468 if not lines[-1]:
1468 1469 del lines[-1]
1469 1470 displayer.flush(rev)
1470 1471 edges = edgefn(type, char, lines, seen, rev, parents)
1471 1472 for type, char, lines, coldata in edges:
1472 1473 graphmod.ascii(ui, state, type, char, lines, coldata)
1473 1474 displayer.close()
1474 1475
1475 1476 def graphlog(ui, repo, *pats, **opts):
1476 1477 # Parameters are identical to log command ones
1477 1478 revs, expr, filematcher = getgraphlogrevs(repo, pats, opts)
1478 1479 revdag = graphmod.dagwalker(repo, revs)
1479 1480
1480 1481 getrenamed = None
1481 1482 if opts.get('copies'):
1482 1483 endrev = None
1483 1484 if opts.get('rev'):
1484 1485 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
1485 1486 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
1486 1487 displayer = show_changeset(ui, repo, opts, buffered=True)
1487 1488 showparents = [ctx.node() for ctx in repo[None].parents()]
1488 1489 displaygraph(ui, revdag, displayer, showparents,
1489 1490 graphmod.asciiedges, getrenamed, filematcher)
1490 1491
1491 1492 def checkunsupportedgraphflags(pats, opts):
1492 1493 for op in ["newest_first"]:
1493 1494 if op in opts and opts[op]:
1494 1495 raise util.Abort(_("-G/--graph option is incompatible with --%s")
1495 1496 % op.replace("_", "-"))
1496 1497
1497 1498 def graphrevs(repo, nodes, opts):
1498 1499 limit = loglimit(opts)
1499 1500 nodes.reverse()
1500 1501 if limit is not None:
1501 1502 nodes = nodes[:limit]
1502 1503 return graphmod.nodes(repo, nodes)
1503 1504
1504 1505 def add(ui, repo, match, dryrun, listsubrepos, prefix, explicitonly):
1505 1506 join = lambda f: os.path.join(prefix, f)
1506 1507 bad = []
1507 1508 oldbad = match.bad
1508 1509 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1509 1510 names = []
1510 1511 wctx = repo[None]
1511 1512 cca = None
1512 1513 abort, warn = scmutil.checkportabilityalert(ui)
1513 1514 if abort or warn:
1514 1515 cca = scmutil.casecollisionauditor(ui, abort, repo.dirstate)
1515 1516 for f in repo.walk(match):
1516 1517 exact = match.exact(f)
1517 1518 if exact or not explicitonly and f not in repo.dirstate:
1518 1519 if cca:
1519 1520 cca(f)
1520 1521 names.append(f)
1521 1522 if ui.verbose or not exact:
1522 1523 ui.status(_('adding %s\n') % match.rel(join(f)))
1523 1524
1524 1525 for subpath in sorted(wctx.substate):
1525 1526 sub = wctx.sub(subpath)
1526 1527 try:
1527 1528 submatch = matchmod.narrowmatcher(subpath, match)
1528 1529 if listsubrepos:
1529 1530 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1530 1531 False))
1531 1532 else:
1532 1533 bad.extend(sub.add(ui, submatch, dryrun, listsubrepos, prefix,
1533 1534 True))
1534 1535 except error.LookupError:
1535 1536 ui.status(_("skipping missing subrepository: %s\n")
1536 1537 % join(subpath))
1537 1538
1538 1539 if not dryrun:
1539 1540 rejected = wctx.add(names, prefix)
1540 1541 bad.extend(f for f in rejected if f in match.files())
1541 1542 return bad
1542 1543
1543 1544 def forget(ui, repo, match, prefix, explicitonly):
1544 1545 join = lambda f: os.path.join(prefix, f)
1545 1546 bad = []
1546 1547 oldbad = match.bad
1547 1548 match.bad = lambda x, y: bad.append(x) or oldbad(x, y)
1548 1549 wctx = repo[None]
1549 1550 forgot = []
1550 1551 s = repo.status(match=match, clean=True)
1551 1552 forget = sorted(s[0] + s[1] + s[3] + s[6])
1552 1553 if explicitonly:
1553 1554 forget = [f for f in forget if match.exact(f)]
1554 1555
1555 1556 for subpath in sorted(wctx.substate):
1556 1557 sub = wctx.sub(subpath)
1557 1558 try:
1558 1559 submatch = matchmod.narrowmatcher(subpath, match)
1559 1560 subbad, subforgot = sub.forget(ui, submatch, prefix)
1560 1561 bad.extend([subpath + '/' + f for f in subbad])
1561 1562 forgot.extend([subpath + '/' + f for f in subforgot])
1562 1563 except error.LookupError:
1563 1564 ui.status(_("skipping missing subrepository: %s\n")
1564 1565 % join(subpath))
1565 1566
1566 1567 if not explicitonly:
1567 1568 for f in match.files():
1568 1569 if f not in repo.dirstate and not os.path.isdir(match.rel(join(f))):
1569 1570 if f not in forgot:
1570 1571 if os.path.exists(match.rel(join(f))):
1571 1572 ui.warn(_('not removing %s: '
1572 1573 'file is already untracked\n')
1573 1574 % match.rel(join(f)))
1574 1575 bad.append(f)
1575 1576
1576 1577 for f in forget:
1577 1578 if ui.verbose or not match.exact(f):
1578 1579 ui.status(_('removing %s\n') % match.rel(join(f)))
1579 1580
1580 1581 rejected = wctx.forget(forget, prefix)
1581 1582 bad.extend(f for f in rejected if f in match.files())
1582 1583 forgot.extend(forget)
1583 1584 return bad, forgot
1584 1585
1585 1586 def duplicatecopies(repo, rev, p1):
1586 1587 "Reproduce copies found in the source revision in the dirstate for grafts"
1587 1588 for dst, src in copies.pathcopies(repo[p1], repo[rev]).iteritems():
1588 1589 repo.dirstate.copy(src, dst)
1589 1590
1590 1591 def commit(ui, repo, commitfunc, pats, opts):
1591 1592 '''commit the specified files or all outstanding changes'''
1592 1593 date = opts.get('date')
1593 1594 if date:
1594 1595 opts['date'] = util.parsedate(date)
1595 1596 message = logmessage(ui, opts)
1596 1597
1597 1598 # extract addremove carefully -- this function can be called from a command
1598 1599 # that doesn't support addremove
1599 1600 if opts.get('addremove'):
1600 1601 scmutil.addremove(repo, pats, opts)
1601 1602
1602 1603 return commitfunc(ui, repo, message,
1603 1604 scmutil.match(repo[None], pats, opts), opts)
1604 1605
1605 1606 def amend(ui, repo, commitfunc, old, extra, pats, opts):
1606 1607 ui.note(_('amending changeset %s\n') % old)
1607 1608 base = old.p1()
1608 1609
1609 1610 wlock = lock = newid = None
1610 1611 try:
1611 1612 wlock = repo.wlock()
1612 1613 lock = repo.lock()
1613 1614 tr = repo.transaction('amend')
1614 1615 try:
1615 1616 # See if we got a message from -m or -l, if not, open the editor
1616 1617 # with the message of the changeset to amend
1617 1618 message = logmessage(ui, opts)
1618 1619 # ensure logfile does not conflict with later enforcement of the
1619 1620 # message. potential logfile content has been processed by
1620 1621 # `logmessage` anyway.
1621 1622 opts.pop('logfile')
1622 1623 # First, do a regular commit to record all changes in the working
1623 1624 # directory (if there are any)
1624 1625 ui.callhooks = False
1625 1626 currentbookmark = repo._bookmarkcurrent
1626 1627 try:
1627 1628 repo._bookmarkcurrent = None
1628 1629 opts['message'] = 'temporary amend commit for %s' % old
1629 1630 node = commit(ui, repo, commitfunc, pats, opts)
1630 1631 finally:
1631 1632 repo._bookmarkcurrent = currentbookmark
1632 1633 ui.callhooks = True
1633 1634 ctx = repo[node]
1634 1635
1635 1636 # Participating changesets:
1636 1637 #
1637 1638 # node/ctx o - new (intermediate) commit that contains changes
1638 1639 # | from working dir to go into amending commit
1639 1640 # | (or a workingctx if there were no changes)
1640 1641 # |
1641 1642 # old o - changeset to amend
1642 1643 # |
1643 1644 # base o - parent of amending changeset
1644 1645
1645 1646 # Update extra dict from amended commit (e.g. to preserve graft
1646 1647 # source)
1647 1648 extra.update(old.extra())
1648 1649
1649 1650 # Also update it from the intermediate commit or from the wctx
1650 1651 extra.update(ctx.extra())
1651 1652
1652 1653 files = set(old.files())
1653 1654
1654 1655 # Second, we use either the commit we just did, or if there were no
1655 1656 # changes the parent of the working directory as the version of the
1656 1657 # files in the final amend commit
1657 1658 if node:
1658 1659 ui.note(_('copying changeset %s to %s\n') % (ctx, base))
1659 1660
1660 1661 user = ctx.user()
1661 1662 date = ctx.date()
1662 1663 # Recompute copies (avoid recording a -> b -> a)
1663 1664 copied = copies.pathcopies(base, ctx)
1664 1665
1665 1666 # Prune files which were reverted by the updates: if old
1666 1667 # introduced file X and our intermediate commit, node,
1667 1668 # renamed that file, then those two files are the same and
1668 1669 # we can discard X from our list of files. Likewise if X
1669 1670 # was deleted, it's no longer relevant
1670 1671 files.update(ctx.files())
1671 1672
1672 1673 def samefile(f):
1673 1674 if f in ctx.manifest():
1674 1675 a = ctx.filectx(f)
1675 1676 if f in base.manifest():
1676 1677 b = base.filectx(f)
1677 1678 return (not a.cmp(b)
1678 1679 and a.flags() == b.flags())
1679 1680 else:
1680 1681 return False
1681 1682 else:
1682 1683 return f not in base.manifest()
1683 1684 files = [f for f in files if not samefile(f)]
1684 1685
1685 1686 def filectxfn(repo, ctx_, path):
1686 1687 try:
1687 1688 fctx = ctx[path]
1688 1689 flags = fctx.flags()
1689 1690 mctx = context.memfilectx(fctx.path(), fctx.data(),
1690 1691 islink='l' in flags,
1691 1692 isexec='x' in flags,
1692 1693 copied=copied.get(path))
1693 1694 return mctx
1694 1695 except KeyError:
1695 1696 raise IOError
1696 1697 else:
1697 1698 ui.note(_('copying changeset %s to %s\n') % (old, base))
1698 1699
1699 1700 # Use version of files as in the old cset
1700 1701 def filectxfn(repo, ctx_, path):
1701 1702 try:
1702 1703 return old.filectx(path)
1703 1704 except KeyError:
1704 1705 raise IOError
1705 1706
1706 1707 user = opts.get('user') or old.user()
1707 1708 date = opts.get('date') or old.date()
1708 1709 editmsg = False
1709 1710 if not message:
1710 1711 editmsg = True
1711 1712 message = old.description()
1712 1713
1713 1714 pureextra = extra.copy()
1714 1715 extra['amend_source'] = old.hex()
1715 1716
1716 1717 new = context.memctx(repo,
1717 1718 parents=[base.node(), nullid],
1718 1719 text=message,
1719 1720 files=files,
1720 1721 filectxfn=filectxfn,
1721 1722 user=user,
1722 1723 date=date,
1723 1724 extra=extra)
1724 1725 if editmsg:
1725 1726 new._text = commitforceeditor(repo, new, [])
1726 1727
1727 1728 newdesc = changelog.stripdesc(new.description())
1728 1729 if ((not node)
1729 1730 and newdesc == old.description()
1730 1731 and user == old.user()
1731 1732 and date == old.date()
1732 1733 and pureextra == old.extra()):
1733 1734 # nothing changed. continuing here would create a new node
1734 1735 # anyway because of the amend_source noise.
1735 1736 #
1736 1737 # This not what we expect from amend.
1737 1738 return old.node()
1738 1739
1739 1740 ph = repo.ui.config('phases', 'new-commit', phases.draft)
1740 1741 try:
1741 1742 repo.ui.setconfig('phases', 'new-commit', old.phase())
1742 1743 newid = repo.commitctx(new)
1743 1744 finally:
1744 1745 repo.ui.setconfig('phases', 'new-commit', ph)
1745 1746 if newid != old.node():
1746 1747 # Reroute the working copy parent to the new changeset
1747 1748 repo.setparents(newid, nullid)
1748 1749
1749 1750 # Move bookmarks from old parent to amend commit
1750 1751 bms = repo.nodebookmarks(old.node())
1751 1752 if bms:
1752 1753 marks = repo._bookmarks
1753 1754 for bm in bms:
1754 1755 marks[bm] = newid
1755 1756 marks.write()
1756 1757 #commit the whole amend process
1757 1758 if obsolete._enabled and newid != old.node():
1758 1759 # mark the new changeset as successor of the rewritten one
1759 1760 new = repo[newid]
1760 1761 obs = [(old, (new,))]
1761 1762 if node:
1762 1763 obs.append((ctx, ()))
1763 1764
1764 1765 obsolete.createmarkers(repo, obs)
1765 1766 tr.close()
1766 1767 finally:
1767 1768 tr.release()
1768 1769 if (not obsolete._enabled) and newid != old.node():
1769 1770 # Strip the intermediate commit (if there was one) and the amended
1770 1771 # commit
1771 1772 if node:
1772 1773 ui.note(_('stripping intermediate changeset %s\n') % ctx)
1773 1774 ui.note(_('stripping amended changeset %s\n') % old)
1774 1775 repair.strip(ui, repo, old.node(), topic='amend-backup')
1775 1776 finally:
1776 1777 if newid is None:
1777 1778 repo.dirstate.invalidate()
1778 1779 lockmod.release(wlock, lock)
1779 1780 return newid
1780 1781
1781 1782 def commiteditor(repo, ctx, subs):
1782 1783 if ctx.description():
1783 1784 return ctx.description()
1784 1785 return commitforceeditor(repo, ctx, subs)
1785 1786
1786 1787 def commitforceeditor(repo, ctx, subs):
1787 1788 edittext = []
1788 1789 modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
1789 1790 if ctx.description():
1790 1791 edittext.append(ctx.description())
1791 1792 edittext.append("")
1792 1793 edittext.append("") # Empty line between message and comments.
1793 1794 edittext.append(_("HG: Enter commit message."
1794 1795 " Lines beginning with 'HG:' are removed."))
1795 1796 edittext.append(_("HG: Leave message empty to abort commit."))
1796 1797 edittext.append("HG: --")
1797 1798 edittext.append(_("HG: user: %s") % ctx.user())
1798 1799 if ctx.p2():
1799 1800 edittext.append(_("HG: branch merge"))
1800 1801 if ctx.branch():
1801 1802 edittext.append(_("HG: branch '%s'") % ctx.branch())
1802 1803 if bookmarks.iscurrent(repo):
1803 1804 edittext.append(_("HG: bookmark '%s'") % repo._bookmarkcurrent)
1804 1805 edittext.extend([_("HG: subrepo %s") % s for s in subs])
1805 1806 edittext.extend([_("HG: added %s") % f for f in added])
1806 1807 edittext.extend([_("HG: changed %s") % f for f in modified])
1807 1808 edittext.extend([_("HG: removed %s") % f for f in removed])
1808 1809 if not added and not modified and not removed:
1809 1810 edittext.append(_("HG: no files changed"))
1810 1811 edittext.append("")
1811 1812 # run editor in the repository root
1812 1813 olddir = os.getcwd()
1813 1814 os.chdir(repo.root)
1814 1815 text = repo.ui.edit("\n".join(edittext), ctx.user())
1815 1816 text = re.sub("(?m)^HG:.*(\n|$)", "", text)
1816 1817 os.chdir(olddir)
1817 1818
1818 1819 if not text.strip():
1819 1820 raise util.Abort(_("empty commit message"))
1820 1821
1821 1822 return text
1822 1823
1823 1824 def revert(ui, repo, ctx, parents, *pats, **opts):
1824 1825 parent, p2 = parents
1825 1826 node = ctx.node()
1826 1827
1827 1828 mf = ctx.manifest()
1828 1829 if node == parent:
1829 1830 pmf = mf
1830 1831 else:
1831 1832 pmf = None
1832 1833
1833 1834 # need all matching names in dirstate and manifest of target rev,
1834 1835 # so have to walk both. do not print errors if files exist in one
1835 1836 # but not other.
1836 1837
1837 1838 names = {}
1838 1839
1839 1840 wlock = repo.wlock()
1840 1841 try:
1841 1842 # walk dirstate.
1842 1843
1843 1844 m = scmutil.match(repo[None], pats, opts)
1844 1845 m.bad = lambda x, y: False
1845 1846 for abs in repo.walk(m):
1846 1847 names[abs] = m.rel(abs), m.exact(abs)
1847 1848
1848 1849 # walk target manifest.
1849 1850
1850 1851 def badfn(path, msg):
1851 1852 if path in names:
1852 1853 return
1853 1854 if path in ctx.substate:
1854 1855 return
1855 1856 path_ = path + '/'
1856 1857 for f in names:
1857 1858 if f.startswith(path_):
1858 1859 return
1859 1860 ui.warn("%s: %s\n" % (m.rel(path), msg))
1860 1861
1861 1862 m = scmutil.match(ctx, pats, opts)
1862 1863 m.bad = badfn
1863 1864 for abs in ctx.walk(m):
1864 1865 if abs not in names:
1865 1866 names[abs] = m.rel(abs), m.exact(abs)
1866 1867
1867 1868 # get the list of subrepos that must be reverted
1868 1869 targetsubs = sorted(s for s in ctx.substate if m(s))
1869 1870 m = scmutil.matchfiles(repo, names)
1870 1871 changes = repo.status(match=m)[:4]
1871 1872 modified, added, removed, deleted = map(set, changes)
1872 1873
1873 1874 # if f is a rename, also revert the source
1874 1875 cwd = repo.getcwd()
1875 1876 for f in added:
1876 1877 src = repo.dirstate.copied(f)
1877 1878 if src and src not in names and repo.dirstate[src] == 'r':
1878 1879 removed.add(src)
1879 1880 names[src] = (repo.pathto(src, cwd), True)
1880 1881
1881 1882 def removeforget(abs):
1882 1883 if repo.dirstate[abs] == 'a':
1883 1884 return _('forgetting %s\n')
1884 1885 return _('removing %s\n')
1885 1886
1886 1887 revert = ([], _('reverting %s\n'))
1887 1888 add = ([], _('adding %s\n'))
1888 1889 remove = ([], removeforget)
1889 1890 undelete = ([], _('undeleting %s\n'))
1890 1891
1891 1892 disptable = (
1892 1893 # dispatch table:
1893 1894 # file state
1894 1895 # action if in target manifest
1895 1896 # action if not in target manifest
1896 1897 # make backup if in target manifest
1897 1898 # make backup if not in target manifest
1898 1899 (modified, revert, remove, True, True),
1899 1900 (added, revert, remove, True, False),
1900 1901 (removed, undelete, None, False, False),
1901 1902 (deleted, revert, remove, False, False),
1902 1903 )
1903 1904
1904 1905 for abs, (rel, exact) in sorted(names.items()):
1905 1906 mfentry = mf.get(abs)
1906 1907 target = repo.wjoin(abs)
1907 1908 def handle(xlist, dobackup):
1908 1909 xlist[0].append(abs)
1909 1910 if (dobackup and not opts.get('no_backup') and
1910 1911 os.path.lexists(target)):
1911 1912 bakname = "%s.orig" % rel
1912 1913 ui.note(_('saving current version of %s as %s\n') %
1913 1914 (rel, bakname))
1914 1915 if not opts.get('dry_run'):
1915 1916 util.rename(target, bakname)
1916 1917 if ui.verbose or not exact:
1917 1918 msg = xlist[1]
1918 1919 if not isinstance(msg, basestring):
1919 1920 msg = msg(abs)
1920 1921 ui.status(msg % rel)
1921 1922 for table, hitlist, misslist, backuphit, backupmiss in disptable:
1922 1923 if abs not in table:
1923 1924 continue
1924 1925 # file has changed in dirstate
1925 1926 if mfentry:
1926 1927 handle(hitlist, backuphit)
1927 1928 elif misslist is not None:
1928 1929 handle(misslist, backupmiss)
1929 1930 break
1930 1931 else:
1931 1932 if abs not in repo.dirstate:
1932 1933 if mfentry:
1933 1934 handle(add, True)
1934 1935 elif exact:
1935 1936 ui.warn(_('file not managed: %s\n') % rel)
1936 1937 continue
1937 1938 # file has not changed in dirstate
1938 1939 if node == parent:
1939 1940 if exact:
1940 1941 ui.warn(_('no changes needed to %s\n') % rel)
1941 1942 continue
1942 1943 if pmf is None:
1943 1944 # only need parent manifest in this unlikely case,
1944 1945 # so do not read by default
1945 1946 pmf = repo[parent].manifest()
1946 1947 if abs in pmf and mfentry:
1947 1948 # if version of file is same in parent and target
1948 1949 # manifests, do nothing
1949 1950 if (pmf[abs] != mfentry or
1950 1951 pmf.flags(abs) != mf.flags(abs)):
1951 1952 handle(revert, False)
1952 1953 else:
1953 1954 handle(remove, False)
1954 1955
1955 1956 if not opts.get('dry_run'):
1956 1957 def checkout(f):
1957 1958 fc = ctx[f]
1958 1959 repo.wwrite(f, fc.data(), fc.flags())
1959 1960
1960 1961 audit_path = scmutil.pathauditor(repo.root)
1961 1962 for f in remove[0]:
1962 1963 if repo.dirstate[f] == 'a':
1963 1964 repo.dirstate.drop(f)
1964 1965 continue
1965 1966 audit_path(f)
1966 1967 try:
1967 1968 util.unlinkpath(repo.wjoin(f))
1968 1969 except OSError:
1969 1970 pass
1970 1971 repo.dirstate.remove(f)
1971 1972
1972 1973 normal = None
1973 1974 if node == parent:
1974 1975 # We're reverting to our parent. If possible, we'd like status
1975 1976 # to report the file as clean. We have to use normallookup for
1976 1977 # merges to avoid losing information about merged/dirty files.
1977 1978 if p2 != nullid:
1978 1979 normal = repo.dirstate.normallookup
1979 1980 else:
1980 1981 normal = repo.dirstate.normal
1981 1982 for f in revert[0]:
1982 1983 checkout(f)
1983 1984 if normal:
1984 1985 normal(f)
1985 1986
1986 1987 for f in add[0]:
1987 1988 checkout(f)
1988 1989 repo.dirstate.add(f)
1989 1990
1990 1991 normal = repo.dirstate.normallookup
1991 1992 if node == parent and p2 == nullid:
1992 1993 normal = repo.dirstate.normal
1993 1994 for f in undelete[0]:
1994 1995 checkout(f)
1995 1996 normal(f)
1996 1997
1997 1998 if targetsubs:
1998 1999 # Revert the subrepos on the revert list
1999 2000 for sub in targetsubs:
2000 2001 ctx.sub(sub).revert(ui, ctx.substate[sub], *pats, **opts)
2001 2002 finally:
2002 2003 wlock.release()
2003 2004
2004 2005 def command(table):
2005 2006 '''returns a function object bound to table which can be used as
2006 2007 a decorator for populating table as a command table'''
2007 2008
2008 2009 def cmd(name, options=(), synopsis=None):
2009 2010 def decorator(func):
2010 2011 if synopsis:
2011 2012 table[name] = func, list(options), synopsis
2012 2013 else:
2013 2014 table[name] = func, list(options)
2014 2015 return func
2015 2016 return decorator
2016 2017
2017 2018 return cmd
@@ -1,425 +1,426 b''
1 1 $ HGFOO=BAR; export HGFOO
2 2 $ cat >> $HGRCPATH <<EOF
3 3 > [extensions]
4 4 > graphlog=
5 5 >
6 6 > [alias]
7 7 > # should clobber ci but not commit (issue2993)
8 8 > ci = version
9 9 > myinit = init
10 10 > optionalrepo = showconfig alias.myinit
11 11 > cleanstatus = status -c
12 12 > unknown = bargle
13 13 > ambiguous = s
14 14 > recursive = recursive
15 15 > nodefinition =
16 16 > no--cwd = status --cwd elsewhere
17 17 > no-R = status -R elsewhere
18 18 > no--repo = status --repo elsewhere
19 19 > no--repository = status --repository elsewhere
20 20 > mylog = log
21 21 > lognull = log -r null
22 22 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
23 23 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
24 24 > dln = lognull --debug
25 25 > nousage = rollback
26 26 > put = export -r 0 -o "\$FOO/%R.diff"
27 27 > blank = !printf '\n'
28 28 > self = !printf '\$0\n'
29 29 > echoall = !printf '\$@\n'
30 30 > echo1 = !printf '\$1\n'
31 31 > echo2 = !printf '\$2\n'
32 32 > echo13 = !printf '\$1 \$3\n'
33 33 > count = !hg log -r "\$@" --template=. | wc -c | sed -e 's/ //g'
34 34 > mcount = !hg log \$@ --template=. | wc -c | sed -e 's/ //g'
35 35 > rt = root
36 36 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
37 37 > idalias = id
38 38 > idaliaslong = id
39 39 > idaliasshell = !echo test
40 40 > parentsshell1 = !echo one
41 41 > parentsshell2 = !echo two
42 42 > escaped1 = !printf 'test\$\$test\n'
43 43 > escaped2 = !sh -c 'echo "HGFOO is \$\$HGFOO"'
44 44 > escaped3 = !sh -c 'echo "\$1 is \$\$\$1"'
45 45 > escaped4 = !printf '\$\$0 \$\$@\n'
46 46 >
47 47 > [defaults]
48 48 > mylog = -q
49 49 > lognull = -q
50 50 > log = -v
51 51 > EOF
52 52
53 53
54 54 basic
55 55
56 56 $ hg myinit alias
57 57
58 58
59 59 unknown
60 60
61 61 $ hg unknown
62 62 alias 'unknown' resolves to unknown command 'bargle'
63 63 $ hg help unknown
64 64 alias 'unknown' resolves to unknown command 'bargle'
65 65
66 66
67 67 ambiguous
68 68
69 69 $ hg ambiguous
70 70 alias 'ambiguous' resolves to ambiguous command 's'
71 71 $ hg help ambiguous
72 72 alias 'ambiguous' resolves to ambiguous command 's'
73 73
74 74
75 75 recursive
76 76
77 77 $ hg recursive
78 78 alias 'recursive' resolves to unknown command 'recursive'
79 79 $ hg help recursive
80 80 alias 'recursive' resolves to unknown command 'recursive'
81 81
82 82
83 83 no definition
84 84
85 85 $ hg nodef
86 86 no definition for alias 'nodefinition'
87 87 $ hg help nodef
88 88 no definition for alias 'nodefinition'
89 89
90 90
91 91 invalid options
92 92
93 93 $ hg no--cwd
94 94 error in definition for alias 'no--cwd': --cwd may only be given on the command line
95 95 $ hg help no--cwd
96 96 error in definition for alias 'no--cwd': --cwd may only be given on the command line
97 97 $ hg no-R
98 98 error in definition for alias 'no-R': -R may only be given on the command line
99 99 $ hg help no-R
100 100 error in definition for alias 'no-R': -R may only be given on the command line
101 101 $ hg no--repo
102 102 error in definition for alias 'no--repo': --repo may only be given on the command line
103 103 $ hg help no--repo
104 104 error in definition for alias 'no--repo': --repo may only be given on the command line
105 105 $ hg no--repository
106 106 error in definition for alias 'no--repository': --repository may only be given on the command line
107 107 $ hg help no--repository
108 108 error in definition for alias 'no--repository': --repository may only be given on the command line
109 109
110 110 optional repository
111 111
112 112 #if no-outer-repo
113 113 $ hg optionalrepo
114 114 init
115 115 #endif
116 116 $ cd alias
117 117 $ cat > .hg/hgrc <<EOF
118 118 > [alias]
119 119 > myinit = init -q
120 120 > EOF
121 121 $ hg optionalrepo
122 122 init -q
123 123
124 124 no usage
125 125
126 126 $ hg nousage
127 127 no rollback information available
128 128
129 129 $ echo foo > foo
130 130 $ hg commit -Amfoo
131 131 adding foo
132 132
133 133
134 134 with opts
135 135
136 136 $ hg cleanst
137 137 C foo
138 138
139 139
140 140 with opts and whitespace
141 141
142 142 $ hg shortlog
143 143 0 e63c23eaa88a | 1970-01-01 00:00 +0000
144 144
145 145 positional arguments
146 146
147 147 $ hg positional
148 148 abort: too few arguments for command alias
149 149 [255]
150 150 $ hg positional a
151 151 abort: too few arguments for command alias
152 152 [255]
153 153 $ hg positional 'node|short' rev
154 154 0 e63c23eaa88a | 1970-01-01 00:00 +0000
155 155
156 156 interaction with defaults
157 157
158 158 $ hg mylog
159 159 0:e63c23eaa88a
160 160 $ hg lognull
161 161 -1:000000000000
162 162
163 163
164 164 properly recursive
165 165
166 166 $ hg dln
167 167 changeset: -1:0000000000000000000000000000000000000000
168 168 parent: -1:0000000000000000000000000000000000000000
169 169 parent: -1:0000000000000000000000000000000000000000
170 170 manifest: -1:0000000000000000000000000000000000000000
171 171 user:
172 172 date: Thu Jan 01 00:00:00 1970 +0000
173 173 extra: branch=default
174 174
175 175
176 176
177 177 path expanding
178 178
179 179 $ FOO=`pwd` hg put
180 180 $ cat 0.diff
181 181 # HG changeset patch
182 182 # User test
183 183 # Date 0 0
184 # Thu Jan 01 00:00:00 1970 +0000
184 185 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
185 186 # Parent 0000000000000000000000000000000000000000
186 187 foo
187 188
188 189 diff -r 000000000000 -r e63c23eaa88a foo
189 190 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
190 191 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
191 192 @@ -0,0 +1,1 @@
192 193 +foo
193 194
194 195
195 196 simple shell aliases
196 197
197 198 $ hg blank
198 199
199 200 $ hg blank foo
200 201
201 202 $ hg self
202 203 self
203 204 $ hg echoall
204 205
205 206 $ hg echoall foo
206 207 foo
207 208 $ hg echoall 'test $2' foo
208 209 test $2 foo
209 210 $ hg echo1 foo bar baz
210 211 foo
211 212 $ hg echo2 foo bar baz
212 213 bar
213 214 $ hg echo13 foo bar baz test
214 215 foo baz
215 216 $ hg echo2 foo
216 217
217 218 $ echo bar > bar
218 219 $ hg commit -qA -m bar
219 220 $ hg count .
220 221 1
221 222 $ hg count 'branch(default)'
222 223 2
223 224 $ hg mcount -r '"branch(default)"'
224 225 2
225 226
226 227 $ hg tglog
227 @ 1:7e7f92de180e: 'bar'
228 @ 1:042423737847: 'bar'
228 229 |
229 230 o 0:e63c23eaa88a: 'foo'
230 231
231 232
232 233
233 234 shadowing
234 235
235 236 $ hg i
236 237 hg: command 'i' is ambiguous:
237 238 idalias idaliaslong idaliasshell identify import incoming init
238 239 [255]
239 240 $ hg id
240 7e7f92de180e tip
241 042423737847 tip
241 242 $ hg ida
242 243 hg: command 'ida' is ambiguous:
243 244 idalias idaliaslong idaliasshell
244 245 [255]
245 246 $ hg idalias
246 7e7f92de180e tip
247 042423737847 tip
247 248 $ hg idaliasl
248 7e7f92de180e tip
249 042423737847 tip
249 250 $ hg idaliass
250 251 test
251 252 $ hg parentsshell
252 253 hg: command 'parentsshell' is ambiguous:
253 254 parentsshell1 parentsshell2
254 255 [255]
255 256 $ hg parentsshell1
256 257 one
257 258 $ hg parentsshell2
258 259 two
259 260
260 261
261 262 shell aliases with global options
262 263
263 264 $ hg init sub
264 265 $ cd sub
265 266 $ hg count 'branch(default)'
266 267 0
267 268 $ hg -v count 'branch(default)'
268 269 0
269 270 $ hg -R .. count 'branch(default)'
270 271 0
271 272 $ hg --cwd .. count 'branch(default)'
272 273 2
273 274 $ hg echoall --cwd ..
274 275
275 276
276 277
277 278 repo specific shell aliases
278 279
279 280 $ cat >> .hg/hgrc <<EOF
280 281 > [alias]
281 282 > subalias = !echo sub
282 283 > EOF
283 284 $ cat >> ../.hg/hgrc <<EOF
284 285 > [alias]
285 286 > mainalias = !echo main
286 287 > EOF
287 288
288 289
289 290 shell alias defined in current repo
290 291
291 292 $ hg subalias
292 293 sub
293 294 $ hg --cwd .. subalias > /dev/null
294 295 hg: unknown command 'subalias'
295 296 [255]
296 297 $ hg -R .. subalias > /dev/null
297 298 hg: unknown command 'subalias'
298 299 [255]
299 300
300 301
301 302 shell alias defined in other repo
302 303
303 304 $ hg mainalias > /dev/null
304 305 hg: unknown command 'mainalias'
305 306 [255]
306 307 $ hg -R .. mainalias
307 308 main
308 309 $ hg --cwd .. mainalias
309 310 main
310 311
311 312
312 313 shell aliases with escaped $ chars
313 314
314 315 $ hg escaped1
315 316 test$test
316 317 $ hg escaped2
317 318 HGFOO is BAR
318 319 $ hg escaped3 HGFOO
319 320 HGFOO is BAR
320 321 $ hg escaped4 test
321 322 $0 $@
322 323
323 324
324 325 invalid arguments
325 326
326 327 $ hg rt foo
327 328 hg rt: invalid arguments
328 329 hg rt
329 330
330 331 alias for: hg root
331 332
332 333 use "hg help rt" to show the full help text
333 334 [255]
334 335
335 336 invalid global arguments for normal commands, aliases, and shell aliases
336 337
337 338 $ hg --invalid root
338 339 hg: option --invalid not recognized
339 340 Mercurial Distributed SCM
340 341
341 342 basic commands:
342 343
343 344 add add the specified files on the next commit
344 345 annotate show changeset information by line for each file
345 346 clone make a copy of an existing repository
346 347 commit commit the specified files or all outstanding changes
347 348 diff diff repository (or selected files)
348 349 export dump the header and diffs for one or more changesets
349 350 forget forget the specified files on the next commit
350 351 init create a new repository in the given directory
351 352 log show revision history of entire repository or files
352 353 merge merge working directory with another revision
353 354 pull pull changes from the specified source
354 355 push push changes to the specified destination
355 356 remove remove the specified files on the next commit
356 357 serve start stand-alone webserver
357 358 status show changed files in the working directory
358 359 summary summarize working directory state
359 360 update update working directory (or switch revisions)
360 361
361 362 use "hg help" for the full list of commands or "hg -v" for details
362 363 [255]
363 364 $ hg --invalid mylog
364 365 hg: option --invalid not recognized
365 366 Mercurial Distributed SCM
366 367
367 368 basic commands:
368 369
369 370 add add the specified files on the next commit
370 371 annotate show changeset information by line for each file
371 372 clone make a copy of an existing repository
372 373 commit commit the specified files or all outstanding changes
373 374 diff diff repository (or selected files)
374 375 export dump the header and diffs for one or more changesets
375 376 forget forget the specified files on the next commit
376 377 init create a new repository in the given directory
377 378 log show revision history of entire repository or files
378 379 merge merge working directory with another revision
379 380 pull pull changes from the specified source
380 381 push push changes to the specified destination
381 382 remove remove the specified files on the next commit
382 383 serve start stand-alone webserver
383 384 status show changed files in the working directory
384 385 summary summarize working directory state
385 386 update update working directory (or switch revisions)
386 387
387 388 use "hg help" for the full list of commands or "hg -v" for details
388 389 [255]
389 390 $ hg --invalid blank
390 391 hg: option --invalid not recognized
391 392 Mercurial Distributed SCM
392 393
393 394 basic commands:
394 395
395 396 add add the specified files on the next commit
396 397 annotate show changeset information by line for each file
397 398 clone make a copy of an existing repository
398 399 commit commit the specified files or all outstanding changes
399 400 diff diff repository (or selected files)
400 401 export dump the header and diffs for one or more changesets
401 402 forget forget the specified files on the next commit
402 403 init create a new repository in the given directory
403 404 log show revision history of entire repository or files
404 405 merge merge working directory with another revision
405 406 pull pull changes from the specified source
406 407 push push changes to the specified destination
407 408 remove remove the specified files on the next commit
408 409 serve start stand-alone webserver
409 410 status show changed files in the working directory
410 411 summary summarize working directory state
411 412 update update working directory (or switch revisions)
412 413
413 414 use "hg help" for the full list of commands or "hg -v" for details
414 415 [255]
415 416
416 417 This should show id:
417 418
418 419 $ hg --config alias.log='id' log
419 420 000000000000 tip
420 421
421 422 This shouldn't:
422 423
423 424 $ hg --config alias.log='id' history
424 425
425 426 $ cd ../..
@@ -1,186 +1,188 b''
1 1 $ hg init repo
2 2 $ cd repo
3 3 $ touch foo
4 4 $ hg add foo
5 5 $ for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
6 6 > echo "foo-$i" >> foo
7 7 > hg ci -m "foo-$i"
8 8 > done
9 9
10 10 $ for out in "%nof%N" "%%%H" "%b-%R" "%h" "%r" "%m"; do
11 11 > echo
12 12 > echo "# foo-$out.patch"
13 13 > hg export -v -o "foo-$out.patch" 2:tip
14 14 > done
15 15
16 16 # foo-%nof%N.patch
17 17 exporting patches:
18 18 foo-01of10.patch
19 19 foo-02of10.patch
20 20 foo-03of10.patch
21 21 foo-04of10.patch
22 22 foo-05of10.patch
23 23 foo-06of10.patch
24 24 foo-07of10.patch
25 25 foo-08of10.patch
26 26 foo-09of10.patch
27 27 foo-10of10.patch
28 28
29 29 # foo-%%%H.patch
30 30 exporting patches:
31 31 foo-%617188a1c80f869a7b66c85134da88a6fb145f67.patch
32 32 foo-%dd41a5ff707a5225204105611ba49cc5c229d55f.patch
33 33 foo-%f95a5410f8664b6e1490a4af654e4b7d41a7b321.patch
34 34 foo-%4346bcfde53b4d9042489078bcfa9c3e28201db2.patch
35 35 foo-%afda8c3a009cc99449a05ad8aa4655648c4ecd34.patch
36 36 foo-%35284ce2b6b99c9d2ac66268fe99e68e1974e1aa.patch
37 37 foo-%9688c41894e6931305fa7165a37f6568050b4e9b.patch
38 38 foo-%747d3c68f8ec44bb35816bfcd59aeb50b9654c2f.patch
39 39 foo-%5f17a83f5fbd9414006a5e563eab4c8a00729efd.patch
40 40 foo-%f3acbafac161ec68f1598af38f794f28847ca5d3.patch
41 41
42 42 # foo-%b-%R.patch
43 43 exporting patches:
44 44 foo-repo-2.patch
45 45 foo-repo-3.patch
46 46 foo-repo-4.patch
47 47 foo-repo-5.patch
48 48 foo-repo-6.patch
49 49 foo-repo-7.patch
50 50 foo-repo-8.patch
51 51 foo-repo-9.patch
52 52 foo-repo-10.patch
53 53 foo-repo-11.patch
54 54
55 55 # foo-%h.patch
56 56 exporting patches:
57 57 foo-617188a1c80f.patch
58 58 foo-dd41a5ff707a.patch
59 59 foo-f95a5410f866.patch
60 60 foo-4346bcfde53b.patch
61 61 foo-afda8c3a009c.patch
62 62 foo-35284ce2b6b9.patch
63 63 foo-9688c41894e6.patch
64 64 foo-747d3c68f8ec.patch
65 65 foo-5f17a83f5fbd.patch
66 66 foo-f3acbafac161.patch
67 67
68 68 # foo-%r.patch
69 69 exporting patches:
70 70 foo-02.patch
71 71 foo-03.patch
72 72 foo-04.patch
73 73 foo-05.patch
74 74 foo-06.patch
75 75 foo-07.patch
76 76 foo-08.patch
77 77 foo-09.patch
78 78 foo-10.patch
79 79 foo-11.patch
80 80
81 81 # foo-%m.patch
82 82 exporting patches:
83 83 foo-foo_2.patch
84 84 foo-foo_3.patch
85 85 foo-foo_4.patch
86 86 foo-foo_5.patch
87 87 foo-foo_6.patch
88 88 foo-foo_7.patch
89 89 foo-foo_8.patch
90 90 foo-foo_9.patch
91 91 foo-foo_10.patch
92 92 foo-foo_11.patch
93 93
94 94 Doing it again clobbers the files rather than appending:
95 95 $ hg export -v -o "foo-%m.patch" 2:3
96 96 exporting patches:
97 97 foo-foo_2.patch
98 98 foo-foo_3.patch
99 99 $ grep HG foo-foo_2.patch | wc -l
100 100 \s*1 (re)
101 101 $ grep HG foo-foo_3.patch | wc -l
102 102 \s*1 (re)
103 103
104 104 Exporting 4 changesets to a file:
105 105
106 106 $ hg export -o export_internal 1 2 3 4
107 107 $ grep HG export_internal | wc -l
108 108 \s*4 (re)
109 109
110 110 Doing it again clobbers the file rather than appending:
111 111 $ hg export -o export_internal 1 2 3 4
112 112 $ grep HG export_internal | wc -l
113 113 \s*4 (re)
114 114
115 115 Exporting 4 changesets to stdout:
116 116
117 117 $ hg export 1 2 3 4 | grep HG | wc -l
118 118 \s*4 (re)
119 119
120 120 Exporting revision -2 to a file:
121 121
122 122 $ hg export -- -2
123 123 # HG changeset patch
124 124 # User test
125 125 # Date 0 0
126 # Thu Jan 01 00:00:00 1970 +0000
126 127 # Node ID 5f17a83f5fbd9414006a5e563eab4c8a00729efd
127 128 # Parent 747d3c68f8ec44bb35816bfcd59aeb50b9654c2f
128 129 foo-10
129 130
130 131 diff -r 747d3c68f8ec -r 5f17a83f5fbd foo
131 132 --- a/foo Thu Jan 01 00:00:00 1970 +0000
132 133 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
133 134 @@ -8,3 +8,4 @@
134 135 foo-7
135 136 foo-8
136 137 foo-9
137 138 +foo-10
138 139
139 140 Checking if only alphanumeric characters are used in the file name (%m option):
140 141
141 142 $ echo "line" >> foo
142 143 $ hg commit -m " !\"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~"
143 144 $ hg export -v -o %m.patch tip
144 145 exporting patch:
145 146 ____________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz____.patch
146 147
147 148 Catch exporting unknown revisions (especially empty revsets, see issue3353)
148 149
149 150 $ hg export
150 151 abort: export requires at least one changeset
151 152 [255]
152 153 $ hg export ""
153 154 hg: parse error: empty query
154 155 [255]
155 156 $ hg export 999
156 157 abort: unknown revision '999'!
157 158 [255]
158 159 $ hg export "not all()"
159 160 abort: export requires at least one changeset
160 161 [255]
161 162
162 163 Check for color output
163 164 $ echo "[color]" >> $HGRCPATH
164 165 $ echo "mode = ansi" >> $HGRCPATH
165 166 $ echo "[extensions]" >> $HGRCPATH
166 167 $ echo "color=" >> $HGRCPATH
167 168
168 169 $ hg export --color always --nodates tip
169 170 # HG changeset patch
170 171 # User test
171 172 # Date 0 0
173 # Thu Jan 01 00:00:00 1970 +0000
172 174 # Node ID * (glob)
173 175 # Parent * (glob)
174 176 !"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
175 177
176 178 \x1b[0;1mdiff -r f3acbafac161 -r 197ecd81a57f foo\x1b[0m (esc)
177 179 \x1b[0;31;1m--- a/foo\x1b[0m (esc)
178 180 \x1b[0;32;1m+++ b/foo\x1b[0m (esc)
179 181 \x1b[0;35m@@ -10,3 +10,4 @@\x1b[0m (esc)
180 182 foo-9
181 183 foo-10
182 184 foo-11
183 185 \x1b[0;32m+line\x1b[0m (esc)
184 186
185 187
186 188 $ cd ..
@@ -1,535 +1,538 b''
1 1 Create a repo with some stuff in it:
2 2
3 3 $ hg init a
4 4 $ cd a
5 5 $ echo a > a
6 6 $ echo a > d
7 7 $ echo a > e
8 8 $ hg ci -qAm0
9 9 $ echo b > a
10 10 $ hg ci -m1 -u bar
11 11 $ hg mv a b
12 12 $ hg ci -m2
13 13 $ hg cp b c
14 14 $ hg ci -m3 -u baz
15 15 $ echo b > d
16 16 $ echo f > e
17 17 $ hg ci -m4
18 18 $ hg up -q 3
19 19 $ echo b > e
20 20 $ hg branch -q stable
21 21 $ hg ci -m5
22 22 $ hg merge -q default --tool internal:local
23 23 $ hg branch -q default
24 24 $ hg ci -m6
25 25 $ hg phase --public 3
26 26 $ hg phase --force --secret 6
27 27
28 28 $ hg --config extensions.graphlog= log -G --template '{author}@{rev}.{phase}: {desc}\n'
29 29 @ test@6.secret: 6
30 30 |\
31 31 | o test@5.draft: 5
32 32 | |
33 33 o | test@4.draft: 4
34 34 |/
35 35 o baz@3.public: 3
36 36 |
37 37 o test@2.public: 2
38 38 |
39 39 o bar@1.public: 1
40 40 |
41 41 o test@0.public: 0
42 42
43 43
44 44 Need to specify a rev:
45 45
46 46 $ hg graft
47 47 abort: no revisions specified
48 48 [255]
49 49
50 50 Can't graft ancestor:
51 51
52 52 $ hg graft 1 2
53 53 skipping ancestor revision 1
54 54 skipping ancestor revision 2
55 55 [255]
56 56
57 57 Specify revisions with -r:
58 58
59 59 $ hg graft -r 1 -r 2
60 60 skipping ancestor revision 1
61 61 skipping ancestor revision 2
62 62 [255]
63 63
64 64 $ hg graft -r 1 2
65 65 skipping ancestor revision 2
66 66 skipping ancestor revision 1
67 67 [255]
68 68
69 69 Can't graft with dirty wd:
70 70
71 71 $ hg up -q 0
72 72 $ echo foo > a
73 73 $ hg graft 1
74 74 abort: outstanding uncommitted changes
75 75 [255]
76 76 $ hg revert a
77 77
78 78 Graft a rename:
79 79
80 80 $ hg graft 2 -u foo
81 81 grafting revision 2
82 82 merging a and b to b
83 83 $ hg export tip --git
84 84 # HG changeset patch
85 85 # User foo
86 86 # Date 0 0
87 # Thu Jan 01 00:00:00 1970 +0000
87 88 # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82
88 89 # Parent 68795b066622ca79a25816a662041d8f78f3cd9e
89 90 2
90 91
91 92 diff --git a/a b/b
92 93 rename from a
93 94 rename to b
94 95
95 96 Look for extra:source
96 97
97 98 $ hg log --debug -r tip
98 99 changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
99 100 tag: tip
100 101 phase: draft
101 102 parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e
102 103 parent: -1:0000000000000000000000000000000000000000
103 104 manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb
104 105 user: foo
105 106 date: Thu Jan 01 00:00:00 1970 +0000
106 107 files+: b
107 108 files-: a
108 109 extra: branch=default
109 110 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
110 111 description:
111 112 2
112 113
113 114
114 115
115 116 Graft out of order, skipping a merge and a duplicate
116 117
117 118 $ hg graft 1 5 4 3 'merge()' 2 -n
118 119 skipping ungraftable merge revision 6
119 120 skipping already grafted revision 2
120 121 grafting revision 1
121 122 grafting revision 5
122 123 grafting revision 4
123 124 grafting revision 3
124 125
125 126 $ hg graft 1 5 4 3 'merge()' 2 --debug
126 127 skipping ungraftable merge revision 6
127 128 scanning for duplicate grafts
128 129 skipping already grafted revision 2
129 130 grafting revision 1
130 131 searching for copies back to rev 1
131 132 unmatched files in local:
132 133 b
133 134 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
134 135 src: 'a' -> dst: 'b' *
135 136 checking for directory renames
136 137 resolving manifests
137 138 branchmerge: True, force: True, partial: False
138 139 ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6
139 140 b: local copied/moved to a -> m
140 141 preserving b for resolve of b
141 142 updating: b 1/1 files (100.00%)
142 143 picked tool 'internal:merge' for b (binary False symlink False)
143 144 merging b and a to b
144 145 my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622
145 146 premerge successful
146 147 b
147 148 grafting revision 5
148 149 searching for copies back to rev 1
149 150 resolving manifests
150 151 branchmerge: True, force: True, partial: False
151 152 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
152 153 e: remote is newer -> g
153 154 getting e
154 155 updating: e 1/1 files (100.00%)
155 156 e
156 157 grafting revision 4
157 158 searching for copies back to rev 1
158 159 resolving manifests
159 160 branchmerge: True, force: True, partial: False
160 161 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
161 162 d: remote is newer -> g
162 163 e: versions differ -> m
163 164 preserving e for resolve of e
164 165 getting d
165 166 updating: d 1/2 files (50.00%)
166 167 updating: e 2/2 files (100.00%)
167 168 picked tool 'internal:merge' for e (binary False symlink False)
168 169 merging e
169 170 my e@1905859650ec+ other e@9c233e8e184d ancestor e@68795b066622
170 171 warning: conflicts during merge.
171 172 merging e incomplete! (edit conflicts, then use 'hg resolve --mark')
172 173 abort: unresolved conflicts, can't continue
173 174 (use hg resolve and hg graft --continue)
174 175 [255]
175 176
176 177 Continue without resolve should fail:
177 178
178 179 $ hg graft -c
179 180 grafting revision 4
180 181 abort: unresolved merge conflicts (see hg help resolve)
181 182 [255]
182 183
183 184 Fix up:
184 185
185 186 $ echo b > e
186 187 $ hg resolve -m e
187 188
188 189 Continue with a revision should fail:
189 190
190 191 $ hg graft -c 6
191 192 abort: can't specify --continue and revisions
192 193 [255]
193 194
194 195 $ hg graft -c -r 6
195 196 abort: can't specify --continue and revisions
196 197 [255]
197 198
198 199 Continue for real, clobber usernames
199 200
200 201 $ hg graft -c -U
201 202 grafting revision 4
202 203 grafting revision 3
203 204
204 205 Compare with original:
205 206
206 207 $ hg diff -r 6
207 208 $ hg status --rev 0:. -C
208 209 M d
209 210 M e
210 211 A b
211 212 a
212 213 A c
213 214 a
214 215 R a
215 216
216 217 View graph:
217 218
218 219 $ hg --config extensions.graphlog= log -G --template '{author}@{rev}.{phase}: {desc}\n'
219 220 @ test@11.draft: 3
220 221 |
221 222 o test@10.draft: 4
222 223 |
223 224 o test@9.draft: 5
224 225 |
225 226 o bar@8.draft: 1
226 227 |
227 228 o foo@7.draft: 2
228 229 |
229 230 | o test@6.secret: 6
230 231 | |\
231 232 | | o test@5.draft: 5
232 233 | | |
233 234 | o | test@4.draft: 4
234 235 | |/
235 236 | o baz@3.public: 3
236 237 | |
237 238 | o test@2.public: 2
238 239 | |
239 240 | o bar@1.public: 1
240 241 |/
241 242 o test@0.public: 0
242 243
243 244 Graft again onto another branch should preserve the original source
244 245 $ hg up -q 0
245 246 $ echo 'g'>g
246 247 $ hg add g
247 248 $ hg ci -m 7
248 249 created new head
249 250 $ hg graft 7
250 251 grafting revision 7
251 252
252 253 $ hg log -r 7 --template '{rev}:{node}\n'
253 254 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82
254 255 $ hg log -r 2 --template '{rev}:{node}\n'
255 256 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4
256 257
257 258 $ hg log --debug -r tip
258 259 changeset: 13:9db0f28fd3747e92c57d015f53b5593aeec53c2d
259 260 tag: tip
260 261 phase: draft
261 262 parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f
262 263 parent: -1:0000000000000000000000000000000000000000
263 264 manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637
264 265 user: foo
265 266 date: Thu Jan 01 00:00:00 1970 +0000
266 267 files+: b
267 268 files-: a
268 269 extra: branch=default
269 270 extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4
270 271 description:
271 272 2
272 273
273 274
274 275 Disallow grafting an already grafted cset onto its original branch
275 276 $ hg up -q 6
276 277 $ hg graft 7
277 278 skipping already grafted revision 7 (was grafted from 2)
278 279 [255]
279 280
280 281 Disallow grafting already grafted csets with the same origin onto each other
281 282 $ hg up -q 13
282 283 $ hg graft 2
283 284 skipping already grafted revision 2
284 285 [255]
285 286 $ hg graft 7
286 287 skipping already grafted revision 7 (same origin 2)
287 288 [255]
288 289
289 290 $ hg up -q 7
290 291 $ hg graft 2
291 292 skipping already grafted revision 2
292 293 [255]
293 294 $ hg graft tip
294 295 skipping already grafted revision 13 (same origin 2)
295 296 [255]
296 297
297 298 Graft with --log
298 299
299 300 $ hg up -Cq 1
300 301 $ hg graft 3 --log -u foo
301 302 grafting revision 3
302 303 warning: can't find ancestor for 'c' copied from 'b'!
303 304 $ hg log --template '{rev} {parents} {desc}\n' -r tip
304 305 14 1:5d205f8b35b6 3
305 306 (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
306 307
307 308 Resolve conflicted graft
308 309 $ hg up -q 0
309 310 $ echo b > a
310 311 $ hg ci -m 8
311 312 created new head
312 313 $ echo a > a
313 314 $ hg ci -m 9
314 315 $ hg graft 1 --tool internal:fail
315 316 grafting revision 1
316 317 abort: unresolved conflicts, can't continue
317 318 (use hg resolve and hg graft --continue)
318 319 [255]
319 320 $ hg resolve --all
320 321 merging a
321 322 $ hg graft -c
322 323 grafting revision 1
323 324 $ hg export tip --git
324 325 # HG changeset patch
325 326 # User bar
326 327 # Date 0 0
328 # Thu Jan 01 00:00:00 1970 +0000
327 329 # Node ID 64ecd9071ce83c6e62f538d8ce7709d53f32ebf7
328 330 # Parent 4bdb9a9d0b84ffee1d30f0dfc7744cade17aa19c
329 331 1
330 332
331 333 diff --git a/a b/a
332 334 --- a/a
333 335 +++ b/a
334 336 @@ -1,1 +1,1 @@
335 337 -a
336 338 +b
337 339
338 340 Resolve conflicted graft with rename
339 341 $ echo c > a
340 342 $ hg ci -m 10
341 343 $ hg graft 2 --tool internal:fail
342 344 grafting revision 2
343 345 abort: unresolved conflicts, can't continue
344 346 (use hg resolve and hg graft --continue)
345 347 [255]
346 348 $ hg resolve --all
347 349 merging a and b to b
348 350 $ hg graft -c
349 351 grafting revision 2
350 352 $ hg export tip --git
351 353 # HG changeset patch
352 354 # User test
353 355 # Date 0 0
356 # Thu Jan 01 00:00:00 1970 +0000
354 357 # Node ID 2e80e1351d6ed50302fe1e05f8bd1d4d412b6e11
355 358 # Parent e5a51ae854a8bbaaf25cc5c6a57ff46042dadbb4
356 359 2
357 360
358 361 diff --git a/a b/b
359 362 rename from a
360 363 rename to b
361 364
362 365 Test simple origin(), with and without args
363 366 $ hg log -r 'origin()'
364 367 changeset: 1:5d205f8b35b6
365 368 user: bar
366 369 date: Thu Jan 01 00:00:00 1970 +0000
367 370 summary: 1
368 371
369 372 changeset: 2:5c095ad7e90f
370 373 user: test
371 374 date: Thu Jan 01 00:00:00 1970 +0000
372 375 summary: 2
373 376
374 377 changeset: 3:4c60f11aa304
375 378 user: baz
376 379 date: Thu Jan 01 00:00:00 1970 +0000
377 380 summary: 3
378 381
379 382 changeset: 4:9c233e8e184d
380 383 user: test
381 384 date: Thu Jan 01 00:00:00 1970 +0000
382 385 summary: 4
383 386
384 387 changeset: 5:97f8bfe72746
385 388 branch: stable
386 389 parent: 3:4c60f11aa304
387 390 user: test
388 391 date: Thu Jan 01 00:00:00 1970 +0000
389 392 summary: 5
390 393
391 394 $ hg log -r 'origin(7)'
392 395 changeset: 2:5c095ad7e90f
393 396 user: test
394 397 date: Thu Jan 01 00:00:00 1970 +0000
395 398 summary: 2
396 399
397 400 Now transplant a graft to test following through copies
398 401 $ hg up -q 0
399 402 $ hg branch -q dev
400 403 $ hg ci -qm "dev branch"
401 404 $ hg --config extensions.transplant= transplant -q 7
402 405 $ hg log -r 'origin(.)'
403 406 changeset: 2:5c095ad7e90f
404 407 user: test
405 408 date: Thu Jan 01 00:00:00 1970 +0000
406 409 summary: 2
407 410
408 411 Test simple destination
409 412 $ hg log -r 'destination()'
410 413 changeset: 7:ef0ef43d49e7
411 414 parent: 0:68795b066622
412 415 user: foo
413 416 date: Thu Jan 01 00:00:00 1970 +0000
414 417 summary: 2
415 418
416 419 changeset: 8:6b9e5368ca4e
417 420 user: bar
418 421 date: Thu Jan 01 00:00:00 1970 +0000
419 422 summary: 1
420 423
421 424 changeset: 9:1905859650ec
422 425 user: test
423 426 date: Thu Jan 01 00:00:00 1970 +0000
424 427 summary: 5
425 428
426 429 changeset: 10:52dc0b4c6907
427 430 user: test
428 431 date: Thu Jan 01 00:00:00 1970 +0000
429 432 summary: 4
430 433
431 434 changeset: 11:882b35362a6b
432 435 user: test
433 436 date: Thu Jan 01 00:00:00 1970 +0000
434 437 summary: 3
435 438
436 439 changeset: 13:9db0f28fd374
437 440 user: foo
438 441 date: Thu Jan 01 00:00:00 1970 +0000
439 442 summary: 2
440 443
441 444 changeset: 14:f64defefacee
442 445 parent: 1:5d205f8b35b6
443 446 user: foo
444 447 date: Thu Jan 01 00:00:00 1970 +0000
445 448 summary: 3
446 449
447 450 changeset: 17:64ecd9071ce8
448 451 user: bar
449 452 date: Thu Jan 01 00:00:00 1970 +0000
450 453 summary: 1
451 454
452 455 changeset: 19:2e80e1351d6e
453 456 user: test
454 457 date: Thu Jan 01 00:00:00 1970 +0000
455 458 summary: 2
456 459
457 460 changeset: 21:7e61b508e709
458 461 branch: dev
459 462 tag: tip
460 463 user: foo
461 464 date: Thu Jan 01 00:00:00 1970 +0000
462 465 summary: 2
463 466
464 467 $ hg log -r 'destination(2)'
465 468 changeset: 7:ef0ef43d49e7
466 469 parent: 0:68795b066622
467 470 user: foo
468 471 date: Thu Jan 01 00:00:00 1970 +0000
469 472 summary: 2
470 473
471 474 changeset: 13:9db0f28fd374
472 475 user: foo
473 476 date: Thu Jan 01 00:00:00 1970 +0000
474 477 summary: 2
475 478
476 479 changeset: 19:2e80e1351d6e
477 480 user: test
478 481 date: Thu Jan 01 00:00:00 1970 +0000
479 482 summary: 2
480 483
481 484 changeset: 21:7e61b508e709
482 485 branch: dev
483 486 tag: tip
484 487 user: foo
485 488 date: Thu Jan 01 00:00:00 1970 +0000
486 489 summary: 2
487 490
488 491 Transplants of grafts can find a destination...
489 492 $ hg log -r 'destination(7)'
490 493 changeset: 21:7e61b508e709
491 494 branch: dev
492 495 tag: tip
493 496 user: foo
494 497 date: Thu Jan 01 00:00:00 1970 +0000
495 498 summary: 2
496 499
497 500 ... grafts of grafts unfortunately can't
498 501 $ hg graft -q 13
499 502 $ hg log -r 'destination(13)'
500 503 All copies of a cset
501 504 $ hg log -r 'origin(13) or destination(origin(13))'
502 505 changeset: 2:5c095ad7e90f
503 506 user: test
504 507 date: Thu Jan 01 00:00:00 1970 +0000
505 508 summary: 2
506 509
507 510 changeset: 7:ef0ef43d49e7
508 511 parent: 0:68795b066622
509 512 user: foo
510 513 date: Thu Jan 01 00:00:00 1970 +0000
511 514 summary: 2
512 515
513 516 changeset: 13:9db0f28fd374
514 517 user: foo
515 518 date: Thu Jan 01 00:00:00 1970 +0000
516 519 summary: 2
517 520
518 521 changeset: 19:2e80e1351d6e
519 522 user: test
520 523 date: Thu Jan 01 00:00:00 1970 +0000
521 524 summary: 2
522 525
523 526 changeset: 21:7e61b508e709
524 527 branch: dev
525 528 user: foo
526 529 date: Thu Jan 01 00:00:00 1970 +0000
527 530 summary: 2
528 531
529 532 changeset: 22:1313d0a825e2
530 533 branch: dev
531 534 tag: tip
532 535 user: foo
533 536 date: Thu Jan 01 00:00:00 1970 +0000
534 537 summary: 2
535 538
@@ -1,317 +1,318 b''
1 1 $ . "$TESTDIR/histedit-helpers.sh"
2 2
3 3 $ cat >> $HGRCPATH <<EOF
4 4 > [extensions]
5 5 > graphlog=
6 6 > histedit=
7 7 > EOF
8 8
9 9 $ EDITED="$TESTTMP/editedhistory"
10 10 $ cat > $EDITED <<EOF
11 11 > pick e860deea161a e
12 12 > pick 652413bf663e f
13 13 > fold 177f92b77385 c
14 14 > pick 055a42cdd887 d
15 15 > EOF
16 16 $ initrepo ()
17 17 > {
18 18 > hg init r
19 19 > cd r
20 20 > for x in a b c d e f ; do
21 21 > echo $x > $x
22 22 > hg add $x
23 23 > hg ci -m $x
24 24 > done
25 25 > }
26 26
27 27 $ initrepo
28 28
29 29 log before edit
30 30 $ hg log --graph
31 31 @ changeset: 5:652413bf663e
32 32 | tag: tip
33 33 | user: test
34 34 | date: Thu Jan 01 00:00:00 1970 +0000
35 35 | summary: f
36 36 |
37 37 o changeset: 4:e860deea161a
38 38 | user: test
39 39 | date: Thu Jan 01 00:00:00 1970 +0000
40 40 | summary: e
41 41 |
42 42 o changeset: 3:055a42cdd887
43 43 | user: test
44 44 | date: Thu Jan 01 00:00:00 1970 +0000
45 45 | summary: d
46 46 |
47 47 o changeset: 2:177f92b77385
48 48 | user: test
49 49 | date: Thu Jan 01 00:00:00 1970 +0000
50 50 | summary: c
51 51 |
52 52 o changeset: 1:d2ae7f538514
53 53 | user: test
54 54 | date: Thu Jan 01 00:00:00 1970 +0000
55 55 | summary: b
56 56 |
57 57 o changeset: 0:cb9a9f314b8b
58 58 user: test
59 59 date: Thu Jan 01 00:00:00 1970 +0000
60 60 summary: a
61 61
62 62
63 63 edit the history
64 64 $ HGEDITOR="cat \"$EDITED\" > " hg histedit 177f92b77385 2>&1 | fixbundle
65 65 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
66 66 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 67 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
68 68 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
69 69 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
70 70 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
71 71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 72
73 73 log after edit
74 74 $ hg log --graph
75 75 @ changeset: 4:7e0a290363ed
76 76 | tag: tip
77 77 | user: test
78 78 | date: Thu Jan 01 00:00:00 1970 +0000
79 79 | summary: d
80 80 |
81 81 o changeset: 3:5e24935bad3d
82 82 | user: test
83 83 | date: Thu Jan 01 00:00:00 1970 +0000
84 84 | summary: pick e860deea161a e
85 85 |
86 86 o changeset: 2:ee283cb5f2d5
87 87 | user: test
88 88 | date: Thu Jan 01 00:00:00 1970 +0000
89 89 | summary: e
90 90 |
91 91 o changeset: 1:d2ae7f538514
92 92 | user: test
93 93 | date: Thu Jan 01 00:00:00 1970 +0000
94 94 | summary: b
95 95 |
96 96 o changeset: 0:cb9a9f314b8b
97 97 user: test
98 98 date: Thu Jan 01 00:00:00 1970 +0000
99 99 summary: a
100 100
101 101
102 102 post-fold manifest
103 103 $ hg manifest
104 104 a
105 105 b
106 106 c
107 107 d
108 108 e
109 109 f
110 110
111 111
112 112 check histedit_source
113 113
114 114 $ hg log --debug --rev 3
115 115 changeset: 3:5e24935bad3d5a4486de3b90f233e991465ced72
116 116 phase: draft
117 117 parent: 2:ee283cb5f2d5955443f23a27b697a04339e9a39a
118 118 parent: -1:0000000000000000000000000000000000000000
119 119 manifest: 3:81eede616954057198ead0b2c73b41d1f392829a
120 120 user: test
121 121 date: Thu Jan 01 00:00:00 1970 +0000
122 122 files+: c f
123 123 extra: branch=default
124 124 extra: histedit_source=a4f7421b80f79fcc59fff01bcbf4a53d127dd6d3,177f92b773850b59254aa5e923436f921b55483b
125 125 description:
126 126 pick e860deea161a e
127 127 pick 652413bf663e f
128 128 fold 177f92b77385 c
129 129 pick 055a42cdd887 d
130 130
131 131
132 132
133 133 $ cd ..
134 134
135 135 folding and creating no new change doesn't break:
136 136 $ mkdir fold-to-empty-test
137 137 $ cd fold-to-empty-test
138 138 $ hg init
139 139 $ printf "1\n2\n3\n" > file
140 140 $ hg add file
141 141 $ hg commit -m '1+2+3'
142 142 $ echo 4 >> file
143 143 $ hg commit -m '+4'
144 144 $ echo 5 >> file
145 145 $ hg commit -m '+5'
146 146 $ echo 6 >> file
147 147 $ hg commit -m '+6'
148 148 $ hg log --graph
149 149 @ changeset: 3:251d831eeec5
150 150 | tag: tip
151 151 | user: test
152 152 | date: Thu Jan 01 00:00:00 1970 +0000
153 153 | summary: +6
154 154 |
155 155 o changeset: 2:888f9082bf99
156 156 | user: test
157 157 | date: Thu Jan 01 00:00:00 1970 +0000
158 158 | summary: +5
159 159 |
160 160 o changeset: 1:617f94f13c0f
161 161 | user: test
162 162 | date: Thu Jan 01 00:00:00 1970 +0000
163 163 | summary: +4
164 164 |
165 165 o changeset: 0:0189ba417d34
166 166 user: test
167 167 date: Thu Jan 01 00:00:00 1970 +0000
168 168 summary: 1+2+3
169 169
170 170
171 171 $ cat > editor.py <<EOF
172 172 > import re, sys
173 173 > rules = sys.argv[1]
174 174 > data = open(rules).read()
175 175 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+5)', r'drop \1', data)
176 176 > data = re.sub(r'pick ([0-9a-f]{12} 2 \+6)', r'fold \1', data)
177 177 > open(rules, 'w').write(data)
178 178 > EOF
179 179
180 180 $ HGEDITOR='python editor.py' hg histedit 1
181 181 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
182 182 merging file
183 183 warning: conflicts during merge.
184 184 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
185 185 abort: Fix up the change and run hg histedit --continue
186 186 [255]
187 187 There were conflicts, we keep P1 content. This
188 188 should effectively drop the changes from +6.
189 189 $ hg status
190 190 M file
191 191 ? editor.py
192 192 ? file.orig
193 193 $ hg resolve -l
194 194 U file
195 195 $ hg revert -r 'p1()' file
196 196 $ hg resolve --mark file
197 197 $ hg histedit --continue
198 198 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
199 199 saved backup bundle to $TESTTMP/*-backup.hg (glob)
200 200 $ hg log --graph
201 201 @ changeset: 1:617f94f13c0f
202 202 | tag: tip
203 203 | user: test
204 204 | date: Thu Jan 01 00:00:00 1970 +0000
205 205 | summary: +4
206 206 |
207 207 o changeset: 0:0189ba417d34
208 208 user: test
209 209 date: Thu Jan 01 00:00:00 1970 +0000
210 210 summary: 1+2+3
211 211
212 212
213 213 $ cd ..
214 214
215 215 Test corner case where folded revision is separated from its parent by a
216 216 dropped revision.
217 217
218 218
219 219 $ hg init fold-with-dropped
220 220 $ cd fold-with-dropped
221 221 $ printf "1\n2\n3\n" > file
222 222 $ hg commit -Am '1+2+3'
223 223 adding file
224 224 $ echo 4 >> file
225 225 $ hg commit -m '+4'
226 226 $ echo 5 >> file
227 227 $ hg commit -m '+5'
228 228 $ echo 6 >> file
229 229 $ hg commit -m '+6'
230 230 $ hg log -G --template '{rev}:{node|short} {desc|firstline}\n'
231 231 @ 3:251d831eeec5 +6
232 232 |
233 233 o 2:888f9082bf99 +5
234 234 |
235 235 o 1:617f94f13c0f +4
236 236 |
237 237 o 0:0189ba417d34 1+2+3
238 238
239 239 $ EDITED="$TESTTMP/editcommands"
240 240 $ cat > $EDITED <<EOF
241 241 > pick 617f94f13c0f 1 +4
242 242 > drop 888f9082bf99 2 +5
243 243 > fold 251d831eeec5 3 +6
244 244 > EOF
245 245 $ HGEDITOR="cat $EDITED >" hg histedit 1
246 246 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
247 247 merging file
248 248 warning: conflicts during merge.
249 249 merging file incomplete! (edit conflicts, then use 'hg resolve --mark')
250 250 abort: Fix up the change and run hg histedit --continue
251 251 [255]
252 252 $ cat > file << EOF
253 253 > 1
254 254 > 2
255 255 > 3
256 256 > 4
257 257 > 5
258 258 > EOF
259 259 $ hg resolve --mark file
260 260 $ hg commit -m '+5.2'
261 261 created new head
262 262 $ echo 6 >> file
263 263 $ HGEDITOR=cat hg histedit --continue
264 264 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 265 +4
266 266 ***
267 267 +5.2
268 268 ***
269 269 +6
270 270
271 271
272 272
273 273 HG: Enter commit message. Lines beginning with 'HG:' are removed.
274 274 HG: Leave message empty to abort commit.
275 275 HG: --
276 276 HG: user: test
277 277 HG: branch 'default'
278 278 HG: changed file
279 279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 280 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
281 281 saved backup bundle to $TESTTMP/fold-with-dropped/.hg/strip-backup/617f94f13c0f-backup.hg (glob)
282 282 $ hg log -G
283 283 @ changeset: 1:10c647b2cdd5
284 284 | tag: tip
285 285 | user: test
286 286 | date: Thu Jan 01 00:00:00 1970 +0000
287 287 | summary: +4
288 288 |
289 289 o changeset: 0:0189ba417d34
290 290 user: test
291 291 date: Thu Jan 01 00:00:00 1970 +0000
292 292 summary: 1+2+3
293 293
294 294 $ hg export tip
295 295 # HG changeset patch
296 296 # User test
297 297 # Date 0 0
298 # Thu Jan 01 00:00:00 1970 +0000
298 299 # Node ID 10c647b2cdd54db0603ecb99b2ff5ce66d5a5323
299 300 # Parent 0189ba417d34df9dda55f88b637dcae9917b5964
300 301 +4
301 302 ***
302 303 +5.2
303 304 ***
304 305 +6
305 306
306 307 diff -r 0189ba417d34 -r 10c647b2cdd5 file
307 308 --- a/file Thu Jan 01 00:00:00 1970 +0000
308 309 +++ b/file Thu Jan 01 00:00:00 1970 +0000
309 310 @@ -1,3 +1,6 @@
310 311 1
311 312 2
312 313 3
313 314 +4
314 315 +5
315 316 +6
316 317 $ cd ..
317 318
@@ -1,1158 +1,1159 b''
1 1 $ hg init a
2 2 $ mkdir a/d1
3 3 $ mkdir a/d1/d2
4 4 $ echo line 1 > a/a
5 5 $ echo line 1 > a/d1/d2/a
6 6 $ hg --cwd a ci -Ama
7 7 adding a
8 8 adding d1/d2/a
9 9
10 10 $ echo line 2 >> a/a
11 11 $ hg --cwd a ci -u someone -d '1 0' -m'second change'
12 12
13 13 import with no args:
14 14
15 15 $ hg --cwd a import
16 16 abort: need at least one patch to import
17 17 [255]
18 18
19 19 generate patches for the test
20 20
21 21 $ hg --cwd a export tip > exported-tip.patch
22 22 $ hg --cwd a diff -r0:1 > diffed-tip.patch
23 23
24 24
25 25 import exported patch
26 26
27 27 $ hg clone -r0 a b
28 28 adding changesets
29 29 adding manifests
30 30 adding file changes
31 31 added 1 changesets with 2 changes to 2 files
32 32 updating to branch default
33 33 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ hg --cwd b import ../exported-tip.patch
35 35 applying ../exported-tip.patch
36 36
37 message and committer should be same
37 message and committer and date should be same
38 38
39 39 $ hg --cwd b tip
40 40 changeset: 1:1d4bd90af0e4
41 41 tag: tip
42 42 user: someone
43 43 date: Thu Jan 01 00:00:01 1970 +0000
44 44 summary: second change
45 45
46 46 $ rm -r b
47 47
48 48
49 49 import exported patch with external patcher
50 50
51 51 $ cat > dummypatch.py <<EOF
52 52 > print 'patching file a'
53 53 > file('a', 'wb').write('line2\n')
54 54 > EOF
55 55 $ hg clone -r0 a b
56 56 adding changesets
57 57 adding manifests
58 58 adding file changes
59 59 added 1 changesets with 2 changes to 2 files
60 60 updating to branch default
61 61 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
62 62 $ hg --config ui.patch='python ../dummypatch.py' --cwd b import ../exported-tip.patch
63 63 applying ../exported-tip.patch
64 64 $ cat b/a
65 65 line2
66 66 $ rm -r b
67 67
68 68
69 69 import of plain diff should fail without message
70 70
71 71 $ hg clone -r0 a b
72 72 adding changesets
73 73 adding manifests
74 74 adding file changes
75 75 added 1 changesets with 2 changes to 2 files
76 76 updating to branch default
77 77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 78 $ hg --cwd b import ../diffed-tip.patch
79 79 applying ../diffed-tip.patch
80 80 abort: empty commit message
81 81 [255]
82 82 $ rm -r b
83 83
84 84
85 85 import of plain diff should be ok with message
86 86
87 87 $ hg clone -r0 a b
88 88 adding changesets
89 89 adding manifests
90 90 adding file changes
91 91 added 1 changesets with 2 changes to 2 files
92 92 updating to branch default
93 93 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
94 94 $ hg --cwd b import -mpatch ../diffed-tip.patch
95 95 applying ../diffed-tip.patch
96 96 $ rm -r b
97 97
98 98
99 99 import of plain diff with specific date and user
100 100
101 101 $ hg clone -r0 a b
102 102 adding changesets
103 103 adding manifests
104 104 adding file changes
105 105 added 1 changesets with 2 changes to 2 files
106 106 updating to branch default
107 107 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 108 $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
109 109 applying ../diffed-tip.patch
110 110 $ hg -R b tip -pv
111 111 changeset: 1:ca68f19f3a40
112 112 tag: tip
113 113 user: user@nowhere.net
114 114 date: Thu Jan 01 00:00:01 1970 +0000
115 115 files: a
116 116 description:
117 117 patch
118 118
119 119
120 120 diff -r 80971e65b431 -r ca68f19f3a40 a
121 121 --- a/a Thu Jan 01 00:00:00 1970 +0000
122 122 +++ b/a Thu Jan 01 00:00:01 1970 +0000
123 123 @@ -1,1 +1,2 @@
124 124 line 1
125 125 +line 2
126 126
127 127 $ rm -r b
128 128
129 129
130 130 import of plain diff should be ok with --no-commit
131 131
132 132 $ hg clone -r0 a b
133 133 adding changesets
134 134 adding manifests
135 135 adding file changes
136 136 added 1 changesets with 2 changes to 2 files
137 137 updating to branch default
138 138 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
139 139 $ hg --cwd b import --no-commit ../diffed-tip.patch
140 140 applying ../diffed-tip.patch
141 141 $ hg --cwd b diff --nodates
142 142 diff -r 80971e65b431 a
143 143 --- a/a
144 144 +++ b/a
145 145 @@ -1,1 +1,2 @@
146 146 line 1
147 147 +line 2
148 148 $ rm -r b
149 149
150 150
151 151 import of malformed plain diff should fail
152 152
153 153 $ hg clone -r0 a b
154 154 adding changesets
155 155 adding manifests
156 156 adding file changes
157 157 added 1 changesets with 2 changes to 2 files
158 158 updating to branch default
159 159 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 160 $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
161 161 $ hg --cwd b import -mpatch ../broken.patch
162 162 applying ../broken.patch
163 163 abort: bad hunk #1
164 164 [255]
165 165 $ rm -r b
166 166
167 167
168 168 hg -R repo import
169 169 put the clone in a subdir - having a directory named "a"
170 170 used to hide a bug.
171 171
172 172 $ mkdir dir
173 173 $ hg clone -r0 a dir/b
174 174 adding changesets
175 175 adding manifests
176 176 adding file changes
177 177 added 1 changesets with 2 changes to 2 files
178 178 updating to branch default
179 179 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
180 180 $ cd dir
181 181 $ hg -R b import ../exported-tip.patch
182 182 applying ../exported-tip.patch
183 183 $ cd ..
184 184 $ rm -r dir
185 185
186 186
187 187 import from stdin
188 188
189 189 $ hg clone -r0 a b
190 190 adding changesets
191 191 adding manifests
192 192 adding file changes
193 193 added 1 changesets with 2 changes to 2 files
194 194 updating to branch default
195 195 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
196 196 $ hg --cwd b import - < exported-tip.patch
197 197 applying patch from stdin
198 198 $ rm -r b
199 199
200 200
201 201 import two patches in one stream
202 202
203 203 $ hg init b
204 204 $ hg --cwd a export 0:tip | hg --cwd b import -
205 205 applying patch from stdin
206 206 $ hg --cwd a id
207 207 1d4bd90af0e4 tip
208 208 $ hg --cwd b id
209 209 1d4bd90af0e4 tip
210 210 $ rm -r b
211 211
212 212
213 213 override commit message
214 214
215 215 $ hg clone -r0 a b
216 216 adding changesets
217 217 adding manifests
218 218 adding file changes
219 219 added 1 changesets with 2 changes to 2 files
220 220 updating to branch default
221 221 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 222 $ hg --cwd b import -m 'override' - < exported-tip.patch
223 223 applying patch from stdin
224 224 $ hg --cwd b tip | grep override
225 225 summary: override
226 226 $ rm -r b
227 227
228 228 $ cat > mkmsg.py <<EOF
229 229 > import email.Message, sys
230 230 > msg = email.Message.Message()
231 231 > patch = open(sys.argv[1], 'rb').read()
232 232 > msg.set_payload('email commit message\n' + patch)
233 233 > msg['Subject'] = 'email patch'
234 234 > msg['From'] = 'email patcher'
235 235 > file(sys.argv[2], 'wb').write(msg.as_string())
236 236 > EOF
237 237
238 238
239 239 plain diff in email, subject, message body
240 240
241 241 $ hg clone -r0 a b
242 242 adding changesets
243 243 adding manifests
244 244 adding file changes
245 245 added 1 changesets with 2 changes to 2 files
246 246 updating to branch default
247 247 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
248 248 $ python mkmsg.py diffed-tip.patch msg.patch
249 249 $ hg --cwd b import ../msg.patch
250 250 applying ../msg.patch
251 251 $ hg --cwd b tip | grep email
252 252 user: email patcher
253 253 summary: email patch
254 254 $ rm -r b
255 255
256 256
257 257 plain diff in email, no subject, message body
258 258
259 259 $ hg clone -r0 a b
260 260 adding changesets
261 261 adding manifests
262 262 adding file changes
263 263 added 1 changesets with 2 changes to 2 files
264 264 updating to branch default
265 265 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
266 266 $ grep -v '^Subject:' msg.patch | hg --cwd b import -
267 267 applying patch from stdin
268 268 $ rm -r b
269 269
270 270
271 271 plain diff in email, subject, no message body
272 272
273 273 $ hg clone -r0 a b
274 274 adding changesets
275 275 adding manifests
276 276 adding file changes
277 277 added 1 changesets with 2 changes to 2 files
278 278 updating to branch default
279 279 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 280 $ grep -v '^email ' msg.patch | hg --cwd b import -
281 281 applying patch from stdin
282 282 $ rm -r b
283 283
284 284
285 285 plain diff in email, no subject, no message body, should fail
286 286
287 287 $ hg clone -r0 a b
288 288 adding changesets
289 289 adding manifests
290 290 adding file changes
291 291 added 1 changesets with 2 changes to 2 files
292 292 updating to branch default
293 293 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
294 294 $ egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
295 295 applying patch from stdin
296 296 abort: empty commit message
297 297 [255]
298 298 $ rm -r b
299 299
300 300
301 301 hg export in email, should use patch header
302 302
303 303 $ hg clone -r0 a b
304 304 adding changesets
305 305 adding manifests
306 306 adding file changes
307 307 added 1 changesets with 2 changes to 2 files
308 308 updating to branch default
309 309 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
310 310 $ python mkmsg.py exported-tip.patch msg.patch
311 311 $ cat msg.patch | hg --cwd b import -
312 312 applying patch from stdin
313 313 $ hg --cwd b tip | grep second
314 314 summary: second change
315 315 $ rm -r b
316 316
317 317
318 318 subject: duplicate detection, removal of [PATCH]
319 319 The '---' tests the gitsendmail handling without proper mail headers
320 320
321 321 $ cat > mkmsg2.py <<EOF
322 322 > import email.Message, sys
323 323 > msg = email.Message.Message()
324 324 > patch = open(sys.argv[1], 'rb').read()
325 325 > msg.set_payload('email patch\n\nnext line\n---\n' + patch)
326 326 > msg['Subject'] = '[PATCH] email patch'
327 327 > msg['From'] = 'email patcher'
328 328 > file(sys.argv[2], 'wb').write(msg.as_string())
329 329 > EOF
330 330
331 331
332 332 plain diff in email, [PATCH] subject, message body with subject
333 333
334 334 $ hg clone -r0 a b
335 335 adding changesets
336 336 adding manifests
337 337 adding file changes
338 338 added 1 changesets with 2 changes to 2 files
339 339 updating to branch default
340 340 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 341 $ python mkmsg2.py diffed-tip.patch msg.patch
342 342 $ cat msg.patch | hg --cwd b import -
343 343 applying patch from stdin
344 344 $ hg --cwd b tip --template '{desc}\n'
345 345 email patch
346 346
347 347 next line
348 348 ---
349 349 $ rm -r b
350 350
351 351
352 352 Issue963: Parent of working dir incorrect after import of multiple
353 353 patches and rollback
354 354
355 355 We weren't backing up the correct dirstate file when importing many
356 356 patches: import patch1 patch2; rollback
357 357
358 358 $ echo line 3 >> a/a
359 359 $ hg --cwd a ci -m'third change'
360 360 $ hg --cwd a export -o '../patch%R' 1 2
361 361 $ hg clone -qr0 a b
362 362 $ hg --cwd b parents --template 'parent: {rev}\n'
363 363 parent: 0
364 364 $ hg --cwd b import -v ../patch1 ../patch2
365 365 applying ../patch1
366 366 patching file a
367 367 a
368 368 created 1d4bd90af0e4
369 369 applying ../patch2
370 370 patching file a
371 371 a
372 372 created 6d019af21222
373 373 $ hg --cwd b rollback
374 374 repository tip rolled back to revision 0 (undo import)
375 375 working directory now based on revision 0
376 376 $ hg --cwd b parents --template 'parent: {rev}\n'
377 377 parent: 0
378 378 $ rm -r b
379 379
380 380
381 381 importing a patch in a subdirectory failed at the commit stage
382 382
383 383 $ echo line 2 >> a/d1/d2/a
384 384 $ hg --cwd a ci -u someoneelse -d '1 0' -m'subdir change'
385 385
386 386 hg import in a subdirectory
387 387
388 388 $ hg clone -r0 a b
389 389 adding changesets
390 390 adding manifests
391 391 adding file changes
392 392 added 1 changesets with 2 changes to 2 files
393 393 updating to branch default
394 394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 395 $ hg --cwd a export tip > tmp
396 396 $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
397 397 $ dir=`pwd`
398 398 $ cd b/d1/d2 2>&1 > /dev/null
399 399 $ hg import ../../../subdir-tip.patch
400 400 applying ../../../subdir-tip.patch
401 401 $ cd "$dir"
402 402
403 403 message should be 'subdir change'
404 404 committer should be 'someoneelse'
405 405
406 406 $ hg --cwd b tip
407 407 changeset: 1:3577f5aea227
408 408 tag: tip
409 409 user: someoneelse
410 410 date: Thu Jan 01 00:00:01 1970 +0000
411 411 summary: subdir change
412 412
413 413
414 414 should be empty
415 415
416 416 $ hg --cwd b status
417 417
418 418
419 419 Test fuzziness (ambiguous patch location, fuzz=2)
420 420
421 421 $ hg init fuzzy
422 422 $ cd fuzzy
423 423 $ echo line1 > a
424 424 $ echo line0 >> a
425 425 $ echo line3 >> a
426 426 $ hg ci -Am adda
427 427 adding a
428 428 $ echo line1 > a
429 429 $ echo line2 >> a
430 430 $ echo line0 >> a
431 431 $ echo line3 >> a
432 432 $ hg ci -m change a
433 433 $ hg export tip > fuzzy-tip.patch
434 434 $ hg up -C 0
435 435 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
436 436 $ echo line1 > a
437 437 $ echo line0 >> a
438 438 $ echo line1 >> a
439 439 $ echo line0 >> a
440 440 $ hg ci -m brancha
441 441 created new head
442 442 $ hg import --no-commit -v fuzzy-tip.patch
443 443 applying fuzzy-tip.patch
444 444 patching file a
445 445 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
446 446 applied to working directory
447 447 $ hg revert -a
448 448 reverting a
449 449
450 450
451 451 import with --no-commit should have written .hg/last-message.txt
452 452
453 453 $ cat .hg/last-message.txt
454 454 change (no-eol)
455 455
456 456
457 457 test fuzziness with eol=auto
458 458
459 459 $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
460 460 applying fuzzy-tip.patch
461 461 patching file a
462 462 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
463 463 applied to working directory
464 464 $ cd ..
465 465
466 466
467 467 Test hunk touching empty files (issue906)
468 468
469 469 $ hg init empty
470 470 $ cd empty
471 471 $ touch a
472 472 $ touch b1
473 473 $ touch c1
474 474 $ echo d > d
475 475 $ hg ci -Am init
476 476 adding a
477 477 adding b1
478 478 adding c1
479 479 adding d
480 480 $ echo a > a
481 481 $ echo b > b1
482 482 $ hg mv b1 b2
483 483 $ echo c > c1
484 484 $ hg copy c1 c2
485 485 $ rm d
486 486 $ touch d
487 487 $ hg diff --git
488 488 diff --git a/a b/a
489 489 --- a/a
490 490 +++ b/a
491 491 @@ -0,0 +1,1 @@
492 492 +a
493 493 diff --git a/b1 b/b2
494 494 rename from b1
495 495 rename to b2
496 496 --- a/b1
497 497 +++ b/b2
498 498 @@ -0,0 +1,1 @@
499 499 +b
500 500 diff --git a/c1 b/c1
501 501 --- a/c1
502 502 +++ b/c1
503 503 @@ -0,0 +1,1 @@
504 504 +c
505 505 diff --git a/c1 b/c2
506 506 copy from c1
507 507 copy to c2
508 508 --- a/c1
509 509 +++ b/c2
510 510 @@ -0,0 +1,1 @@
511 511 +c
512 512 diff --git a/d b/d
513 513 --- a/d
514 514 +++ b/d
515 515 @@ -1,1 +0,0 @@
516 516 -d
517 517 $ hg ci -m empty
518 518 $ hg export --git tip > empty.diff
519 519 $ hg up -C 0
520 520 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
521 521 $ hg import empty.diff
522 522 applying empty.diff
523 523 $ for name in a b1 b2 c1 c2 d; do
524 524 > echo % $name file
525 525 > test -f $name && cat $name
526 526 > done
527 527 % a file
528 528 a
529 529 % b1 file
530 530 % b2 file
531 531 b
532 532 % c1 file
533 533 c
534 534 % c2 file
535 535 c
536 536 % d file
537 537 $ cd ..
538 538
539 539
540 540 Test importing a patch ending with a binary file removal
541 541
542 542 $ hg init binaryremoval
543 543 $ cd binaryremoval
544 544 $ echo a > a
545 545 $ python -c "file('b', 'wb').write('a\x00b')"
546 546 $ hg ci -Am addall
547 547 adding a
548 548 adding b
549 549 $ hg rm a
550 550 $ hg rm b
551 551 $ hg st
552 552 R a
553 553 R b
554 554 $ hg ci -m remove
555 555 $ hg export --git . > remove.diff
556 556 $ cat remove.diff | grep git
557 557 diff --git a/a b/a
558 558 diff --git a/b b/b
559 559 $ hg up -C 0
560 560 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
561 561 $ hg import remove.diff
562 562 applying remove.diff
563 563 $ hg manifest
564 564 $ cd ..
565 565
566 566
567 567 Issue927: test update+rename with common name
568 568
569 569 $ hg init t
570 570 $ cd t
571 571 $ touch a
572 572 $ hg ci -Am t
573 573 adding a
574 574 $ echo a > a
575 575
576 576 Here, bfile.startswith(afile)
577 577
578 578 $ hg copy a a2
579 579 $ hg ci -m copya
580 580 $ hg export --git tip > copy.diff
581 581 $ hg up -C 0
582 582 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
583 583 $ hg import copy.diff
584 584 applying copy.diff
585 585
586 586 a should contain an 'a'
587 587
588 588 $ cat a
589 589 a
590 590
591 591 and a2 should have duplicated it
592 592
593 593 $ cat a2
594 594 a
595 595 $ cd ..
596 596
597 597
598 598 test -p0
599 599
600 600 $ hg init p0
601 601 $ cd p0
602 602 $ echo a > a
603 603 $ hg ci -Am t
604 604 adding a
605 605 $ hg import -p foo
606 606 abort: invalid value 'foo' for option -p, expected int
607 607 [255]
608 608 $ hg import -p0 - << EOF
609 609 > foobar
610 610 > --- a Sat Apr 12 22:43:58 2008 -0400
611 611 > +++ a Sat Apr 12 22:44:05 2008 -0400
612 612 > @@ -1,1 +1,1 @@
613 613 > -a
614 614 > +bb
615 615 > EOF
616 616 applying patch from stdin
617 617 $ hg status
618 618 $ cat a
619 619 bb
620 620 $ cd ..
621 621
622 622
623 623 test paths outside repo root
624 624
625 625 $ mkdir outside
626 626 $ touch outside/foo
627 627 $ hg init inside
628 628 $ cd inside
629 629 $ hg import - <<EOF
630 630 > diff --git a/a b/b
631 631 > rename from ../outside/foo
632 632 > rename to bar
633 633 > EOF
634 634 applying patch from stdin
635 635 abort: path contains illegal component: ../outside/foo (glob)
636 636 [255]
637 637 $ cd ..
638 638
639 639
640 640 test import with similarity and git and strip (issue295 et al.)
641 641
642 642 $ hg init sim
643 643 $ cd sim
644 644 $ echo 'this is a test' > a
645 645 $ hg ci -Ama
646 646 adding a
647 647 $ cat > ../rename.diff <<EOF
648 648 > diff --git a/foo/a b/foo/a
649 649 > deleted file mode 100644
650 650 > --- a/foo/a
651 651 > +++ /dev/null
652 652 > @@ -1,1 +0,0 @@
653 653 > -this is a test
654 654 > diff --git a/foo/b b/foo/b
655 655 > new file mode 100644
656 656 > --- /dev/null
657 657 > +++ b/foo/b
658 658 > @@ -0,0 +1,2 @@
659 659 > +this is a test
660 660 > +foo
661 661 > EOF
662 662 $ hg import --no-commit -v -s 1 ../rename.diff -p2
663 663 applying ../rename.diff
664 664 patching file a
665 665 patching file b
666 666 adding b
667 667 recording removal of a as rename to b (88% similar)
668 668 applied to working directory
669 669 $ hg st -C
670 670 A b
671 671 a
672 672 R a
673 673 $ hg revert -a
674 674 undeleting a
675 675 forgetting b
676 676 $ rm b
677 677 $ hg import --no-commit -v -s 100 ../rename.diff -p2
678 678 applying ../rename.diff
679 679 patching file a
680 680 patching file b
681 681 adding b
682 682 applied to working directory
683 683 $ hg st -C
684 684 A b
685 685 R a
686 686 $ cd ..
687 687
688 688
689 689 Issue1495: add empty file from the end of patch
690 690
691 691 $ hg init addemptyend
692 692 $ cd addemptyend
693 693 $ touch a
694 694 $ hg addremove
695 695 adding a
696 696 $ hg ci -m "commit"
697 697 $ cat > a.patch <<EOF
698 698 > add a, b
699 699 > diff --git a/a b/a
700 700 > --- a/a
701 701 > +++ b/a
702 702 > @@ -0,0 +1,1 @@
703 703 > +a
704 704 > diff --git a/b b/b
705 705 > new file mode 100644
706 706 > EOF
707 707 $ hg import --no-commit a.patch
708 708 applying a.patch
709 709
710 710 apply a good patch followed by an empty patch (mainly to ensure
711 711 that dirstate is *not* updated when import crashes)
712 712 $ hg update -q -C .
713 713 $ rm b
714 714 $ touch empty.patch
715 715 $ hg import a.patch empty.patch
716 716 applying a.patch
717 717 applying empty.patch
718 718 transaction abort!
719 719 rollback completed
720 720 abort: empty.patch: no diffs found
721 721 [255]
722 722 $ hg tip --template '{rev} {desc|firstline}\n'
723 723 0 commit
724 724 $ hg -q status
725 725 M a
726 726 $ cd ..
727 727
728 728 create file when source is not /dev/null
729 729
730 730 $ cat > create.patch <<EOF
731 731 > diff -Naur proj-orig/foo proj-new/foo
732 732 > --- proj-orig/foo 1969-12-31 16:00:00.000000000 -0800
733 733 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
734 734 > @@ -0,0 +1,1 @@
735 735 > +a
736 736 > EOF
737 737
738 738 some people have patches like the following too
739 739
740 740 $ cat > create2.patch <<EOF
741 741 > diff -Naur proj-orig/foo proj-new/foo
742 742 > --- proj-orig/foo.orig 1969-12-31 16:00:00.000000000 -0800
743 743 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
744 744 > @@ -0,0 +1,1 @@
745 745 > +a
746 746 > EOF
747 747 $ hg init oddcreate
748 748 $ cd oddcreate
749 749 $ hg import --no-commit ../create.patch
750 750 applying ../create.patch
751 751 $ cat foo
752 752 a
753 753 $ rm foo
754 754 $ hg revert foo
755 755 $ hg import --no-commit ../create2.patch
756 756 applying ../create2.patch
757 757 $ cat foo
758 758 a
759 759
760 760 $ cd ..
761 761
762 762 Issue1859: first line mistaken for email headers
763 763
764 764 $ hg init emailconfusion
765 765 $ cd emailconfusion
766 766 $ cat > a.patch <<EOF
767 767 > module: summary
768 768 >
769 769 > description
770 770 >
771 771 >
772 772 > diff -r 000000000000 -r 9b4c1e343b55 test.txt
773 773 > --- /dev/null
774 774 > +++ b/a
775 775 > @@ -0,0 +1,1 @@
776 776 > +a
777 777 > EOF
778 778 $ hg import -d '0 0' a.patch
779 779 applying a.patch
780 780 $ hg parents -v
781 781 changeset: 0:5a681217c0ad
782 782 tag: tip
783 783 user: test
784 784 date: Thu Jan 01 00:00:00 1970 +0000
785 785 files: a
786 786 description:
787 787 module: summary
788 788
789 789 description
790 790
791 791
792 792 $ cd ..
793 793
794 794
795 795 in commit message
796 796
797 797 $ hg init commitconfusion
798 798 $ cd commitconfusion
799 799 $ cat > a.patch <<EOF
800 800 > module: summary
801 801 >
802 802 > --- description
803 803 >
804 804 > diff --git a/a b/a
805 805 > new file mode 100644
806 806 > --- /dev/null
807 807 > +++ b/a
808 808 > @@ -0,0 +1,1 @@
809 809 > +a
810 810 > EOF
811 811 > hg import -d '0 0' a.patch
812 812 > hg parents -v
813 813 > cd ..
814 814 >
815 815 > echo '% tricky header splitting'
816 816 > cat > trickyheaders.patch <<EOF
817 817 > From: User A <user@a>
818 818 > Subject: [PATCH] from: tricky!
819 819 >
820 820 > # HG changeset patch
821 821 > # User User B
822 822 > # Date 1266264441 18000
823 823 > # Branch stable
824 824 > # Node ID f2be6a1170ac83bf31cb4ae0bad00d7678115bc0
825 825 > # Parent 0000000000000000000000000000000000000000
826 826 > from: tricky!
827 827 >
828 828 > That is not a header.
829 829 >
830 830 > diff -r 000000000000 -r f2be6a1170ac foo
831 831 > --- /dev/null
832 832 > +++ b/foo
833 833 > @@ -0,0 +1,1 @@
834 834 > +foo
835 835 > EOF
836 836 applying a.patch
837 837 changeset: 0:f34d9187897d
838 838 tag: tip
839 839 user: test
840 840 date: Thu Jan 01 00:00:00 1970 +0000
841 841 files: a
842 842 description:
843 843 module: summary
844 844
845 845
846 846 % tricky header splitting
847 847
848 848 $ hg init trickyheaders
849 849 $ cd trickyheaders
850 850 $ hg import -d '0 0' ../trickyheaders.patch
851 851 applying ../trickyheaders.patch
852 852 $ hg export --git tip
853 853 # HG changeset patch
854 854 # User User B
855 855 # Date 0 0
856 # Thu Jan 01 00:00:00 1970 +0000
856 857 # Node ID eb56ab91903632294ac504838508cb370c0901d2
857 858 # Parent 0000000000000000000000000000000000000000
858 859 from: tricky!
859 860
860 861 That is not a header.
861 862
862 863 diff --git a/foo b/foo
863 864 new file mode 100644
864 865 --- /dev/null
865 866 +++ b/foo
866 867 @@ -0,0 +1,1 @@
867 868 +foo
868 869 $ cd ..
869 870
870 871
871 872 Issue2102: hg export and hg import speak different languages
872 873
873 874 $ hg init issue2102
874 875 $ cd issue2102
875 876 $ mkdir -p src/cmd/gc
876 877 $ touch src/cmd/gc/mksys.bash
877 878 $ hg ci -Am init
878 879 adding src/cmd/gc/mksys.bash
879 880 $ hg import - <<EOF
880 881 > # HG changeset patch
881 882 > # User Rob Pike
882 883 > # Date 1216685449 25200
883 884 > # Node ID 03aa2b206f499ad6eb50e6e207b9e710d6409c98
884 885 > # Parent 93d10138ad8df586827ca90b4ddb5033e21a3a84
885 886 > help management of empty pkg and lib directories in perforce
886 887 >
887 888 > R=gri
888 889 > DELTA=4 (4 added, 0 deleted, 0 changed)
889 890 > OCL=13328
890 891 > CL=13328
891 892 >
892 893 > diff --git a/lib/place-holder b/lib/place-holder
893 894 > new file mode 100644
894 895 > --- /dev/null
895 896 > +++ b/lib/place-holder
896 897 > @@ -0,0 +1,2 @@
897 898 > +perforce does not maintain empty directories.
898 899 > +this file helps.
899 900 > diff --git a/pkg/place-holder b/pkg/place-holder
900 901 > new file mode 100644
901 902 > --- /dev/null
902 903 > +++ b/pkg/place-holder
903 904 > @@ -0,0 +1,2 @@
904 905 > +perforce does not maintain empty directories.
905 906 > +this file helps.
906 907 > diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
907 908 > old mode 100644
908 909 > new mode 100755
909 910 > EOF
910 911 applying patch from stdin
911 912
912 913 #if execbit
913 914
914 915 $ hg sum
915 916 parent: 1:d59915696727 tip
916 917 help management of empty pkg and lib directories in perforce
917 918 branch: default
918 919 commit: (clean)
919 920 update: (current)
920 921
921 922 $ hg diff --git -c tip
922 923 diff --git a/lib/place-holder b/lib/place-holder
923 924 new file mode 100644
924 925 --- /dev/null
925 926 +++ b/lib/place-holder
926 927 @@ -0,0 +1,2 @@
927 928 +perforce does not maintain empty directories.
928 929 +this file helps.
929 930 diff --git a/pkg/place-holder b/pkg/place-holder
930 931 new file mode 100644
931 932 --- /dev/null
932 933 +++ b/pkg/place-holder
933 934 @@ -0,0 +1,2 @@
934 935 +perforce does not maintain empty directories.
935 936 +this file helps.
936 937 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
937 938 old mode 100644
938 939 new mode 100755
939 940
940 941 #else
941 942
942 943 $ hg sum
943 944 parent: 1:28f089cc9ccc tip
944 945 help management of empty pkg and lib directories in perforce
945 946 branch: default
946 947 commit: (clean)
947 948 update: (current)
948 949
949 950 $ hg diff --git -c tip
950 951 diff --git a/lib/place-holder b/lib/place-holder
951 952 new file mode 100644
952 953 --- /dev/null
953 954 +++ b/lib/place-holder
954 955 @@ -0,0 +1,2 @@
955 956 +perforce does not maintain empty directories.
956 957 +this file helps.
957 958 diff --git a/pkg/place-holder b/pkg/place-holder
958 959 new file mode 100644
959 960 --- /dev/null
960 961 +++ b/pkg/place-holder
961 962 @@ -0,0 +1,2 @@
962 963 +perforce does not maintain empty directories.
963 964 +this file helps.
964 965
965 966 /* The mode change for mksys.bash is missing here, because on platforms */
966 967 /* that don't support execbits, mode changes in patches are ignored when */
967 968 /* they are imported. This is obviously also the reason for why the hash */
968 969 /* in the created changeset is different to the one you see above the */
969 970 /* #else clause */
970 971
971 972 #endif
972 973 $ cd ..
973 974
974 975
975 976 diff lines looking like headers
976 977
977 978 $ hg init difflineslikeheaders
978 979 $ cd difflineslikeheaders
979 980 $ echo a >a
980 981 $ echo b >b
981 982 $ echo c >c
982 983 $ hg ci -Am1
983 984 adding a
984 985 adding b
985 986 adding c
986 987
987 988 $ echo "key: value" >>a
988 989 $ echo "key: value" >>b
989 990 $ echo "foo" >>c
990 991 $ hg ci -m2
991 992
992 993 $ hg up -C 0
993 994 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
994 995 $ hg diff --git -c1 >want
995 996 $ hg diff -c1 | hg import --no-commit -
996 997 applying patch from stdin
997 998 $ hg diff --git >have
998 999 $ diff want have
999 1000 $ cd ..
1000 1001
1001 1002 import a unified diff with no lines of context (diff -U0)
1002 1003
1003 1004 $ hg init diffzero
1004 1005 $ cd diffzero
1005 1006 $ cat > f << EOF
1006 1007 > c2
1007 1008 > c4
1008 1009 > c5
1009 1010 > EOF
1010 1011 $ hg commit -Am0
1011 1012 adding f
1012 1013
1013 1014 $ hg import --no-commit - << EOF
1014 1015 > # HG changeset patch
1015 1016 > # User test
1016 1017 > # Date 0 0
1017 1018 > # Node ID f4974ab632f3dee767567b0576c0ec9a4508575c
1018 1019 > # Parent 8679a12a975b819fae5f7ad3853a2886d143d794
1019 1020 > 1
1020 1021 > diff -r 8679a12a975b -r f4974ab632f3 f
1021 1022 > --- a/f Thu Jan 01 00:00:00 1970 +0000
1022 1023 > +++ b/f Thu Jan 01 00:00:00 1970 +0000
1023 1024 > @@ -0,0 +1,1 @@
1024 1025 > +c1
1025 1026 > @@ -1,0 +3,1 @@
1026 1027 > +c3
1027 1028 > @@ -3,1 +4,0 @@
1028 1029 > -c5
1029 1030 > EOF
1030 1031 applying patch from stdin
1031 1032
1032 1033 $ cat f
1033 1034 c1
1034 1035 c2
1035 1036 c3
1036 1037 c4
1037 1038
1038 1039 $ cd ..
1039 1040
1040 1041 no segfault while importing a unified diff which start line is zero but chunk
1041 1042 size is non-zero
1042 1043
1043 1044 $ hg init startlinezero
1044 1045 $ cd startlinezero
1045 1046 $ echo foo > foo
1046 1047 $ hg commit -Amfoo
1047 1048 adding foo
1048 1049
1049 1050 $ hg import --no-commit - << EOF
1050 1051 > diff a/foo b/foo
1051 1052 > --- a/foo
1052 1053 > +++ b/foo
1053 1054 > @@ -0,1 +0,1 @@
1054 1055 > foo
1055 1056 > EOF
1056 1057 applying patch from stdin
1057 1058
1058 1059 $ cd ..
1059 1060
1060 1061 Test corner case involving fuzz and skew
1061 1062
1062 1063 $ hg init morecornercases
1063 1064 $ cd morecornercases
1064 1065
1065 1066 $ cat > 01-no-context-beginning-of-file.diff <<EOF
1066 1067 > diff --git a/a b/a
1067 1068 > --- a/a
1068 1069 > +++ b/a
1069 1070 > @@ -1,0 +1,1 @@
1070 1071 > +line
1071 1072 > EOF
1072 1073
1073 1074 $ cat > 02-no-context-middle-of-file.diff <<EOF
1074 1075 > diff --git a/a b/a
1075 1076 > --- a/a
1076 1077 > +++ b/a
1077 1078 > @@ -1,1 +1,1 @@
1078 1079 > -2
1079 1080 > +add some skew
1080 1081 > @@ -2,0 +2,1 @@
1081 1082 > +line
1082 1083 > EOF
1083 1084
1084 1085 $ cat > 03-no-context-end-of-file.diff <<EOF
1085 1086 > diff --git a/a b/a
1086 1087 > --- a/a
1087 1088 > +++ b/a
1088 1089 > @@ -10,0 +10,1 @@
1089 1090 > +line
1090 1091 > EOF
1091 1092
1092 1093 $ cat > 04-middle-of-file-completely-fuzzed.diff <<EOF
1093 1094 > diff --git a/a b/a
1094 1095 > --- a/a
1095 1096 > +++ b/a
1096 1097 > @@ -1,1 +1,1 @@
1097 1098 > -2
1098 1099 > +add some skew
1099 1100 > @@ -2,2 +2,3 @@
1100 1101 > not matching, should fuzz
1101 1102 > ... a bit
1102 1103 > +line
1103 1104 > EOF
1104 1105
1105 1106 $ cat > a <<EOF
1106 1107 > 1
1107 1108 > 2
1108 1109 > 3
1109 1110 > 4
1110 1111 > EOF
1111 1112 $ hg ci -Am adda a
1112 1113 $ for p in *.diff; do
1113 1114 > hg import -v --no-commit $p
1114 1115 > cat a
1115 1116 > hg revert -aqC a
1116 1117 > # patch -p1 < $p
1117 1118 > # cat a
1118 1119 > # hg revert -aC a
1119 1120 > done
1120 1121 applying 01-no-context-beginning-of-file.diff
1121 1122 patching file a
1122 1123 applied to working directory
1123 1124 1
1124 1125 line
1125 1126 2
1126 1127 3
1127 1128 4
1128 1129 applying 02-no-context-middle-of-file.diff
1129 1130 patching file a
1130 1131 Hunk #1 succeeded at 2 (offset 1 lines).
1131 1132 Hunk #2 succeeded at 4 (offset 1 lines).
1132 1133 applied to working directory
1133 1134 1
1134 1135 add some skew
1135 1136 3
1136 1137 line
1137 1138 4
1138 1139 applying 03-no-context-end-of-file.diff
1139 1140 patching file a
1140 1141 Hunk #1 succeeded at 5 (offset -6 lines).
1141 1142 applied to working directory
1142 1143 1
1143 1144 2
1144 1145 3
1145 1146 4
1146 1147 line
1147 1148 applying 04-middle-of-file-completely-fuzzed.diff
1148 1149 patching file a
1149 1150 Hunk #1 succeeded at 2 (offset 1 lines).
1150 1151 Hunk #2 succeeded at 5 with fuzz 2 (offset 1 lines).
1151 1152 applied to working directory
1152 1153 1
1153 1154 add some skew
1154 1155 3
1155 1156 4
1156 1157 line
1157 1158
1158 1159 $ cd ..
@@ -1,53 +1,54 b''
1 1 http://mercurial.selenic.com/bts/issue1175
2 2
3 3 $ hg init
4 4 $ touch a
5 5 $ hg ci -Am0
6 6 adding a
7 7
8 8 $ hg mv a a1
9 9 $ hg ci -m1
10 10
11 11 $ hg co 0
12 12 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
13 13
14 14 $ hg mv a a2
15 15 $ hg up
16 16 note: possible conflict - a was renamed multiple times to:
17 17 a2
18 18 a1
19 19 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
20 20
21 21 $ hg ci -m2
22 22
23 23 $ touch a
24 24 $ hg ci -Am3
25 25 adding a
26 26
27 27 $ hg mv a b
28 28 $ hg ci -Am4 a
29 29
30 30 $ hg ci --debug --traceback -Am5 b
31 31 b
32 32 b: searching for copy revision for a
33 33 b: copy a:b80de5d138758541c5f05265ad144ab9fa86d1db
34 34 committed changeset 5:89e8e4be0de296fa3d6dd7825ccc44d7dc0f1f3b
35 35
36 36 $ hg verify
37 37 checking changesets
38 38 checking manifests
39 39 crosschecking files in changesets and manifests
40 40 checking files
41 41 4 files, 6 changesets, 4 total revisions
42 42
43 43 $ hg export --git tip
44 44 # HG changeset patch
45 45 # User test
46 46 # Date 0 0
47 # Thu Jan 01 00:00:00 1970 +0000
47 48 # Node ID 89e8e4be0de296fa3d6dd7825ccc44d7dc0f1f3b
48 49 # Parent 7fc86ba705e717a721dbc361bf8c9bc05a18ca2f
49 50 5
50 51
51 52 diff --git a/b b/b
52 53 new file mode 100644
53 54
@@ -1,1154 +1,1155 b''
1 1 $ cat <<EOF >> $HGRCPATH
2 2 > [extensions]
3 3 > keyword =
4 4 > mq =
5 5 > notify =
6 6 > record =
7 7 > transplant =
8 8 > [ui]
9 9 > interactive = true
10 10 > EOF
11 11
12 12 hide outer repo
13 13 $ hg init
14 14
15 15 Run kwdemo before [keyword] files are set up
16 16 as it would succeed without uisetup otherwise
17 17
18 18 $ hg --quiet kwdemo
19 19 [extensions]
20 20 keyword =
21 21 [keyword]
22 22 demo.txt =
23 23 [keywordset]
24 24 svn = False
25 25 [keywordmaps]
26 26 Author = {author|user}
27 27 Date = {date|utcdate}
28 28 Header = {root}/{file},v {node|short} {date|utcdate} {author|user}
29 29 Id = {file|basename},v {node|short} {date|utcdate} {author|user}
30 30 RCSFile = {file|basename},v
31 31 RCSfile = {file|basename},v
32 32 Revision = {node|short}
33 33 Source = {root}/{file},v
34 34 $Author: test $
35 35 $Date: ????/??/?? ??:??:?? $ (glob)
36 36 $Header: */demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
37 37 $Id: demo.txt,v ???????????? ????/??/?? ??:??:?? test $ (glob)
38 38 $RCSFile: demo.txt,v $
39 39 $RCSfile: demo.txt,v $
40 40 $Revision: ???????????? $ (glob)
41 41 $Source: */demo.txt,v $ (glob)
42 42
43 43 $ hg --quiet kwdemo "Branch = {branches}"
44 44 [extensions]
45 45 keyword =
46 46 [keyword]
47 47 demo.txt =
48 48 [keywordset]
49 49 svn = False
50 50 [keywordmaps]
51 51 Branch = {branches}
52 52 $Branch: demobranch $
53 53
54 54 $ cat <<EOF >> $HGRCPATH
55 55 > [keyword]
56 56 > ** =
57 57 > b = ignore
58 58 > i = ignore
59 59 > [hooks]
60 60 > EOF
61 61 $ cp $HGRCPATH $HGRCPATH.nohooks
62 62 > cat <<EOF >> $HGRCPATH
63 63 > commit=
64 64 > commit.test=cp a hooktest
65 65 > EOF
66 66
67 67 $ hg init Test-bndl
68 68 $ cd Test-bndl
69 69
70 70 kwshrink should exit silently in empty/invalid repo
71 71
72 72 $ hg kwshrink
73 73
74 74 Symlinks cannot be created on Windows.
75 75 A bundle to test this was made with:
76 76 hg init t
77 77 cd t
78 78 echo a > a
79 79 ln -s a sym
80 80 hg add sym
81 81 hg ci -m addsym -u mercurial
82 82 hg bundle --base null ../test-keyword.hg
83 83
84 84 $ hg pull -u "$TESTDIR"/bundles/test-keyword.hg
85 85 pulling from *test-keyword.hg (glob)
86 86 requesting all changes
87 87 adding changesets
88 88 adding manifests
89 89 adding file changes
90 90 added 1 changesets with 1 changes to 1 files
91 91 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
92 92
93 93 $ echo 'expand $Id$' > a
94 94 $ echo 'do not process $Id:' >> a
95 95 $ echo 'xxx $' >> a
96 96 $ echo 'ignore $Id$' > b
97 97
98 98 Output files as they were created
99 99
100 100 $ cat a b
101 101 expand $Id$
102 102 do not process $Id:
103 103 xxx $
104 104 ignore $Id$
105 105
106 106 no kwfiles
107 107
108 108 $ hg kwfiles
109 109
110 110 untracked candidates
111 111
112 112 $ hg -v kwfiles --unknown
113 113 k a
114 114
115 115 Add files and check status
116 116
117 117 $ hg addremove
118 118 adding a
119 119 adding b
120 120 $ hg status
121 121 A a
122 122 A b
123 123
124 124
125 125 Default keyword expansion including commit hook
126 126 Interrupted commit should not change state or run commit hook
127 127
128 128 $ hg --debug commit
129 129 abort: empty commit message
130 130 [255]
131 131 $ hg status
132 132 A a
133 133 A b
134 134
135 135 Commit with several checks
136 136
137 137 $ hg --debug commit -mabsym -u 'User Name <user@example.com>'
138 138 a
139 139 b
140 140 overwriting a expanding keywords
141 141 running hook commit.test: cp a hooktest
142 142 committed changeset 1:ef63ca68695bc9495032c6fda1350c71e6d256e9
143 143 $ hg status
144 144 ? hooktest
145 145 $ hg debugrebuildstate
146 146 $ hg --quiet identify
147 147 ef63ca68695b
148 148
149 149 cat files in working directory with keywords expanded
150 150
151 151 $ cat a b
152 152 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
153 153 do not process $Id:
154 154 xxx $
155 155 ignore $Id$
156 156
157 157 hg cat files and symlink, no expansion
158 158
159 159 $ hg cat sym a b && echo
160 160 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
161 161 do not process $Id:
162 162 xxx $
163 163 ignore $Id$
164 164 a
165 165
166 166 $ diff a hooktest
167 167
168 168 $ cp $HGRCPATH.nohooks $HGRCPATH
169 169 $ rm hooktest
170 170
171 171 hg status of kw-ignored binary file starting with '\1\n'
172 172
173 173 >>> open("i", "wb").write("\1\nfoo")
174 174 $ hg -q commit -Am metasep i
175 175 $ hg status
176 176 >>> open("i", "wb").write("\1\nbar")
177 177 $ hg status
178 178 M i
179 179 $ hg -q commit -m "modify metasep" i
180 180 $ hg status --rev 2:3
181 181 M i
182 182 $ touch empty
183 183 $ hg -q commit -A -m "another file"
184 184 $ hg status -A --rev 3:4 i
185 185 C i
186 186
187 187 $ hg -q strip -n 2
188 188
189 189 Test hook execution
190 190
191 191 bundle
192 192
193 193 $ hg bundle --base null ../kw.hg
194 194 2 changesets found
195 195 $ cd ..
196 196 $ hg init Test
197 197 $ cd Test
198 198
199 199 Notify on pull to check whether keywords stay as is in email
200 200 ie. if patch.diff wrapper acts as it should
201 201
202 202 $ cat <<EOF >> $HGRCPATH
203 203 > [hooks]
204 204 > incoming.notify = python:hgext.notify.hook
205 205 > [notify]
206 206 > sources = pull
207 207 > diffstat = False
208 208 > maxsubject = 15
209 209 > [reposubs]
210 210 > * = Test
211 211 > EOF
212 212
213 213 Pull from bundle and trigger notify
214 214
215 215 $ hg pull -u ../kw.hg
216 216 pulling from ../kw.hg
217 217 requesting all changes
218 218 adding changesets
219 219 adding manifests
220 220 adding file changes
221 221 added 2 changesets with 3 changes to 3 files
222 222 Content-Type: text/plain; charset="us-ascii"
223 223 MIME-Version: 1.0
224 224 Content-Transfer-Encoding: 7bit
225 225 Date: * (glob)
226 226 Subject: changeset in...
227 227 From: mercurial
228 228 X-Hg-Notification: changeset a2392c293916
229 229 Message-Id: <hg.a2392c293916*> (glob)
230 230 To: Test
231 231
232 232 changeset a2392c293916 in $TESTTMP/Test (glob)
233 233 details: $TESTTMP/Test?cmd=changeset;node=a2392c293916
234 234 description:
235 235 addsym
236 236
237 237 diffs (6 lines):
238 238
239 239 diff -r 000000000000 -r a2392c293916 sym
240 240 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
241 241 +++ b/sym Sat Feb 09 20:25:47 2008 +0100
242 242 @@ -0,0 +1,1 @@
243 243 +a
244 244 \ No newline at end of file
245 245 Content-Type: text/plain; charset="us-ascii"
246 246 MIME-Version: 1.0
247 247 Content-Transfer-Encoding: 7bit
248 248 Date:* (glob)
249 249 Subject: changeset in...
250 250 From: User Name <user@example.com>
251 251 X-Hg-Notification: changeset ef63ca68695b
252 252 Message-Id: <hg.ef63ca68695b*> (glob)
253 253 To: Test
254 254
255 255 changeset ef63ca68695b in $TESTTMP/Test (glob)
256 256 details: $TESTTMP/Test?cmd=changeset;node=ef63ca68695b
257 257 description:
258 258 absym
259 259
260 260 diffs (12 lines):
261 261
262 262 diff -r a2392c293916 -r ef63ca68695b a
263 263 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
264 264 +++ b/a Thu Jan 01 00:00:00 1970 +0000
265 265 @@ -0,0 +1,3 @@
266 266 +expand $Id$
267 267 +do not process $Id:
268 268 +xxx $
269 269 diff -r a2392c293916 -r ef63ca68695b b
270 270 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
271 271 +++ b/b Thu Jan 01 00:00:00 1970 +0000
272 272 @@ -0,0 +1,1 @@
273 273 +ignore $Id$
274 274 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
275 275
276 276 $ cp $HGRCPATH.nohooks $HGRCPATH
277 277
278 278 Touch files and check with status
279 279
280 280 $ touch a b
281 281 $ hg status
282 282
283 283 Update and expand
284 284
285 285 $ rm sym a b
286 286 $ hg update -C
287 287 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 288 $ cat a b
289 289 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
290 290 do not process $Id:
291 291 xxx $
292 292 ignore $Id$
293 293
294 294 Check whether expansion is filewise and file mode is preserved
295 295
296 296 $ echo '$Id$' > c
297 297 $ echo 'tests for different changenodes' >> c
298 298 #if unix-permissions
299 299 $ chmod 600 c
300 300 $ ls -l c | cut -b 1-10
301 301 -rw-------
302 302 #endif
303 303
304 304 commit file c
305 305
306 306 $ hg commit -A -mcndiff -d '1 0' -u 'User Name <user@example.com>'
307 307 adding c
308 308 #if unix-permissions
309 309 $ ls -l c | cut -b 1-10
310 310 -rw-------
311 311 #endif
312 312
313 313 force expansion
314 314
315 315 $ hg -v kwexpand
316 316 overwriting a expanding keywords
317 317 overwriting c expanding keywords
318 318
319 319 compare changenodes in a and c
320 320
321 321 $ cat a c
322 322 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
323 323 do not process $Id:
324 324 xxx $
325 325 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
326 326 tests for different changenodes
327 327
328 328 record
329 329
330 330 $ echo '$Id$' > r
331 331 $ hg add r
332 332
333 333 record chunk
334 334
335 335 >>> lines = open('a', 'rb').readlines()
336 336 >>> lines.insert(1, 'foo\n')
337 337 >>> lines.append('bar\n')
338 338 >>> open('a', 'wb').writelines(lines)
339 339 $ hg record -d '10 1' -m rectest a<<EOF
340 340 > y
341 341 > y
342 342 > n
343 343 > EOF
344 344 diff --git a/a b/a
345 345 2 hunks, 2 lines changed
346 346 examine changes to 'a'? [Ynesfdaq?]
347 347 @@ -1,3 +1,4 @@
348 348 expand $Id$
349 349 +foo
350 350 do not process $Id:
351 351 xxx $
352 352 record change 1/2 to 'a'? [Ynesfdaq?]
353 353 @@ -2,2 +3,3 @@
354 354 do not process $Id:
355 355 xxx $
356 356 +bar
357 357 record change 2/2 to 'a'? [Ynesfdaq?]
358 358
359 359 $ hg identify
360 360 5f5eb23505c3+ tip
361 361 $ hg status
362 362 M a
363 363 A r
364 364
365 365 Cat modified file a
366 366
367 367 $ cat a
368 368 expand $Id: a,v 5f5eb23505c3 1970/01/01 00:00:10 test $
369 369 foo
370 370 do not process $Id:
371 371 xxx $
372 372 bar
373 373
374 374 Diff remaining chunk
375 375
376 376 $ hg diff a
377 377 diff -r 5f5eb23505c3 a
378 378 --- a/a Thu Jan 01 00:00:09 1970 -0000
379 379 +++ b/a * (glob)
380 380 @@ -2,3 +2,4 @@
381 381 foo
382 382 do not process $Id:
383 383 xxx $
384 384 +bar
385 385
386 386 $ hg rollback
387 387 repository tip rolled back to revision 2 (undo commit)
388 388 working directory now based on revision 2
389 389
390 390 Record all chunks in file a
391 391
392 392 $ echo foo > msg
393 393
394 394 - do not use "hg record -m" here!
395 395
396 396 $ hg record -l msg -d '11 1' a<<EOF
397 397 > y
398 398 > y
399 399 > y
400 400 > EOF
401 401 diff --git a/a b/a
402 402 2 hunks, 2 lines changed
403 403 examine changes to 'a'? [Ynesfdaq?]
404 404 @@ -1,3 +1,4 @@
405 405 expand $Id$
406 406 +foo
407 407 do not process $Id:
408 408 xxx $
409 409 record change 1/2 to 'a'? [Ynesfdaq?]
410 410 @@ -2,2 +3,3 @@
411 411 do not process $Id:
412 412 xxx $
413 413 +bar
414 414 record change 2/2 to 'a'? [Ynesfdaq?]
415 415
416 416 File a should be clean
417 417
418 418 $ hg status -A a
419 419 C a
420 420
421 421 rollback and revert expansion
422 422
423 423 $ cat a
424 424 expand $Id: a,v 78e0a02d76aa 1970/01/01 00:00:11 test $
425 425 foo
426 426 do not process $Id:
427 427 xxx $
428 428 bar
429 429 $ hg --verbose rollback
430 430 repository tip rolled back to revision 2 (undo commit)
431 431 working directory now based on revision 2
432 432 overwriting a expanding keywords
433 433 $ hg status a
434 434 M a
435 435 $ cat a
436 436 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
437 437 foo
438 438 do not process $Id:
439 439 xxx $
440 440 bar
441 441 $ echo '$Id$' > y
442 442 $ echo '$Id$' > z
443 443 $ hg add y
444 444 $ hg commit -Am "rollback only" z
445 445 $ cat z
446 446 $Id: z,v 45a5d3adce53 1970/01/01 00:00:00 test $
447 447 $ hg --verbose rollback
448 448 repository tip rolled back to revision 2 (undo commit)
449 449 working directory now based on revision 2
450 450 overwriting z shrinking keywords
451 451
452 452 Only z should be overwritten
453 453
454 454 $ hg status a y z
455 455 M a
456 456 A y
457 457 A z
458 458 $ cat z
459 459 $Id$
460 460 $ hg forget y z
461 461 $ rm y z
462 462
463 463 record added file alone
464 464
465 465 $ hg -v record -l msg -d '12 2' r<<EOF
466 466 > y
467 467 > EOF
468 468 diff --git a/r b/r
469 469 new file mode 100644
470 470 examine changes to 'r'? [Ynesfdaq?]
471 471 r
472 472 committed changeset 3:82a2f715724d
473 473 overwriting r expanding keywords
474 474 - status call required for dirstate.normallookup() check
475 475 $ hg status r
476 476 $ hg --verbose rollback
477 477 repository tip rolled back to revision 2 (undo commit)
478 478 working directory now based on revision 2
479 479 overwriting r shrinking keywords
480 480 $ hg forget r
481 481 $ rm msg r
482 482 $ hg update -C
483 483 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
484 484
485 485 record added keyword ignored file
486 486
487 487 $ echo '$Id$' > i
488 488 $ hg add i
489 489 $ hg --verbose record -d '13 1' -m recignored<<EOF
490 490 > y
491 491 > EOF
492 492 diff --git a/i b/i
493 493 new file mode 100644
494 494 examine changes to 'i'? [Ynesfdaq?]
495 495 i
496 496 committed changeset 3:9f40ceb5a072
497 497 $ cat i
498 498 $Id$
499 499 $ hg -q rollback
500 500 $ hg forget i
501 501 $ rm i
502 502
503 503 amend
504 504
505 505 $ echo amend >> a
506 506 $ echo amend >> b
507 507 $ hg -q commit -d '14 1' -m 'prepare amend'
508 508
509 509 $ hg --debug commit --amend -d '15 1' -m 'amend without changes' | grep keywords
510 510 invalid branchheads cache (served): tip differs
511 511 overwriting a expanding keywords
512 512 $ hg -q id
513 513 67d8c481a6be
514 514 $ head -1 a
515 515 expand $Id: a,v 67d8c481a6be 1970/01/01 00:00:15 test $
516 516
517 517 $ hg -q strip -n tip
518 518
519 519 Test patch queue repo
520 520
521 521 $ hg init --mq
522 522 $ hg qimport -r tip -n mqtest.diff
523 523 $ hg commit --mq -m mqtest
524 524
525 525 Keywords should not be expanded in patch
526 526
527 527 $ cat .hg/patches/mqtest.diff
528 528 # HG changeset patch
529 529 # User User Name <user@example.com>
530 530 # Date 1 0
531 # Thu Jan 01 00:00:01 1970 +0000
531 532 # Node ID 40a904bbbe4cd4ab0a1f28411e35db26341a40ad
532 533 # Parent ef63ca68695bc9495032c6fda1350c71e6d256e9
533 534 cndiff
534 535
535 536 diff -r ef63ca68695b -r 40a904bbbe4c c
536 537 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
537 538 +++ b/c Thu Jan 01 00:00:01 1970 +0000
538 539 @@ -0,0 +1,2 @@
539 540 +$Id$
540 541 +tests for different changenodes
541 542
542 543 $ hg qpop
543 544 popping mqtest.diff
544 545 patch queue now empty
545 546
546 547 qgoto, implying qpush, should expand
547 548
548 549 $ hg qgoto mqtest.diff
549 550 applying mqtest.diff
550 551 now at: mqtest.diff
551 552 $ cat c
552 553 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
553 554 tests for different changenodes
554 555 $ hg cat c
555 556 $Id: c,v 40a904bbbe4c 1970/01/01 00:00:01 user $
556 557 tests for different changenodes
557 558
558 559 Keywords should not be expanded in filelog
559 560
560 561 $ hg --config 'extensions.keyword=!' cat c
561 562 $Id$
562 563 tests for different changenodes
563 564
564 565 qpop and move on
565 566
566 567 $ hg qpop
567 568 popping mqtest.diff
568 569 patch queue now empty
569 570
570 571 Copy and show added kwfiles
571 572
572 573 $ hg cp a c
573 574 $ hg kwfiles
574 575 a
575 576 c
576 577
577 578 Commit and show expansion in original and copy
578 579
579 580 $ hg --debug commit -ma2c -d '1 0' -u 'User Name <user@example.com>'
580 581 invalid branchheads cache (served): tip differs
581 582 c
582 583 c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
583 584 invalid branchheads cache (served): tip differs
584 585 overwriting c expanding keywords
585 586 committed changeset 2:25736cf2f5cbe41f6be4e6784ef6ecf9f3bbcc7d
586 587 $ cat a c
587 588 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
588 589 do not process $Id:
589 590 xxx $
590 591 expand $Id: c,v 25736cf2f5cb 1970/01/01 00:00:01 user $
591 592 do not process $Id:
592 593 xxx $
593 594
594 595 Touch copied c and check its status
595 596
596 597 $ touch c
597 598 $ hg status
598 599
599 600 Copy kwfile to keyword ignored file unexpanding keywords
600 601
601 602 $ hg --verbose copy a i
602 603 copying a to i
603 604 overwriting i shrinking keywords
604 605 $ head -n 1 i
605 606 expand $Id$
606 607 $ hg forget i
607 608 $ rm i
608 609
609 610 Copy ignored file to ignored file: no overwriting
610 611
611 612 $ hg --verbose copy b i
612 613 copying b to i
613 614 $ hg forget i
614 615 $ rm i
615 616
616 617 cp symlink file; hg cp -A symlink file (part1)
617 618 - copied symlink points to kwfile: overwrite
618 619
619 620 #if symlink
620 621 $ cp sym i
621 622 $ ls -l i
622 623 -rw-r--r--* (glob)
623 624 $ head -1 i
624 625 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
625 626 $ hg copy --after --verbose sym i
626 627 copying sym to i
627 628 overwriting i shrinking keywords
628 629 $ head -1 i
629 630 expand $Id$
630 631 $ hg forget i
631 632 $ rm i
632 633 #endif
633 634
634 635 Test different options of hg kwfiles
635 636
636 637 $ hg kwfiles
637 638 a
638 639 c
639 640 $ hg -v kwfiles --ignore
640 641 I b
641 642 I sym
642 643 $ hg kwfiles --all
643 644 K a
644 645 K c
645 646 I b
646 647 I sym
647 648
648 649 Diff specific revision
649 650
650 651 $ hg diff --rev 1
651 652 diff -r ef63ca68695b c
652 653 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
653 654 +++ b/c * (glob)
654 655 @@ -0,0 +1,3 @@
655 656 +expand $Id$
656 657 +do not process $Id:
657 658 +xxx $
658 659
659 660 Status after rollback:
660 661
661 662 $ hg rollback
662 663 repository tip rolled back to revision 1 (undo commit)
663 664 working directory now based on revision 1
664 665 $ hg status
665 666 A c
666 667 $ hg update --clean
667 668 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
668 669
669 670 #if symlink
670 671
671 672 cp symlink file; hg cp -A symlink file (part2)
672 673 - copied symlink points to kw ignored file: do not overwrite
673 674
674 675 $ cat a > i
675 676 $ ln -s i symignored
676 677 $ hg commit -Am 'fake expansion in ignored and symlink' i symignored
677 678 $ cp symignored x
678 679 $ hg copy --after --verbose symignored x
679 680 copying symignored to x
680 681 $ head -n 1 x
681 682 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
682 683 $ hg forget x
683 684 $ rm x
684 685
685 686 $ hg rollback
686 687 repository tip rolled back to revision 1 (undo commit)
687 688 working directory now based on revision 1
688 689 $ hg update --clean
689 690 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
690 691 $ rm i symignored
691 692
692 693 #endif
693 694
694 695 Custom keywordmaps as argument to kwdemo
695 696
696 697 $ hg --quiet kwdemo "Xinfo = {author}: {desc}"
697 698 [extensions]
698 699 keyword =
699 700 [keyword]
700 701 ** =
701 702 b = ignore
702 703 demo.txt =
703 704 i = ignore
704 705 [keywordset]
705 706 svn = False
706 707 [keywordmaps]
707 708 Xinfo = {author}: {desc}
708 709 $Xinfo: test: hg keyword configuration and expansion example $
709 710
710 711 Configure custom keywordmaps
711 712
712 713 $ cat <<EOF >>$HGRCPATH
713 714 > [keywordmaps]
714 715 > Id = {file} {node|short} {date|rfc822date} {author|user}
715 716 > Xinfo = {author}: {desc}
716 717 > EOF
717 718
718 719 Cat and hg cat files before custom expansion
719 720
720 721 $ cat a b
721 722 expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $
722 723 do not process $Id:
723 724 xxx $
724 725 ignore $Id$
725 726 $ hg cat sym a b && echo
726 727 expand $Id: a ef63ca68695b Thu, 01 Jan 1970 00:00:00 +0000 user $
727 728 do not process $Id:
728 729 xxx $
729 730 ignore $Id$
730 731 a
731 732
732 733 Write custom keyword and prepare multi-line commit message
733 734
734 735 $ echo '$Xinfo$' >> a
735 736 $ cat <<EOF >> log
736 737 > firstline
737 738 > secondline
738 739 > EOF
739 740
740 741 Interrupted commit should not change state
741 742
742 743 $ hg commit
743 744 abort: empty commit message
744 745 [255]
745 746 $ hg status
746 747 M a
747 748 ? c
748 749 ? log
749 750
750 751 Commit with multi-line message and custom expansion
751 752
752 753 |Note:
753 754 |
754 755 | After the last rollback, the "served" branchheads cache became invalid, but
755 756 | all changesets in the repo were public. For filtering this means:
756 757 | "immutable" == "served" == ΓΈ.
757 758 |
758 759 | As the "served" cache is invalid, we fall back to the "immutable" cache. But
759 760 | no update is needed between "immutable" and "served" and the "served" cache
760 761 | is not updated on disk. The on-disk version therefore stays invalid for some
761 762 | time. This explains why the "served" branchheads cache is detected as
762 763 | invalid here.
763 764
764 765 $ hg --debug commit -l log -d '2 0' -u 'User Name <user@example.com>'
765 766 invalid branchheads cache (served): tip differs
766 767 a
767 768 invalid branchheads cache (served): tip differs
768 769 overwriting a expanding keywords
769 770 committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
770 771 $ rm log
771 772
772 773 Stat, verify and show custom expansion (firstline)
773 774
774 775 $ hg status
775 776 ? c
776 777 $ hg verify
777 778 checking changesets
778 779 checking manifests
779 780 crosschecking files in changesets and manifests
780 781 checking files
781 782 3 files, 3 changesets, 4 total revisions
782 783 $ cat a b
783 784 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
784 785 do not process $Id:
785 786 xxx $
786 787 $Xinfo: User Name <user@example.com>: firstline $
787 788 ignore $Id$
788 789 $ hg cat sym a b && echo
789 790 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
790 791 do not process $Id:
791 792 xxx $
792 793 $Xinfo: User Name <user@example.com>: firstline $
793 794 ignore $Id$
794 795 a
795 796
796 797 annotate
797 798
798 799 $ hg annotate a
799 800 1: expand $Id$
800 801 1: do not process $Id:
801 802 1: xxx $
802 803 2: $Xinfo$
803 804
804 805 remove with status checks
805 806
806 807 $ hg debugrebuildstate
807 808 $ hg remove a
808 809 $ hg --debug commit -m rma
809 810 committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
810 811 $ hg status
811 812 ? c
812 813
813 814 Rollback, revert, and check expansion
814 815
815 816 $ hg rollback
816 817 repository tip rolled back to revision 2 (undo commit)
817 818 working directory now based on revision 2
818 819 $ hg status
819 820 R a
820 821 ? c
821 822 $ hg revert --no-backup --rev tip a
822 823 $ cat a
823 824 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
824 825 do not process $Id:
825 826 xxx $
826 827 $Xinfo: User Name <user@example.com>: firstline $
827 828
828 829 Clone to test global and local configurations
829 830
830 831 $ cd ..
831 832
832 833 Expansion in destination with global configuration
833 834
834 835 $ hg --quiet clone Test globalconf
835 836 $ cat globalconf/a
836 837 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
837 838 do not process $Id:
838 839 xxx $
839 840 $Xinfo: User Name <user@example.com>: firstline $
840 841
841 842 No expansion in destination with local configuration in origin only
842 843
843 844 $ hg --quiet --config 'keyword.**=ignore' clone Test localconf
844 845 $ cat localconf/a
845 846 expand $Id$
846 847 do not process $Id:
847 848 xxx $
848 849 $Xinfo$
849 850
850 851 Clone to test incoming
851 852
852 853 $ hg clone -r1 Test Test-a
853 854 adding changesets
854 855 adding manifests
855 856 adding file changes
856 857 added 2 changesets with 3 changes to 3 files
857 858 updating to branch default
858 859 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
859 860 $ cd Test-a
860 861 $ cat <<EOF >> .hg/hgrc
861 862 > [paths]
862 863 > default = ../Test
863 864 > EOF
864 865 $ hg incoming
865 866 comparing with $TESTTMP/Test (glob)
866 867 searching for changes
867 868 changeset: 2:bb948857c743
868 869 tag: tip
869 870 user: User Name <user@example.com>
870 871 date: Thu Jan 01 00:00:02 1970 +0000
871 872 summary: firstline
872 873
873 874 Imported patch should not be rejected
874 875
875 876 >>> import re
876 877 >>> text = re.sub(r'(Id.*)', r'\1 rejecttest', open('a').read())
877 878 >>> open('a', 'wb').write(text)
878 879 $ hg --debug commit -m'rejects?' -d '3 0' -u 'User Name <user@example.com>'
879 880 a
880 881 overwriting a expanding keywords
881 882 committed changeset 2:85e279d709ffc28c9fdd1b868570985fc3d87082
882 883 $ hg export -o ../rejecttest.diff tip
883 884 $ cd ../Test
884 885 $ hg import ../rejecttest.diff
885 886 applying ../rejecttest.diff
886 887 $ cat a b
887 888 expand $Id: a 4e0994474d25 Thu, 01 Jan 1970 00:00:03 +0000 user $ rejecttest
888 889 do not process $Id: rejecttest
889 890 xxx $
890 891 $Xinfo: User Name <user@example.com>: rejects? $
891 892 ignore $Id$
892 893
893 894 $ hg rollback
894 895 repository tip rolled back to revision 2 (undo import)
895 896 working directory now based on revision 2
896 897 $ hg update --clean
897 898 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
898 899
899 900 kwexpand/kwshrink on selected files
900 901
901 902 $ mkdir x
902 903 $ hg copy a x/a
903 904 $ hg --verbose kwshrink a
904 905 overwriting a shrinking keywords
905 906 - sleep required for dirstate.normal() check
906 907 $ sleep 1
907 908 $ hg status a
908 909 $ hg --verbose kwexpand a
909 910 overwriting a expanding keywords
910 911 $ hg status a
911 912
912 913 kwexpand x/a should abort
913 914
914 915 $ hg --verbose kwexpand x/a
915 916 abort: outstanding uncommitted changes
916 917 [255]
917 918 $ cd x
918 919 $ hg --debug commit -m xa -d '3 0' -u 'User Name <user@example.com>'
919 920 x/a
920 921 x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
921 922 overwriting x/a expanding keywords
922 923 committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
923 924 $ cat a
924 925 expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
925 926 do not process $Id:
926 927 xxx $
927 928 $Xinfo: User Name <user@example.com>: xa $
928 929
929 930 kwshrink a inside directory x
930 931
931 932 $ hg --verbose kwshrink a
932 933 overwriting x/a shrinking keywords
933 934 $ cat a
934 935 expand $Id$
935 936 do not process $Id:
936 937 xxx $
937 938 $Xinfo$
938 939 $ cd ..
939 940
940 941 kwexpand nonexistent
941 942
942 943 $ hg kwexpand nonexistent
943 944 nonexistent:* (glob)
944 945
945 946
946 947 #if serve
947 948 hg serve
948 949 - expand with hgweb file
949 950 - no expansion with hgweb annotate/changeset/filediff
950 951 - check errors
951 952
952 953 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
953 954 $ cat hg.pid >> $DAEMON_PIDS
954 955 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'file/tip/a/?style=raw'
955 956 200 Script output follows
956 957
957 958 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
958 959 do not process $Id:
959 960 xxx $
960 961 $Xinfo: User Name <user@example.com>: firstline $
961 962 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'annotate/tip/a/?style=raw'
962 963 200 Script output follows
963 964
964 965
965 966 user@1: expand $Id$
966 967 user@1: do not process $Id:
967 968 user@1: xxx $
968 969 user@2: $Xinfo$
969 970
970 971
971 972
972 973
973 974 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'rev/tip/?style=raw'
974 975 200 Script output follows
975 976
976 977
977 978 # HG changeset patch
978 979 # User User Name <user@example.com>
979 980 # Date 3 0
980 981 # Node ID b4560182a3f9a358179fd2d835c15e9da379c1e4
981 982 # Parent bb948857c743469b22bbf51f7ec8112279ca5d83
982 983 xa
983 984
984 985 diff -r bb948857c743 -r b4560182a3f9 x/a
985 986 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
986 987 +++ b/x/a Thu Jan 01 00:00:03 1970 +0000
987 988 @@ -0,0 +1,4 @@
988 989 +expand $Id$
989 990 +do not process $Id:
990 991 +xxx $
991 992 +$Xinfo$
992 993
993 994 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT 'diff/bb948857c743/a?style=raw'
994 995 200 Script output follows
995 996
996 997
997 998 diff -r ef63ca68695b -r bb948857c743 a
998 999 --- a/a Thu Jan 01 00:00:00 1970 +0000
999 1000 +++ b/a Thu Jan 01 00:00:02 1970 +0000
1000 1001 @@ -1,3 +1,4 @@
1001 1002 expand $Id$
1002 1003 do not process $Id:
1003 1004 xxx $
1004 1005 +$Xinfo$
1005 1006
1006 1007
1007 1008
1008 1009
1009 1010 $ cat errors.log
1010 1011 #endif
1011 1012
1012 1013 Prepare merge and resolve tests
1013 1014
1014 1015 $ echo '$Id$' > m
1015 1016 $ hg add m
1016 1017 $ hg commit -m 4kw
1017 1018 $ echo foo >> m
1018 1019 $ hg commit -m 5foo
1019 1020
1020 1021 simplemerge
1021 1022
1022 1023 $ hg update 4
1023 1024 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1024 1025 $ echo foo >> m
1025 1026 $ hg commit -m 6foo
1026 1027 created new head
1027 1028 $ hg merge
1028 1029 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1029 1030 (branch merge, don't forget to commit)
1030 1031 $ hg commit -m simplemerge
1031 1032 $ cat m
1032 1033 $Id: m 27d48ee14f67 Thu, 01 Jan 1970 00:00:00 +0000 test $
1033 1034 foo
1034 1035
1035 1036 conflict: keyword should stay outside conflict zone
1036 1037
1037 1038 $ hg update 4
1038 1039 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1039 1040 $ echo bar >> m
1040 1041 $ hg commit -m 8bar
1041 1042 created new head
1042 1043 $ hg merge
1043 1044 merging m
1044 1045 warning: conflicts during merge.
1045 1046 merging m incomplete! (edit conflicts, then use 'hg resolve --mark')
1046 1047 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1047 1048 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1048 1049 [1]
1049 1050 $ cat m
1050 1051 $Id$
1051 1052 <<<<<<< local
1052 1053 bar
1053 1054 =======
1054 1055 foo
1055 1056 >>>>>>> other
1056 1057
1057 1058 resolve to local
1058 1059
1059 1060 $ HGMERGE=internal:local hg resolve -a
1060 1061 $ hg commit -m localresolve
1061 1062 $ cat m
1062 1063 $Id: m 800511b3a22d Thu, 01 Jan 1970 00:00:00 +0000 test $
1063 1064 bar
1064 1065
1065 1066 Test restricted mode with transplant -b
1066 1067
1067 1068 $ hg update 6
1068 1069 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1069 1070 $ hg branch foo
1070 1071 marked working directory as branch foo
1071 1072 (branches are permanent and global, did you want a bookmark?)
1072 1073 $ mv a a.bak
1073 1074 $ echo foobranch > a
1074 1075 $ cat a.bak >> a
1075 1076 $ rm a.bak
1076 1077 $ hg commit -m 9foobranch
1077 1078 $ hg update default
1078 1079 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1079 1080 $ hg -y transplant -b foo tip
1080 1081 applying 4aa30d025d50
1081 1082 4aa30d025d50 transplanted to e00abbf63521
1082 1083
1083 1084 Expansion in changeset but not in file
1084 1085
1085 1086 $ hg tip -p
1086 1087 changeset: 11:e00abbf63521
1087 1088 tag: tip
1088 1089 parent: 9:800511b3a22d
1089 1090 user: test
1090 1091 date: Thu Jan 01 00:00:00 1970 +0000
1091 1092 summary: 9foobranch
1092 1093
1093 1094 diff -r 800511b3a22d -r e00abbf63521 a
1094 1095 --- a/a Thu Jan 01 00:00:00 1970 +0000
1095 1096 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1096 1097 @@ -1,3 +1,4 @@
1097 1098 +foobranch
1098 1099 expand $Id$
1099 1100 do not process $Id:
1100 1101 xxx $
1101 1102
1102 1103 $ head -n 2 a
1103 1104 foobranch
1104 1105 expand $Id: a e00abbf63521 Thu, 01 Jan 1970 00:00:00 +0000 test $
1105 1106
1106 1107 Turn off expansion
1107 1108
1108 1109 $ hg -q rollback
1109 1110 $ hg -q update -C
1110 1111
1111 1112 kwshrink with unknown file u
1112 1113
1113 1114 $ cp a u
1114 1115 $ hg --verbose kwshrink
1115 1116 overwriting a shrinking keywords
1116 1117 overwriting m shrinking keywords
1117 1118 overwriting x/a shrinking keywords
1118 1119
1119 1120 Keywords shrunk in working directory, but not yet disabled
1120 1121 - cat shows unexpanded keywords
1121 1122 - hg cat shows expanded keywords
1122 1123
1123 1124 $ cat a b
1124 1125 expand $Id$
1125 1126 do not process $Id:
1126 1127 xxx $
1127 1128 $Xinfo$
1128 1129 ignore $Id$
1129 1130 $ hg cat sym a b && echo
1130 1131 expand $Id: a bb948857c743 Thu, 01 Jan 1970 00:00:02 +0000 user $
1131 1132 do not process $Id:
1132 1133 xxx $
1133 1134 $Xinfo: User Name <user@example.com>: firstline $
1134 1135 ignore $Id$
1135 1136 a
1136 1137
1137 1138 Now disable keyword expansion
1138 1139
1139 1140 $ rm "$HGRCPATH"
1140 1141 $ cat a b
1141 1142 expand $Id$
1142 1143 do not process $Id:
1143 1144 xxx $
1144 1145 $Xinfo$
1145 1146 ignore $Id$
1146 1147 $ hg cat sym a b && echo
1147 1148 expand $Id$
1148 1149 do not process $Id:
1149 1150 xxx $
1150 1151 $Xinfo$
1151 1152 ignore $Id$
1152 1153 a
1153 1154
1154 1155 $ cd ..
@@ -1,2353 +1,2406 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "patchbomb=" >> $HGRCPATH
3 3
4 4 $ hg init t
5 5 $ cd t
6 6 $ echo a > a
7 7 $ hg commit -Ama -d '1 0'
8 8 adding a
9 9
10 10 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -r tip
11 11 this patch series consists of 1 patches.
12 12
13 13
14 14 displaying [PATCH] a ...
15 15 Content-Type: text/plain; charset="us-ascii"
16 16 MIME-Version: 1.0
17 17 Content-Transfer-Encoding: 7bit
18 18 Subject: [PATCH] a
19 19 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
20 20 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
21 21 User-Agent: Mercurial-patchbomb/* (glob)
22 22 Date: Thu, 01 Jan 1970 00:01:00 +0000
23 23 From: quux
24 24 To: foo
25 25 Cc: bar
26 26
27 27 # HG changeset patch
28 28 # User test
29 29 # Date 1 0
30 # Thu Jan 01 00:00:01 1970 +0000
30 31 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
31 32 # Parent 0000000000000000000000000000000000000000
32 33 a
33 34
34 35 diff -r 000000000000 -r 8580ff50825a a
35 36 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36 37 +++ b/a Thu Jan 01 00:00:01 1970 +0000
37 38 @@ -0,0 +1,1 @@
38 39 +a
39 40
40 41
41 42 $ hg --config ui.interactive=1 email --confirm -n -f quux -t foo -c bar -r tip<<EOF
42 43 > n
43 44 > EOF
44 45 this patch series consists of 1 patches.
45 46
46 47
47 48 Final summary:
48 49
49 50 From: quux
50 51 To: foo
51 52 Cc: bar
52 53 Subject: [PATCH] a
53 54 a | 1 +
54 55 1 files changed, 1 insertions(+), 0 deletions(-)
55 56
56 57 are you sure you want to send (yn)? abort: patchbomb canceled
57 58 [255]
58 59
59 60 $ echo b > b
60 61 $ hg commit -Amb -d '2 0'
61 62 adding b
62 63
63 64 $ hg email --date '1970-1-1 0:2' -n -f quux -t foo -c bar -s test -r 0:tip
64 65 this patch series consists of 2 patches.
65 66
66 67
67 68 Write the introductory message for the patch series.
68 69
69 70
70 71 displaying [PATCH 0 of 2] test ...
71 72 Content-Type: text/plain; charset="us-ascii"
72 73 MIME-Version: 1.0
73 74 Content-Transfer-Encoding: 7bit
74 75 Subject: [PATCH 0 of 2] test
75 76 Message-Id: <patchbomb.120@*> (glob)
76 77 User-Agent: Mercurial-patchbomb/* (glob)
77 78 Date: Thu, 01 Jan 1970 00:02:00 +0000
78 79 From: quux
79 80 To: foo
80 81 Cc: bar
81 82
82 83
83 84 displaying [PATCH 1 of 2] a ...
84 85 Content-Type: text/plain; charset="us-ascii"
85 86 MIME-Version: 1.0
86 87 Content-Transfer-Encoding: 7bit
87 88 Subject: [PATCH 1 of 2] a
88 89 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
89 90 Message-Id: <8580ff50825a50c8f716.121@*> (glob)
90 91 In-Reply-To: <patchbomb.120@*> (glob)
91 92 References: <patchbomb.120@*> (glob)
92 93 User-Agent: Mercurial-patchbomb/* (glob)
93 94 Date: Thu, 01 Jan 1970 00:02:01 +0000
94 95 From: quux
95 96 To: foo
96 97 Cc: bar
97 98
98 99 # HG changeset patch
99 100 # User test
100 101 # Date 1 0
102 # Thu Jan 01 00:00:01 1970 +0000
101 103 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
102 104 # Parent 0000000000000000000000000000000000000000
103 105 a
104 106
105 107 diff -r 000000000000 -r 8580ff50825a a
106 108 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
107 109 +++ b/a Thu Jan 01 00:00:01 1970 +0000
108 110 @@ -0,0 +1,1 @@
109 111 +a
110 112
111 113 displaying [PATCH 2 of 2] b ...
112 114 Content-Type: text/plain; charset="us-ascii"
113 115 MIME-Version: 1.0
114 116 Content-Transfer-Encoding: 7bit
115 117 Subject: [PATCH 2 of 2] b
116 118 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
117 119 Message-Id: <97d72e5f12c7e84f8506.122@*> (glob)
118 120 In-Reply-To: <patchbomb.120@*> (glob)
119 121 References: <patchbomb.120@*> (glob)
120 122 User-Agent: Mercurial-patchbomb/* (glob)
121 123 Date: Thu, 01 Jan 1970 00:02:02 +0000
122 124 From: quux
123 125 To: foo
124 126 Cc: bar
125 127
126 128 # HG changeset patch
127 129 # User test
128 130 # Date 2 0
131 # Thu Jan 01 00:00:02 1970 +0000
129 132 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
130 133 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
131 134 b
132 135
133 136 diff -r 8580ff50825a -r 97d72e5f12c7 b
134 137 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
135 138 +++ b/b Thu Jan 01 00:00:02 1970 +0000
136 139 @@ -0,0 +1,1 @@
137 140 +b
138 141
139 142
140 143 .hg/last-email.txt
141 144
142 145 $ cat > editor.sh << '__EOF__'
143 146 > echo "a precious introductory message" > "$1"
144 147 > __EOF__
145 148 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg email -n -t foo -s test -r 0:tip > /dev/null
146 149 $ cat .hg/last-email.txt
147 150 a precious introductory message
148 151
149 152 $ hg email -m test.mbox -f quux -t foo -c bar -s test 0:tip \
150 153 > --config extensions.progress= --config progress.assume-tty=1 \
151 154 > --config progress.delay=0 --config progress.refresh=0 \
152 155 > --config progress.width=60
153 156 this patch series consists of 2 patches.
154 157
155 158
156 159 Write the introductory message for the patch series.
157 160
158 161 \r (no-eol) (esc)
159 162 sending [ ] 0/3\r (no-eol) (esc)
160 163 sending [ ] 0/3\r (no-eol) (esc)
161 164 \r (no-eol) (esc)
162 165 \r (no-eol) (esc)
163 166 \r (no-eol) (esc)
164 167 \r (no-eol) (esc)
165 168 sending [==============> ] 1/3\r (no-eol) (esc)
166 169 sending [==============> ] 1/3\r (no-eol) (esc)
167 170 \r (no-eol) (esc)
168 171 \r (no-eol) (esc)
169 172 \r (no-eol) (esc)
170 173 \r (no-eol) (esc)
171 174 sending [=============================> ] 2/3\r (no-eol) (esc)
172 175 sending [=============================> ] 2/3\r (no-eol) (esc)
173 176 \r (esc)
174 177 sending [PATCH 0 of 2] test ...
175 178 sending [PATCH 1 of 2] a ...
176 179 sending [PATCH 2 of 2] b ...
177 180
178 181 $ cd ..
179 182
180 183 $ hg clone -q t t2
181 184 $ cd t2
182 185 $ echo c > c
183 186 $ hg commit -Amc -d '3 0'
184 187 adding c
185 188
186 189 $ cat > description <<EOF
187 190 > a multiline
188 191 >
189 192 > description
190 193 > EOF
191 194
192 195
193 196 test bundle and description:
194 197 $ hg email --date '1970-1-1 0:3' -n -f quux -t foo \
195 198 > -c bar -s test -r tip -b --desc description
196 199 searching for changes
197 200 1 changesets found
198 201
199 202 displaying test ...
200 203 Content-Type: multipart/mixed; boundary="===*" (glob)
201 204 MIME-Version: 1.0
202 205 Subject: test
203 206 Message-Id: <patchbomb.180@*> (glob)
204 207 User-Agent: Mercurial-patchbomb/* (glob)
205 208 Date: Thu, 01 Jan 1970 00:03:00 +0000
206 209 From: quux
207 210 To: foo
208 211 Cc: bar
209 212
210 213 --===* (glob)
211 214 Content-Type: text/plain; charset="us-ascii"
212 215 MIME-Version: 1.0
213 216 Content-Transfer-Encoding: 7bit
214 217
215 218 a multiline
216 219
217 220 description
218 221
219 222 --===* (glob)
220 223 Content-Type: application/x-mercurial-bundle
221 224 MIME-Version: 1.0
222 225 Content-Disposition: attachment; filename="bundle.hg"
223 226 Content-Transfer-Encoding: base64
224 227
225 228 SEcxMEJaaDkxQVkmU1nvR7I3AAAN////lFYQWj1/4HwRkdC/AywIAk0E4pfoSIIIgQCgGEQOcLAA
226 229 2tA1VPyp4mkeoG0EaaPU0GTT1GjRiNPIg9CZGBqZ6UbU9J+KFU09DNUaGgAAAAAANAGgAAAAA1U8
227 230 oGgAADQGgAANNANAAAAAAZipFLz3XoakCEQB3PVPyHJVi1iYkAAKQAZQGpQGZESInRnCFMqLDla2
228 231 Bx3qfRQeA2N4lnzKkAmP8kR2asievLLXXebVU8Vg4iEBqcJNJAxIapSU6SM4888ZAciRG6MYAIEE
229 232 SlIBpFisgGkyRjX//TMtfcUAEsGu56+YnE1OlTZmzKm8BSu2rvo4rHAYYaadIFFuTy0LYgIkgLVD
230 233 sgVa2F19D1tx9+hgbAygLgQwaIqcDdgA4BjQgIiz/AEP72++llgDKhKducqodGE4B0ETqF3JFOFC
231 234 Q70eyNw=
232 235 --===*-- (glob)
233 236
234 237 utf-8 patch:
235 238 $ python -c 'fp = open("utf", "wb"); fp.write("h\xC3\xB6mma!\n"); fp.close();'
236 239 $ hg commit -A -d '4 0' -m 'utf-8 content'
237 240 adding description
238 241 adding utf
239 242
240 243 no mime encoding for email --test:
241 244 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
242 245 this patch series consists of 1 patches.
243 246
244 247
245 248 displaying [PATCH] utf-8 content ...
246 249 Content-Type: text/plain; charset="us-ascii"
247 250 MIME-Version: 1.0
248 251 Content-Transfer-Encoding: 8bit
249 252 Subject: [PATCH] utf-8 content
250 253 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
251 254 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
252 255 User-Agent: Mercurial-patchbomb/* (glob)
253 256 Date: Thu, 01 Jan 1970 00:04:00 +0000
254 257 From: quux
255 258 To: foo
256 259 Cc: bar
257 260
258 261 # HG changeset patch
259 262 # User test
260 263 # Date 4 0
264 # Thu Jan 01 00:00:04 1970 +0000
261 265 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
262 266 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
263 267 utf-8 content
264 268
265 269 diff -r ff2c9fa2018b -r 909a00e13e9d description
266 270 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
267 271 +++ b/description Thu Jan 01 00:00:04 1970 +0000
268 272 @@ -0,0 +1,3 @@
269 273 +a multiline
270 274 +
271 275 +description
272 276 diff -r ff2c9fa2018b -r 909a00e13e9d utf
273 277 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
274 278 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
275 279 @@ -0,0 +1,1 @@
276 280 +h\xc3\xb6mma! (esc)
277 281
278 282
279 283 mime encoded mbox (base64):
280 284 $ hg email --date '1970-1-1 0:4' -f 'Q <quux>' -t foo -c bar -r tip -m mbox
281 285 this patch series consists of 1 patches.
282 286
283 287
284 288 sending [PATCH] utf-8 content ...
285 289
286 290 $ cat mbox
287 291 From quux ... ... .. ..:..:.. .... (re)
288 292 Content-Type: text/plain; charset="utf-8"
289 293 MIME-Version: 1.0
290 294 Content-Transfer-Encoding: base64
291 295 Subject: [PATCH] utf-8 content
292 296 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
293 297 Message-Id: <909a00e13e9d78b575ae.240@*> (glob)
294 298 User-Agent: Mercurial-patchbomb/* (glob)
295 299 Date: Thu, 01 Jan 1970 00:04:00 +0000
296 300 From: Q <quux>
297 301 To: foo
298 302 Cc: bar
299 303
300 IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojIE5vZGUgSUQgOTA5
301 YTAwZTEzZTlkNzhiNTc1YWVlZTIzZGRkYmFkYTQ2ZDVhMTQzZgojIFBhcmVudCAgZmYyYzlmYTIw
302 MThiMTVmYTc0YjMzMzYzYmRhOTUyNzMyM2UyYTk5Zgp1dGYtOCBjb250ZW50CgpkaWZmIC1yIGZm
303 MmM5ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgZGVzY3JpcHRpb24KLS0tIC9kZXYvbnVsbAlUaHUg
304 SmFuIDAxIDAwOjAwOjAwIDE5NzAgKzAwMDAKKysrIGIvZGVzY3JpcHRpb24JVGh1IEphbiAwMSAw
305 MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMyBAQAorYSBtdWx0aWxpbmUKKworZGVzY3Jp
306 cHRpb24KZGlmZiAtciBmZjJjOWZhMjAxOGIgLXIgOTA5YTAwZTEzZTlkIHV0ZgotLS0gL2Rldi9u
307 dWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3MCArMDAwMAorKysgYi91dGYJVGh1IEphbiAwMSAw
308 MDowMDowNCAxOTcwICswMDAwCkBAIC0wLDAgKzEsMSBAQAoraMO2bW1hIQo=
304 IyBIRyBjaGFuZ2VzZXQgcGF0Y2gKIyBVc2VyIHRlc3QKIyBEYXRlIDQgMAojICAgICAgVGh1IEph
305 biAwMSAwMDowMDowNCAxOTcwICswMDAwCiMgTm9kZSBJRCA5MDlhMDBlMTNlOWQ3OGI1NzVhZWVl
306 MjNkZGRiYWRhNDZkNWExNDNmCiMgUGFyZW50ICBmZjJjOWZhMjAxOGIxNWZhNzRiMzMzNjNiZGE5
307 NTI3MzIzZTJhOTlmCnV0Zi04IGNvbnRlbnQKCmRpZmYgLXIgZmYyYzlmYTIwMThiIC1yIDkwOWEw
308 MGUxM2U5ZCBkZXNjcmlwdGlvbgotLS0gL2Rldi9udWxsCVRodSBKYW4gMDEgMDA6MDA6MDAgMTk3
309 MCArMDAwMAorKysgYi9kZXNjcmlwdGlvbglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
310 QEAgLTAsMCArMSwzIEBACithIG11bHRpbGluZQorCitkZXNjcmlwdGlvbgpkaWZmIC1yIGZmMmM5
311 ZmEyMDE4YiAtciA5MDlhMDBlMTNlOWQgdXRmCi0tLSAvZGV2L251bGwJVGh1IEphbiAwMSAwMDow
312 MDowMCAxOTcwICswMDAwCisrKyBiL3V0ZglUaHUgSmFuIDAxIDAwOjAwOjA0IDE5NzAgKzAwMDAK
313 QEAgLTAsMCArMSwxIEBACitow7ZtbWEhCg==
309 314
310 315
311 316 $ python -c 'print open("mbox").read().split("\n\n")[1].decode("base64")'
312 317 # HG changeset patch
313 318 # User test
314 319 # Date 4 0
320 # Thu Jan 01 00:00:04 1970 +0000
315 321 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
316 322 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
317 323 utf-8 content
318 324
319 325 diff -r ff2c9fa2018b -r 909a00e13e9d description
320 326 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
321 327 +++ b/description Thu Jan 01 00:00:04 1970 +0000
322 328 @@ -0,0 +1,3 @@
323 329 +a multiline
324 330 +
325 331 +description
326 332 diff -r ff2c9fa2018b -r 909a00e13e9d utf
327 333 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
328 334 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
329 335 @@ -0,0 +1,1 @@
330 336 +h\xc3\xb6mma! (esc)
331 337
332 338 $ rm mbox
333 339
334 340 mime encoded mbox (quoted-printable):
335 341 $ python -c 'fp = open("long", "wb"); fp.write("%s\nfoo\n\nbar\n" % ("x" * 1024)); fp.close();'
336 342 $ hg commit -A -d '4 0' -m 'long line'
337 343 adding long
338 344
339 345 no mime encoding for email --test:
340 346 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -n
341 347 this patch series consists of 1 patches.
342 348
343 349
344 350 displaying [PATCH] long line ...
345 351 Content-Type: text/plain; charset="us-ascii"
346 352 MIME-Version: 1.0
347 353 Content-Transfer-Encoding: quoted-printable
348 354 Subject: [PATCH] long line
349 355 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
350 356 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
351 357 User-Agent: Mercurial-patchbomb/* (glob)
352 358 Date: Thu, 01 Jan 1970 00:04:00 +0000
353 359 From: quux
354 360 To: foo
355 361 Cc: bar
356 362
357 363 # HG changeset patch
358 364 # User test
359 365 # Date 4 0
366 # Thu Jan 01 00:00:04 1970 +0000
360 367 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
361 368 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
362 369 long line
363 370
364 371 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
365 372 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
366 373 +++ b/long Thu Jan 01 00:00:04 1970 +0000
367 374 @@ -0,0 +1,4 @@
368 375 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
369 376 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
370 377 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
371 378 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
372 379 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
373 380 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
374 381 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
375 382 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
376 383 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
377 384 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
378 385 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
379 386 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
380 387 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
381 388 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
382 389 +foo
383 390 +
384 391 +bar
385 392
386 393
387 394 mime encoded mbox (quoted-printable):
388 395 $ hg email --date '1970-1-1 0:4' -f quux -t foo -c bar -r tip -m mbox
389 396 this patch series consists of 1 patches.
390 397
391 398
392 399 sending [PATCH] long line ...
393 400 $ cat mbox
394 401 From quux ... ... .. ..:..:.. .... (re)
395 402 Content-Type: text/plain; charset="us-ascii"
396 403 MIME-Version: 1.0
397 404 Content-Transfer-Encoding: quoted-printable
398 405 Subject: [PATCH] long line
399 406 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
400 407 Message-Id: <a2ea8fc83dd8b93cfd86.240@*> (glob)
401 408 User-Agent: Mercurial-patchbomb/* (glob)
402 409 Date: Thu, 01 Jan 1970 00:04:00 +0000
403 410 From: quux
404 411 To: foo
405 412 Cc: bar
406 413
407 414 # HG changeset patch
408 415 # User test
409 416 # Date 4 0
417 # Thu Jan 01 00:00:04 1970 +0000
410 418 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
411 419 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
412 420 long line
413 421
414 422 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
415 423 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
416 424 +++ b/long Thu Jan 01 00:00:04 1970 +0000
417 425 @@ -0,0 +1,4 @@
418 426 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
419 427 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
420 428 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
421 429 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
422 430 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
423 431 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
424 432 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
425 433 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
426 434 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
427 435 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
428 436 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
429 437 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
430 438 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
431 439 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
432 440 +foo
433 441 +
434 442 +bar
435 443
436 444
437 445
438 446 $ rm mbox
439 447
440 448 iso-8859-1 patch:
441 449 $ python -c 'fp = open("isolatin", "wb"); fp.write("h\xF6mma!\n"); fp.close();'
442 450 $ hg commit -A -d '5 0' -m 'isolatin 8-bit encoding'
443 451 adding isolatin
444 452
445 453 fake ascii mbox:
446 454 $ hg email --date '1970-1-1 0:5' -f quux -t foo -c bar -r tip -m mbox
447 455 this patch series consists of 1 patches.
448 456
449 457
450 458 sending [PATCH] isolatin 8-bit encoding ...
451 459 $ cat mbox
452 460 From quux ... ... .. ..:..:.. .... (re)
453 461 Content-Type: text/plain; charset="us-ascii"
454 462 MIME-Version: 1.0
455 463 Content-Transfer-Encoding: 8bit
456 464 Subject: [PATCH] isolatin 8-bit encoding
457 465 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
458 466 Message-Id: <240fb913fc1b7ff15ddb.300@*> (glob)
459 467 User-Agent: Mercurial-patchbomb/* (glob)
460 468 Date: Thu, 01 Jan 1970 00:05:00 +0000
461 469 From: quux
462 470 To: foo
463 471 Cc: bar
464 472
465 473 # HG changeset patch
466 474 # User test
467 475 # Date 5 0
476 # Thu Jan 01 00:00:05 1970 +0000
468 477 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
469 478 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
470 479 isolatin 8-bit encoding
471 480
472 481 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
473 482 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
474 483 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
475 484 @@ -0,0 +1,1 @@
476 485 +h\xf6mma! (esc)
477 486
478 487
479 488
480 489 test diffstat for single patch:
481 490 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y -r 2
482 491 this patch series consists of 1 patches.
483 492
484 493
485 494 Final summary:
486 495
487 496 From: quux
488 497 To: foo
489 498 Cc: bar
490 499 Subject: [PATCH] test
491 500 c | 1 +
492 501 1 files changed, 1 insertions(+), 0 deletions(-)
493 502
494 503 are you sure you want to send (yn)? y
495 504
496 505 displaying [PATCH] test ...
497 506 Content-Type: text/plain; charset="us-ascii"
498 507 MIME-Version: 1.0
499 508 Content-Transfer-Encoding: 7bit
500 509 Subject: [PATCH] test
501 510 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
502 511 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
503 512 User-Agent: Mercurial-patchbomb/* (glob)
504 513 Date: Thu, 01 Jan 1970 00:01:00 +0000
505 514 From: quux
506 515 To: foo
507 516 Cc: bar
508 517
509 518 c | 1 +
510 519 1 files changed, 1 insertions(+), 0 deletions(-)
511 520
512 521
513 522 # HG changeset patch
514 523 # User test
515 524 # Date 3 0
525 # Thu Jan 01 00:00:03 1970 +0000
516 526 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
517 527 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
518 528 c
519 529
520 530 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
521 531 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
522 532 +++ b/c Thu Jan 01 00:00:03 1970 +0000
523 533 @@ -0,0 +1,1 @@
524 534 +c
525 535
526 536
527 537 test diffstat for multiple patches:
528 538 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -d -y \
529 539 > -r 0:1
530 540 this patch series consists of 2 patches.
531 541
532 542
533 543 Write the introductory message for the patch series.
534 544
535 545
536 546 Final summary:
537 547
538 548 From: quux
539 549 To: foo
540 550 Cc: bar
541 551 Subject: [PATCH 0 of 2] test
542 552 a | 1 +
543 553 b | 1 +
544 554 2 files changed, 2 insertions(+), 0 deletions(-)
545 555 Subject: [PATCH 1 of 2] a
546 556 a | 1 +
547 557 1 files changed, 1 insertions(+), 0 deletions(-)
548 558 Subject: [PATCH 2 of 2] b
549 559 b | 1 +
550 560 1 files changed, 1 insertions(+), 0 deletions(-)
551 561
552 562 are you sure you want to send (yn)? y
553 563
554 564 displaying [PATCH 0 of 2] test ...
555 565 Content-Type: text/plain; charset="us-ascii"
556 566 MIME-Version: 1.0
557 567 Content-Transfer-Encoding: 7bit
558 568 Subject: [PATCH 0 of 2] test
559 569 Message-Id: <patchbomb.60@*> (glob)
560 570 User-Agent: Mercurial-patchbomb/* (glob)
561 571 Date: Thu, 01 Jan 1970 00:01:00 +0000
562 572 From: quux
563 573 To: foo
564 574 Cc: bar
565 575
566 576
567 577 a | 1 +
568 578 b | 1 +
569 579 2 files changed, 2 insertions(+), 0 deletions(-)
570 580
571 581 displaying [PATCH 1 of 2] a ...
572 582 Content-Type: text/plain; charset="us-ascii"
573 583 MIME-Version: 1.0
574 584 Content-Transfer-Encoding: 7bit
575 585 Subject: [PATCH 1 of 2] a
576 586 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
577 587 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
578 588 In-Reply-To: <patchbomb.60@*> (glob)
579 589 References: <patchbomb.60@*> (glob)
580 590 User-Agent: Mercurial-patchbomb/* (glob)
581 591 Date: Thu, 01 Jan 1970 00:01:01 +0000
582 592 From: quux
583 593 To: foo
584 594 Cc: bar
585 595
586 596 a | 1 +
587 597 1 files changed, 1 insertions(+), 0 deletions(-)
588 598
589 599
590 600 # HG changeset patch
591 601 # User test
592 602 # Date 1 0
603 # Thu Jan 01 00:00:01 1970 +0000
593 604 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
594 605 # Parent 0000000000000000000000000000000000000000
595 606 a
596 607
597 608 diff -r 000000000000 -r 8580ff50825a a
598 609 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
599 610 +++ b/a Thu Jan 01 00:00:01 1970 +0000
600 611 @@ -0,0 +1,1 @@
601 612 +a
602 613
603 614 displaying [PATCH 2 of 2] b ...
604 615 Content-Type: text/plain; charset="us-ascii"
605 616 MIME-Version: 1.0
606 617 Content-Transfer-Encoding: 7bit
607 618 Subject: [PATCH 2 of 2] b
608 619 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
609 620 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
610 621 In-Reply-To: <patchbomb.60@*> (glob)
611 622 References: <patchbomb.60@*> (glob)
612 623 User-Agent: Mercurial-patchbomb/* (glob)
613 624 Date: Thu, 01 Jan 1970 00:01:02 +0000
614 625 From: quux
615 626 To: foo
616 627 Cc: bar
617 628
618 629 b | 1 +
619 630 1 files changed, 1 insertions(+), 0 deletions(-)
620 631
621 632
622 633 # HG changeset patch
623 634 # User test
624 635 # Date 2 0
636 # Thu Jan 01 00:00:02 1970 +0000
625 637 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
626 638 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
627 639 b
628 640
629 641 diff -r 8580ff50825a -r 97d72e5f12c7 b
630 642 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
631 643 +++ b/b Thu Jan 01 00:00:02 1970 +0000
632 644 @@ -0,0 +1,1 @@
633 645 +b
634 646
635 647
636 648 test inline for single patch:
637 649 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2
638 650 this patch series consists of 1 patches.
639 651
640 652
641 653 displaying [PATCH] test ...
642 654 Content-Type: multipart/mixed; boundary="===*" (glob)
643 655 MIME-Version: 1.0
644 656 Subject: [PATCH] test
645 657 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
646 658 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
647 659 User-Agent: Mercurial-patchbomb/* (glob)
648 660 Date: Thu, 01 Jan 1970 00:01:00 +0000
649 661 From: quux
650 662 To: foo
651 663 Cc: bar
652 664
653 665 --===* (glob)
654 666 Content-Type: text/x-patch; charset="us-ascii"
655 667 MIME-Version: 1.0
656 668 Content-Transfer-Encoding: 7bit
657 669 Content-Disposition: inline; filename=t2.patch
658 670
659 671 # HG changeset patch
660 672 # User test
661 673 # Date 3 0
674 # Thu Jan 01 00:00:03 1970 +0000
662 675 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
663 676 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
664 677 c
665 678
666 679 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
667 680 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
668 681 +++ b/c Thu Jan 01 00:00:03 1970 +0000
669 682 @@ -0,0 +1,1 @@
670 683 +c
671 684
672 685 --===*-- (glob)
673 686
674 687
675 688 test inline for single patch (quoted-printable):
676 689 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 4
677 690 this patch series consists of 1 patches.
678 691
679 692
680 693 displaying [PATCH] test ...
681 694 Content-Type: multipart/mixed; boundary="===*" (glob)
682 695 MIME-Version: 1.0
683 696 Subject: [PATCH] test
684 697 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
685 698 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
686 699 User-Agent: Mercurial-patchbomb/* (glob)
687 700 Date: Thu, 01 Jan 1970 00:01:00 +0000
688 701 From: quux
689 702 To: foo
690 703 Cc: bar
691 704
692 705 --===* (glob)
693 706 Content-Type: text/x-patch; charset="us-ascii"
694 707 MIME-Version: 1.0
695 708 Content-Transfer-Encoding: quoted-printable
696 709 Content-Disposition: inline; filename=t2.patch
697 710
698 711 # HG changeset patch
699 712 # User test
700 713 # Date 4 0
714 # Thu Jan 01 00:00:04 1970 +0000
701 715 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
702 716 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
703 717 long line
704 718
705 719 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
706 720 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
707 721 +++ b/long Thu Jan 01 00:00:04 1970 +0000
708 722 @@ -0,0 +1,4 @@
709 723 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
710 724 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
711 725 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
712 726 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
713 727 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
714 728 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
715 729 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
716 730 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
717 731 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
718 732 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
719 733 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
720 734 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
721 735 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
722 736 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
723 737 +foo
724 738 +
725 739 +bar
726 740
727 741 --===*-- (glob)
728 742
729 743 test inline for multiple patches:
730 744 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i \
731 745 > -r 0:1 -r 4
732 746 this patch series consists of 3 patches.
733 747
734 748
735 749 Write the introductory message for the patch series.
736 750
737 751
738 752 displaying [PATCH 0 of 3] test ...
739 753 Content-Type: text/plain; charset="us-ascii"
740 754 MIME-Version: 1.0
741 755 Content-Transfer-Encoding: 7bit
742 756 Subject: [PATCH 0 of 3] test
743 757 Message-Id: <patchbomb.60@*> (glob)
744 758 User-Agent: Mercurial-patchbomb/* (glob)
745 759 Date: Thu, 01 Jan 1970 00:01:00 +0000
746 760 From: quux
747 761 To: foo
748 762 Cc: bar
749 763
750 764
751 765 displaying [PATCH 1 of 3] a ...
752 766 Content-Type: multipart/mixed; boundary="===*" (glob)
753 767 MIME-Version: 1.0
754 768 Subject: [PATCH 1 of 3] a
755 769 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
756 770 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
757 771 In-Reply-To: <patchbomb.60@*> (glob)
758 772 References: <patchbomb.60@*> (glob)
759 773 User-Agent: Mercurial-patchbomb/* (glob)
760 774 Date: Thu, 01 Jan 1970 00:01:01 +0000
761 775 From: quux
762 776 To: foo
763 777 Cc: bar
764 778
765 779 --===* (glob)
766 780 Content-Type: text/x-patch; charset="us-ascii"
767 781 MIME-Version: 1.0
768 782 Content-Transfer-Encoding: 7bit
769 783 Content-Disposition: inline; filename=t2-1.patch
770 784
771 785 # HG changeset patch
772 786 # User test
773 787 # Date 1 0
788 # Thu Jan 01 00:00:01 1970 +0000
774 789 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
775 790 # Parent 0000000000000000000000000000000000000000
776 791 a
777 792
778 793 diff -r 000000000000 -r 8580ff50825a a
779 794 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
780 795 +++ b/a Thu Jan 01 00:00:01 1970 +0000
781 796 @@ -0,0 +1,1 @@
782 797 +a
783 798
784 799 --===*-- (glob)
785 800 displaying [PATCH 2 of 3] b ...
786 801 Content-Type: multipart/mixed; boundary="===*" (glob)
787 802 MIME-Version: 1.0
788 803 Subject: [PATCH 2 of 3] b
789 804 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
790 805 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
791 806 In-Reply-To: <patchbomb.60@*> (glob)
792 807 References: <patchbomb.60@*> (glob)
793 808 User-Agent: Mercurial-patchbomb/* (glob)
794 809 Date: Thu, 01 Jan 1970 00:01:02 +0000
795 810 From: quux
796 811 To: foo
797 812 Cc: bar
798 813
799 814 --===* (glob)
800 815 Content-Type: text/x-patch; charset="us-ascii"
801 816 MIME-Version: 1.0
802 817 Content-Transfer-Encoding: 7bit
803 818 Content-Disposition: inline; filename=t2-2.patch
804 819
805 820 # HG changeset patch
806 821 # User test
807 822 # Date 2 0
823 # Thu Jan 01 00:00:02 1970 +0000
808 824 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
809 825 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
810 826 b
811 827
812 828 diff -r 8580ff50825a -r 97d72e5f12c7 b
813 829 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
814 830 +++ b/b Thu Jan 01 00:00:02 1970 +0000
815 831 @@ -0,0 +1,1 @@
816 832 +b
817 833
818 834 --===*-- (glob)
819 835 displaying [PATCH 3 of 3] long line ...
820 836 Content-Type: multipart/mixed; boundary="===*" (glob)
821 837 MIME-Version: 1.0
822 838 Subject: [PATCH 3 of 3] long line
823 839 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
824 840 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
825 841 In-Reply-To: <patchbomb.60@*> (glob)
826 842 References: <patchbomb.60@*> (glob)
827 843 User-Agent: Mercurial-patchbomb/* (glob)
828 844 Date: Thu, 01 Jan 1970 00:01:03 +0000
829 845 From: quux
830 846 To: foo
831 847 Cc: bar
832 848
833 849 --===* (glob)
834 850 Content-Type: text/x-patch; charset="us-ascii"
835 851 MIME-Version: 1.0
836 852 Content-Transfer-Encoding: quoted-printable
837 853 Content-Disposition: inline; filename=t2-3.patch
838 854
839 855 # HG changeset patch
840 856 # User test
841 857 # Date 4 0
858 # Thu Jan 01 00:00:04 1970 +0000
842 859 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
843 860 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
844 861 long line
845 862
846 863 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
847 864 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
848 865 +++ b/long Thu Jan 01 00:00:04 1970 +0000
849 866 @@ -0,0 +1,4 @@
850 867 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
851 868 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
852 869 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
853 870 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
854 871 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
855 872 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
856 873 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
857 874 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
858 875 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
859 876 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
860 877 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
861 878 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
862 879 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
863 880 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
864 881 +foo
865 882 +
866 883 +bar
867 884
868 885 --===*-- (glob)
869 886
870 887 test attach for single patch:
871 888 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 2
872 889 this patch series consists of 1 patches.
873 890
874 891
875 892 displaying [PATCH] test ...
876 893 Content-Type: multipart/mixed; boundary="===*" (glob)
877 894 MIME-Version: 1.0
878 895 Subject: [PATCH] test
879 896 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
880 897 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
881 898 User-Agent: Mercurial-patchbomb/* (glob)
882 899 Date: Thu, 01 Jan 1970 00:01:00 +0000
883 900 From: quux
884 901 To: foo
885 902 Cc: bar
886 903
887 904 --===* (glob)
888 905 Content-Type: text/plain; charset="us-ascii"
889 906 MIME-Version: 1.0
890 907 Content-Transfer-Encoding: 7bit
891 908
892 909 Patch subject is complete summary.
893 910
894 911
895 912
896 913 --===* (glob)
897 914 Content-Type: text/x-patch; charset="us-ascii"
898 915 MIME-Version: 1.0
899 916 Content-Transfer-Encoding: 7bit
900 917 Content-Disposition: attachment; filename=t2.patch
901 918
902 919 # HG changeset patch
903 920 # User test
904 921 # Date 3 0
922 # Thu Jan 01 00:00:03 1970 +0000
905 923 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
906 924 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
907 925 c
908 926
909 927 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
910 928 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
911 929 +++ b/c Thu Jan 01 00:00:03 1970 +0000
912 930 @@ -0,0 +1,1 @@
913 931 +c
914 932
915 933 --===*-- (glob)
916 934
917 935 test attach for single patch (quoted-printable):
918 936 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a -r 4
919 937 this patch series consists of 1 patches.
920 938
921 939
922 940 displaying [PATCH] test ...
923 941 Content-Type: multipart/mixed; boundary="===*" (glob)
924 942 MIME-Version: 1.0
925 943 Subject: [PATCH] test
926 944 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
927 945 Message-Id: <a2ea8fc83dd8b93cfd86.60@*> (glob)
928 946 User-Agent: Mercurial-patchbomb/* (glob)
929 947 Date: Thu, 01 Jan 1970 00:01:00 +0000
930 948 From: quux
931 949 To: foo
932 950 Cc: bar
933 951
934 952 --===* (glob)
935 953 Content-Type: text/plain; charset="us-ascii"
936 954 MIME-Version: 1.0
937 955 Content-Transfer-Encoding: 7bit
938 956
939 957 Patch subject is complete summary.
940 958
941 959
942 960
943 961 --===* (glob)
944 962 Content-Type: text/x-patch; charset="us-ascii"
945 963 MIME-Version: 1.0
946 964 Content-Transfer-Encoding: quoted-printable
947 965 Content-Disposition: attachment; filename=t2.patch
948 966
949 967 # HG changeset patch
950 968 # User test
951 969 # Date 4 0
970 # Thu Jan 01 00:00:04 1970 +0000
952 971 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
953 972 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
954 973 long line
955 974
956 975 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
957 976 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
958 977 +++ b/long Thu Jan 01 00:00:04 1970 +0000
959 978 @@ -0,0 +1,4 @@
960 979 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
961 980 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
962 981 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
963 982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
964 983 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
965 984 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
966 985 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
967 986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
968 987 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
969 988 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
970 989 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
971 990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
972 991 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
973 992 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
974 993 +foo
975 994 +
976 995 +bar
977 996
978 997 --===*-- (glob)
979 998
980 999 test attach and body for single patch:
981 1000 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a --body -r 2
982 1001 this patch series consists of 1 patches.
983 1002
984 1003
985 1004 displaying [PATCH] test ...
986 1005 Content-Type: multipart/mixed; boundary="===*" (glob)
987 1006 MIME-Version: 1.0
988 1007 Subject: [PATCH] test
989 1008 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
990 1009 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
991 1010 User-Agent: Mercurial-patchbomb/* (glob)
992 1011 Date: Thu, 01 Jan 1970 00:01:00 +0000
993 1012 From: quux
994 1013 To: foo
995 1014 Cc: bar
996 1015
997 1016 --===* (glob)
998 1017 Content-Type: text/plain; charset="us-ascii"
999 1018 MIME-Version: 1.0
1000 1019 Content-Transfer-Encoding: 7bit
1001 1020
1002 1021 # HG changeset patch
1003 1022 # User test
1004 1023 # Date 3 0
1024 # Thu Jan 01 00:00:03 1970 +0000
1005 1025 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1006 1026 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1007 1027 c
1008 1028
1009 1029 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1010 1030 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1011 1031 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1012 1032 @@ -0,0 +1,1 @@
1013 1033 +c
1014 1034
1015 1035 --===* (glob)
1016 1036 Content-Type: text/x-patch; charset="us-ascii"
1017 1037 MIME-Version: 1.0
1018 1038 Content-Transfer-Encoding: 7bit
1019 1039 Content-Disposition: attachment; filename=t2.patch
1020 1040
1021 1041 # HG changeset patch
1022 1042 # User test
1023 1043 # Date 3 0
1044 # Thu Jan 01 00:00:03 1970 +0000
1024 1045 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1025 1046 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1026 1047 c
1027 1048
1028 1049 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1029 1050 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1030 1051 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1031 1052 @@ -0,0 +1,1 @@
1032 1053 +c
1033 1054
1034 1055 --===*-- (glob)
1035 1056
1036 1057 test attach for multiple patches:
1037 1058 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -a \
1038 1059 > -r 0:1 -r 4
1039 1060 this patch series consists of 3 patches.
1040 1061
1041 1062
1042 1063 Write the introductory message for the patch series.
1043 1064
1044 1065
1045 1066 displaying [PATCH 0 of 3] test ...
1046 1067 Content-Type: text/plain; charset="us-ascii"
1047 1068 MIME-Version: 1.0
1048 1069 Content-Transfer-Encoding: 7bit
1049 1070 Subject: [PATCH 0 of 3] test
1050 1071 Message-Id: <patchbomb.60@*> (glob)
1051 1072 User-Agent: Mercurial-patchbomb/* (glob)
1052 1073 Date: Thu, 01 Jan 1970 00:01:00 +0000
1053 1074 From: quux
1054 1075 To: foo
1055 1076 Cc: bar
1056 1077
1057 1078
1058 1079 displaying [PATCH 1 of 3] a ...
1059 1080 Content-Type: multipart/mixed; boundary="===*" (glob)
1060 1081 MIME-Version: 1.0
1061 1082 Subject: [PATCH 1 of 3] a
1062 1083 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1063 1084 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1064 1085 In-Reply-To: <patchbomb.60@*> (glob)
1065 1086 References: <patchbomb.60@*> (glob)
1066 1087 User-Agent: Mercurial-patchbomb/* (glob)
1067 1088 Date: Thu, 01 Jan 1970 00:01:01 +0000
1068 1089 From: quux
1069 1090 To: foo
1070 1091 Cc: bar
1071 1092
1072 1093 --===* (glob)
1073 1094 Content-Type: text/plain; charset="us-ascii"
1074 1095 MIME-Version: 1.0
1075 1096 Content-Transfer-Encoding: 7bit
1076 1097
1077 1098 Patch subject is complete summary.
1078 1099
1079 1100
1080 1101
1081 1102 --===* (glob)
1082 1103 Content-Type: text/x-patch; charset="us-ascii"
1083 1104 MIME-Version: 1.0
1084 1105 Content-Transfer-Encoding: 7bit
1085 1106 Content-Disposition: attachment; filename=t2-1.patch
1086 1107
1087 1108 # HG changeset patch
1088 1109 # User test
1089 1110 # Date 1 0
1111 # Thu Jan 01 00:00:01 1970 +0000
1090 1112 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1091 1113 # Parent 0000000000000000000000000000000000000000
1092 1114 a
1093 1115
1094 1116 diff -r 000000000000 -r 8580ff50825a a
1095 1117 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1096 1118 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1097 1119 @@ -0,0 +1,1 @@
1098 1120 +a
1099 1121
1100 1122 --===*-- (glob)
1101 1123 displaying [PATCH 2 of 3] b ...
1102 1124 Content-Type: multipart/mixed; boundary="===*" (glob)
1103 1125 MIME-Version: 1.0
1104 1126 Subject: [PATCH 2 of 3] b
1105 1127 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1106 1128 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1107 1129 In-Reply-To: <patchbomb.60@*> (glob)
1108 1130 References: <patchbomb.60@*> (glob)
1109 1131 User-Agent: Mercurial-patchbomb/* (glob)
1110 1132 Date: Thu, 01 Jan 1970 00:01:02 +0000
1111 1133 From: quux
1112 1134 To: foo
1113 1135 Cc: bar
1114 1136
1115 1137 --===* (glob)
1116 1138 Content-Type: text/plain; charset="us-ascii"
1117 1139 MIME-Version: 1.0
1118 1140 Content-Transfer-Encoding: 7bit
1119 1141
1120 1142 Patch subject is complete summary.
1121 1143
1122 1144
1123 1145
1124 1146 --===* (glob)
1125 1147 Content-Type: text/x-patch; charset="us-ascii"
1126 1148 MIME-Version: 1.0
1127 1149 Content-Transfer-Encoding: 7bit
1128 1150 Content-Disposition: attachment; filename=t2-2.patch
1129 1151
1130 1152 # HG changeset patch
1131 1153 # User test
1132 1154 # Date 2 0
1155 # Thu Jan 01 00:00:02 1970 +0000
1133 1156 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1134 1157 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1135 1158 b
1136 1159
1137 1160 diff -r 8580ff50825a -r 97d72e5f12c7 b
1138 1161 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1139 1162 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1140 1163 @@ -0,0 +1,1 @@
1141 1164 +b
1142 1165
1143 1166 --===*-- (glob)
1144 1167 displaying [PATCH 3 of 3] long line ...
1145 1168 Content-Type: multipart/mixed; boundary="===*" (glob)
1146 1169 MIME-Version: 1.0
1147 1170 Subject: [PATCH 3 of 3] long line
1148 1171 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1149 1172 Message-Id: <a2ea8fc83dd8b93cfd86.63@*> (glob)
1150 1173 In-Reply-To: <patchbomb.60@*> (glob)
1151 1174 References: <patchbomb.60@*> (glob)
1152 1175 User-Agent: Mercurial-patchbomb/* (glob)
1153 1176 Date: Thu, 01 Jan 1970 00:01:03 +0000
1154 1177 From: quux
1155 1178 To: foo
1156 1179 Cc: bar
1157 1180
1158 1181 --===* (glob)
1159 1182 Content-Type: text/plain; charset="us-ascii"
1160 1183 MIME-Version: 1.0
1161 1184 Content-Transfer-Encoding: 7bit
1162 1185
1163 1186 Patch subject is complete summary.
1164 1187
1165 1188
1166 1189
1167 1190 --===* (glob)
1168 1191 Content-Type: text/x-patch; charset="us-ascii"
1169 1192 MIME-Version: 1.0
1170 1193 Content-Transfer-Encoding: quoted-printable
1171 1194 Content-Disposition: attachment; filename=t2-3.patch
1172 1195
1173 1196 # HG changeset patch
1174 1197 # User test
1175 1198 # Date 4 0
1199 # Thu Jan 01 00:00:04 1970 +0000
1176 1200 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
1177 1201 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
1178 1202 long line
1179 1203
1180 1204 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
1181 1205 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1182 1206 +++ b/long Thu Jan 01 00:00:04 1970 +0000
1183 1207 @@ -0,0 +1,4 @@
1184 1208 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1185 1209 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1186 1210 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1187 1211 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1188 1212 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1189 1213 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1190 1214 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1191 1215 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1192 1216 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1193 1217 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1194 1218 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1195 1219 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1196 1220 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
1197 1221 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1198 1222 +foo
1199 1223 +
1200 1224 +bar
1201 1225
1202 1226 --===*-- (glob)
1203 1227
1204 1228 test intro for single patch:
1205 1229 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1206 1230 > -r 2
1207 1231 this patch series consists of 1 patches.
1208 1232
1209 1233
1210 1234 Write the introductory message for the patch series.
1211 1235
1212 1236
1213 1237 displaying [PATCH 0 of 1] test ...
1214 1238 Content-Type: text/plain; charset="us-ascii"
1215 1239 MIME-Version: 1.0
1216 1240 Content-Transfer-Encoding: 7bit
1217 1241 Subject: [PATCH 0 of 1] test
1218 1242 Message-Id: <patchbomb.60@*> (glob)
1219 1243 User-Agent: Mercurial-patchbomb/* (glob)
1220 1244 Date: Thu, 01 Jan 1970 00:01:00 +0000
1221 1245 From: quux
1222 1246 To: foo
1223 1247 Cc: bar
1224 1248
1225 1249
1226 1250 displaying [PATCH 1 of 1] c ...
1227 1251 Content-Type: text/plain; charset="us-ascii"
1228 1252 MIME-Version: 1.0
1229 1253 Content-Transfer-Encoding: 7bit
1230 1254 Subject: [PATCH 1 of 1] c
1231 1255 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1232 1256 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1233 1257 In-Reply-To: <patchbomb.60@*> (glob)
1234 1258 References: <patchbomb.60@*> (glob)
1235 1259 User-Agent: Mercurial-patchbomb/* (glob)
1236 1260 Date: Thu, 01 Jan 1970 00:01:01 +0000
1237 1261 From: quux
1238 1262 To: foo
1239 1263 Cc: bar
1240 1264
1241 1265 # HG changeset patch
1242 1266 # User test
1243 1267 # Date 3 0
1268 # Thu Jan 01 00:00:03 1970 +0000
1244 1269 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1245 1270 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1246 1271 c
1247 1272
1248 1273 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1249 1274 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1250 1275 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1251 1276 @@ -0,0 +1,1 @@
1252 1277 +c
1253 1278
1254 1279
1255 1280 test --desc without --intro for a single patch:
1256 1281 $ echo foo > intro.text
1257 1282 $ hg email --date '1970-1-1 0:1' -n --desc intro.text -f quux -t foo -c bar \
1258 1283 > -s test -r 2
1259 1284 this patch series consists of 1 patches.
1260 1285
1261 1286
1262 1287 displaying [PATCH 0 of 1] test ...
1263 1288 Content-Type: text/plain; charset="us-ascii"
1264 1289 MIME-Version: 1.0
1265 1290 Content-Transfer-Encoding: 7bit
1266 1291 Subject: [PATCH 0 of 1] test
1267 1292 Message-Id: <patchbomb.60@*> (glob)
1268 1293 User-Agent: Mercurial-patchbomb/* (glob)
1269 1294 Date: Thu, 01 Jan 1970 00:01:00 +0000
1270 1295 From: quux
1271 1296 To: foo
1272 1297 Cc: bar
1273 1298
1274 1299 foo
1275 1300
1276 1301 displaying [PATCH 1 of 1] c ...
1277 1302 Content-Type: text/plain; charset="us-ascii"
1278 1303 MIME-Version: 1.0
1279 1304 Content-Transfer-Encoding: 7bit
1280 1305 Subject: [PATCH 1 of 1] c
1281 1306 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1282 1307 Message-Id: <ff2c9fa2018b15fa74b3.61@*> (glob)
1283 1308 In-Reply-To: <patchbomb.60@*> (glob)
1284 1309 References: <patchbomb.60@*> (glob)
1285 1310 User-Agent: Mercurial-patchbomb/* (glob)
1286 1311 Date: Thu, 01 Jan 1970 00:01:01 +0000
1287 1312 From: quux
1288 1313 To: foo
1289 1314 Cc: bar
1290 1315
1291 1316 # HG changeset patch
1292 1317 # User test
1293 1318 # Date 3 0
1319 # Thu Jan 01 00:00:03 1970 +0000
1294 1320 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1295 1321 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1296 1322 c
1297 1323
1298 1324 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1299 1325 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1300 1326 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1301 1327 @@ -0,0 +1,1 @@
1302 1328 +c
1303 1329
1304 1330
1305 1331 test intro for multiple patches:
1306 1332 $ hg email --date '1970-1-1 0:1' -n --intro -f quux -t foo -c bar -s test \
1307 1333 > -r 0:1
1308 1334 this patch series consists of 2 patches.
1309 1335
1310 1336
1311 1337 Write the introductory message for the patch series.
1312 1338
1313 1339
1314 1340 displaying [PATCH 0 of 2] test ...
1315 1341 Content-Type: text/plain; charset="us-ascii"
1316 1342 MIME-Version: 1.0
1317 1343 Content-Transfer-Encoding: 7bit
1318 1344 Subject: [PATCH 0 of 2] test
1319 1345 Message-Id: <patchbomb.60@*> (glob)
1320 1346 User-Agent: Mercurial-patchbomb/* (glob)
1321 1347 Date: Thu, 01 Jan 1970 00:01:00 +0000
1322 1348 From: quux
1323 1349 To: foo
1324 1350 Cc: bar
1325 1351
1326 1352
1327 1353 displaying [PATCH 1 of 2] a ...
1328 1354 Content-Type: text/plain; charset="us-ascii"
1329 1355 MIME-Version: 1.0
1330 1356 Content-Transfer-Encoding: 7bit
1331 1357 Subject: [PATCH 1 of 2] a
1332 1358 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1333 1359 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1334 1360 In-Reply-To: <patchbomb.60@*> (glob)
1335 1361 References: <patchbomb.60@*> (glob)
1336 1362 User-Agent: Mercurial-patchbomb/* (glob)
1337 1363 Date: Thu, 01 Jan 1970 00:01:01 +0000
1338 1364 From: quux
1339 1365 To: foo
1340 1366 Cc: bar
1341 1367
1342 1368 # HG changeset patch
1343 1369 # User test
1344 1370 # Date 1 0
1371 # Thu Jan 01 00:00:01 1970 +0000
1345 1372 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1346 1373 # Parent 0000000000000000000000000000000000000000
1347 1374 a
1348 1375
1349 1376 diff -r 000000000000 -r 8580ff50825a a
1350 1377 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1351 1378 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1352 1379 @@ -0,0 +1,1 @@
1353 1380 +a
1354 1381
1355 1382 displaying [PATCH 2 of 2] b ...
1356 1383 Content-Type: text/plain; charset="us-ascii"
1357 1384 MIME-Version: 1.0
1358 1385 Content-Transfer-Encoding: 7bit
1359 1386 Subject: [PATCH 2 of 2] b
1360 1387 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1361 1388 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1362 1389 In-Reply-To: <patchbomb.60@*> (glob)
1363 1390 References: <patchbomb.60@*> (glob)
1364 1391 User-Agent: Mercurial-patchbomb/* (glob)
1365 1392 Date: Thu, 01 Jan 1970 00:01:02 +0000
1366 1393 From: quux
1367 1394 To: foo
1368 1395 Cc: bar
1369 1396
1370 1397 # HG changeset patch
1371 1398 # User test
1372 1399 # Date 2 0
1400 # Thu Jan 01 00:00:02 1970 +0000
1373 1401 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1374 1402 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1375 1403 b
1376 1404
1377 1405 diff -r 8580ff50825a -r 97d72e5f12c7 b
1378 1406 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1379 1407 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1380 1408 @@ -0,0 +1,1 @@
1381 1409 +b
1382 1410
1383 1411
1384 1412 test reply-to via config:
1385 1413 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1386 1414 > --config patchbomb.reply-to='baz@example.com'
1387 1415 this patch series consists of 1 patches.
1388 1416
1389 1417
1390 1418 displaying [PATCH] test ...
1391 1419 Content-Type: text/plain; charset="us-ascii"
1392 1420 MIME-Version: 1.0
1393 1421 Content-Transfer-Encoding: 7bit
1394 1422 Subject: [PATCH] test
1395 1423 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1396 1424 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1397 1425 User-Agent: Mercurial-patchbomb/* (glob)
1398 1426 Date: Thu, 01 Jan 1970 00:01:00 +0000
1399 1427 From: quux
1400 1428 To: foo
1401 1429 Cc: bar
1402 1430 Reply-To: baz@example.com
1403 1431
1404 1432 # HG changeset patch
1405 1433 # User test
1406 1434 # Date 3 0
1435 # Thu Jan 01 00:00:03 1970 +0000
1407 1436 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1408 1437 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1409 1438 c
1410 1439
1411 1440 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1412 1441 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1413 1442 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1414 1443 @@ -0,0 +1,1 @@
1415 1444 +c
1416 1445
1417 1446
1418 1447 test reply-to via command line:
1419 1448 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -r 2 \
1420 1449 > --reply-to baz --reply-to fred
1421 1450 this patch series consists of 1 patches.
1422 1451
1423 1452
1424 1453 displaying [PATCH] test ...
1425 1454 Content-Type: text/plain; charset="us-ascii"
1426 1455 MIME-Version: 1.0
1427 1456 Content-Transfer-Encoding: 7bit
1428 1457 Subject: [PATCH] test
1429 1458 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1430 1459 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1431 1460 User-Agent: Mercurial-patchbomb/* (glob)
1432 1461 Date: Thu, 01 Jan 1970 00:01:00 +0000
1433 1462 From: quux
1434 1463 To: foo
1435 1464 Cc: bar
1436 1465 Reply-To: baz, fred
1437 1466
1438 1467 # HG changeset patch
1439 1468 # User test
1440 1469 # Date 3 0
1470 # Thu Jan 01 00:00:03 1970 +0000
1441 1471 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1442 1472 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1443 1473 c
1444 1474
1445 1475 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1446 1476 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1447 1477 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1448 1478 @@ -0,0 +1,1 @@
1449 1479 +c
1450 1480
1451 1481
1452 1482 tagging csets:
1453 1483 $ hg tag -r0 zero zero.foo
1454 1484 $ hg tag -r1 one one.patch
1455 1485 $ hg tag -r2 two two.diff
1456 1486
1457 1487 test inline for single named patch:
1458 1488 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 2
1459 1489 this patch series consists of 1 patches.
1460 1490
1461 1491
1462 1492 displaying [PATCH] test ...
1463 1493 Content-Type: multipart/mixed; boundary="===*" (glob)
1464 1494 MIME-Version: 1.0
1465 1495 Subject: [PATCH] test
1466 1496 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1467 1497 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1468 1498 User-Agent: Mercurial-patchbomb/* (glob)
1469 1499 Date: Thu, 01 Jan 1970 00:01:00 +0000
1470 1500 From: quux
1471 1501 To: foo
1472 1502 Cc: bar
1473 1503
1474 1504 --===* (glob)
1475 1505 Content-Type: text/x-patch; charset="us-ascii"
1476 1506 MIME-Version: 1.0
1477 1507 Content-Transfer-Encoding: 7bit
1478 1508 Content-Disposition: inline; filename=two.diff
1479 1509
1480 1510 # HG changeset patch
1481 1511 # User test
1482 1512 # Date 3 0
1513 # Thu Jan 01 00:00:03 1970 +0000
1483 1514 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1484 1515 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1485 1516 c
1486 1517
1487 1518 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1488 1519 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1489 1520 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1490 1521 @@ -0,0 +1,1 @@
1491 1522 +c
1492 1523
1493 1524 --===*-- (glob)
1494 1525
1495 1526 test inline for multiple named/unnamed patches:
1496 1527 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar -s test -i -r 0:1
1497 1528 this patch series consists of 2 patches.
1498 1529
1499 1530
1500 1531 Write the introductory message for the patch series.
1501 1532
1502 1533
1503 1534 displaying [PATCH 0 of 2] test ...
1504 1535 Content-Type: text/plain; charset="us-ascii"
1505 1536 MIME-Version: 1.0
1506 1537 Content-Transfer-Encoding: 7bit
1507 1538 Subject: [PATCH 0 of 2] test
1508 1539 Message-Id: <patchbomb.60@*> (glob)
1509 1540 User-Agent: Mercurial-patchbomb/* (glob)
1510 1541 Date: Thu, 01 Jan 1970 00:01:00 +0000
1511 1542 From: quux
1512 1543 To: foo
1513 1544 Cc: bar
1514 1545
1515 1546
1516 1547 displaying [PATCH 1 of 2] a ...
1517 1548 Content-Type: multipart/mixed; boundary="===*" (glob)
1518 1549 MIME-Version: 1.0
1519 1550 Subject: [PATCH 1 of 2] a
1520 1551 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1521 1552 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1522 1553 In-Reply-To: <patchbomb.60@*> (glob)
1523 1554 References: <patchbomb.60@*> (glob)
1524 1555 User-Agent: Mercurial-patchbomb/* (glob)
1525 1556 Date: Thu, 01 Jan 1970 00:01:01 +0000
1526 1557 From: quux
1527 1558 To: foo
1528 1559 Cc: bar
1529 1560
1530 1561 --===* (glob)
1531 1562 Content-Type: text/x-patch; charset="us-ascii"
1532 1563 MIME-Version: 1.0
1533 1564 Content-Transfer-Encoding: 7bit
1534 1565 Content-Disposition: inline; filename=t2-1.patch
1535 1566
1536 1567 # HG changeset patch
1537 1568 # User test
1538 1569 # Date 1 0
1570 # Thu Jan 01 00:00:01 1970 +0000
1539 1571 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1540 1572 # Parent 0000000000000000000000000000000000000000
1541 1573 a
1542 1574
1543 1575 diff -r 000000000000 -r 8580ff50825a a
1544 1576 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1545 1577 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1546 1578 @@ -0,0 +1,1 @@
1547 1579 +a
1548 1580
1549 1581 --===*-- (glob)
1550 1582 displaying [PATCH 2 of 2] b ...
1551 1583 Content-Type: multipart/mixed; boundary="===*" (glob)
1552 1584 MIME-Version: 1.0
1553 1585 Subject: [PATCH 2 of 2] b
1554 1586 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1555 1587 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1556 1588 In-Reply-To: <patchbomb.60@*> (glob)
1557 1589 References: <patchbomb.60@*> (glob)
1558 1590 User-Agent: Mercurial-patchbomb/* (glob)
1559 1591 Date: Thu, 01 Jan 1970 00:01:02 +0000
1560 1592 From: quux
1561 1593 To: foo
1562 1594 Cc: bar
1563 1595
1564 1596 --===* (glob)
1565 1597 Content-Type: text/x-patch; charset="us-ascii"
1566 1598 MIME-Version: 1.0
1567 1599 Content-Transfer-Encoding: 7bit
1568 1600 Content-Disposition: inline; filename=one.patch
1569 1601
1570 1602 # HG changeset patch
1571 1603 # User test
1572 1604 # Date 2 0
1605 # Thu Jan 01 00:00:02 1970 +0000
1573 1606 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1574 1607 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1575 1608 b
1576 1609
1577 1610 diff -r 8580ff50825a -r 97d72e5f12c7 b
1578 1611 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1579 1612 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1580 1613 @@ -0,0 +1,1 @@
1581 1614 +b
1582 1615
1583 1616 --===*-- (glob)
1584 1617
1585 1618
1586 1619 test inreplyto:
1587 1620 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1588 1621 > -r tip
1589 1622 this patch series consists of 1 patches.
1590 1623
1591 1624
1592 1625 displaying [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b ...
1593 1626 Content-Type: text/plain; charset="us-ascii"
1594 1627 MIME-Version: 1.0
1595 1628 Content-Transfer-Encoding: 7bit
1596 1629 Subject: [PATCH] Added tag two, two.diff for changeset ff2c9fa2018b
1597 1630 X-Mercurial-Node: 7aead2484924c445ad8ce2613df91f52f9e502ed
1598 1631 Message-Id: <7aead2484924c445ad8c.60@*> (glob)
1599 1632 In-Reply-To: <baz>
1600 1633 References: <baz>
1601 1634 User-Agent: Mercurial-patchbomb/* (glob)
1602 1635 Date: Thu, 01 Jan 1970 00:01:00 +0000
1603 1636 From: quux
1604 1637 To: foo
1605 1638 Cc: bar
1606 1639
1607 1640 # HG changeset patch
1608 1641 # User test
1609 1642 # Date 0 0
1643 # Thu Jan 01 00:00:00 1970 +0000
1610 1644 # Node ID 7aead2484924c445ad8ce2613df91f52f9e502ed
1611 1645 # Parent 045ca29b1ea20e4940411e695e20e521f2f0f98e
1612 1646 Added tag two, two.diff for changeset ff2c9fa2018b
1613 1647
1614 1648 diff -r 045ca29b1ea2 -r 7aead2484924 .hgtags
1615 1649 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
1616 1650 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1617 1651 @@ -2,3 +2,5 @@
1618 1652 8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
1619 1653 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one
1620 1654 97d72e5f12c7e84f85064aa72e5a297142c36ed9 one.patch
1621 1655 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two
1622 1656 +ff2c9fa2018b15fa74b33363bda9527323e2a99f two.diff
1623 1657
1624 1658 no intro message in non-interactive mode
1625 1659 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1626 1660 > -r 0:1
1627 1661 this patch series consists of 2 patches.
1628 1662
1629 1663 (optional) Subject: [PATCH 0 of 2]
1630 1664
1631 1665 displaying [PATCH 1 of 2] a ...
1632 1666 Content-Type: text/plain; charset="us-ascii"
1633 1667 MIME-Version: 1.0
1634 1668 Content-Transfer-Encoding: 7bit
1635 1669 Subject: [PATCH 1 of 2] a
1636 1670 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1637 1671 Message-Id: <8580ff50825a50c8f716.60@*> (glob)
1638 1672 In-Reply-To: <baz>
1639 1673 References: <baz>
1640 1674 User-Agent: Mercurial-patchbomb/* (glob)
1641 1675 Date: Thu, 01 Jan 1970 00:01:00 +0000
1642 1676 From: quux
1643 1677 To: foo
1644 1678 Cc: bar
1645 1679
1646 1680 # HG changeset patch
1647 1681 # User test
1648 1682 # Date 1 0
1683 # Thu Jan 01 00:00:01 1970 +0000
1649 1684 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1650 1685 # Parent 0000000000000000000000000000000000000000
1651 1686 a
1652 1687
1653 1688 diff -r 000000000000 -r 8580ff50825a a
1654 1689 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1655 1690 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1656 1691 @@ -0,0 +1,1 @@
1657 1692 +a
1658 1693
1659 1694 displaying [PATCH 2 of 2] b ...
1660 1695 Content-Type: text/plain; charset="us-ascii"
1661 1696 MIME-Version: 1.0
1662 1697 Content-Transfer-Encoding: 7bit
1663 1698 Subject: [PATCH 2 of 2] b
1664 1699 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1665 1700 Message-Id: <97d72e5f12c7e84f8506.61@*> (glob)
1666 1701 In-Reply-To: <baz>
1667 1702 References: <baz>
1668 1703 User-Agent: Mercurial-patchbomb/* (glob)
1669 1704 Date: Thu, 01 Jan 1970 00:01:01 +0000
1670 1705 From: quux
1671 1706 To: foo
1672 1707 Cc: bar
1673 1708
1674 1709 # HG changeset patch
1675 1710 # User test
1676 1711 # Date 2 0
1712 # Thu Jan 01 00:00:02 1970 +0000
1677 1713 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1678 1714 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1679 1715 b
1680 1716
1681 1717 diff -r 8580ff50825a -r 97d72e5f12c7 b
1682 1718 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1683 1719 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1684 1720 @@ -0,0 +1,1 @@
1685 1721 +b
1686 1722
1687 1723
1688 1724
1689 1725
1690 1726 $ hg email --date '1970-1-1 0:1' -n -f quux -t foo -c bar --in-reply-to baz \
1691 1727 > -s test -r 0:1
1692 1728 this patch series consists of 2 patches.
1693 1729
1694 1730
1695 1731 Write the introductory message for the patch series.
1696 1732
1697 1733
1698 1734 displaying [PATCH 0 of 2] test ...
1699 1735 Content-Type: text/plain; charset="us-ascii"
1700 1736 MIME-Version: 1.0
1701 1737 Content-Transfer-Encoding: 7bit
1702 1738 Subject: [PATCH 0 of 2] test
1703 1739 Message-Id: <patchbomb.60@*> (glob)
1704 1740 In-Reply-To: <baz>
1705 1741 References: <baz>
1706 1742 User-Agent: Mercurial-patchbomb/* (glob)
1707 1743 Date: Thu, 01 Jan 1970 00:01:00 +0000
1708 1744 From: quux
1709 1745 To: foo
1710 1746 Cc: bar
1711 1747
1712 1748
1713 1749 displaying [PATCH 1 of 2] a ...
1714 1750 Content-Type: text/plain; charset="us-ascii"
1715 1751 MIME-Version: 1.0
1716 1752 Content-Transfer-Encoding: 7bit
1717 1753 Subject: [PATCH 1 of 2] a
1718 1754 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1719 1755 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1720 1756 In-Reply-To: <patchbomb.60@*> (glob)
1721 1757 References: <patchbomb.60@*> (glob)
1722 1758 User-Agent: Mercurial-patchbomb/* (glob)
1723 1759 Date: Thu, 01 Jan 1970 00:01:01 +0000
1724 1760 From: quux
1725 1761 To: foo
1726 1762 Cc: bar
1727 1763
1728 1764 # HG changeset patch
1729 1765 # User test
1730 1766 # Date 1 0
1767 # Thu Jan 01 00:00:01 1970 +0000
1731 1768 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1732 1769 # Parent 0000000000000000000000000000000000000000
1733 1770 a
1734 1771
1735 1772 diff -r 000000000000 -r 8580ff50825a a
1736 1773 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1737 1774 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1738 1775 @@ -0,0 +1,1 @@
1739 1776 +a
1740 1777
1741 1778 displaying [PATCH 2 of 2] b ...
1742 1779 Content-Type: text/plain; charset="us-ascii"
1743 1780 MIME-Version: 1.0
1744 1781 Content-Transfer-Encoding: 7bit
1745 1782 Subject: [PATCH 2 of 2] b
1746 1783 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1747 1784 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1748 1785 In-Reply-To: <patchbomb.60@*> (glob)
1749 1786 References: <patchbomb.60@*> (glob)
1750 1787 User-Agent: Mercurial-patchbomb/* (glob)
1751 1788 Date: Thu, 01 Jan 1970 00:01:02 +0000
1752 1789 From: quux
1753 1790 To: foo
1754 1791 Cc: bar
1755 1792
1756 1793 # HG changeset patch
1757 1794 # User test
1758 1795 # Date 2 0
1796 # Thu Jan 01 00:00:02 1970 +0000
1759 1797 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1760 1798 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1761 1799 b
1762 1800
1763 1801 diff -r 8580ff50825a -r 97d72e5f12c7 b
1764 1802 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1765 1803 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1766 1804 @@ -0,0 +1,1 @@
1767 1805 +b
1768 1806
1769 1807
1770 1808 test single flag for single patch:
1771 1809 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
1772 1810 > -r 2
1773 1811 this patch series consists of 1 patches.
1774 1812
1775 1813
1776 1814 displaying [PATCH fooFlag] test ...
1777 1815 Content-Type: text/plain; charset="us-ascii"
1778 1816 MIME-Version: 1.0
1779 1817 Content-Transfer-Encoding: 7bit
1780 1818 Subject: [PATCH fooFlag] test
1781 1819 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1782 1820 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1783 1821 User-Agent: Mercurial-patchbomb/* (glob)
1784 1822 Date: Thu, 01 Jan 1970 00:01:00 +0000
1785 1823 From: quux
1786 1824 To: foo
1787 1825 Cc: bar
1788 1826
1789 1827 # HG changeset patch
1790 1828 # User test
1791 1829 # Date 3 0
1830 # Thu Jan 01 00:00:03 1970 +0000
1792 1831 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1793 1832 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1794 1833 c
1795 1834
1796 1835 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1797 1836 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1798 1837 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1799 1838 @@ -0,0 +1,1 @@
1800 1839 +c
1801 1840
1802 1841
1803 1842 test single flag for multiple patches:
1804 1843 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag -f quux -t foo -c bar -s test \
1805 1844 > -r 0:1
1806 1845 this patch series consists of 2 patches.
1807 1846
1808 1847
1809 1848 Write the introductory message for the patch series.
1810 1849
1811 1850
1812 1851 displaying [PATCH 0 of 2 fooFlag] test ...
1813 1852 Content-Type: text/plain; charset="us-ascii"
1814 1853 MIME-Version: 1.0
1815 1854 Content-Transfer-Encoding: 7bit
1816 1855 Subject: [PATCH 0 of 2 fooFlag] test
1817 1856 Message-Id: <patchbomb.60@*> (glob)
1818 1857 User-Agent: Mercurial-patchbomb/* (glob)
1819 1858 Date: Thu, 01 Jan 1970 00:01:00 +0000
1820 1859 From: quux
1821 1860 To: foo
1822 1861 Cc: bar
1823 1862
1824 1863
1825 1864 displaying [PATCH 1 of 2 fooFlag] a ...
1826 1865 Content-Type: text/plain; charset="us-ascii"
1827 1866 MIME-Version: 1.0
1828 1867 Content-Transfer-Encoding: 7bit
1829 1868 Subject: [PATCH 1 of 2 fooFlag] a
1830 1869 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1831 1870 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1832 1871 In-Reply-To: <patchbomb.60@*> (glob)
1833 1872 References: <patchbomb.60@*> (glob)
1834 1873 User-Agent: Mercurial-patchbomb/* (glob)
1835 1874 Date: Thu, 01 Jan 1970 00:01:01 +0000
1836 1875 From: quux
1837 1876 To: foo
1838 1877 Cc: bar
1839 1878
1840 1879 # HG changeset patch
1841 1880 # User test
1842 1881 # Date 1 0
1882 # Thu Jan 01 00:00:01 1970 +0000
1843 1883 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1844 1884 # Parent 0000000000000000000000000000000000000000
1845 1885 a
1846 1886
1847 1887 diff -r 000000000000 -r 8580ff50825a a
1848 1888 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1849 1889 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1850 1890 @@ -0,0 +1,1 @@
1851 1891 +a
1852 1892
1853 1893 displaying [PATCH 2 of 2 fooFlag] b ...
1854 1894 Content-Type: text/plain; charset="us-ascii"
1855 1895 MIME-Version: 1.0
1856 1896 Content-Transfer-Encoding: 7bit
1857 1897 Subject: [PATCH 2 of 2 fooFlag] b
1858 1898 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1859 1899 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1860 1900 In-Reply-To: <patchbomb.60@*> (glob)
1861 1901 References: <patchbomb.60@*> (glob)
1862 1902 User-Agent: Mercurial-patchbomb/* (glob)
1863 1903 Date: Thu, 01 Jan 1970 00:01:02 +0000
1864 1904 From: quux
1865 1905 To: foo
1866 1906 Cc: bar
1867 1907
1868 1908 # HG changeset patch
1869 1909 # User test
1870 1910 # Date 2 0
1911 # Thu Jan 01 00:00:02 1970 +0000
1871 1912 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1872 1913 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1873 1914 b
1874 1915
1875 1916 diff -r 8580ff50825a -r 97d72e5f12c7 b
1876 1917 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1877 1918 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1878 1919 @@ -0,0 +1,1 @@
1879 1920 +b
1880 1921
1881 1922
1882 1923 test multiple flags for single patch:
1883 1924 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
1884 1925 > -c bar -s test -r 2
1885 1926 this patch series consists of 1 patches.
1886 1927
1887 1928
1888 1929 displaying [PATCH fooFlag barFlag] test ...
1889 1930 Content-Type: text/plain; charset="us-ascii"
1890 1931 MIME-Version: 1.0
1891 1932 Content-Transfer-Encoding: 7bit
1892 1933 Subject: [PATCH fooFlag barFlag] test
1893 1934 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
1894 1935 Message-Id: <ff2c9fa2018b15fa74b3.60@*> (glob)
1895 1936 User-Agent: Mercurial-patchbomb/* (glob)
1896 1937 Date: Thu, 01 Jan 1970 00:01:00 +0000
1897 1938 From: quux
1898 1939 To: foo
1899 1940 Cc: bar
1900 1941
1901 1942 # HG changeset patch
1902 1943 # User test
1903 1944 # Date 3 0
1945 # Thu Jan 01 00:00:03 1970 +0000
1904 1946 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
1905 1947 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1906 1948 c
1907 1949
1908 1950 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
1909 1951 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1910 1952 +++ b/c Thu Jan 01 00:00:03 1970 +0000
1911 1953 @@ -0,0 +1,1 @@
1912 1954 +c
1913 1955
1914 1956
1915 1957 test multiple flags for multiple patches:
1916 1958 $ hg email --date '1970-1-1 0:1' -n --flag fooFlag --flag barFlag -f quux -t foo \
1917 1959 > -c bar -s test -r 0:1
1918 1960 this patch series consists of 2 patches.
1919 1961
1920 1962
1921 1963 Write the introductory message for the patch series.
1922 1964
1923 1965
1924 1966 displaying [PATCH 0 of 2 fooFlag barFlag] test ...
1925 1967 Content-Type: text/plain; charset="us-ascii"
1926 1968 MIME-Version: 1.0
1927 1969 Content-Transfer-Encoding: 7bit
1928 1970 Subject: [PATCH 0 of 2 fooFlag barFlag] test
1929 1971 Message-Id: <patchbomb.60@*> (glob)
1930 1972 User-Agent: Mercurial-patchbomb/* (glob)
1931 1973 Date: Thu, 01 Jan 1970 00:01:00 +0000
1932 1974 From: quux
1933 1975 To: foo
1934 1976 Cc: bar
1935 1977
1936 1978
1937 1979 displaying [PATCH 1 of 2 fooFlag barFlag] a ...
1938 1980 Content-Type: text/plain; charset="us-ascii"
1939 1981 MIME-Version: 1.0
1940 1982 Content-Transfer-Encoding: 7bit
1941 1983 Subject: [PATCH 1 of 2 fooFlag barFlag] a
1942 1984 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
1943 1985 Message-Id: <8580ff50825a50c8f716.61@*> (glob)
1944 1986 In-Reply-To: <patchbomb.60@*> (glob)
1945 1987 References: <patchbomb.60@*> (glob)
1946 1988 User-Agent: Mercurial-patchbomb/* (glob)
1947 1989 Date: Thu, 01 Jan 1970 00:01:01 +0000
1948 1990 From: quux
1949 1991 To: foo
1950 1992 Cc: bar
1951 1993
1952 1994 # HG changeset patch
1953 1995 # User test
1954 1996 # Date 1 0
1997 # Thu Jan 01 00:00:01 1970 +0000
1955 1998 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
1956 1999 # Parent 0000000000000000000000000000000000000000
1957 2000 a
1958 2001
1959 2002 diff -r 000000000000 -r 8580ff50825a a
1960 2003 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1961 2004 +++ b/a Thu Jan 01 00:00:01 1970 +0000
1962 2005 @@ -0,0 +1,1 @@
1963 2006 +a
1964 2007
1965 2008 displaying [PATCH 2 of 2 fooFlag barFlag] b ...
1966 2009 Content-Type: text/plain; charset="us-ascii"
1967 2010 MIME-Version: 1.0
1968 2011 Content-Transfer-Encoding: 7bit
1969 2012 Subject: [PATCH 2 of 2 fooFlag barFlag] b
1970 2013 X-Mercurial-Node: 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1971 2014 Message-Id: <97d72e5f12c7e84f8506.62@*> (glob)
1972 2015 In-Reply-To: <patchbomb.60@*> (glob)
1973 2016 References: <patchbomb.60@*> (glob)
1974 2017 User-Agent: Mercurial-patchbomb/* (glob)
1975 2018 Date: Thu, 01 Jan 1970 00:01:02 +0000
1976 2019 From: quux
1977 2020 To: foo
1978 2021 Cc: bar
1979 2022
1980 2023 # HG changeset patch
1981 2024 # User test
1982 2025 # Date 2 0
2026 # Thu Jan 01 00:00:02 1970 +0000
1983 2027 # Node ID 97d72e5f12c7e84f85064aa72e5a297142c36ed9
1984 2028 # Parent 8580ff50825a50c8f716709acdf8de0deddcd6ab
1985 2029 b
1986 2030
1987 2031 diff -r 8580ff50825a -r 97d72e5f12c7 b
1988 2032 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1989 2033 +++ b/b Thu Jan 01 00:00:02 1970 +0000
1990 2034 @@ -0,0 +1,1 @@
1991 2035 +b
1992 2036
1993 2037
1994 2038 test multi-address parsing:
1995 2039 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t 'spam<spam><eggs>' \
1996 2040 > -t toast -c 'foo,bar@example.com' -c '"A, B <>" <a@example.com>' -s test -r 0 \
1997 2041 > --config email.bcc='"Quux, A." <quux>'
1998 2042 this patch series consists of 1 patches.
1999 2043
2000 2044
2001 2045 sending [PATCH] test ...
2002 2046 $ cat < tmp.mbox
2003 2047 From quux ... ... .. ..:..:.. .... (re)
2004 2048 Content-Type: text/plain; charset="us-ascii"
2005 2049 MIME-Version: 1.0
2006 2050 Content-Transfer-Encoding: 7bit
2007 2051 Subject: [PATCH] test
2008 2052 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2009 2053 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2010 2054 User-Agent: Mercurial-patchbomb/* (glob)
2011 2055 Date: Tue, 01 Jan 1980 00:01:00 +0000
2012 2056 From: quux
2013 2057 To: spam <spam>, eggs, toast
2014 2058 Cc: foo, bar@example.com, "A, B <>" <a@example.com>
2015 2059 Bcc: "Quux, A." <quux>
2016 2060
2017 2061 # HG changeset patch
2018 2062 # User test
2019 2063 # Date 1 0
2064 # Thu Jan 01 00:00:01 1970 +0000
2020 2065 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2021 2066 # Parent 0000000000000000000000000000000000000000
2022 2067 a
2023 2068
2024 2069 diff -r 000000000000 -r 8580ff50825a a
2025 2070 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2026 2071 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2027 2072 @@ -0,0 +1,1 @@
2028 2073 +a
2029 2074
2030 2075
2031 2076
2032 2077 test multi-byte domain parsing:
2033 2078 $ UUML=`python -c 'import sys; sys.stdout.write("\374")'`
2034 2079 $ HGENCODING=iso-8859-1
2035 2080 $ export HGENCODING
2036 2081 $ hg email --date '1980-1-1 0:1' -m tmp.mbox -f quux -t "bar@${UUML}nicode.com" -s test -r 0
2037 2082 this patch series consists of 1 patches.
2038 2083
2039 2084 Cc:
2040 2085
2041 2086 sending [PATCH] test ...
2042 2087
2043 2088 $ cat tmp.mbox
2044 2089 From quux ... ... .. ..:..:.. .... (re)
2045 2090 Content-Type: text/plain; charset="us-ascii"
2046 2091 MIME-Version: 1.0
2047 2092 Content-Transfer-Encoding: 7bit
2048 2093 Subject: [PATCH] test
2049 2094 X-Mercurial-Node: 8580ff50825a50c8f716709acdf8de0deddcd6ab
2050 2095 Message-Id: <8580ff50825a50c8f716.315532860@*> (glob)
2051 2096 User-Agent: Mercurial-patchbomb/* (glob)
2052 2097 Date: Tue, 01 Jan 1980 00:01:00 +0000
2053 2098 From: quux
2054 2099 To: bar@xn--nicode-2ya.com
2055 2100
2056 2101 # HG changeset patch
2057 2102 # User test
2058 2103 # Date 1 0
2104 # Thu Jan 01 00:00:01 1970 +0000
2059 2105 # Node ID 8580ff50825a50c8f716709acdf8de0deddcd6ab
2060 2106 # Parent 0000000000000000000000000000000000000000
2061 2107 a
2062 2108
2063 2109 diff -r 000000000000 -r 8580ff50825a a
2064 2110 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2065 2111 +++ b/a Thu Jan 01 00:00:01 1970 +0000
2066 2112 @@ -0,0 +1,1 @@
2067 2113 +a
2068 2114
2069 2115
2070 2116
2071 2117 test outgoing:
2072 2118 $ hg up 1
2073 2119 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
2074 2120
2075 2121 $ hg branch test
2076 2122 marked working directory as branch test
2077 2123 (branches are permanent and global, did you want a bookmark?)
2078 2124
2079 2125 $ echo d > d
2080 2126 $ hg add d
2081 2127 $ hg ci -md -d '4 0'
2082 2128 $ echo d >> d
2083 2129 $ hg ci -mdd -d '5 0'
2084 2130 $ hg --config extensions.graphlog= glog --template "{rev}:{node|short} {desc|firstline}\n"
2085 2131 @ 10:3b6f1ec9dde9 dd
2086 2132 |
2087 2133 o 9:2f9fa9b998c5 d
2088 2134 |
2089 2135 | o 8:7aead2484924 Added tag two, two.diff for changeset ff2c9fa2018b
2090 2136 | |
2091 2137 | o 7:045ca29b1ea2 Added tag one, one.patch for changeset 97d72e5f12c7
2092 2138 | |
2093 2139 | o 6:5d5ef15dfe5e Added tag zero, zero.foo for changeset 8580ff50825a
2094 2140 | |
2095 2141 | o 5:240fb913fc1b isolatin 8-bit encoding
2096 2142 | |
2097 2143 | o 4:a2ea8fc83dd8 long line
2098 2144 | |
2099 2145 | o 3:909a00e13e9d utf-8 content
2100 2146 | |
2101 2147 | o 2:ff2c9fa2018b c
2102 2148 |/
2103 2149 o 1:97d72e5f12c7 b
2104 2150 |
2105 2151 o 0:8580ff50825a a
2106 2152
2107 2153 $ hg phase --force --secret -r 10
2108 2154 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t -r 'rev(10) or rev(6)'
2109 2155 comparing with ../t
2110 2156 From [test]: test
2111 2157 this patch series consists of 6 patches.
2112 2158
2113 2159
2114 2160 Write the introductory message for the patch series.
2115 2161
2116 2162 Cc:
2117 2163
2118 2164 displaying [PATCH 0 of 6] test ...
2119 2165 Content-Type: text/plain; charset="us-ascii"
2120 2166 MIME-Version: 1.0
2121 2167 Content-Transfer-Encoding: 7bit
2122 2168 Subject: [PATCH 0 of 6] test
2123 2169 Message-Id: <patchbomb.315532860@*> (glob)
2124 2170 User-Agent: Mercurial-patchbomb/* (glob)
2125 2171 Date: Tue, 01 Jan 1980 00:01:00 +0000
2126 2172 From: test
2127 2173 To: foo
2128 2174
2129 2175
2130 2176 displaying [PATCH 1 of 6] c ...
2131 2177 Content-Type: text/plain; charset="us-ascii"
2132 2178 MIME-Version: 1.0
2133 2179 Content-Transfer-Encoding: 7bit
2134 2180 Subject: [PATCH 1 of 6] c
2135 2181 X-Mercurial-Node: ff2c9fa2018b15fa74b33363bda9527323e2a99f
2136 2182 Message-Id: <ff2c9fa2018b15fa74b3.315532861@*> (glob)
2137 2183 In-Reply-To: <patchbomb.315532860@*> (glob)
2138 2184 References: <patchbomb.315532860@*> (glob)
2139 2185 User-Agent: Mercurial-patchbomb/* (glob)
2140 2186 Date: Tue, 01 Jan 1980 00:01:01 +0000
2141 2187 From: test
2142 2188 To: foo
2143 2189
2144 2190 # HG changeset patch
2145 2191 # User test
2146 2192 # Date 3 0
2193 # Thu Jan 01 00:00:03 1970 +0000
2147 2194 # Node ID ff2c9fa2018b15fa74b33363bda9527323e2a99f
2148 2195 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2149 2196 c
2150 2197
2151 2198 diff -r 97d72e5f12c7 -r ff2c9fa2018b c
2152 2199 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2153 2200 +++ b/c Thu Jan 01 00:00:03 1970 +0000
2154 2201 @@ -0,0 +1,1 @@
2155 2202 +c
2156 2203
2157 2204 displaying [PATCH 2 of 6] utf-8 content ...
2158 2205 Content-Type: text/plain; charset="us-ascii"
2159 2206 MIME-Version: 1.0
2160 2207 Content-Transfer-Encoding: 8bit
2161 2208 Subject: [PATCH 2 of 6] utf-8 content
2162 2209 X-Mercurial-Node: 909a00e13e9d78b575aeee23dddbada46d5a143f
2163 2210 Message-Id: <909a00e13e9d78b575ae.315532862@*> (glob)
2164 2211 In-Reply-To: <patchbomb.315532860@*> (glob)
2165 2212 References: <patchbomb.315532860@*> (glob)
2166 2213 User-Agent: Mercurial-patchbomb/* (glob)
2167 2214 Date: Tue, 01 Jan 1980 00:01:02 +0000
2168 2215 From: test
2169 2216 To: foo
2170 2217
2171 2218 # HG changeset patch
2172 2219 # User test
2173 2220 # Date 4 0
2221 # Thu Jan 01 00:00:04 1970 +0000
2174 2222 # Node ID 909a00e13e9d78b575aeee23dddbada46d5a143f
2175 2223 # Parent ff2c9fa2018b15fa74b33363bda9527323e2a99f
2176 2224 utf-8 content
2177 2225
2178 2226 diff -r ff2c9fa2018b -r 909a00e13e9d description
2179 2227 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2180 2228 +++ b/description Thu Jan 01 00:00:04 1970 +0000
2181 2229 @@ -0,0 +1,3 @@
2182 2230 +a multiline
2183 2231 +
2184 2232 +description
2185 2233 diff -r ff2c9fa2018b -r 909a00e13e9d utf
2186 2234 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2187 2235 +++ b/utf Thu Jan 01 00:00:04 1970 +0000
2188 2236 @@ -0,0 +1,1 @@
2189 2237 +h\xc3\xb6mma! (esc)
2190 2238
2191 2239 displaying [PATCH 3 of 6] long line ...
2192 2240 Content-Type: text/plain; charset="us-ascii"
2193 2241 MIME-Version: 1.0
2194 2242 Content-Transfer-Encoding: quoted-printable
2195 2243 Subject: [PATCH 3 of 6] long line
2196 2244 X-Mercurial-Node: a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2197 2245 Message-Id: <a2ea8fc83dd8b93cfd86.315532863@*> (glob)
2198 2246 In-Reply-To: <patchbomb.315532860@*> (glob)
2199 2247 References: <patchbomb.315532860@*> (glob)
2200 2248 User-Agent: Mercurial-patchbomb/* (glob)
2201 2249 Date: Tue, 01 Jan 1980 00:01:03 +0000
2202 2250 From: test
2203 2251 To: foo
2204 2252
2205 2253 # HG changeset patch
2206 2254 # User test
2207 2255 # Date 4 0
2256 # Thu Jan 01 00:00:04 1970 +0000
2208 2257 # Node ID a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2209 2258 # Parent 909a00e13e9d78b575aeee23dddbada46d5a143f
2210 2259 long line
2211 2260
2212 2261 diff -r 909a00e13e9d -r a2ea8fc83dd8 long
2213 2262 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2214 2263 +++ b/long Thu Jan 01 00:00:04 1970 +0000
2215 2264 @@ -0,0 +1,4 @@
2216 2265 +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2217 2266 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2218 2267 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2219 2268 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2220 2269 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2221 2270 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2222 2271 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2223 2272 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2224 2273 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2225 2274 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2226 2275 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2227 2276 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2228 2277 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
2229 2278 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2230 2279 +foo
2231 2280 +
2232 2281 +bar
2233 2282
2234 2283 displaying [PATCH 4 of 6] isolatin 8-bit encoding ...
2235 2284 Content-Type: text/plain; charset="us-ascii"
2236 2285 MIME-Version: 1.0
2237 2286 Content-Transfer-Encoding: 8bit
2238 2287 Subject: [PATCH 4 of 6] isolatin 8-bit encoding
2239 2288 X-Mercurial-Node: 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2240 2289 Message-Id: <240fb913fc1b7ff15ddb.315532864@*> (glob)
2241 2290 In-Reply-To: <patchbomb.315532860@*> (glob)
2242 2291 References: <patchbomb.315532860@*> (glob)
2243 2292 User-Agent: Mercurial-patchbomb/* (glob)
2244 2293 Date: Tue, 01 Jan 1980 00:01:04 +0000
2245 2294 From: test
2246 2295 To: foo
2247 2296
2248 2297 # HG changeset patch
2249 2298 # User test
2250 2299 # Date 5 0
2300 # Thu Jan 01 00:00:05 1970 +0000
2251 2301 # Node ID 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2252 2302 # Parent a2ea8fc83dd8b93cfd86ac97b28287204ab806e1
2253 2303 isolatin 8-bit encoding
2254 2304
2255 2305 diff -r a2ea8fc83dd8 -r 240fb913fc1b isolatin
2256 2306 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2257 2307 +++ b/isolatin Thu Jan 01 00:00:05 1970 +0000
2258 2308 @@ -0,0 +1,1 @@
2259 2309 +h\xf6mma! (esc)
2260 2310
2261 2311 displaying [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a ...
2262 2312 Content-Type: text/plain; charset="us-ascii"
2263 2313 MIME-Version: 1.0
2264 2314 Content-Transfer-Encoding: 7bit
2265 2315 Subject: [PATCH 5 of 6] Added tag zero, zero.foo for changeset 8580ff50825a
2266 2316 X-Mercurial-Node: 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2267 2317 Message-Id: <5d5ef15dfe5e7bd3a4ee.315532865@*> (glob)
2268 2318 In-Reply-To: <patchbomb.315532860@*> (glob)
2269 2319 References: <patchbomb.315532860@*> (glob)
2270 2320 User-Agent: Mercurial-patchbomb/* (glob)
2271 2321 Date: Tue, 01 Jan 1980 00:01:05 +0000
2272 2322 From: test
2273 2323 To: foo
2274 2324
2275 2325 # HG changeset patch
2276 2326 # User test
2277 2327 # Date 0 0
2328 # Thu Jan 01 00:00:00 1970 +0000
2278 2329 # Node ID 5d5ef15dfe5e7bd3a4ee154b5fff76c7945ec433
2279 2330 # Parent 240fb913fc1b7ff15ddb9f33e73d82bf5277c720
2280 2331 Added tag zero, zero.foo for changeset 8580ff50825a
2281 2332
2282 2333 diff -r 240fb913fc1b -r 5d5ef15dfe5e .hgtags
2283 2334 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2284 2335 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
2285 2336 @@ -0,0 +1,2 @@
2286 2337 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero
2287 2338 +8580ff50825a50c8f716709acdf8de0deddcd6ab zero.foo
2288 2339
2289 2340 displaying [PATCH 6 of 6] d ...
2290 2341 Content-Type: text/plain; charset="us-ascii"
2291 2342 MIME-Version: 1.0
2292 2343 Content-Transfer-Encoding: 7bit
2293 2344 Subject: [PATCH 6 of 6] d
2294 2345 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2295 2346 Message-Id: <2f9fa9b998c5fe3ac2bd.315532866@*> (glob)
2296 2347 In-Reply-To: <patchbomb.315532860@*> (glob)
2297 2348 References: <patchbomb.315532860@*> (glob)
2298 2349 User-Agent: Mercurial-patchbomb/* (glob)
2299 2350 Date: Tue, 01 Jan 1980 00:01:06 +0000
2300 2351 From: test
2301 2352 To: foo
2302 2353
2303 2354 # HG changeset patch
2304 2355 # User test
2305 2356 # Date 4 0
2357 # Thu Jan 01 00:00:04 1970 +0000
2306 2358 # Branch test
2307 2359 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2308 2360 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2309 2361 d
2310 2362
2311 2363 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2312 2364 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2313 2365 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2314 2366 @@ -0,0 +1,1 @@
2315 2367 +d
2316 2368
2317 2369
2318 2370 dest#branch URIs:
2319 2371 $ hg email --date '1980-1-1 0:1' -n -t foo -s test -o ../t#test
2320 2372 comparing with ../t
2321 2373 From [test]: test
2322 2374 this patch series consists of 1 patches.
2323 2375
2324 2376 Cc:
2325 2377
2326 2378 displaying [PATCH] test ...
2327 2379 Content-Type: text/plain; charset="us-ascii"
2328 2380 MIME-Version: 1.0
2329 2381 Content-Transfer-Encoding: 7bit
2330 2382 Subject: [PATCH] test
2331 2383 X-Mercurial-Node: 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2332 2384 Message-Id: <2f9fa9b998c5fe3ac2bd.315532860@*> (glob)
2333 2385 User-Agent: Mercurial-patchbomb/* (glob)
2334 2386 Date: Tue, 01 Jan 1980 00:01:00 +0000
2335 2387 From: test
2336 2388 To: foo
2337 2389
2338 2390 # HG changeset patch
2339 2391 # User test
2340 2392 # Date 4 0
2393 # Thu Jan 01 00:00:04 1970 +0000
2341 2394 # Branch test
2342 2395 # Node ID 2f9fa9b998c5fe3ac2bd9a2b14bfcbeecbc7c268
2343 2396 # Parent 97d72e5f12c7e84f85064aa72e5a297142c36ed9
2344 2397 d
2345 2398
2346 2399 diff -r 97d72e5f12c7 -r 2f9fa9b998c5 d
2347 2400 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2348 2401 +++ b/d Thu Jan 01 00:00:04 1970 +0000
2349 2402 @@ -0,0 +1,1 @@
2350 2403 +d
2351 2404
2352 2405
2353 2406 $ cd ..
@@ -1,723 +1,724 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 > mq=
6 6 >
7 7 > [phases]
8 8 > publish=False
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
12 12 > tglogp = log -G --template "{rev}:{phase} '{desc}' {branches}\n"
13 13 > EOF
14 14
15 15 Create repo a:
16 16
17 17 $ hg init a
18 18 $ cd a
19 19 $ hg unbundle "$TESTDIR/bundles/rebase.hg"
20 20 adding changesets
21 21 adding manifests
22 22 adding file changes
23 23 added 8 changesets with 7 changes to 7 files (+2 heads)
24 24 (run 'hg heads' to see heads, 'hg merge' to merge)
25 25 $ hg up tip
26 26 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
27 27
28 28 $ hg tglog
29 29 @ 7: 'H'
30 30 |
31 31 | o 6: 'G'
32 32 |/|
33 33 o | 5: 'F'
34 34 | |
35 35 | o 4: 'E'
36 36 |/
37 37 | o 3: 'D'
38 38 | |
39 39 | o 2: 'C'
40 40 | |
41 41 | o 1: 'B'
42 42 |/
43 43 o 0: 'A'
44 44
45 45 $ cd ..
46 46
47 47
48 48 Rebasing B onto H and collapsing changesets with different phases:
49 49
50 50
51 51 $ hg clone -q -u 3 a a1
52 52 $ cd a1
53 53
54 54 $ hg phase --force --secret 3
55 55
56 56 $ hg rebase --collapse --keepbranches
57 57 saved backup bundle to $TESTTMP/a1/.hg/strip-backup/*-backup.hg (glob)
58 58
59 59 $ hg tglogp
60 60 @ 5:secret 'Collapsed revision
61 61 | * B
62 62 | * C
63 63 | * D'
64 64 o 4:draft 'H'
65 65 |
66 66 | o 3:draft 'G'
67 67 |/|
68 68 o | 2:draft 'F'
69 69 | |
70 70 | o 1:draft 'E'
71 71 |/
72 72 o 0:draft 'A'
73 73
74 74 $ hg manifest
75 75 A
76 76 B
77 77 C
78 78 D
79 79 F
80 80 H
81 81
82 82 $ cd ..
83 83
84 84
85 85 Rebasing E onto H:
86 86
87 87 $ hg clone -q -u . a a2
88 88 $ cd a2
89 89
90 90 $ hg phase --force --secret 6
91 91 $ hg rebase --source 4 --collapse
92 92 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
93 93
94 94 $ hg tglog
95 95 @ 6: 'Collapsed revision
96 96 | * E
97 97 | * G'
98 98 o 5: 'H'
99 99 |
100 100 o 4: 'F'
101 101 |
102 102 | o 3: 'D'
103 103 | |
104 104 | o 2: 'C'
105 105 | |
106 106 | o 1: 'B'
107 107 |/
108 108 o 0: 'A'
109 109
110 110 $ hg manifest
111 111 A
112 112 E
113 113 F
114 114 H
115 115
116 116 $ cd ..
117 117
118 118 Rebasing G onto H with custom message:
119 119
120 120 $ hg clone -q -u . a a3
121 121 $ cd a3
122 122
123 123 $ hg rebase --base 6 -m 'custom message'
124 124 abort: message can only be specified with collapse
125 125 [255]
126 126
127 127 $ hg rebase --source 4 --collapse -m 'custom message'
128 128 saved backup bundle to $TESTTMP/a3/.hg/strip-backup/*-backup.hg (glob)
129 129
130 130 $ hg tglog
131 131 @ 6: 'custom message'
132 132 |
133 133 o 5: 'H'
134 134 |
135 135 o 4: 'F'
136 136 |
137 137 | o 3: 'D'
138 138 | |
139 139 | o 2: 'C'
140 140 | |
141 141 | o 1: 'B'
142 142 |/
143 143 o 0: 'A'
144 144
145 145 $ hg manifest
146 146 A
147 147 E
148 148 F
149 149 H
150 150
151 151 $ cd ..
152 152
153 153 Create repo b:
154 154
155 155 $ hg init b
156 156 $ cd b
157 157
158 158 $ echo A > A
159 159 $ hg ci -Am A
160 160 adding A
161 161 $ echo B > B
162 162 $ hg ci -Am B
163 163 adding B
164 164
165 165 $ hg up -q 0
166 166
167 167 $ echo C > C
168 168 $ hg ci -Am C
169 169 adding C
170 170 created new head
171 171
172 172 $ hg merge
173 173 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
174 174 (branch merge, don't forget to commit)
175 175
176 176 $ echo D > D
177 177 $ hg ci -Am D
178 178 adding D
179 179
180 180 $ hg up -q 1
181 181
182 182 $ echo E > E
183 183 $ hg ci -Am E
184 184 adding E
185 185 created new head
186 186
187 187 $ echo F > F
188 188 $ hg ci -Am F
189 189 adding F
190 190
191 191 $ hg merge
192 192 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 (branch merge, don't forget to commit)
194 194 $ hg ci -m G
195 195
196 196 $ hg up -q 0
197 197
198 198 $ echo H > H
199 199 $ hg ci -Am H
200 200 adding H
201 201 created new head
202 202
203 203 $ hg tglog
204 204 @ 7: 'H'
205 205 |
206 206 | o 6: 'G'
207 207 | |\
208 208 | | o 5: 'F'
209 209 | | |
210 210 | | o 4: 'E'
211 211 | | |
212 212 | o | 3: 'D'
213 213 | |\|
214 214 | o | 2: 'C'
215 215 |/ /
216 216 | o 1: 'B'
217 217 |/
218 218 o 0: 'A'
219 219
220 220 $ cd ..
221 221
222 222
223 223 Rebase and collapse - more than one external (fail):
224 224
225 225 $ hg clone -q -u . b b1
226 226 $ cd b1
227 227
228 228 $ hg rebase -s 2 --collapse
229 229 abort: unable to collapse, there is more than one external parent
230 230 [255]
231 231
232 232 Rebase and collapse - E onto H:
233 233
234 234 $ hg rebase -s 4 --collapse # root (4) is not a merge
235 235 saved backup bundle to $TESTTMP/b1/.hg/strip-backup/*-backup.hg (glob)
236 236
237 237 $ hg tglog
238 238 @ 5: 'Collapsed revision
239 239 |\ * E
240 240 | | * F
241 241 | | * G'
242 242 | o 4: 'H'
243 243 | |
244 244 o | 3: 'D'
245 245 |\ \
246 246 | o | 2: 'C'
247 247 | |/
248 248 o / 1: 'B'
249 249 |/
250 250 o 0: 'A'
251 251
252 252 $ hg manifest
253 253 A
254 254 C
255 255 D
256 256 E
257 257 F
258 258 H
259 259
260 260 $ cd ..
261 261
262 262
263 263
264 264
265 265 Test that branchheads cache is updated correctly when doing a strip in which
266 266 the parent of the ancestor node to be stripped does not become a head and also,
267 267 the parent of a node that is a child of the node stripped becomes a head (node
268 268 3). The code is now much simpler and we could just test a simpler scenario
269 269 We keep it the test this way in case new complexity is injected.
270 270
271 271 $ hg clone -q -u . b b2
272 272 $ cd b2
273 273
274 274 $ hg heads --template="{rev}:{node} {branch}\n"
275 275 7:c65502d4178782309ce0574c5ae6ee9485a9bafa default
276 276 6:c772a8b2dc17629cec88a19d09c926c4814b12c7 default
277 277
278 278 $ cat $TESTTMP/b2/.hg/cache/branchheads-served
279 279 c65502d4178782309ce0574c5ae6ee9485a9bafa 7
280 280 c772a8b2dc17629cec88a19d09c926c4814b12c7 default
281 281 c65502d4178782309ce0574c5ae6ee9485a9bafa default
282 282
283 283 $ hg strip 4
284 284 saved backup bundle to $TESTTMP/b2/.hg/strip-backup/8a5212ebc852-backup.hg (glob)
285 285
286 286 $ cat $TESTTMP/b2/.hg/cache/branchheads-served
287 287 c65502d4178782309ce0574c5ae6ee9485a9bafa 4
288 288 2870ad076e541e714f3c2bc32826b5c6a6e5b040 default
289 289 c65502d4178782309ce0574c5ae6ee9485a9bafa default
290 290
291 291 $ hg heads --template="{rev}:{node} {branch}\n"
292 292 4:c65502d4178782309ce0574c5ae6ee9485a9bafa default
293 293 3:2870ad076e541e714f3c2bc32826b5c6a6e5b040 default
294 294
295 295 $ cd ..
296 296
297 297
298 298
299 299
300 300
301 301
302 302 Create repo c:
303 303
304 304 $ hg init c
305 305 $ cd c
306 306
307 307 $ echo A > A
308 308 $ hg ci -Am A
309 309 adding A
310 310 $ echo B > B
311 311 $ hg ci -Am B
312 312 adding B
313 313
314 314 $ hg up -q 0
315 315
316 316 $ echo C > C
317 317 $ hg ci -Am C
318 318 adding C
319 319 created new head
320 320
321 321 $ hg merge
322 322 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
323 323 (branch merge, don't forget to commit)
324 324
325 325 $ echo D > D
326 326 $ hg ci -Am D
327 327 adding D
328 328
329 329 $ hg up -q 1
330 330
331 331 $ echo E > E
332 332 $ hg ci -Am E
333 333 adding E
334 334 created new head
335 335 $ echo F > E
336 336 $ hg ci -m 'F'
337 337
338 338 $ echo G > G
339 339 $ hg ci -Am G
340 340 adding G
341 341
342 342 $ hg merge
343 343 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
344 344 (branch merge, don't forget to commit)
345 345
346 346 $ hg ci -m H
347 347
348 348 $ hg up -q 0
349 349
350 350 $ echo I > I
351 351 $ hg ci -Am I
352 352 adding I
353 353 created new head
354 354
355 355 $ hg tglog
356 356 @ 8: 'I'
357 357 |
358 358 | o 7: 'H'
359 359 | |\
360 360 | | o 6: 'G'
361 361 | | |
362 362 | | o 5: 'F'
363 363 | | |
364 364 | | o 4: 'E'
365 365 | | |
366 366 | o | 3: 'D'
367 367 | |\|
368 368 | o | 2: 'C'
369 369 |/ /
370 370 | o 1: 'B'
371 371 |/
372 372 o 0: 'A'
373 373
374 374 $ cd ..
375 375
376 376
377 377 Rebase and collapse - E onto I:
378 378
379 379 $ hg clone -q -u . c c1
380 380 $ cd c1
381 381
382 382 $ hg rebase -s 4 --collapse # root (4) is not a merge
383 383 merging E
384 384 saved backup bundle to $TESTTMP/c1/.hg/strip-backup/*-backup.hg (glob)
385 385
386 386 $ hg tglog
387 387 @ 5: 'Collapsed revision
388 388 |\ * E
389 389 | | * F
390 390 | | * G
391 391 | | * H'
392 392 | o 4: 'I'
393 393 | |
394 394 o | 3: 'D'
395 395 |\ \
396 396 | o | 2: 'C'
397 397 | |/
398 398 o / 1: 'B'
399 399 |/
400 400 o 0: 'A'
401 401
402 402 $ hg manifest
403 403 A
404 404 C
405 405 D
406 406 E
407 407 G
408 408 I
409 409
410 410 $ cat E
411 411 F
412 412
413 413 $ cd ..
414 414
415 415
416 416 Create repo d:
417 417
418 418 $ hg init d
419 419 $ cd d
420 420
421 421 $ echo A > A
422 422 $ hg ci -Am A
423 423 adding A
424 424 $ echo B > B
425 425 $ hg ci -Am B
426 426 adding B
427 427 $ echo C > C
428 428 $ hg ci -Am C
429 429 adding C
430 430
431 431 $ hg up -q 1
432 432
433 433 $ echo D > D
434 434 $ hg ci -Am D
435 435 adding D
436 436 created new head
437 437 $ hg merge
438 438 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
439 439 (branch merge, don't forget to commit)
440 440
441 441 $ hg ci -m E
442 442
443 443 $ hg up -q 0
444 444
445 445 $ echo F > F
446 446 $ hg ci -Am F
447 447 adding F
448 448 created new head
449 449
450 450 $ hg tglog
451 451 @ 5: 'F'
452 452 |
453 453 | o 4: 'E'
454 454 | |\
455 455 | | o 3: 'D'
456 456 | | |
457 457 | o | 2: 'C'
458 458 | |/
459 459 | o 1: 'B'
460 460 |/
461 461 o 0: 'A'
462 462
463 463 $ cd ..
464 464
465 465
466 466 Rebase and collapse - B onto F:
467 467
468 468 $ hg clone -q -u . d d1
469 469 $ cd d1
470 470
471 471 $ hg rebase -s 1 --collapse
472 472 saved backup bundle to $TESTTMP/d1/.hg/strip-backup/*-backup.hg (glob)
473 473
474 474 $ hg tglog
475 475 @ 2: 'Collapsed revision
476 476 | * B
477 477 | * C
478 478 | * D
479 479 | * E'
480 480 o 1: 'F'
481 481 |
482 482 o 0: 'A'
483 483
484 484 $ hg manifest
485 485 A
486 486 B
487 487 C
488 488 D
489 489 F
490 490
491 491 Interactions between collapse and keepbranches
492 492 $ cd ..
493 493 $ hg init e
494 494 $ cd e
495 495 $ echo 'a' > a
496 496 $ hg ci -Am 'A'
497 497 adding a
498 498
499 499 $ hg branch 'one'
500 500 marked working directory as branch one
501 501 (branches are permanent and global, did you want a bookmark?)
502 502 $ echo 'b' > b
503 503 $ hg ci -Am 'B'
504 504 adding b
505 505
506 506 $ hg branch 'two'
507 507 marked working directory as branch two
508 508 (branches are permanent and global, did you want a bookmark?)
509 509 $ echo 'c' > c
510 510 $ hg ci -Am 'C'
511 511 adding c
512 512
513 513 $ hg up -q 0
514 514 $ echo 'd' > d
515 515 $ hg ci -Am 'D'
516 516 adding d
517 517
518 518 $ hg tglog
519 519 @ 3: 'D'
520 520 |
521 521 | o 2: 'C' two
522 522 | |
523 523 | o 1: 'B' one
524 524 |/
525 525 o 0: 'A'
526 526
527 527 $ hg rebase --keepbranches --collapse -s 1 -d 3
528 528 abort: cannot collapse multiple named branches
529 529 [255]
530 530
531 531 $ repeatchange() {
532 532 > hg checkout $1
533 533 > hg cp d z
534 534 > echo blah >> z
535 535 > hg commit -Am "$2" --user "$3"
536 536 > }
537 537 $ repeatchange 3 "E" "user1"
538 538 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
539 539 $ repeatchange 3 "E" "user2"
540 540 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
541 541 created new head
542 542 $ hg tglog
543 543 @ 5: 'E'
544 544 |
545 545 | o 4: 'E'
546 546 |/
547 547 o 3: 'D'
548 548 |
549 549 | o 2: 'C' two
550 550 | |
551 551 | o 1: 'B' one
552 552 |/
553 553 o 0: 'A'
554 554
555 555 $ hg rebase -s 5 -d 4
556 556 saved backup bundle to $TESTTMP/e/.hg/strip-backup/*-backup.hg (glob)
557 557 $ hg tglog
558 558 @ 4: 'E'
559 559 |
560 560 o 3: 'D'
561 561 |
562 562 | o 2: 'C' two
563 563 | |
564 564 | o 1: 'B' one
565 565 |/
566 566 o 0: 'A'
567 567
568 568 $ hg export tip
569 569 # HG changeset patch
570 570 # User user1
571 571 # Date 0 0
572 # Thu Jan 01 00:00:00 1970 +0000
572 573 # Node ID f338eb3c2c7cc5b5915676a2376ba7ac558c5213
573 574 # Parent 41acb9dca9eb976e84cd21fcb756b4afa5a35c09
574 575 E
575 576
576 577 diff -r 41acb9dca9eb -r f338eb3c2c7c z
577 578 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
578 579 +++ b/z Thu Jan 01 00:00:00 1970 +0000
579 580 @@ -0,0 +1,2 @@
580 581 +d
581 582 +blah
582 583
583 584 $ cd ..
584 585
585 586 Rebase, collapse and copies
586 587
587 588 $ hg init copies
588 589 $ cd copies
589 590 $ hg unbundle "$TESTDIR/bundles/renames.hg"
590 591 adding changesets
591 592 adding manifests
592 593 adding file changes
593 594 added 4 changesets with 11 changes to 7 files (+1 heads)
594 595 (run 'hg heads' to see heads, 'hg merge' to merge)
595 596 $ hg up -q tip
596 597 $ hg tglog
597 598 @ 3: 'move2'
598 599 |
599 600 o 2: 'move1'
600 601 |
601 602 | o 1: 'change'
602 603 |/
603 604 o 0: 'add'
604 605
605 606 $ hg rebase --collapse -d 1
606 607 merging a and d to d
607 608 merging b and e to e
608 609 merging c and f to f
609 610 merging e and g to g
610 611 merging f and c to c
611 612 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
612 613 $ hg st
613 614 $ hg st --copies --change .
614 615 A d
615 616 a
616 617 A g
617 618 b
618 619 R b
619 620 $ cat c
620 621 c
621 622 c
622 623 $ cat d
623 624 a
624 625 a
625 626 $ cat g
626 627 b
627 628 b
628 629 $ hg log -r . --template "{file_copies}\n"
629 630 d (a)g (b)
630 631
631 632 Test collapsing a middle revision in-place
632 633
633 634 $ hg tglog
634 635 @ 2: 'Collapsed revision
635 636 | * move1
636 637 | * move2'
637 638 o 1: 'change'
638 639 |
639 640 o 0: 'add'
640 641
641 642 $ hg rebase --collapse -r 1 -d 0
642 643 abort: can't remove original changesets with unrebased descendants
643 644 (use --keep to keep original changesets)
644 645 [255]
645 646
646 647 Test collapsing in place
647 648
648 649 $ hg rebase --collapse -b . -d 0
649 650 saved backup bundle to $TESTTMP/copies/.hg/strip-backup/*-backup.hg (glob)
650 651 $ hg st --change . --copies
651 652 M a
652 653 M c
653 654 A d
654 655 a
655 656 A g
656 657 b
657 658 R b
658 659 $ cat a
659 660 a
660 661 a
661 662 $ cat c
662 663 c
663 664 c
664 665 $ cat d
665 666 a
666 667 a
667 668 $ cat g
668 669 b
669 670 b
670 671 $ cd ..
671 672
672 673
673 674 Test stripping a revision with another child
674 675
675 676 $ hg init f
676 677 $ cd f
677 678
678 679 $ echo A > A
679 680 $ hg ci -Am A
680 681 adding A
681 682 $ echo B > B
682 683 $ hg ci -Am B
683 684 adding B
684 685
685 686 $ hg up -q 0
686 687
687 688 $ echo C > C
688 689 $ hg ci -Am C
689 690 adding C
690 691 created new head
691 692
692 693 $ hg tglog
693 694 @ 2: 'C'
694 695 |
695 696 | o 1: 'B'
696 697 |/
697 698 o 0: 'A'
698 699
699 700
700 701
701 702 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
702 703 2:c5cefa58fd557f84b72b87f970135984337acbc5 default: C
703 704 1:27547f69f25460a52fff66ad004e58da7ad3fb56 default: B
704 705
705 706 $ hg strip 2
706 707 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
707 708 saved backup bundle to $TESTTMP/f/.hg/strip-backup/*-backup.hg (glob)
708 709
709 710 $ hg tglog
710 711 o 1: 'B'
711 712 |
712 713 @ 0: 'A'
713 714
714 715
715 716
716 717 $ hg heads --template="{rev}:{node} {branch}: {desc}\n"
717 718 1:27547f69f25460a52fff66ad004e58da7ad3fb56 default: B
718 719
719 720 $ cd ..
720 721
721 722
722 723
723 724
@@ -1,343 +1,347 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 > mq=
6 6 >
7 7 > [mq]
8 8 > plain=true
9 9 >
10 10 > [alias]
11 11 > tglog = log -G --template "{rev}: '{desc}' tags: {tags}\n"
12 12 > EOF
13 13
14 14
15 15 $ hg init a
16 16 $ cd a
17 17 $ hg qinit -c
18 18
19 19 $ echo c1 > f
20 20 $ hg add f
21 21 $ hg ci -m C1
22 22
23 23 $ echo r1 > f
24 24 $ hg ci -m R1
25 25
26 26 $ hg up -q 0
27 27
28 28 $ hg qnew f.patch
29 29 $ echo mq1 > f
30 30 $ hg qref -m P0
31 31
32 32 $ hg qnew f2.patch
33 33 $ echo mq2 > f
34 34 $ hg qref -m P1
35 35
36 36 $ hg tglog
37 37 @ 3: 'P1' tags: f2.patch qtip tip
38 38 |
39 39 o 2: 'P0' tags: f.patch qbase
40 40 |
41 41 | o 1: 'R1' tags:
42 42 |/
43 43 o 0: 'C1' tags: qparent
44 44
45 45
46 46 Rebase - try to rebase on an applied mq patch:
47 47
48 48 $ hg rebase -s 1 -d 3
49 49 abort: cannot rebase onto an applied mq patch
50 50 [255]
51 51
52 52 Rebase - same thing, but mq patch is default dest:
53 53
54 54 $ hg up -q 1
55 55 $ hg rebase
56 56 abort: cannot rebase onto an applied mq patch
57 57 [255]
58 58 $ hg up -q qtip
59 59
60 60 Rebase - generate a conflict:
61 61
62 62 $ hg rebase -s 2 -d 1
63 63 merging f
64 64 warning: conflicts during merge.
65 65 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
66 66 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
67 67 [255]
68 68
69 69 Fix the 1st conflict:
70 70
71 71 $ echo mq1r1 > f
72 72 $ hg resolve -m f
73 73 $ hg rebase -c
74 74 merging f
75 75 warning: conflicts during merge.
76 76 merging f incomplete! (edit conflicts, then use 'hg resolve --mark')
77 77 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
78 78 [255]
79 79
80 80 Fix the 2nd conflict:
81 81
82 82 $ echo mq1r1mq2 > f
83 83 $ hg resolve -m f
84 84 $ hg rebase -c
85 85 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
86 86
87 87 $ hg tglog
88 88 @ 3: 'P1' tags: f2.patch qtip tip
89 89 |
90 90 o 2: 'P0' tags: f.patch qbase
91 91 |
92 92 o 1: 'R1' tags: qparent
93 93 |
94 94 o 0: 'C1' tags:
95 95
96 96 $ hg up -q qbase
97 97
98 98 $ cat f
99 99 mq1r1
100 100
101 101 $ cat .hg/patches/f.patch
102 102 # HG changeset patch
103 103 # User test
104 104 # Date ?????????? ? (glob)
105 # * (glob)
105 106 # Node ID ???????????????????????????????????????? (glob)
106 107 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
107 108 P0
108 109
109 110 diff -r bac9ed9960d8 -r ???????????? f (glob)
110 111 --- a/f Thu Jan 01 00:00:00 1970 +0000
111 112 +++ b/f ??? ??? ?? ??:??:?? ???? ????? (glob)
112 113 @@ -1,1 +1,1 @@
113 114 -r1
114 115 +mq1r1
115 116
116 117 Update to qtip:
117 118
118 119 $ hg up -q qtip
119 120
120 121 $ cat f
121 122 mq1r1mq2
122 123
123 124 $ cat .hg/patches/f2.patch
124 125 # HG changeset patch
125 126 # User test
126 127 # Date ?????????? ? (glob)
128 # * (glob)
127 129 # Node ID ???????????????????????????????????????? (glob)
128 130 # Parent ???????????????????????????????????????? (glob)
129 131 P1
130 132
131 133 diff -r ???????????? -r ???????????? f (glob)
132 134 --- a/f ??? ??? ?? ??:??:?? ???? ????? (glob)
133 135 +++ b/f ??? ??? ?? ??:??:?? ???? ????? (glob)
134 136 @@ -1,1 +1,1 @@
135 137 -mq1r1
136 138 +mq1r1mq2
137 139
138 140 Adding one git-style patch and one normal:
139 141
140 142 $ hg qpop -a
141 143 popping f2.patch
142 144 popping f.patch
143 145 patch queue now empty
144 146
145 147 $ rm -fr .hg/patches
146 148 $ hg qinit -c
147 149
148 150 $ hg up -q 0
149 151
150 152 $ hg qnew --git f_git.patch
151 153 $ echo mq1 > p
152 154 $ hg add p
153 155 $ hg qref --git -m 'P0 (git)'
154 156
155 157 $ hg qnew f.patch
156 158 $ echo mq2 > p
157 159 $ hg qref -m P1
158 160 $ hg qci -m 'save patch state'
159 161
160 162 $ hg qseries -s
161 163 f_git.patch: P0 (git)
162 164 f.patch: P1
163 165
164 166 $ hg -R .hg/patches manifest
165 167 .hgignore
166 168 f.patch
167 169 f_git.patch
168 170 series
169 171
170 172 $ cat .hg/patches/f_git.patch
171 173 P0 (git)
172 174
173 175 diff --git a/p b/p
174 176 new file mode 100644
175 177 --- /dev/null
176 178 +++ b/p
177 179 @@ -0,0 +1,1 @@
178 180 +mq1
179 181
180 182 $ cat .hg/patches/f.patch
181 183 P1
182 184
183 185 diff -r ???????????? p (glob)
184 186 --- a/p ??? ??? ?? ??:??:?? ???? ????? (glob)
185 187 +++ b/p ??? ??? ?? ??:??:?? ???? ????? (glob)
186 188 @@ -1,1 +1,1 @@
187 189 -mq1
188 190 +mq2
189 191
190 192
191 193 Rebase the applied mq patches:
192 194
193 195 $ hg rebase -s 2 -d 1
194 196 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
195 197
196 198 $ hg qci -m 'save patch state'
197 199
198 200 $ hg qseries -s
199 201 f_git.patch: P0 (git)
200 202 f.patch: P1
201 203
202 204 $ hg -R .hg/patches manifest
203 205 .hgignore
204 206 f.patch
205 207 f_git.patch
206 208 series
207 209
208 210 $ cat .hg/patches/f_git.patch
209 211 # HG changeset patch
210 212 # User test
211 213 # Date ?????????? ? (glob)
214 # * (glob)
212 215 # Node ID ???????????????????????????????????????? (glob)
213 216 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
214 217 P0 (git)
215 218
216 219 diff --git a/p b/p
217 220 new file mode 100644
218 221 --- /dev/null
219 222 +++ b/p
220 223 @@ -0,0 +1,1 @@
221 224 +mq1
222 225
223 226 $ cat .hg/patches/f.patch
224 227 # HG changeset patch
225 228 # User test
226 229 # Date ?????????? ? (glob)
230 # * (glob)
227 231 # Node ID ???????????????????????????????????????? (glob)
228 232 # Parent ???????????????????????????????????????? (glob)
229 233 P1
230 234
231 235 diff -r ???????????? -r ???????????? p (glob)
232 236 --- a/p ??? ??? ?? ??:??:?? ???? ????? (glob)
233 237 +++ b/p ??? ??? ?? ??:??:?? ???? ????? (glob)
234 238 @@ -1,1 +1,1 @@
235 239 -mq1
236 240 +mq2
237 241
238 242 $ cd ..
239 243
240 244 Rebase with guards
241 245
242 246 $ hg init foo
243 247 $ cd foo
244 248 $ echo a > a
245 249 $ hg ci -Am a
246 250 adding a
247 251
248 252 Create mq repo with guarded patches foo and bar and empty patch:
249 253
250 254 $ hg qinit
251 255 $ echo guarded > guarded
252 256 $ hg add guarded
253 257 $ hg qnew guarded
254 258 $ hg qnew empty-important -m 'important commit message'
255 259 $ echo bar > bar
256 260 $ hg add bar
257 261 $ hg qnew bar
258 262 $ echo foo > foo
259 263 $ hg add foo
260 264 $ hg qnew foo
261 265 $ hg qpop -a
262 266 popping foo
263 267 popping bar
264 268 popping empty-important
265 269 popping guarded
266 270 patch queue now empty
267 271 $ hg qguard guarded +guarded
268 272 $ hg qguard bar +baz
269 273 $ hg qguard foo +baz
270 274 $ hg qselect baz
271 275 number of unguarded, unapplied patches has changed from 1 to 3
272 276 $ hg qpush bar
273 277 applying empty-important
274 278 patch empty-important is empty
275 279 applying bar
276 280 now at: bar
277 281
278 282 $ hg qguard -l
279 283 guarded: +guarded
280 284 empty-important: unguarded
281 285 bar: +baz
282 286 foo: +baz
283 287
284 288 $ hg tglog
285 289 @ 2: 'imported patch bar' tags: bar qtip tip
286 290 |
287 291 o 1: 'important commit message' tags: empty-important qbase
288 292 |
289 293 o 0: 'a' tags: qparent
290 294
291 295 Create new head to rebase bar onto:
292 296
293 297 $ hg up -C 0
294 298 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
295 299 $ echo b > b
296 300 $ hg add b
297 301 $ hg ci -m b
298 302 created new head
299 303 $ hg up -C 2
300 304 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
301 305 $ echo a >> a
302 306 $ hg qref
303 307
304 308 $ hg tglog
305 309 @ 3: '[mq]: bar' tags: bar qtip tip
306 310 |
307 311 | o 2: 'b' tags:
308 312 | |
309 313 o | 1: 'important commit message' tags: empty-important qbase
310 314 |/
311 315 o 0: 'a' tags: qparent
312 316
313 317
314 318 Rebase bar (make sure series order is preserved and empty-important also is
315 319 removed from the series):
316 320
317 321 $ hg qseries
318 322 guarded
319 323 empty-important
320 324 bar
321 325 foo
322 326 $ [ -f .hg/patches/empty-important ]
323 327 $ hg -q rebase -d 2
324 328 $ hg qseries
325 329 guarded
326 330 bar
327 331 foo
328 332 $ [ -f .hg/patches/empty-important ]
329 333 [1]
330 334
331 335 $ hg qguard -l
332 336 guarded: +guarded
333 337 bar: +baz
334 338 foo: +baz
335 339
336 340 $ hg tglog
337 341 @ 2:* '[mq]: bar' tags: bar qbase qtip tip (glob)
338 342 |
339 343 o 1:* 'b' tags: qparent (glob)
340 344 |
341 345 o 0:* 'a' tags: (glob)
342 346
343 347 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now