Details
Details
- Reviewers
 pulkit - Group Reviewers
 hg-reviewers - Commits
 - rHGfc8e29ffc380: dog-raft: work with str-keyed opts throughout
 
Diff Detail
Diff Detail
- Repository
 - rHG Mercurial
 - Branch
 - default
 - Lint
 No Linters Available - Unit
 No Unit Test Coverage 
| pulkit | 
| hg-reviewers | 
| No Linters Available | 
| No Unit Test Coverage | 
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/commands.py (95 lines) | 
| Commit | Parents | Author | Summary | Date | 
|---|---|---|---|---|
| 39eb1c1d2f38 | 22cc135fd71a | Martin von Zweigbergk | Jun 10 2021, 6:56 PM | 
| Status | Author | Revision | |
|---|---|---|---|
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz | 
| revs = list(revs) | revs = list(revs) | ||||
| revs.extend(opts.get('rev')) | revs.extend(opts.get('rev')) | ||||
| # a dict of data to be stored in state file | # a dict of data to be stored in state file | ||||
| statedata = {} | statedata = {} | ||||
| # list of new nodes created by ongoing graft | # list of new nodes created by ongoing graft | ||||
| statedata[b'newnodes'] = [] | statedata[b'newnodes'] = [] | ||||
| cmdutil.resolve_commit_options(ui, opts) | cmdutil.resolve_commit_options(ui, opts) | ||||
| opts = pycompat.byteskwargs(opts) | |||||
| editor = cmdutil.getcommiteditor( | editor = cmdutil.getcommiteditor(editform=b'graft', **opts) | ||||
| editform=b'graft', **pycompat.strkwargs(opts) | |||||
| ) | |||||
| cmdutil.check_at_most_one_arg(opts, b'abort', b'stop', b'continue') | cmdutil.check_at_most_one_arg(opts, 'abort', 'stop', 'continue') | ||||
| cont = False | cont = False | ||||
| if opts.get(b'no_commit'): | if opts.get('no_commit'): | ||||
| cmdutil.check_incompatible_arguments( | cmdutil.check_incompatible_arguments( | ||||
| opts, | opts, | ||||
| b'no_commit', | 'no_commit', | ||||
| [b'edit', b'currentuser', b'currentdate', b'log'], | ['edit', 'currentuser', 'currentdate', 'log'], | ||||
| ) | ) | ||||
| graftstate = statemod.cmdstate(repo, b'graftstate') | graftstate = statemod.cmdstate(repo, b'graftstate') | ||||
| if opts.get(b'stop'): | if opts.get('stop'): | ||||
| cmdutil.check_incompatible_arguments( | cmdutil.check_incompatible_arguments( | ||||
| opts, | opts, | ||||
| b'stop', | 'stop', | ||||
| [ | [ | ||||
| b'edit', | 'edit', | ||||
| b'log', | 'log', | ||||
| b'user', | 'user', | ||||
| b'date', | 'date', | ||||
| b'currentdate', | 'currentdate', | ||||
| b'currentuser', | 'currentuser', | ||||
| b'rev', | 'rev', | ||||
| ], | ], | ||||
| ) | ) | ||||
| return _stopgraft(ui, repo, graftstate) | return _stopgraft(ui, repo, graftstate) | ||||
| elif opts.get(b'abort'): | elif opts.get('abort'): | ||||
| cmdutil.check_incompatible_arguments( | cmdutil.check_incompatible_arguments( | ||||
| opts, | opts, | ||||
| b'abort', | 'abort', | ||||
| [ | [ | ||||
| b'edit', | 'edit', | ||||
| b'log', | 'log', | ||||
| b'user', | 'user', | ||||
| b'date', | 'date', | ||||
| b'currentdate', | 'currentdate', | ||||
| b'currentuser', | 'currentuser', | ||||
| b'rev', | 'rev', | ||||
| ], | ], | ||||
| ) | ) | ||||
| return cmdutil.abortgraft(ui, repo, graftstate) | return cmdutil.abortgraft(ui, repo, graftstate) | ||||
| elif opts.get(b'continue'): | elif opts.get('continue'): | ||||
| cont = True | cont = True | ||||
| if revs: | if revs: | ||||
| raise error.InputError(_(b"can't specify --continue and revisions")) | raise error.InputError(_(b"can't specify --continue and revisions")) | ||||
| # read in unfinished revisions | # read in unfinished revisions | ||||
| if graftstate.exists(): | if graftstate.exists(): | ||||
| statedata = cmdutil.readgraftstate(repo, graftstate) | statedata = cmdutil.readgraftstate(repo, graftstate) | ||||
| if statedata.get(b'date'): | if statedata.get(b'date'): | ||||
| opts[b'date'] = statedata[b'date'] | opts['date'] = statedata[b'date'] | ||||
| if statedata.get(b'user'): | if statedata.get(b'user'): | ||||
| opts[b'user'] = statedata[b'user'] | opts['user'] = statedata[b'user'] | ||||
| if statedata.get(b'log'): | if statedata.get(b'log'): | ||||
| opts[b'log'] = True | opts['log'] = True | ||||
| if statedata.get(b'no_commit'): | if statedata.get(b'no_commit'): | ||||
| opts[b'no_commit'] = statedata.get(b'no_commit') | opts['no_commit'] = statedata.get(b'no_commit') | ||||
| if statedata.get(b'base'): | if statedata.get(b'base'): | ||||
| opts[b'base'] = statedata.get(b'base') | opts['base'] = statedata.get(b'base') | ||||
| nodes = statedata[b'nodes'] | nodes = statedata[b'nodes'] | ||||
| revs = [repo[node].rev() for node in nodes] | revs = [repo[node].rev() for node in nodes] | ||||
| else: | else: | ||||
| cmdutil.wrongtooltocontinue(repo, _(b'graft')) | cmdutil.wrongtooltocontinue(repo, _(b'graft')) | ||||
| else: | else: | ||||
| if not revs: | if not revs: | ||||
| raise error.InputError(_(b'no revisions specified')) | raise error.InputError(_(b'no revisions specified')) | ||||
| cmdutil.checkunfinished(repo) | cmdutil.checkunfinished(repo) | ||||
| cmdutil.bailifchanged(repo) | cmdutil.bailifchanged(repo) | ||||
| revs = scmutil.revrange(repo, revs) | revs = scmutil.revrange(repo, revs) | ||||
| skipped = set() | skipped = set() | ||||
| basectx = None | basectx = None | ||||
| if opts.get(b'base'): | if opts.get('base'): | ||||
| basectx = scmutil.revsingle(repo, opts[b'base'], None) | basectx = scmutil.revsingle(repo, opts['base'], None) | ||||
| if basectx is None: | if basectx is None: | ||||
| # check for merges | # check for merges | ||||
| for rev in repo.revs(b'%ld and merge()', revs): | for rev in repo.revs(b'%ld and merge()', revs): | ||||
| ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev) | ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev) | ||||
| skipped.add(rev) | skipped.add(rev) | ||||
| revs = [r for r in revs if r not in skipped] | revs = [r for r in revs if r not in skipped] | ||||
| if not revs: | if not revs: | ||||
| return -1 | return -1 | ||||
| if basectx is not None and len(revs) != 1: | if basectx is not None and len(revs) != 1: | ||||
| raise error.InputError(_(b'only one revision allowed with --base ')) | raise error.InputError(_(b'only one revision allowed with --base ')) | ||||
| # Don't check in the --continue case, in effect retaining --force across | # Don't check in the --continue case, in effect retaining --force across | ||||
| # --continues. That's because without --force, any revisions we decided to | # --continues. That's because without --force, any revisions we decided to | ||||
| # skip would have been filtered out here, so they wouldn't have made their | # skip would have been filtered out here, so they wouldn't have made their | ||||
| # way to the graftstate. With --force, any revisions we would have otherwise | # way to the graftstate. With --force, any revisions we would have otherwise | ||||
| # skipped would not have been filtered out, and if they hadn't been applied | # skipped would not have been filtered out, and if they hadn't been applied | ||||
| # already, they'd have been in the graftstate. | # already, they'd have been in the graftstate. | ||||
| if not (cont or opts.get(b'force')) and basectx is None: | if not (cont or opts.get('force')) and basectx is None: | ||||
| # check for ancestors of dest branch | # check for ancestors of dest branch | ||||
| ancestors = repo.revs(b'%ld & (::.)', revs) | ancestors = repo.revs(b'%ld & (::.)', revs) | ||||
| for rev in ancestors: | for rev in ancestors: | ||||
| ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev])) | ui.warn(_(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev])) | ||||
| revs = [r for r in revs if r not in ancestors] | revs = [r for r in revs if r not in ancestors] | ||||
| if not revs: | if not revs: | ||||
| b'(was grafted from %d:%s)\n' | b'(was grafted from %d:%s)\n' | ||||
| ) | ) | ||||
| % (r, repo[r], rev, ctx) | % (r, repo[r], rev, ctx) | ||||
| ) | ) | ||||
| revs.remove(r) | revs.remove(r) | ||||
| if not revs: | if not revs: | ||||
| return -1 | return -1 | ||||
| if opts.get(b'no_commit'): | if opts.get('no_commit'): | ||||
| statedata[b'no_commit'] = True | statedata[b'no_commit'] = True | ||||
| if opts.get(b'base'): | if opts.get('base'): | ||||
| statedata[b'base'] = opts[b'base'] | statedata[b'base'] = opts['base'] | ||||
| for pos, ctx in enumerate(repo.set(b"%ld", revs)): | for pos, ctx in enumerate(repo.set(b"%ld", revs)): | ||||
| desc = b'%d:%s "%s"' % ( | desc = b'%d:%s "%s"' % ( | ||||
| ctx.rev(), | ctx.rev(), | ||||
| ctx, | ctx, | ||||
| ctx.description().split(b'\n', 1)[0], | ctx.description().split(b'\n', 1)[0], | ||||
| ) | ) | ||||
| names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) | names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) | ||||
| if names: | if names: | ||||
| desc += b' (%s)' % b' '.join(names) | desc += b' (%s)' % b' '.join(names) | ||||
| ui.status(_(b'grafting %s\n') % desc) | ui.status(_(b'grafting %s\n') % desc) | ||||
| if opts.get(b'dry_run'): | if opts.get('dry_run'): | ||||
| continue | continue | ||||
| source = ctx.extra().get(b'source') | source = ctx.extra().get(b'source') | ||||
| extra = {} | extra = {} | ||||
| if source: | if source: | ||||
| extra[b'source'] = source | extra[b'source'] = source | ||||
| extra[b'intermediate-source'] = ctx.hex() | extra[b'intermediate-source'] = ctx.hex() | ||||
| else: | else: | ||||
| extra[b'source'] = ctx.hex() | extra[b'source'] = ctx.hex() | ||||
| user = ctx.user() | user = ctx.user() | ||||
| if opts.get(b'user'): | if opts.get('user'): | ||||
| user = opts[b'user'] | user = opts['user'] | ||||
| statedata[b'user'] = user | statedata[b'user'] = user | ||||
| date = ctx.date() | date = ctx.date() | ||||
| if opts.get(b'date'): | if opts.get('date'): | ||||
| date = opts[b'date'] | date = opts['date'] | ||||
| statedata[b'date'] = date | statedata[b'date'] = date | ||||
| message = ctx.description() | message = ctx.description() | ||||
| if opts.get(b'log'): | if opts.get('log'): | ||||
| message += b'\n(grafted from %s)' % ctx.hex() | message += b'\n(grafted from %s)' % ctx.hex() | ||||
| statedata[b'log'] = True | statedata[b'log'] = True | ||||
| # we don't merge the first commit when continuing | # we don't merge the first commit when continuing | ||||
| if not cont: | if not cont: | ||||
| # perform the graft merge with p1(rev) as 'ancestor' | # perform the graft merge with p1(rev) as 'ancestor' | ||||
| overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')} | overrides = {(b'ui', b'forcemerge'): opts.get('tool', b'')} | ||||
| base = ctx.p1() if basectx is None else basectx | base = ctx.p1() if basectx is None else basectx | ||||
| with ui.configoverride(overrides, b'graft'): | with ui.configoverride(overrides, b'graft'): | ||||
| stats = mergemod.graft(repo, ctx, base, [b'local', b'graft']) | stats = mergemod.graft(repo, ctx, base, [b'local', b'graft']) | ||||
| # report any conflicts | # report any conflicts | ||||
| if stats.unresolvedcount > 0: | if stats.unresolvedcount > 0: | ||||
| # write out state for --continue | # write out state for --continue | ||||
| nodes = [repo[rev].hex() for rev in revs[pos:]] | nodes = [repo[rev].hex() for rev in revs[pos:]] | ||||
| statedata[b'nodes'] = nodes | statedata[b'nodes'] = nodes | ||||
| stateversion = 1 | stateversion = 1 | ||||
| graftstate.save(stateversion, statedata) | graftstate.save(stateversion, statedata) | ||||
| ui.error(_(b"abort: unresolved conflicts, can't continue\n")) | ui.error(_(b"abort: unresolved conflicts, can't continue\n")) | ||||
| ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n")) | ui.error(_(b"(use 'hg resolve' and 'hg graft --continue')\n")) | ||||
| return 1 | return 1 | ||||
| else: | else: | ||||
| cont = False | cont = False | ||||
| # commit if --no-commit is false | # commit if --no-commit is false | ||||
| if not opts.get(b'no_commit'): | if not opts.get('no_commit'): | ||||
| node = repo.commit( | node = repo.commit( | ||||
| text=message, user=user, date=date, extra=extra, editor=editor | text=message, user=user, date=date, extra=extra, editor=editor | ||||
| ) | ) | ||||
| if node is None: | if node is None: | ||||
| ui.warn( | ui.warn( | ||||
| _(b'note: graft of %d:%s created no changes to commit\n') | _(b'note: graft of %d:%s created no changes to commit\n') | ||||
| % (ctx.rev(), ctx) | % (ctx.rev(), ctx) | ||||
| ) | ) | ||||
| # checking that newnodes exist because old state files won't have it | # checking that newnodes exist because old state files won't have it | ||||
| elif statedata.get(b'newnodes') is not None: | elif statedata.get(b'newnodes') is not None: | ||||
| nn = statedata[b'newnodes'] # type: List[bytes] | nn = statedata[b'newnodes'] # type: List[bytes] | ||||
| nn.append(node) | nn.append(node) | ||||
| # remove state when we complete successfully | # remove state when we complete successfully | ||||
| if not opts.get(b'dry_run'): | if not opts.get('dry_run'): | ||||
| graftstate.delete() | graftstate.delete() | ||||
| return 0 | return 0 | ||||
| def _stopgraft(ui, repo, graftstate): | def _stopgraft(ui, repo, graftstate): | ||||
| """stop the interrupted graft""" | """stop the interrupted graft""" | ||||
| if not graftstate.exists(): | if not graftstate.exists(): | ||||