merge.update() is quite hard to understand, found this an easy win.
The end goal is to have better organized merge and mergestate handling and then
fix some related bugs.
hg-reviewers |
merge.update() is quite hard to understand, found this an easy win.
The end goal is to have better organized merge and mergestate handling and then
fix some related bugs.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
progress.complete() | progress.complete() | ||||
assert len(getfiledata) == ( | assert len(getfiledata) == ( | ||||
len(actions[mergestatemod.ACTION_GET]) if wantfiledata else 0 | len(actions[mergestatemod.ACTION_GET]) if wantfiledata else 0 | ||||
) | ) | ||||
return updateresult(updated, merged, removed, unresolved), getfiledata | return updateresult(updated, merged, removed, unresolved), getfiledata | ||||
def _advertisefsmonitor(repo, num_gets, p1node): | |||||
# Advertise fsmonitor when its presence could be useful. | |||||
# | |||||
# We only advertise when performing an update from an empty working | |||||
# directory. This typically only occurs during initial clone. | |||||
# | |||||
# We give users a mechanism to disable the warning in case it is | |||||
# annoying. | |||||
# | |||||
# We only allow on Linux and MacOS because that's where fsmonitor is | |||||
# considered stable. | |||||
fsmonitorwarning = repo.ui.configbool(b'fsmonitor', b'warn_when_unused') | |||||
fsmonitorthreshold = repo.ui.configint( | |||||
b'fsmonitor', b'warn_update_file_count' | |||||
) | |||||
try: | |||||
# avoid cycle: extensions -> cmdutil -> merge | |||||
from . import extensions | |||||
extensions.find(b'fsmonitor') | |||||
fsmonitorenabled = repo.ui.config(b'fsmonitor', b'mode') != b'off' | |||||
# We intentionally don't look at whether fsmonitor has disabled | |||||
# itself because a) fsmonitor may have already printed a warning | |||||
# b) we only care about the config state here. | |||||
except KeyError: | |||||
fsmonitorenabled = False | |||||
if ( | |||||
fsmonitorwarning | |||||
and not fsmonitorenabled | |||||
and p1node == nullid | |||||
and num_gets >= fsmonitorthreshold | |||||
and pycompat.sysplatform.startswith((b'linux', b'darwin')) | |||||
): | |||||
repo.ui.warn( | |||||
_( | |||||
b'(warning: large working directory being used without ' | |||||
b'fsmonitor enabled; enable fsmonitor to improve performance; ' | |||||
b'see "hg help -e fsmonitor")\n' | |||||
) | |||||
) | |||||
UPDATECHECK_ABORT = b'abort' # handled at higher layers | UPDATECHECK_ABORT = b'abort' # handled at higher layers | ||||
UPDATECHECK_NONE = b'none' | UPDATECHECK_NONE = b'none' | ||||
UPDATECHECK_LINEAR = b'linear' | UPDATECHECK_LINEAR = b'linear' | ||||
UPDATECHECK_NO_CONFLICT = b'noconflict' | UPDATECHECK_NO_CONFLICT = b'noconflict' | ||||
def update( | def update( | ||||
repo, | repo, | ||||
# the dirstate. | # the dirstate. | ||||
always = matcher is None or matcher.always() | always = matcher is None or matcher.always() | ||||
updatedirstate = updatedirstate and always and not wc.isinmemory() | updatedirstate = updatedirstate and always and not wc.isinmemory() | ||||
if updatedirstate: | if updatedirstate: | ||||
repo.hook(b'preupdate', throw=True, parent1=xp1, parent2=xp2) | repo.hook(b'preupdate', throw=True, parent1=xp1, parent2=xp2) | ||||
# note that we're in the middle of an update | # note that we're in the middle of an update | ||||
repo.vfs.write(b'updatestate', p2.hex()) | repo.vfs.write(b'updatestate', p2.hex()) | ||||
# Advertise fsmonitor when its presence could be useful. | _advertisefsmonitor( | ||||
# | repo, len(actions[mergestatemod.ACTION_GET]), p1.node() | ||||
# We only advertise when performing an update from an empty working | |||||
# directory. This typically only occurs during initial clone. | |||||
# | |||||
# We give users a mechanism to disable the warning in case it is | |||||
# annoying. | |||||
# | |||||
# We only allow on Linux and MacOS because that's where fsmonitor is | |||||
# considered stable. | |||||
fsmonitorwarning = repo.ui.configbool(b'fsmonitor', b'warn_when_unused') | |||||
fsmonitorthreshold = repo.ui.configint( | |||||
b'fsmonitor', b'warn_update_file_count' | |||||
) | |||||
try: | |||||
# avoid cycle: extensions -> cmdutil -> merge | |||||
from . import extensions | |||||
extensions.find(b'fsmonitor') | |||||
fsmonitorenabled = repo.ui.config(b'fsmonitor', b'mode') != b'off' | |||||
# We intentionally don't look at whether fsmonitor has disabled | |||||
# itself because a) fsmonitor may have already printed a warning | |||||
# b) we only care about the config state here. | |||||
except KeyError: | |||||
fsmonitorenabled = False | |||||
if ( | |||||
fsmonitorwarning | |||||
and not fsmonitorenabled | |||||
and p1.node() == nullid | |||||
and len(actions[mergestatemod.ACTION_GET]) >= fsmonitorthreshold | |||||
and pycompat.sysplatform.startswith((b'linux', b'darwin')) | |||||
): | |||||
repo.ui.warn( | |||||
_( | |||||
b'(warning: large working directory being used without ' | |||||
b'fsmonitor enabled; enable fsmonitor to improve performance; ' | |||||
b'see "hg help -e fsmonitor")\n' | |||||
) | |||||
) | ) | ||||
wantfiledata = updatedirstate and not branchmerge | wantfiledata = updatedirstate and not branchmerge | ||||
stats, getfiledata = applyupdates( | stats, getfiledata = applyupdates( | ||||
repo, actions, wc, p2, overwrite, wantfiledata, labels=labels | repo, actions, wc, p2, overwrite, wantfiledata, labels=labels | ||||
) | ) | ||||
if updatedirstate: | if updatedirstate: | ||||
with repo.dirstate.parentchange(): | with repo.dirstate.parentchange(): |