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(): | ||||