##// END OF EJS Templates
rebase: improve resolve failure message
Steve Borho -
r12896:b19b4c1d stable
parent child Browse files
Show More
@@ -1,577 +1,577 b''
1 1 # rebase.py - rebasing feature for mercurial
2 2 #
3 3 # Copyright 2008 Stefano Tortarolo <stefano.tortarolo at gmail dot 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 '''command to move sets of revisions to a different ancestor
9 9
10 10 This extension lets you rebase changesets in an existing Mercurial
11 11 repository.
12 12
13 13 For more information:
14 14 http://mercurial.selenic.com/wiki/RebaseExtension
15 15 '''
16 16
17 17 from mercurial import hg, util, repair, merge, cmdutil, commands
18 18 from mercurial import extensions, ancestor, copies, patch
19 19 from mercurial.commands import templateopts
20 20 from mercurial.node import nullrev
21 21 from mercurial.lock import release
22 22 from mercurial.i18n import _
23 23 import os, errno
24 24
25 25 nullmerge = -2
26 26
27 27 def rebase(ui, repo, **opts):
28 28 """move changeset (and descendants) to a different branch
29 29
30 30 Rebase uses repeated merging to graft changesets from one part of
31 31 history (the source) onto another (the destination). This can be
32 32 useful for linearizing *local* changes relative to a master
33 33 development tree.
34 34
35 35 You should not rebase changesets that have already been shared
36 36 with others. Doing so will force everybody else to perform the
37 37 same rebase or they will end up with duplicated changesets after
38 38 pulling in your rebased changesets.
39 39
40 40 If you don't specify a destination changeset (``-d/--dest``),
41 41 rebase uses the tipmost head of the current named branch as the
42 42 destination. (The destination changeset is not modified by
43 43 rebasing, but new changesets are added as its descendants.)
44 44
45 45 You can specify which changesets to rebase in two ways: as a
46 46 "source" changeset or as a "base" changeset. Both are shorthand
47 47 for a topologically related set of changesets (the "source
48 48 branch"). If you specify source (``-s/--source``), rebase will
49 49 rebase that changeset and all of its descendants onto dest. If you
50 50 specify base (``-b/--base``), rebase will select ancestors of base
51 51 back to but not including the common ancestor with dest. Thus,
52 52 ``-b`` is less precise but more convenient than ``-s``: you can
53 53 specify any changeset in the source branch, and rebase will select
54 54 the whole branch. If you specify neither ``-s`` nor ``-b``, rebase
55 55 uses the parent of the working directory as the base.
56 56
57 57 By default, rebase recreates the changesets in the source branch
58 58 as descendants of dest and then destroys the originals. Use
59 59 ``--keep`` to preserve the original source changesets. Some
60 60 changesets in the source branch (e.g. merges from the destination
61 61 branch) may be dropped if they no longer contribute any change.
62 62
63 63 One result of the rules for selecting the destination changeset
64 64 and source branch is that, unlike ``merge``, rebase will do
65 65 nothing if you are at the latest (tipmost) head of a named branch
66 66 with two heads. You need to explicitly specify source and/or
67 67 destination (or ``update`` to the other head, if it's the head of
68 68 the intended source branch).
69 69
70 70 If a rebase is interrupted to manually resolve a merge, it can be
71 71 continued with --continue/-c or aborted with --abort/-a.
72 72
73 73 Returns 0 on success, 1 if nothing to rebase.
74 74 """
75 75 originalwd = target = None
76 76 external = nullrev
77 77 state = {}
78 78 skipped = set()
79 79 targetancestors = set()
80 80
81 81 lock = wlock = None
82 82 try:
83 83 lock = repo.lock()
84 84 wlock = repo.wlock()
85 85
86 86 # Validate input and define rebasing points
87 87 destf = opts.get('dest', None)
88 88 srcf = opts.get('source', None)
89 89 basef = opts.get('base', None)
90 90 contf = opts.get('continue')
91 91 abortf = opts.get('abort')
92 92 collapsef = opts.get('collapse', False)
93 93 extrafn = opts.get('extrafn')
94 94 keepf = opts.get('keep', False)
95 95 keepbranchesf = opts.get('keepbranches', False)
96 96 detachf = opts.get('detach', False)
97 97 # keepopen is not meant for use on the command line, but by
98 98 # other extensions
99 99 keepopen = opts.get('keepopen', False)
100 100
101 101 if contf or abortf:
102 102 if contf and abortf:
103 103 raise util.Abort(_('cannot use both abort and continue'))
104 104 if collapsef:
105 105 raise util.Abort(
106 106 _('cannot use collapse with continue or abort'))
107 107 if detachf:
108 108 raise util.Abort(_('cannot use detach with continue or abort'))
109 109 if srcf or basef or destf:
110 110 raise util.Abort(
111 111 _('abort and continue do not allow specifying revisions'))
112 112
113 113 (originalwd, target, state, skipped, collapsef, keepf,
114 114 keepbranchesf, external) = restorestatus(repo)
115 115 if abortf:
116 116 return abort(repo, originalwd, target, state)
117 117 else:
118 118 if srcf and basef:
119 119 raise util.Abort(_('cannot specify both a '
120 120 'revision and a base'))
121 121 if detachf:
122 122 if not srcf:
123 123 raise util.Abort(
124 124 _('detach requires a revision to be specified'))
125 125 if basef:
126 126 raise util.Abort(_('cannot specify a base with detach'))
127 127
128 128 cmdutil.bail_if_changed(repo)
129 129 result = buildstate(repo, destf, srcf, basef, detachf)
130 130 if not result:
131 131 # Empty state built, nothing to rebase
132 132 ui.status(_('nothing to rebase\n'))
133 133 return 1
134 134 else:
135 135 originalwd, target, state = result
136 136 if collapsef:
137 137 targetancestors = set(repo.changelog.ancestors(target))
138 138 external = checkexternal(repo, state, targetancestors)
139 139
140 140 if keepbranchesf:
141 141 if extrafn:
142 142 raise util.Abort(_('cannot use both keepbranches and extrafn'))
143 143 def extrafn(ctx, extra):
144 144 extra['branch'] = ctx.branch()
145 145
146 146 # Rebase
147 147 if not targetancestors:
148 148 targetancestors = set(repo.changelog.ancestors(target))
149 149 targetancestors.add(target)
150 150
151 151 sortedstate = sorted(state)
152 152 total = len(sortedstate)
153 153 pos = 0
154 154 for rev in sortedstate:
155 155 pos += 1
156 156 if state[rev] == -1:
157 157 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, repo[rev])),
158 158 _('changesets'), total)
159 159 storestatus(repo, originalwd, target, state, collapsef, keepf,
160 160 keepbranchesf, external)
161 161 p1, p2 = defineparents(repo, rev, target, state,
162 162 targetancestors)
163 163 if len(repo.parents()) == 2:
164 164 repo.ui.debug('resuming interrupted rebase\n')
165 165 else:
166 166 stats = rebasenode(repo, rev, p1, p2, state)
167 167 if stats and stats[3] > 0:
168 raise util.Abort(_('fix unresolved conflicts with hg '
169 'resolve then run hg rebase --continue'))
168 raise util.Abort(_('unresolved conflicts (see hg '
169 'resolve, then hg rebase --continue)'))
170 170 updatedirstate(repo, rev, target, p2)
171 171 if not collapsef:
172 172 newrev = concludenode(repo, rev, p1, p2, extrafn=extrafn)
173 173 else:
174 174 # Skip commit if we are collapsing
175 175 repo.dirstate.setparents(repo[p1].node())
176 176 newrev = None
177 177 # Update the state
178 178 if newrev is not None:
179 179 state[rev] = repo[newrev].rev()
180 180 else:
181 181 if not collapsef:
182 182 ui.note(_('no changes, revision %d skipped\n') % rev)
183 183 ui.debug('next revision set to %s\n' % p1)
184 184 skipped.add(rev)
185 185 state[rev] = p1
186 186
187 187 ui.progress(_('rebasing'), None)
188 188 ui.note(_('rebase merging completed\n'))
189 189
190 190 if collapsef and not keepopen:
191 191 p1, p2 = defineparents(repo, min(state), target,
192 192 state, targetancestors)
193 193 commitmsg = 'Collapsed revision'
194 194 for rebased in state:
195 195 if rebased not in skipped and state[rebased] != nullmerge:
196 196 commitmsg += '\n* %s' % repo[rebased].description()
197 197 commitmsg = ui.edit(commitmsg, repo.ui.username())
198 198 newrev = concludenode(repo, rev, p1, external, commitmsg=commitmsg,
199 199 extrafn=extrafn)
200 200
201 201 if 'qtip' in repo.tags():
202 202 updatemq(repo, state, skipped, **opts)
203 203
204 204 if not keepf:
205 205 # Remove no more useful revisions
206 206 rebased = [rev for rev in state if state[rev] != nullmerge]
207 207 if rebased:
208 208 if set(repo.changelog.descendants(min(rebased))) - set(state):
209 209 ui.warn(_("warning: new changesets detected "
210 210 "on source branch, not stripping\n"))
211 211 else:
212 212 # backup the old csets by default
213 213 repair.strip(ui, repo, repo[min(rebased)].node(), "all")
214 214
215 215 clearstatus(repo)
216 216 ui.note(_("rebase completed\n"))
217 217 if os.path.exists(repo.sjoin('undo')):
218 218 util.unlink(repo.sjoin('undo'))
219 219 if skipped:
220 220 ui.note(_("%d revisions have been skipped\n") % len(skipped))
221 221 finally:
222 222 release(lock, wlock)
223 223
224 224 def rebasemerge(repo, rev, first=False):
225 225 'return the correct ancestor'
226 226 oldancestor = ancestor.ancestor
227 227
228 228 def newancestor(a, b, pfunc):
229 229 if b == rev:
230 230 return repo[rev].parents()[0].rev()
231 231 return oldancestor(a, b, pfunc)
232 232
233 233 if not first:
234 234 ancestor.ancestor = newancestor
235 235 else:
236 236 repo.ui.debug("first revision, do not change ancestor\n")
237 237 try:
238 238 stats = merge.update(repo, rev, True, True, False)
239 239 return stats
240 240 finally:
241 241 ancestor.ancestor = oldancestor
242 242
243 243 def checkexternal(repo, state, targetancestors):
244 244 """Check whether one or more external revisions need to be taken in
245 245 consideration. In the latter case, abort.
246 246 """
247 247 external = nullrev
248 248 source = min(state)
249 249 for rev in state:
250 250 if rev == source:
251 251 continue
252 252 # Check externals and fail if there are more than one
253 253 for p in repo[rev].parents():
254 254 if (p.rev() not in state
255 255 and p.rev() not in targetancestors):
256 256 if external != nullrev:
257 257 raise util.Abort(_('unable to collapse, there is more '
258 258 'than one external parent'))
259 259 external = p.rev()
260 260 return external
261 261
262 262 def updatedirstate(repo, rev, p1, p2):
263 263 """Keep track of renamed files in the revision that is going to be rebased
264 264 """
265 265 # Here we simulate the copies and renames in the source changeset
266 266 cop, diver = copies.copies(repo, repo[rev], repo[p1], repo[p2], True)
267 267 m1 = repo[rev].manifest()
268 268 m2 = repo[p1].manifest()
269 269 for k, v in cop.iteritems():
270 270 if k in m1:
271 271 if v in m1 or v in m2:
272 272 repo.dirstate.copy(v, k)
273 273 if v in m2 and v not in m1:
274 274 repo.dirstate.remove(v)
275 275
276 276 def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
277 277 'Commit the changes and store useful information in extra'
278 278 try:
279 279 repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
280 280 ctx = repo[rev]
281 281 if commitmsg is None:
282 282 commitmsg = ctx.description()
283 283 extra = {'rebase_source': ctx.hex()}
284 284 if extrafn:
285 285 extrafn(ctx, extra)
286 286 # Commit might fail if unresolved files exist
287 287 newrev = repo.commit(text=commitmsg, user=ctx.user(),
288 288 date=ctx.date(), extra=extra)
289 289 repo.dirstate.setbranch(repo[newrev].branch())
290 290 return newrev
291 291 except util.Abort:
292 292 # Invalidate the previous setparents
293 293 repo.dirstate.invalidate()
294 294 raise
295 295
296 296 def rebasenode(repo, rev, p1, p2, state):
297 297 'Rebase a single revision'
298 298 # Merge phase
299 299 # Update to target and merge it with local
300 300 if repo['.'].rev() != repo[p1].rev():
301 301 repo.ui.debug(" update to %d:%s\n" % (repo[p1].rev(), repo[p1]))
302 302 merge.update(repo, p1, False, True, False)
303 303 else:
304 304 repo.ui.debug(" already in target\n")
305 305 repo.dirstate.write()
306 306 repo.ui.debug(" merge against %d:%s\n" % (repo[rev].rev(), repo[rev]))
307 307 first = repo[rev].rev() == repo[min(state)].rev()
308 308 stats = rebasemerge(repo, rev, first)
309 309 return stats
310 310
311 311 def defineparents(repo, rev, target, state, targetancestors):
312 312 'Return the new parent relationship of the revision that will be rebased'
313 313 parents = repo[rev].parents()
314 314 p1 = p2 = nullrev
315 315
316 316 P1n = parents[0].rev()
317 317 if P1n in targetancestors:
318 318 p1 = target
319 319 elif P1n in state:
320 320 if state[P1n] == nullmerge:
321 321 p1 = target
322 322 else:
323 323 p1 = state[P1n]
324 324 else: # P1n external
325 325 p1 = target
326 326 p2 = P1n
327 327
328 328 if len(parents) == 2 and parents[1].rev() not in targetancestors:
329 329 P2n = parents[1].rev()
330 330 # interesting second parent
331 331 if P2n in state:
332 332 if p1 == target: # P1n in targetancestors or external
333 333 p1 = state[P2n]
334 334 else:
335 335 p2 = state[P2n]
336 336 else: # P2n external
337 337 if p2 != nullrev: # P1n external too => rev is a merged revision
338 338 raise util.Abort(_('cannot use revision %d as base, result '
339 339 'would have 3 parents') % rev)
340 340 p2 = P2n
341 341 repo.ui.debug(" future parents are %d and %d\n" %
342 342 (repo[p1].rev(), repo[p2].rev()))
343 343 return p1, p2
344 344
345 345 def isagitpatch(repo, patchname):
346 346 'Return true if the given patch is in git format'
347 347 mqpatch = os.path.join(repo.mq.path, patchname)
348 348 for line in patch.linereader(file(mqpatch, 'rb')):
349 349 if line.startswith('diff --git'):
350 350 return True
351 351 return False
352 352
353 353 def updatemq(repo, state, skipped, **opts):
354 354 'Update rebased mq patches - finalize and then import them'
355 355 mqrebase = {}
356 356 mq = repo.mq
357 357 for p in mq.applied:
358 358 rev = repo[p.node].rev()
359 359 if rev in state:
360 360 repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
361 361 (rev, p.name))
362 362 mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
363 363
364 364 if mqrebase:
365 365 mq.finish(repo, mqrebase.keys())
366 366
367 367 # We must start import from the newest revision
368 368 for rev in sorted(mqrebase, reverse=True):
369 369 if rev not in skipped:
370 370 name, isgit = mqrebase[rev]
371 371 repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
372 372 mq.qimport(repo, (), patchname=name, git=isgit,
373 373 rev=[str(state[rev])])
374 374 mq.save_dirty()
375 375
376 376 def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
377 377 external):
378 378 'Store the current status to allow recovery'
379 379 f = repo.opener("rebasestate", "w")
380 380 f.write(repo[originalwd].hex() + '\n')
381 381 f.write(repo[target].hex() + '\n')
382 382 f.write(repo[external].hex() + '\n')
383 383 f.write('%d\n' % int(collapse))
384 384 f.write('%d\n' % int(keep))
385 385 f.write('%d\n' % int(keepbranches))
386 386 for d, v in state.iteritems():
387 387 oldrev = repo[d].hex()
388 388 newrev = repo[v].hex()
389 389 f.write("%s:%s\n" % (oldrev, newrev))
390 390 f.close()
391 391 repo.ui.debug('rebase status stored\n')
392 392
393 393 def clearstatus(repo):
394 394 'Remove the status files'
395 395 if os.path.exists(repo.join("rebasestate")):
396 396 util.unlink(repo.join("rebasestate"))
397 397
398 398 def restorestatus(repo):
399 399 'Restore a previously stored status'
400 400 try:
401 401 target = None
402 402 collapse = False
403 403 external = nullrev
404 404 state = {}
405 405 f = repo.opener("rebasestate")
406 406 for i, l in enumerate(f.read().splitlines()):
407 407 if i == 0:
408 408 originalwd = repo[l].rev()
409 409 elif i == 1:
410 410 target = repo[l].rev()
411 411 elif i == 2:
412 412 external = repo[l].rev()
413 413 elif i == 3:
414 414 collapse = bool(int(l))
415 415 elif i == 4:
416 416 keep = bool(int(l))
417 417 elif i == 5:
418 418 keepbranches = bool(int(l))
419 419 else:
420 420 oldrev, newrev = l.split(':')
421 421 state[repo[oldrev].rev()] = repo[newrev].rev()
422 422 skipped = set()
423 423 # recompute the set of skipped revs
424 424 if not collapse:
425 425 seen = set([target])
426 426 for old, new in sorted(state.items()):
427 427 if new != nullrev and new in seen:
428 428 skipped.add(old)
429 429 seen.add(new)
430 430 repo.ui.debug('computed skipped revs: %s\n' % skipped)
431 431 repo.ui.debug('rebase status resumed\n')
432 432 return (originalwd, target, state, skipped,
433 433 collapse, keep, keepbranches, external)
434 434 except IOError, err:
435 435 if err.errno != errno.ENOENT:
436 436 raise
437 437 raise util.Abort(_('no rebase in progress'))
438 438
439 439 def abort(repo, originalwd, target, state):
440 440 'Restore the repository to its original state'
441 441 if set(repo.changelog.descendants(target)) - set(state.values()):
442 442 repo.ui.warn(_("warning: new changesets detected on target branch, "
443 443 "can't abort\n"))
444 444 return -1
445 445 else:
446 446 # Strip from the first rebased revision
447 447 merge.update(repo, repo[originalwd].rev(), False, True, False)
448 448 rebased = filter(lambda x: x > -1 and x != target, state.values())
449 449 if rebased:
450 450 strippoint = min(rebased)
451 451 # no backup of rebased cset versions needed
452 452 repair.strip(repo.ui, repo, repo[strippoint].node())
453 453 clearstatus(repo)
454 454 repo.ui.warn(_('rebase aborted\n'))
455 455 return 0
456 456
457 457 def buildstate(repo, dest, src, base, detach):
458 458 'Define which revisions are going to be rebased and where'
459 459 targetancestors = set()
460 460 detachset = set()
461 461
462 462 if not dest:
463 463 # Destination defaults to the latest revision in the current branch
464 464 branch = repo[None].branch()
465 465 dest = repo[branch].rev()
466 466 else:
467 467 dest = repo[dest].rev()
468 468
469 469 # This check isn't strictly necessary, since mq detects commits over an
470 470 # applied patch. But it prevents messing up the working directory when
471 471 # a partially completed rebase is blocked by mq.
472 472 if 'qtip' in repo.tags() and (repo[dest].node() in
473 473 [s.node for s in repo.mq.applied]):
474 474 raise util.Abort(_('cannot rebase onto an applied mq patch'))
475 475
476 476 if src:
477 477 commonbase = repo[src].ancestor(repo[dest])
478 478 if commonbase == repo[src]:
479 479 raise util.Abort(_('source is ancestor of destination'))
480 480 if commonbase == repo[dest]:
481 481 raise util.Abort(_('source is descendant of destination'))
482 482 source = repo[src].rev()
483 483 if detach:
484 484 # We need to keep track of source's ancestors up to the common base
485 485 srcancestors = set(repo.changelog.ancestors(source))
486 486 baseancestors = set(repo.changelog.ancestors(commonbase.rev()))
487 487 detachset = srcancestors - baseancestors
488 488 detachset.remove(commonbase.rev())
489 489 else:
490 490 if base:
491 491 cwd = repo[base].rev()
492 492 else:
493 493 cwd = repo['.'].rev()
494 494
495 495 if cwd == dest:
496 496 repo.ui.debug('source and destination are the same\n')
497 497 return None
498 498
499 499 targetancestors = set(repo.changelog.ancestors(dest))
500 500 if cwd in targetancestors:
501 501 repo.ui.debug('source is ancestor of destination\n')
502 502 return None
503 503
504 504 cwdancestors = set(repo.changelog.ancestors(cwd))
505 505 if dest in cwdancestors:
506 506 repo.ui.debug('source is descendant of destination\n')
507 507 return None
508 508
509 509 cwdancestors.add(cwd)
510 510 rebasingbranch = cwdancestors - targetancestors
511 511 source = min(rebasingbranch)
512 512
513 513 repo.ui.debug('rebase onto %d starting from %d\n' % (dest, source))
514 514 state = dict.fromkeys(repo.changelog.descendants(source), nullrev)
515 515 state.update(dict.fromkeys(detachset, nullmerge))
516 516 state[source] = nullrev
517 517 return repo['.'].rev(), repo[dest].rev(), state
518 518
519 519 def pullrebase(orig, ui, repo, *args, **opts):
520 520 'Call rebase after pull if the latter has been invoked with --rebase'
521 521 if opts.get('rebase'):
522 522 if opts.get('update'):
523 523 del opts['update']
524 524 ui.debug('--update and --rebase are not compatible, ignoring '
525 525 'the update flag\n')
526 526
527 527 cmdutil.bail_if_changed(repo)
528 528 revsprepull = len(repo)
529 529 origpostincoming = commands.postincoming
530 530 def _dummy(*args, **kwargs):
531 531 pass
532 532 commands.postincoming = _dummy
533 533 try:
534 534 orig(ui, repo, *args, **opts)
535 535 finally:
536 536 commands.postincoming = origpostincoming
537 537 revspostpull = len(repo)
538 538 if revspostpull > revsprepull:
539 539 rebase(ui, repo, **opts)
540 540 branch = repo[None].branch()
541 541 dest = repo[branch].rev()
542 542 if dest != repo['.'].rev():
543 543 # there was nothing to rebase we force an update
544 544 hg.update(repo, dest)
545 545 else:
546 546 orig(ui, repo, *args, **opts)
547 547
548 548 def uisetup(ui):
549 549 'Replace pull with a decorator to provide --rebase option'
550 550 entry = extensions.wrapcommand(commands.table, 'pull', pullrebase)
551 551 entry[1].append(('', 'rebase', None,
552 552 _("rebase working directory to branch head"))
553 553 )
554 554
555 555 cmdtable = {
556 556 "rebase":
557 557 (rebase,
558 558 [
559 559 ('s', 'source', '',
560 560 _('rebase from the specified changeset'), _('REV')),
561 561 ('b', 'base', '',
562 562 _('rebase from the base of the specified changeset '
563 563 '(up to greatest common ancestor of base and dest)'),
564 564 _('REV')),
565 565 ('d', 'dest', '',
566 566 _('rebase onto the specified changeset'), _('REV')),
567 567 ('', 'collapse', False, _('collapse the rebased changesets')),
568 568 ('', 'keep', False, _('keep original changesets')),
569 569 ('', 'keepbranches', False, _('keep original branch names')),
570 570 ('', 'detach', False, _('force detaching of source from its original '
571 571 'branch')),
572 572 ('c', 'continue', False, _('continue an interrupted rebase')),
573 573 ('a', 'abort', False, _('abort an interrupted rebase'))] +
574 574 templateopts,
575 575 _('hg rebase [-s REV | -b REV] [-d REV] [options]\n'
576 576 'hg rebase {-a|-c}'))
577 577 }
@@ -1,148 +1,148 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [alias]
7 7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 8 > EOF
9 9
10 10
11 11 $ hg init a
12 12 $ cd a
13 13
14 14 $ echo c1 > common
15 15 $ hg add common
16 16 $ hg ci -m C1
17 17
18 18 $ echo c2 >> common
19 19 $ hg ci -m C2
20 20
21 21 $ echo c3 >> common
22 22 $ hg ci -m C3
23 23
24 24 $ hg up -q -C 1
25 25
26 26 $ echo l1 >> extra
27 27 $ hg add extra
28 28 $ hg ci -m L1
29 29 created new head
30 30
31 31 $ sed -e 's/c2/l2/' common > common.new
32 32 $ mv common.new common
33 33 $ hg ci -m L2
34 34
35 35 $ hg tglog
36 36 @ 4: 'L2'
37 37 |
38 38 o 3: 'L1'
39 39 |
40 40 | o 2: 'C3'
41 41 |/
42 42 o 1: 'C2'
43 43 |
44 44 o 0: 'C1'
45 45
46 46
47 47 Conflicting rebase:
48 48
49 49 $ hg rebase -s 3 -d 2
50 50 merging common
51 51 warning: conflicts during merge.
52 52 merging common failed!
53 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
53 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
54 54 [255]
55 55
56 56 Abort:
57 57
58 58 $ hg rebase --abort
59 59 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
60 60 rebase aborted
61 61
62 62 $ hg tglog
63 63 @ 4: 'L2'
64 64 |
65 65 o 3: 'L1'
66 66 |
67 67 | o 2: 'C3'
68 68 |/
69 69 o 1: 'C2'
70 70 |
71 71 o 0: 'C1'
72 72
73 73 $ cd ..
74 74
75 75
76 76 Constrcut new repo:
77 77
78 78 $ hg init b
79 79 $ cd b
80 80
81 81 $ echo a > a
82 82 $ hg ci -Am A
83 83 adding a
84 84
85 85 $ echo b > b
86 86 $ hg ci -Am B
87 87 adding b
88 88
89 89 $ echo c > c
90 90 $ hg ci -Am C
91 91 adding c
92 92
93 93 $ hg up -q 0
94 94
95 95 $ echo b > b
96 96 $ hg ci -Am 'B bis'
97 97 adding b
98 98 created new head
99 99
100 100 $ echo c1 > c
101 101 $ hg ci -Am C1
102 102 adding c
103 103
104 104 Rebase and abort without generating new changesets:
105 105
106 106 $ hg tglog
107 107 @ 4: 'C1'
108 108 |
109 109 o 3: 'B bis'
110 110 |
111 111 | o 2: 'C'
112 112 | |
113 113 | o 1: 'B'
114 114 |/
115 115 o 0: 'A'
116 116
117 117 $ hg rebase -b 4 -d 2
118 118 merging c
119 119 warning: conflicts during merge.
120 120 merging c failed!
121 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
121 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
122 122 [255]
123 123
124 124 $ hg tglog
125 125 @ 4: 'C1'
126 126 |
127 127 o 3: 'B bis'
128 128 |
129 129 | @ 2: 'C'
130 130 | |
131 131 | o 1: 'B'
132 132 |/
133 133 o 0: 'A'
134 134
135 135 $ hg rebase -a
136 136 rebase aborted
137 137
138 138 $ hg tglog
139 139 @ 4: 'C1'
140 140 |
141 141 o 3: 'B bis'
142 142 |
143 143 | o 2: 'C'
144 144 | |
145 145 | o 1: 'B'
146 146 |/
147 147 o 0: 'A'
148 148
@@ -1,142 +1,142 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [alias]
7 7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 8 > EOF
9 9
10 10
11 11 $ hg init a
12 12 $ cd a
13 13
14 14 $ echo A > A
15 15 $ hg add A
16 16 $ hg ci -m A
17 17
18 18 $ echo 'B' > B
19 19 $ hg add B
20 20 $ hg ci -m B
21 21
22 22 $ echo C >> A
23 23 $ hg ci -m C
24 24
25 25 $ hg up -q -C 0
26 26
27 27 $ echo D >> A
28 28 $ hg ci -m D
29 29 created new head
30 30
31 31 $ echo E > E
32 32 $ hg add E
33 33 $ hg ci -m E
34 34
35 35 $ hg up -q -C 0
36 36
37 37 $ hg branch 'notdefault'
38 38 marked working directory as branch notdefault
39 39 $ echo F >> A
40 40 $ hg ci -m F
41 41
42 42 $ cd ..
43 43
44 44
45 45 Rebasing B onto E - check keep:
46 46
47 47 $ hg clone -q -u . a a1
48 48 $ cd a1
49 49
50 50 $ hg tglog
51 51 @ 5: 'F' notdefault
52 52 |
53 53 | o 4: 'E'
54 54 | |
55 55 | o 3: 'D'
56 56 |/
57 57 | o 2: 'C'
58 58 | |
59 59 | o 1: 'B'
60 60 |/
61 61 o 0: 'A'
62 62
63 63 $ hg rebase -s 1 -d 4 --keep
64 64 merging A
65 65 warning: conflicts during merge.
66 66 merging A failed!
67 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
67 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
68 68 [255]
69 69
70 70 Solve the conflict and go on:
71 71
72 72 $ echo 'conflict solved' > A
73 73 $ rm A.orig
74 74 $ hg resolve -m A
75 75 $ hg rebase --continue
76 76
77 77 $ hg tglog
78 78 @ 7: 'C'
79 79 |
80 80 o 6: 'B'
81 81 |
82 82 | o 5: 'F' notdefault
83 83 | |
84 84 o | 4: 'E'
85 85 | |
86 86 o | 3: 'D'
87 87 |/
88 88 | o 2: 'C'
89 89 | |
90 90 | o 1: 'B'
91 91 |/
92 92 o 0: 'A'
93 93
94 94 $ cd ..
95 95
96 96
97 97 Rebase F onto E - check keepbranches:
98 98
99 99 $ hg clone -q -u . a a2
100 100 $ cd a2
101 101
102 102 $ hg tglog
103 103 @ 5: 'F' notdefault
104 104 |
105 105 | o 4: 'E'
106 106 | |
107 107 | o 3: 'D'
108 108 |/
109 109 | o 2: 'C'
110 110 | |
111 111 | o 1: 'B'
112 112 |/
113 113 o 0: 'A'
114 114
115 115 $ hg rebase -s 5 -d 4 --keepbranches
116 116 merging A
117 117 warning: conflicts during merge.
118 118 merging A failed!
119 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
119 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
120 120 [255]
121 121
122 122 Solve the conflict and go on:
123 123
124 124 $ echo 'conflict solved' > A
125 125 $ rm A.orig
126 126 $ hg resolve -m A
127 127 $ hg rebase --continue
128 128 saved backup bundle to $TESTTMP/a2/.hg/strip-backup/*-backup.hg (glob)
129 129
130 130 $ hg tglog
131 131 @ 5: 'F' notdefault
132 132 |
133 133 o 4: 'E'
134 134 |
135 135 o 3: 'D'
136 136 |
137 137 | o 2: 'C'
138 138 | |
139 139 | o 1: 'B'
140 140 |/
141 141 o 0: 'A'
142 142
@@ -1,115 +1,115 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [alias]
7 7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 8 > EOF
9 9
10 10 $ hg init a
11 11 $ cd a
12 12 $ echo c1 >common
13 13 $ hg add common
14 14 $ hg ci -m C1
15 15
16 16 $ echo c2 >>common
17 17 $ hg ci -m C2
18 18
19 19 $ echo c3 >>common
20 20 $ hg ci -m C3
21 21
22 22 $ hg up -q -C 1
23 23
24 24 $ echo l1 >>extra
25 25 $ hg add extra
26 26 $ hg ci -m L1
27 27 created new head
28 28
29 29 $ sed -e 's/c2/l2/' common > common.new
30 30 $ mv common.new common
31 31 $ hg ci -m L2
32 32
33 33 $ echo l3 >> extra2
34 34 $ hg add extra2
35 35 $ hg ci -m L3
36 36
37 37 $ hg tglog
38 38 @ 5: 'L3'
39 39 |
40 40 o 4: 'L2'
41 41 |
42 42 o 3: 'L1'
43 43 |
44 44 | o 2: 'C3'
45 45 |/
46 46 o 1: 'C2'
47 47 |
48 48 o 0: 'C1'
49 49
50 50 Try to call --continue:
51 51
52 52 $ hg rebase --continue
53 53 abort: no rebase in progress
54 54 [255]
55 55
56 56 Conflicting rebase:
57 57
58 58 $ hg rebase -s 3 -d 2
59 59 merging common
60 60 warning: conflicts during merge.
61 61 merging common failed!
62 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
62 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
63 63 [255]
64 64
65 65 Try to continue without solving the conflict:
66 66
67 67 $ hg rebase --continue
68 68 abort: unresolved merge conflicts (see hg resolve)
69 69 [255]
70 70
71 71 Conclude rebase:
72 72
73 73 $ echo 'resolved merge' >common
74 74 $ hg resolve -m common
75 75 $ hg rebase --continue
76 76 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
77 77
78 78 $ hg tglog
79 79 @ 5: 'L3'
80 80 |
81 81 o 4: 'L2'
82 82 |
83 83 o 3: 'L1'
84 84 |
85 85 o 2: 'C3'
86 86 |
87 87 o 1: 'C2'
88 88 |
89 89 o 0: 'C1'
90 90
91 91 Check correctness:
92 92
93 93 $ hg cat -r 0 common
94 94 c1
95 95
96 96 $ hg cat -r 1 common
97 97 c1
98 98 c2
99 99
100 100 $ hg cat -r 2 common
101 101 c1
102 102 c2
103 103 c3
104 104
105 105 $ hg cat -r 3 common
106 106 c1
107 107 c2
108 108 c3
109 109
110 110 $ hg cat -r 4 common
111 111 resolved merge
112 112
113 113 $ hg cat -r 5 common
114 114 resolved merge
115 115
@@ -1,194 +1,194 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [extensions]
3 3 > graphlog=
4 4 > rebase=
5 5 >
6 6 > [alias]
7 7 > tglog = log -G --template "{rev}: '{desc}' {branches}\n"
8 8 > EOF
9 9
10 10
11 11 $ hg init a
12 12 $ cd a
13 13
14 14 $ echo A > A
15 15 $ hg ci -Am A
16 16 adding A
17 17
18 18 $ echo B > B
19 19 $ hg ci -Am B
20 20 adding B
21 21
22 22 $ echo C >> A
23 23 $ hg ci -m C
24 24
25 25 $ hg up -q -C 0
26 26
27 27 $ echo D >> A
28 28 $ hg ci -m D
29 29 created new head
30 30
31 31 $ echo E > E
32 32 $ hg ci -Am E
33 33 adding E
34 34
35 35 $ cd ..
36 36
37 37
38 38 Changes during an interruption - continue:
39 39
40 40 $ hg clone -q -u . a a1
41 41 $ cd a1
42 42
43 43 $ hg tglog
44 44 @ 4: 'E'
45 45 |
46 46 o 3: 'D'
47 47 |
48 48 | o 2: 'C'
49 49 | |
50 50 | o 1: 'B'
51 51 |/
52 52 o 0: 'A'
53 53
54 54 Rebasing B onto E:
55 55
56 56 $ hg rebase -s 1 -d 4
57 57 merging A
58 58 warning: conflicts during merge.
59 59 merging A failed!
60 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
60 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
61 61 [255]
62 62
63 63 Force a commit on C during the interruption:
64 64
65 65 $ hg up -q -C 2
66 66
67 67 $ echo 'Extra' > Extra
68 68 $ hg add Extra
69 69 $ hg ci -m 'Extra'
70 70
71 71 $ hg tglog
72 72 @ 6: 'Extra'
73 73 |
74 74 | o 5: 'B'
75 75 | |
76 76 | o 4: 'E'
77 77 | |
78 78 | o 3: 'D'
79 79 | |
80 80 o | 2: 'C'
81 81 | |
82 82 o | 1: 'B'
83 83 |/
84 84 o 0: 'A'
85 85
86 86 Resume the rebasing:
87 87
88 88 $ hg rebase --continue
89 89 merging A
90 90 warning: conflicts during merge.
91 91 merging A failed!
92 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
92 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
93 93 [255]
94 94
95 95 Solve the conflict and go on:
96 96
97 97 $ echo 'conflict solved' > A
98 98 $ rm A.orig
99 99 $ hg resolve -m A
100 100
101 101 $ hg rebase --continue
102 102 warning: new changesets detected on source branch, not stripping
103 103
104 104 $ hg tglog
105 105 @ 7: 'C'
106 106 |
107 107 | o 6: 'Extra'
108 108 | |
109 109 o | 5: 'B'
110 110 | |
111 111 o | 4: 'E'
112 112 | |
113 113 o | 3: 'D'
114 114 | |
115 115 | o 2: 'C'
116 116 | |
117 117 | o 1: 'B'
118 118 |/
119 119 o 0: 'A'
120 120
121 121 $ cd ..
122 122
123 123
124 124 Changes during an interruption - abort:
125 125
126 126 $ hg clone -q -u . a a2
127 127 $ cd a2
128 128
129 129 $ hg tglog
130 130 @ 4: 'E'
131 131 |
132 132 o 3: 'D'
133 133 |
134 134 | o 2: 'C'
135 135 | |
136 136 | o 1: 'B'
137 137 |/
138 138 o 0: 'A'
139 139
140 140 Rebasing B onto E:
141 141
142 142 $ hg rebase -s 1 -d 4
143 143 merging A
144 144 warning: conflicts during merge.
145 145 merging A failed!
146 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
146 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
147 147 [255]
148 148
149 149 Force a commit on B' during the interruption:
150 150
151 151 $ hg up -q -C 5
152 152
153 153 $ echo 'Extra' > Extra
154 154 $ hg add Extra
155 155 $ hg ci -m 'Extra'
156 156
157 157 $ hg tglog
158 158 @ 6: 'Extra'
159 159 |
160 160 o 5: 'B'
161 161 |
162 162 o 4: 'E'
163 163 |
164 164 o 3: 'D'
165 165 |
166 166 | o 2: 'C'
167 167 | |
168 168 | o 1: 'B'
169 169 |/
170 170 o 0: 'A'
171 171
172 172 Abort the rebasing:
173 173
174 174 $ hg rebase --abort
175 175 warning: new changesets detected on target branch, can't abort
176 176 [255]
177 177
178 178 $ hg tglog
179 179 @ 6: 'Extra'
180 180 |
181 181 o 5: 'B'
182 182 |
183 183 o 4: 'E'
184 184 |
185 185 o 3: 'D'
186 186 |
187 187 | o 2: 'C'
188 188 | |
189 189 | o 1: 'B'
190 190 |/
191 191 o 0: 'A'
192 192
193 193 $ cd ..
194 194
@@ -1,136 +1,136 b''
1 1 This emulates the effects of an hg pull --rebase in which the remote repo
2 2 already has one local mq patch
3 3
4 4 $ cat >> $HGRCPATH <<EOF
5 5 > [extensions]
6 6 > graphlog=
7 7 > rebase=
8 8 > mq=
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 > c1
20 20 $ hg add c1
21 21 $ hg ci -m C1
22 22
23 23 $ echo r1 > r1
24 24 $ hg add r1
25 25 $ hg ci -m R1
26 26
27 27 $ hg up -q 0
28 28
29 29 $ hg qnew p0.patch
30 30 $ echo p0 > p0
31 31 $ hg add p0
32 32 $ hg qref -m P0
33 33
34 34 $ hg qnew p1.patch
35 35 $ echo p1 > p1
36 36 $ hg add p1
37 37 $ hg qref -m P1
38 38
39 39 $ hg export qtip > p1.patch
40 40
41 41 $ hg up -q -C 1
42 42
43 43 $ hg import p1.patch
44 44 applying p1.patch
45 45
46 46 $ rm p1.patch
47 47
48 48 $ hg up -q -C qtip
49 49
50 50 $ hg rebase
51 51 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
52 52
53 53 $ hg tglog
54 54 @ 3: 'P0' tags: p0.patch qbase qtip tip
55 55 |
56 56 o 2: 'P1' tags: qparent
57 57 |
58 58 o 1: 'R1' tags:
59 59 |
60 60 o 0: 'C1' tags:
61 61
62 62 $ cd ..
63 63
64 64
65 65 $ hg init b
66 66 $ cd b
67 67 $ hg qinit -c
68 68
69 69 $ for i in r0 r1 r2 r3 r4 r5 r6;
70 70 > do
71 71 > echo $i > $i
72 72 > hg ci -Am $i
73 73 > done
74 74 adding r0
75 75 adding r1
76 76 adding r2
77 77 adding r3
78 78 adding r4
79 79 adding r5
80 80 adding r6
81 81
82 82 $ hg qimport -r 1:tip
83 83
84 84 $ hg up -q 0
85 85
86 86 $ for i in r1 r3 r7 r8;
87 87 > do
88 88 > echo $i > $i
89 89 > hg ci -Am branch2-$i
90 90 > done
91 91 adding r1
92 92 created new head
93 93 adding r3
94 94 adding r7
95 95 adding r8
96 96
97 97 $ echo somethingelse > r4
98 98 $ hg ci -Am branch2-r4
99 99 adding r4
100 100
101 101 $ echo r6 > r6
102 102 $ hg ci -Am branch2-r6
103 103 adding r6
104 104
105 105 $ hg up -q qtip
106 106
107 107 $ HGMERGE=internal:fail hg rebase
108 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
108 abort: unresolved conflicts (see hg resolve, then hg rebase --continue)
109 109 [255]
110 110
111 111 $ HGMERGE=internal:local hg resolve --all
112 112
113 113 $ hg rebase --continue
114 114 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
115 115
116 116 $ hg tglog
117 117 @ 9: 'r5' tags: 5.diff qtip tip
118 118 |
119 119 o 8: 'r4' tags: 4.diff
120 120 |
121 121 o 7: 'r2' tags: 2.diff qbase
122 122 |
123 123 o 6: 'branch2-r6' tags: qparent
124 124 |
125 125 o 5: 'branch2-r4' tags:
126 126 |
127 127 o 4: 'branch2-r8' tags:
128 128 |
129 129 o 3: 'branch2-r7' tags:
130 130 |
131 131 o 2: 'branch2-r3' tags:
132 132 |
133 133 o 1: 'branch2-r1' tags:
134 134 |
135 135 o 0: 'r0' tags:
136 136
@@ -1,237 +1,237 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 failed!
66 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
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 failed!
77 abort: fix unresolved conflicts with hg resolve then run hg rebase --continue
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 105 # Node ID ???????????????????????????????????????? (glob)
106 106 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
107 107 P0
108 108
109 109 diff -r bac9ed9960d8 -r ???????????? f (glob)
110 110 --- a/f Thu Jan 01 00:00:00 1970 +0000
111 111 +++ b/f ??? ??? ?? ??:??:?? ???? ????? (glob)
112 112 @@ -1,1 +1,1 @@
113 113 -r1
114 114 +mq1r1
115 115
116 116 Update to qtip:
117 117
118 118 $ hg up -q qtip
119 119
120 120 $ cat f
121 121 mq1r1mq2
122 122
123 123 $ cat .hg/patches/f2.patch
124 124 # HG changeset patch
125 125 # User test
126 126 # Date ?????????? ? (glob)
127 127 # Node ID ???????????????????????????????????????? (glob)
128 128 # Parent ???????????????????????????????????????? (glob)
129 129 P1
130 130
131 131 diff -r ???????????? -r ???????????? f (glob)
132 132 --- a/f ??? ??? ?? ??:??:?? ???? ????? (glob)
133 133 +++ b/f ??? ??? ?? ??:??:?? ???? ????? (glob)
134 134 @@ -1,1 +1,1 @@
135 135 -mq1r1
136 136 +mq1r1mq2
137 137
138 138 Adding one git-style patch and one normal:
139 139
140 140 $ hg qpop -a
141 141 popping f2.patch
142 142 popping f.patch
143 143 patch queue now empty
144 144
145 145 $ rm -fr .hg/patches
146 146 $ hg qinit -c
147 147
148 148 $ hg up -q 0
149 149
150 150 $ hg qnew --git f_git.patch
151 151 $ echo mq1 > p
152 152 $ hg add p
153 153 $ hg qref --git -m 'P0 (git)'
154 154
155 155 $ hg qnew f.patch
156 156 $ echo mq2 > p
157 157 $ hg qref -m P1
158 158 $ hg qci -m 'save patch state'
159 159
160 160 $ hg qseries -s
161 161 f_git.patch: P0 (git)
162 162 f.patch: P1
163 163
164 164 $ hg -R .hg/patches manifest
165 165 .hgignore
166 166 f.patch
167 167 f_git.patch
168 168 series
169 169
170 170 $ cat .hg/patches/f_git.patch
171 171 P0 (git)
172 172
173 173 diff --git a/p b/p
174 174 new file mode 100644
175 175 --- /dev/null
176 176 +++ b/p
177 177 @@ -0,0 +1,1 @@
178 178 +mq1
179 179
180 180 $ cat .hg/patches/f.patch
181 181 P1
182 182
183 183 diff -r ???????????? p (glob)
184 184 --- a/p ??? ??? ?? ??:??:?? ???? ????? (glob)
185 185 +++ b/p ??? ??? ?? ??:??:?? ???? ????? (glob)
186 186 @@ -1,1 +1,1 @@
187 187 -mq1
188 188 +mq2
189 189
190 190
191 191 Rebase the applied mq patches:
192 192
193 193 $ hg rebase -s 2 -d 1
194 194 saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob)
195 195
196 196 $ hg qci -m 'save patch state'
197 197
198 198 $ hg qseries -s
199 199 f_git.patch: P0 (git)
200 200 f.patch: P1
201 201
202 202 $ hg -R .hg/patches manifest
203 203 .hgignore
204 204 f.patch
205 205 f_git.patch
206 206 series
207 207
208 208 $ cat .hg/patches/f_git.patch
209 209 # HG changeset patch
210 210 # User test
211 211 # Date ?????????? ? (glob)
212 212 # Node ID ???????????????????????????????????????? (glob)
213 213 # Parent bac9ed9960d8992bcad75864a879fa76cadaf1b0
214 214 P0 (git)
215 215
216 216 diff --git a/p b/p
217 217 new file mode 100644
218 218 --- /dev/null
219 219 +++ b/p
220 220 @@ -0,0 +1,1 @@
221 221 +mq1
222 222
223 223 $ cat .hg/patches/f.patch
224 224 # HG changeset patch
225 225 # User test
226 226 # Date ?????????? ? (glob)
227 227 # Node ID ???????????????????????????????????????? (glob)
228 228 # Parent ???????????????????????????????????????? (glob)
229 229 P1
230 230
231 231 diff -r ???????????? -r ???????????? p (glob)
232 232 --- a/p ??? ??? ?? ??:??:?? ???? ????? (glob)
233 233 +++ b/p ??? ??? ?? ??:??:?? ???? ????? (glob)
234 234 @@ -1,1 +1,1 @@
235 235 -mq1
236 236 +mq2
237 237
General Comments 0
You need to be logged in to leave comments. Login now