in eden/scm/edenscm/mercurial/commands/__init__.py [0:0]
def resolve(ui, repo, *pats, **opts):
"""redo merges or set/view the merge status of files
Merges with unresolved conflicts are often the result of
non-interactive merging using the ``internal:merge`` configuration
setting, or a command-line merge tool like ``diff3``. The resolve
command is used to manage the files involved in a merge, after
:hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
working directory must have two parents). See :hg:`help
merge-tools` for information on configuring merge tools.
The resolve command can be used in the following ways:
- :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
files, discarding any previous merge attempts. Re-merging is not
performed for files already marked as resolved. Use ``--all/-a``
to select all unresolved files. ``--tool`` can be used to specify
the merge tool used for the given files. It overrides the HGMERGE
environment variable and your configuration files. Previous file
contents are saved with a ``.orig`` suffix.
- :hg:`resolve -m [FILE]`: mark a file as having been resolved
(e.g. after having manually fixed-up the files). The default is
to mark all unresolved files.
- :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
default is to mark all resolved files.
- :hg:`resolve -l`: list files which had or still have conflicts.
In the printed list, ``U`` = unresolved and ``R`` = resolved.
You can use ``set:unresolved()`` or ``set:resolved()`` to filter
the list. See :hg:`help filesets` for details.
.. note::
Mercurial will not let you commit files with unresolved merge
conflicts. You must use :hg:`resolve -m ...` before you can
commit after a conflicting merge.
Returns 0 on success, 1 if any files fail a resolve attempt.
"""
flaglist = "all mark unmark list no_status root_relative".split()
all, mark, unmark, show, nostatus, rootrel = [opts.get(o) for o in flaglist]
# Enable --root-relative by default if HGPLAIN is set, for compatibility.
if rootrel is None and ui.plain():
rootrel = True
if (show and (mark or unmark)) or (mark and unmark):
raise error.Abort(_("too many options specified"))
if pats and all:
raise error.Abort(_("can't specify --all and patterns"))
if not (all or pats or show or mark or unmark):
raise error.Abort(
_("no files or directories specified"),
hint=_("use --all to re-merge all unresolved files"),
)
if show:
ui.pager("resolve")
fm = ui.formatter("resolve", opts)
ms = mergemod.mergestate.read(repo)
m = scmutil.match(repo[None], pats, opts)
# Labels and keys based on merge state. Unresolved path conflicts show
# as 'P'. Resolved path conflicts show as 'R', the same as normal
# resolved conflicts.
mergestateinfo = {
"u": ("resolve.unresolved", "U"),
"r": ("resolve.resolved", "R"),
"pu": ("resolve.unresolved", "P"),
"pr": ("resolve.resolved", "R"),
"d": ("resolve.driverresolved", "D"),
}
cwd = "" if rootrel else repo.getcwd()
for f in ms:
if not m(f):
continue
label, key = mergestateinfo[ms[f]]
fm.startitem()
fm.condwrite(not nostatus, "status", "%s ", key, label=label)
# User-friendly paths
f = repo.pathto(f, cwd)
fm.write("path", "%s\n", f, label=label)
fm.end()
return 0
with repo.wlock():
ms = mergemod.mergestate.read(repo)
if not (ms.active() or repo.dirstate.p2() != nullid):
raise error.Abort(_("resolve command not applicable when not merging"))
wctx = repo[None]
if ms.mergedriver and ms.mdstate() == "u":
proceed = mergemod.driverpreprocess(repo, ms, wctx)
ms.commit()
# allow mark and unmark to go through
if not mark and not unmark and not proceed:
return 1
m = scmutil.match(wctx, pats, opts)
ret = 0
didwork = False
runconclude = False
tocomplete = []
for f in ms:
if not m(f):
continue
didwork = True
# don't let driver-resolved files be marked, and run the conclude
# step if asked to resolve
if ms[f] == "d":
exact = m.exact(f)
if mark:
if exact:
ui.warn(_("not marking %s as it is driver-resolved\n") % f)
elif unmark:
if exact:
ui.warn(_("not unmarking %s as it is driver-resolved\n") % f)
else:
runconclude = True
continue
# path conflicts must be resolved manually
if ms[f] in ("pu", "pr"):
if mark:
ms.mark(f, "pr")
elif unmark:
ms.mark(f, "pu")
elif ms[f] == "pu":
ui.warn(_("%s: path conflict must be resolved manually\n") % f)
continue
if mark:
ms.mark(f, "r")
elif unmark:
ms.mark(f, "u")
else:
# backup pre-resolve (merge uses .orig for its own purposes)
a = repo.wjoin(f)
try:
util.copyfile(a, a + ".resolve")
except (IOError, OSError) as inst:
if inst.errno != errno.ENOENT:
raise
try:
# preresolve file
ui.setconfig("ui", "forcemerge", opts.get("tool", ""), "resolve")
complete, r = ms.preresolve(f, wctx)
if not complete:
tocomplete.append(f)
elif r:
ret = 1
finally:
ui.setconfig("ui", "forcemerge", "", "resolve")
ms.commit()
# replace filemerge's .orig file with our resolve file, but only
# for merges that are complete
if complete:
try:
util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
except OSError as inst:
if inst.errno != errno.ENOENT:
raise
for f in tocomplete:
try:
# resolve file
ui.setconfig("ui", "forcemerge", opts.get("tool", ""), "resolve")
r = ms.resolve(f, wctx)
if r:
ret = 1
finally:
ui.setconfig("ui", "forcemerge", "", "resolve")
ms.commit()
# replace filemerge's .orig file with our resolve file
a = repo.wjoin(f)
try:
util.rename(a + ".resolve", scmutil.origpath(ui, repo, a))
except OSError as inst:
if inst.errno != errno.ENOENT:
raise
ms.commit()
ms.recordactions()
if not didwork and pats:
hint = None
if not any([p for p in pats if p.find(":") >= 0]):
pats = ["path:%s" % p for p in pats]
m = scmutil.match(wctx, pats, opts)
for f in ms:
if not m(f):
continue
flags = "".join(["-%s " % o[0] for o in flaglist if opts.get(o)])
hint = _("(try: hg resolve %s%s)\n") % (flags, " ".join(pats))
break
ui.warn(_("arguments do not match paths that need resolving\n"))
if hint:
ui.warn(hint)
elif ms.mergedriver and ms.mdstate() != "s":
# run conclude step when either a driver-resolved file is requested
# or there are no driver-resolved files
# we can't use 'ret' to determine whether any files are unresolved
# because we might not have tried to resolve some
if (runconclude or not list(ms.driverresolved())) and not list(
ms.unresolved()
):
proceed = mergemod.driverconclude(repo, ms, wctx)
ms.commit()
ms.recordactions()
if not proceed:
return 1
# Nudge users into finishing an unfinished operation
unresolvedf = list(ms.unresolved())
driverresolvedf = list(ms.driverresolved())
if not unresolvedf and not driverresolvedf:
ui.status(_("(no more unresolved files)\n"))
cmdutil.checkafterresolved(repo)
elif not unresolvedf:
ui.status(
_("(no more unresolved files -- " 'run "hg resolve --all" to conclude)\n')
)
return ret