Commit b4430ac2 authored by Augie Fackler's avatar Augie Fackler
Browse files

mergestate: split out merge state handling code from main merge module

There's already some pretty reasonable encapsulation here, but I want
to make the mergestate storage a property of the context so memctx
instances can do a reasonable thing. This is the first step in a
reshuffle to make that easier.

Differential Revision: https://phab.mercurial-scm.org/D8550
parent 1d2d353e5c4a
......@@ -144,6 +144,7 @@ from mercurial import (
match as matchmod,
mdiff,
merge,
mergestate as mergestatemod,
pycompat,
registrar,
rewriteutil,
......@@ -426,7 +427,9 @@ def getrevstofix(ui, repo, opts):
if not (len(revs) == 1 and wdirrev in revs):
cmdutil.checkunfinished(repo)
rewriteutil.precheck(repo, revs, b'fix')
if wdirrev in revs and list(merge.mergestate.read(repo).unresolved()):
if wdirrev in revs and list(
mergestatemod.mergestate.read(repo).unresolved()
):
raise error.Abort(b'unresolved conflicts', hint=b"use 'hg resolve'")
if not revs:
raise error.Abort(
......
......@@ -224,6 +224,7 @@ from mercurial import (
hg,
logcmdutil,
merge as mergemod,
mergestate as mergestatemod,
mergeutil,
node,
obsolete,
......@@ -2289,7 +2290,7 @@ def _getsummary(ctx):
def bootstrapcontinue(ui, state, opts):
repo = state.repo
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
mergeutil.checkunresolved(ms)
if state.actions:
......
......@@ -31,6 +31,7 @@ from mercurial import (
logcmdutil,
match as matchmod,
merge,
mergestate as mergestatemod,
pathutil,
pycompat,
scmutil,
......@@ -622,7 +623,7 @@ def overridecalculateupdates(
return actions, diverge, renamedelete
@eh.wrapfunction(merge, b'recordupdates')
@eh.wrapfunction(mergestatemod, b'recordupdates')
def mergerecordupdates(orig, repo, actions, branchmerge, getfiledata):
if b'lfmr' in actions:
lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
......
......@@ -36,6 +36,7 @@ from mercurial import (
extensions,
hg,
merge as mergemod,
mergestate as mergestatemod,
mergeutil,
node as nodemod,
obsolete,
......@@ -537,7 +538,7 @@ class rebaseruntime(object):
user=ctx.user(),
date=date,
)
mergemod.mergestate.clean(repo)
mergestatemod.mergestate.clean(repo)
else:
newnode = commitnode(
repo,
......@@ -1074,7 +1075,7 @@ def rebase(ui, repo, **opts):
)
# TODO: Make in-memory merge not use the on-disk merge state, so
# we don't have to clean it here
mergemod.mergestate.clean(repo)
mergestatemod.mergestate.clean(repo)
clearstatus(repo)
clearcollapsemsg(repo)
return _dorebase(ui, repo, action, opts, inmemory=False)
......@@ -1175,7 +1176,7 @@ def _origrebase(
if action == b'abort' and opts.get(b'tool', False):
ui.warn(_(b'tool option will be ignored\n'))
if action == b'continue':
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
mergeutil.checkunresolved(ms)
retcode = rbsrt._prepareabortorcontinue(
......@@ -2185,7 +2186,7 @@ def abortrebase(ui, repo):
def continuerebase(ui, repo):
with repo.wlock(), repo.lock():
rbsrt = rebaseruntime(repo, ui)
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
mergeutil.checkunresolved(ms)
retcode = rbsrt._prepareabortorcontinue(isabort=False)
if retcode is not None:
......
......@@ -13,7 +13,7 @@ from mercurial import (
error,
hg,
lock as lockmod,
merge,
mergestate as mergestatemod,
node as nodemod,
pycompat,
registrar,
......@@ -269,7 +269,7 @@ def stripcmd(ui, repo, *revs, **opts):
repo.dirstate.write(repo.currenttransaction())
# clear resolve state
merge.mergestate.clean(repo, repo[b'.'].node())
mergestatemod.mergestate.clean(repo, repo[b'.'].node())
update = False
......
......@@ -38,6 +38,7 @@ from . import (
logcmdutil,
match as matchmod,
merge as mergemod,
mergestate as mergestatemod,
mergeutil,
obsolete,
patch,
......@@ -890,7 +891,7 @@ To mark files as resolved: hg resolve --mark FILE'''
def readmorestatus(repo):
"""Returns a morestatus object if the repo has unfinished state."""
statetuple = statemod.getrepostate(repo)
mergestate = mergemod.mergestate.read(repo)
mergestate = mergestatemod.mergestate.read(repo)
activemerge = mergestate.active()
if not statetuple and not activemerge:
return None
......@@ -3127,7 +3128,7 @@ def amend(ui, repo, old, extra, pats, opts):
if subs:
subrepoutil.writestate(repo, newsubstate)
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
mergeutil.checkunresolved(ms)
filestoamend = {f for f in wctx.files() if matcher(f)}
......
......@@ -46,6 +46,7 @@ from . import (
hg,
logcmdutil,
merge as mergemod,
mergestate as mergestatemod,
narrowspec,
obsolete,
obsutil,
......@@ -5938,7 +5939,7 @@ def resolve(ui, repo, *pats, **opts):
if show:
ui.pager(b'resolve')
fm = ui.formatter(b'resolve', opts)
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
wctx = repo[None]
m = scmutil.match(wctx, pats, opts)
......@@ -5946,14 +5947,20 @@ def resolve(ui, repo, *pats, **opts):
# as 'P'. Resolved path conflicts show as 'R', the same as normal
# resolved conflicts.
mergestateinfo = {
mergemod.MERGE_RECORD_UNRESOLVED: (b'resolve.unresolved', b'U'),
mergemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
mergemod.MERGE_RECORD_UNRESOLVED_PATH: (
mergestatemod.MERGE_RECORD_UNRESOLVED: (
b'resolve.unresolved',
b'U',
),
mergestatemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
mergestatemod.MERGE_RECORD_UNRESOLVED_PATH: (
b'resolve.unresolved',
b'P',
),
mergemod.MERGE_RECORD_RESOLVED_PATH: (b'resolve.resolved', b'R'),
mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
mergestatemod.MERGE_RECORD_RESOLVED_PATH: (
b'resolve.resolved',
b'R',
),
mergestatemod.MERGE_RECORD_DRIVER_RESOLVED: (
b'resolve.driverresolved',
b'D',
),
......@@ -5963,7 +5970,7 @@ def resolve(ui, repo, *pats, **opts):
if not m(f):
continue
if ms[f] == mergemod.MERGE_RECORD_MERGED_OTHER:
if ms[f] == mergestatemod.MERGE_RECORD_MERGED_OTHER:
continue
label, key = mergestateinfo[ms[f]]
fm.startitem()
......@@ -5975,7 +5982,7 @@ def resolve(ui, repo, *pats, **opts):
return 0
with repo.wlock():
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
if not (ms.active() or repo.dirstate.p2() != nullid):
raise error.Abort(
......@@ -5986,7 +5993,7 @@ def resolve(ui, repo, *pats, **opts):
if (
ms.mergedriver
and ms.mdstate() == mergemod.MERGE_DRIVER_STATE_UNMARKED
and ms.mdstate() == mergestatemod.MERGE_DRIVER_STATE_UNMARKED
):
proceed = mergemod.driverpreprocess(repo, ms, wctx)
ms.commit()
......@@ -6012,12 +6019,12 @@ def resolve(ui, repo, *pats, **opts):
didwork = True
if ms[f] == mergemod.MERGE_RECORD_MERGED_OTHER:
if ms[f] == mergestatemod.MERGE_RECORD_MERGED_OTHER:
continue
# don't let driver-resolved files be marked, and run the conclude
# step if asked to resolve
if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
if ms[f] == mergestatemod.MERGE_RECORD_DRIVER_RESOLVED:
exact = m.exact(f)
if mark:
if exact:
......@@ -6037,14 +6044,14 @@ def resolve(ui, repo, *pats, **opts):
# path conflicts must be resolved manually
if ms[f] in (
mergemod.MERGE_RECORD_UNRESOLVED_PATH,
mergemod.MERGE_RECORD_RESOLVED_PATH,
mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
mergestatemod.MERGE_RECORD_RESOLVED_PATH,
):
if mark:
ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED_PATH)
elif unmark:
ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED_PATH)
elif ms[f] == mergestatemod.MERGE_RECORD_UNRESOLVED_PATH:
ui.warn(
_(b'%s: path conflict must be resolved manually\n')
% uipathfn(f)
......@@ -6056,12 +6063,12 @@ def resolve(ui, repo, *pats, **opts):
fdata = repo.wvfs.tryread(f)
if (
filemerge.hasconflictmarkers(fdata)
and ms[f] != mergemod.MERGE_RECORD_RESOLVED
and ms[f] != mergestatemod.MERGE_RECORD_RESOLVED
):
hasconflictmarkers.append(f)
ms.mark(f, mergemod.MERGE_RECORD_RESOLVED)
ms.mark(f, mergestatemod.MERGE_RECORD_RESOLVED)
elif unmark:
ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
ms.mark(f, mergestatemod.MERGE_RECORD_UNRESOLVED)
else:
# backup pre-resolve (merge uses .orig for its own purposes)
a = repo.wjoin(f)
......@@ -6942,7 +6949,7 @@ def summary(ui, repo, **opts):
marks = []
try:
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
except error.UnsupportedMergeRecords as e:
s = b' '.join(e.recordtypes)
ui.warn(
......
......@@ -58,7 +58,7 @@ from . import (
localrepo,
lock as lockmod,
logcmdutil,
merge as mergemod,
mergestate as mergestatemod,
obsolete,
obsutil,
pathutil,
......@@ -1974,7 +1974,7 @@ def debugmergestate(ui, repo, *args, **opts):
was chosen."""
if ui.verbose:
ms = mergemod.mergestate(repo)
ms = mergestatemod.mergestate(repo)
# sort so that reasonable information is on top
v1records = ms._readrecordsv1()
......@@ -2008,7 +2008,7 @@ def debugmergestate(ui, repo, *args, **opts):
b'"}'
)
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
fm = ui.formatter(b'debugmergestate', opts)
fm.startitem()
......@@ -2034,8 +2034,8 @@ def debugmergestate(ui, repo, *args, **opts):
state = ms._state[f]
fm_files.data(state=state[0])
if state[0] in (
mergemod.MERGE_RECORD_UNRESOLVED,
mergemod.MERGE_RECORD_RESOLVED,
mergestatemod.MERGE_RECORD_UNRESOLVED,
mergestatemod.MERGE_RECORD_RESOLVED,
):
fm_files.data(local_key=state[1])
fm_files.data(local_path=state[2])
......@@ -2045,8 +2045,8 @@ def debugmergestate(ui, repo, *args, **opts):
fm_files.data(other_node=state[6])
fm_files.data(local_flags=state[7])
elif state[0] in (
mergemod.MERGE_RECORD_UNRESOLVED_PATH,
mergemod.MERGE_RECORD_RESOLVED_PATH,
mergestatemod.MERGE_RECORD_UNRESOLVED_PATH,
mergestatemod.MERGE_RECORD_RESOLVED_PATH,
):
fm_files.data(renamed_path=state[1])
fm_files.data(rename_side=state[2])
......
......@@ -16,7 +16,7 @@ from . import (
error,
filesetlang,
match as matchmod,
merge,
mergestate as mergestatemod,
pycompat,
registrar,
scmutil,
......@@ -245,7 +245,7 @@ def resolved(mctx, x):
getargs(x, 0, 0, _(b"resolved takes no arguments"))
if mctx.ctx.rev() is not None:
return mctx.never()
ms = merge.mergestate.read(mctx.ctx.repo())
ms = mergestatemod.mergestate.read(mctx.ctx.repo())
return mctx.predicate(
lambda f: f in ms and ms[f] == b'r', predrepr=b'resolved'
)
......@@ -259,7 +259,7 @@ def unresolved(mctx, x):
getargs(x, 0, 0, _(b"unresolved takes no arguments"))
if mctx.ctx.rev() is not None:
return mctx.never()
ms = merge.mergestate.read(mctx.ctx.repo())
ms = mergestatemod.mergestate.read(mctx.ctx.repo())
return mctx.predicate(
lambda f: f in ms and ms[f] == b'u', predrepr=b'unresolved'
)
......
......@@ -33,6 +33,7 @@ from . import (
logcmdutil,
logexchange,
merge as mergemod,
mergestate as mergestatemod,
narrowspec,
node,
phases,
......@@ -1164,7 +1165,7 @@ def merge(
def abortmerge(ui, repo):
ms = mergemod.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
if ms.active():
# there were conflicts
node = ms.localctx.hex()
......
......@@ -44,7 +44,7 @@ from . import (
hook,
lock as lockmod,
match as matchmod,
merge as mergemod,
mergestate as mergestatemod,
mergeutil,
namespaces,
narrowspec,
......@@ -2468,7 +2468,7 @@ class localrepository(object):
ui.status(
_(b'working directory now based on revision %d\n') % parents
)
mergemod.mergestate.clean(self, self[b'.'].node())
mergestatemod.mergestate.clean(self, self[b'.'].node())
# TODO: if we know which new heads may result from this rollback, pass
# them to destroy(), which will prevent the branchhead cache from being
......@@ -2867,10 +2867,10 @@ class localrepository(object):
fparent2 = nullid
elif not fparentancestors:
# TODO: this whole if-else might be simplified much more
ms = mergemod.mergestate.read(self)
ms = mergestatemod.mergestate.read(self)
if (
fname in ms
and ms[fname] == mergemod.MERGE_RECORD_MERGED_OTHER
and ms[fname] == mergestatemod.MERGE_RECORD_MERGED_OTHER
):
fparent1, fparent2 = fparent2, nullid
......@@ -2968,7 +2968,7 @@ class localrepository(object):
self, status, text, user, date, extra
)
ms = mergemod.mergestate.read(self)
ms = mergestatemod.mergestate.read(self)
mergeutil.checkunresolved(ms)
# internal config: ui.allowemptycommit
......
This diff is collapsed.
This diff is collapsed.
......@@ -14,6 +14,7 @@ from . import (
error,
match as matchmod,
merge,
mergestate as mergestatemod,
scmutil,
sparse,
util,
......@@ -272,7 +273,7 @@ def _deletecleanfiles(repo, files):
def _writeaddedfiles(repo, pctx, files):
actions = merge.emptyactions()
addgaction = actions[merge.ACTION_GET].append
addgaction = actions[mergestatemod.ACTION_GET].append
mf = repo[b'.'].manifest()
for f in files:
if not repo.wvfs.exists(f):
......
......@@ -789,9 +789,9 @@ def conflictlocal(repo, subset, x):
"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
"""
getargs(x, 0, 0, _(b"conflictlocal takes no arguments"))
from . import merge
from . import mergestate as mergestatemod
mergestate = merge.mergestate.read(repo)
mergestate = mergestatemod.mergestate.read(repo)
if mergestate.active() and repo.changelog.hasnode(mergestate.local):
return subset & {repo.changelog.rev(mergestate.local)}
......@@ -805,9 +805,9 @@ def conflictother(repo, subset, x):
"merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'.
"""
getargs(x, 0, 0, _(b"conflictother takes no arguments"))
from . import merge
from . import mergestate as mergestatemod
mergestate = merge.mergestate.read(repo)
mergestate = mergestatemod.mergestate.read(repo)
if mergestate.active() and repo.changelog.hasnode(mergestate.other):
return subset & {repo.changelog.rev(mergestate.other)}
......
......@@ -42,6 +42,7 @@ from . import (
lock as lockmod,
mdiff,
merge,
mergestate as mergestatemod,
node as nodemod,
patch,
phases,
......@@ -801,7 +802,7 @@ def unshelvecontinue(ui, repo, state, opts):
basename = state.name
with repo.lock():
checkparents(repo, state)
ms = merge.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
if list(ms.unresolved()):
raise error.Abort(
_(b"unresolved conflicts, can't continue"),
......
......@@ -18,6 +18,7 @@ from . import (
error,
match as matchmod,
merge as mergemod,
mergestate as mergestatemod,
pathutil,
pycompat,
scmutil,
......@@ -406,7 +407,7 @@ def filterupdatesactions(repo, wctx, mctx, branchmerge, actions):
elif file in wctx:
prunedactions[file] = (b'r', args, msg)
if branchmerge and type == mergemod.ACTION_MERGE:
if branchmerge and type == mergestatemod.ACTION_MERGE:
f1, f2, fa, move, anc = args
if not sparsematch(f1):
temporaryfiles.append(f1)
......
......@@ -419,9 +419,9 @@ def getgraphnodecurrent(repo, ctx, cache):
else:
merge_nodes = cache.get(b'merge_nodes')
if merge_nodes is None:
from . import merge
from . import mergestate as mergestatemod
mergestate = merge.mergestate.read(repo)
mergestate = mergestatemod.mergestate.read(repo)
if mergestate.active():
merge_nodes = (mergestate.local, mergestate.other)
else:
......
......@@ -11,3 +11,6 @@
* logcmdutil.diffordiffstat() now takes contexts instead of nodes.
* The `mergestate` class along with some related methods and constants have
moved from `mercurial.merge` to a new `mercurial.mergestate` module.
......@@ -5,7 +5,7 @@
from __future__ import absolute_import
from mercurial import (
merge,
mergestate as mergestatemod,
registrar,
)
......@@ -23,7 +23,7 @@ command = registrar.command(cmdtable)
)
def fakemergerecord(ui, repo, *pats, **opts):
with repo.wlock():
ms = merge.mergestate.read(repo)
ms = mergestatemod.mergestate.read(repo)
records = ms._makerecords()
if opts.get('mandatory'):
records.append((b'X', b'mandatory record'))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment