Show More
@@ -2449,14 +2449,15 b' def forget(ui, repo, *pats, **opts):' | |||||
2449 |
|
2449 | |||
2450 | @command( |
|
2450 | @command( | |
2451 | 'graft', |
|
2451 | 'graft', | |
2452 | [('e', 'edit', False, _('invoke editor on commit messages')), |
|
2452 | [('c', 'continue', False, _('resume interrupted graft')), | |
2453 | ('D', 'currentdate', False, |
|
2453 | ('e', 'edit', False, _('invoke editor on commit messages')), | |
2454 | _('record the current date as commit date')), |
|
2454 | ('D', 'currentdate', False, | |
2455 | ('U', 'currentuser', False, |
|
2455 | _('record the current date as commit date')), | |
2456 | _('record the current user as committer'), _('DATE'))] |
|
2456 | ('U', 'currentuser', False, | |
|
2457 | _('record the current user as committer'), _('DATE'))] | |||
2457 | + commitopts2 + mergetoolopts, |
|
2458 | + commitopts2 + mergetoolopts, | |
2458 | _('[OPTION]... REVISION...')) |
|
2459 | _('[OPTION]... REVISION...')) | |
2459 |
def graft(ui, repo |
|
2460 | def graft(ui, repo, *revs, **opts): | |
2460 | '''copy changes from other branches onto the current branch |
|
2461 | '''copy changes from other branches onto the current branch | |
2461 |
|
2462 | |||
2462 | This command uses Mercurial's merge logic to copy individual |
|
2463 | This command uses Mercurial's merge logic to copy individual | |
@@ -2467,11 +2468,17 b' def graft(ui, repo, rev, *revs, **opts):' | |||||
2467 | Changesets that are ancestors of the current revision, that have |
|
2468 | Changesets that are ancestors of the current revision, that have | |
2468 | already been grafted, or that are merges will be skipped. |
|
2469 | already been grafted, or that are merges will be skipped. | |
2469 |
|
2470 | |||
|
2471 | If a graft merge results in conflicts, the graft process is | |||
|
2472 | aborted so that the current merge can be manually resolved. Once | |||
|
2473 | all conflicts are addressed, the graft process can be continued | |||
|
2474 | with the -c/--continue option. | |||
|
2475 | ||||
|
2476 | .. note:: | |||
|
2477 | The -c/--continue option does not reapply earlier options. | |||
|
2478 | ||||
2470 | Returns 0 on successful completion. |
|
2479 | Returns 0 on successful completion. | |
2471 | ''' |
|
2480 | ''' | |
2472 |
|
2481 | |||
2473 | cmdutil.bailifchanged(repo) |
|
|||
2474 |
|
||||
2475 | if not opts.get('user') and opts.get('currentuser'): |
|
2482 | if not opts.get('user') and opts.get('currentuser'): | |
2476 | opts['user'] = ui.username() |
|
2483 | opts['user'] = ui.username() | |
2477 | if not opts.get('date') and opts.get('currentdate'): |
|
2484 | if not opts.get('date') and opts.get('currentdate'): | |
@@ -2481,8 +2488,24 b' def graft(ui, repo, rev, *revs, **opts):' | |||||
2481 | if opts.get('edit'): |
|
2488 | if opts.get('edit'): | |
2482 | editor = cmdutil.commitforceeditor |
|
2489 | editor = cmdutil.commitforceeditor | |
2483 |
|
2490 | |||
2484 | revs = [rev] + list(revs) |
|
2491 | cont = False | |
2485 | revs = scmutil.revrange(repo, revs) |
|
2492 | if opts['continue']: | |
|
2493 | cont = True | |||
|
2494 | if revs: | |||
|
2495 | raise util.Abort(_("can't specify --continue and revisions")) | |||
|
2496 | # read in unfinished revisions | |||
|
2497 | try: | |||
|
2498 | nodes = repo.opener.read('graftstate').splitlines() | |||
|
2499 | revs = [repo[node].rev() for node in nodes] | |||
|
2500 | except IOError, inst: | |||
|
2501 | if inst.errno != errno.ENOENT: | |||
|
2502 | raise | |||
|
2503 | raise util.Abort(_("no graft state found, can't continue")) | |||
|
2504 | else: | |||
|
2505 | cmdutil.bailifchanged(repo) | |||
|
2506 | if not revs: | |||
|
2507 | raise util.Abort(_('no revisions specified')) | |||
|
2508 | revs = scmutil.revrange(repo, revs) | |||
2486 |
|
2509 | |||
2487 | # check for merges |
|
2510 | # check for merges | |
2488 | for ctx in repo.set('%ld and merge()', revs): |
|
2511 | for ctx in repo.set('%ld and merge()', revs): | |
@@ -2509,26 +2532,36 b' def graft(ui, repo, rev, *revs, **opts):' | |||||
2509 | if not revs: |
|
2532 | if not revs: | |
2510 | return -1 |
|
2533 | return -1 | |
2511 |
|
2534 | |||
2512 | for ctx in repo.set("%ld", revs): |
|
2535 | for pos, ctx in enumerate(repo.set("%ld", revs)): | |
2513 | current = repo['.'] |
|
2536 | current = repo['.'] | |
2514 | ui.debug('grafting revision %s', ctx.rev()) |
|
2537 | ui.debug('grafting revision %s', ctx.rev()) | |
2515 | # perform the graft merge with p1(rev) as 'ancestor' |
|
2538 | ||
2516 | try: |
|
2539 | # we don't merge the first commit when continuing | |
2517 | # ui.forcemerge is an internal variable, do not document |
|
2540 | if not cont: | |
2518 | repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) |
|
2541 | # perform the graft merge with p1(rev) as 'ancestor' | |
2519 | stats = mergemod.update(repo, ctx.node(), True, True, False, |
|
2542 | try: | |
2520 | ctx.p1().node()) |
|
2543 | # ui.forcemerge is an internal variable, do not document | |
2521 | finally: |
|
2544 | repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) | |
2522 | ui.setconfig('ui', 'forcemerge', '') |
|
2545 | stats = mergemod.update(repo, ctx.node(), True, True, False, | |
2523 | # drop the second merge parent |
|
2546 | ctx.p1().node()) | |
2524 | repo.dirstate.setparents(current.node(), nullid) |
|
2547 | finally: | |
2525 | repo.dirstate.write() |
|
2548 | ui.setconfig('ui', 'forcemerge', '') | |
2526 | # fix up dirstate for copies and renames |
|
2549 | # drop the second merge parent | |
2527 |
|
|
2550 | repo.dirstate.setparents(current.node(), nullid) | |
2528 | # report any conflicts |
|
2551 | repo.dirstate.write() | |
2529 | if stats and stats[3] > 0: |
|
2552 | # fix up dirstate for copies and renames | |
2530 | raise util.Abort(_("unresolved conflicts, can't continue"), |
|
2553 | cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid) | |
2531 | hint=_('use hg resolve and hg graft --continue')) |
|
2554 | # report any conflicts | |
|
2555 | if stats and stats[3] > 0: | |||
|
2556 | # write out state for --continue | |||
|
2557 | nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]] | |||
|
2558 | repo.opener.write('graftstate', ''.join(nodelines)) | |||
|
2559 | raise util.Abort( | |||
|
2560 | _("unresolved conflicts, can't continue"), | |||
|
2561 | hint=_('use hg resolve and hg graft --continue')) | |||
|
2562 | else: | |||
|
2563 | cont = False | |||
|
2564 | ||||
2532 | # commit |
|
2565 | # commit | |
2533 | extra = {'source': ctx.hex()} |
|
2566 | extra = {'source': ctx.hex()} | |
2534 | user = ctx.user() |
|
2567 | user = ctx.user() | |
@@ -2540,6 +2573,10 b' def graft(ui, repo, rev, *revs, **opts):' | |||||
2540 | repo.commit(text=ctx.description(), user=user, |
|
2573 | repo.commit(text=ctx.description(), user=user, | |
2541 | date=date, extra=extra, editor=editor) |
|
2574 | date=date, extra=extra, editor=editor) | |
2542 |
|
2575 | |||
|
2576 | # remove state when we complete successfully | |||
|
2577 | if os.path.exists(repo.join('graftstate')): | |||
|
2578 | util.unlinkpath(repo.join('graftstate')) | |||
|
2579 | ||||
2543 | return 0 |
|
2580 | return 0 | |
2544 |
|
2581 | |||
2545 | @command('grep', |
|
2582 | @command('grep', |
@@ -243,7 +243,7 b' Show all commands + options' | |||||
243 | debugsub: rev |
|
243 | debugsub: rev | |
244 | debugwalk: include, exclude |
|
244 | debugwalk: include, exclude | |
245 | debugwireargs: three, four, five, ssh, remotecmd, insecure |
|
245 | debugwireargs: three, four, five, ssh, remotecmd, insecure | |
246 | graft: edit, currentdate, currentuser, date, user, tool |
|
246 | graft: continue, edit, currentdate, currentuser, date, user, tool | |
247 | grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude |
|
247 | grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude | |
248 | heads: rev, topo, active, closed, style, template |
|
248 | heads: rev, topo, active, closed, style, template | |
249 | help: extension, command |
|
249 | help: extension, command |
General Comments 0
You need to be logged in to leave comments.
Login now