diff --git a/hgext/fsmonitor/__init__.py b/hgext/fsmonitor/__init__.py --- a/hgext/fsmonitor/__init__.py +++ b/hgext/fsmonitor/__init__.py @@ -18,6 +18,9 @@ repository as necessary. You'll need to install Watchman from https://facebook.github.io/watchman/ and make sure it is in your PATH. +fsmonitor is incompatible with the largefiles and eol extensions, and +will disable itself if any of those are active. + The following configuration options exist: :: @@ -58,9 +61,22 @@ that can outpace the IPC overhead of getting the result data for the full repo from Watchman. Defaults to false. -fsmonitor is incompatible with the largefiles and eol extensions, and -will disable itself if any of those are active. +:: + + [fsmonitor] + warn_when_unused = (boolean) + +Whether to print a warning during certain operations when fsmonitor would be +beneficial to performance but isn't enabled. +:: + + [fsmonitor] + warn_update_file_count = (integer) + +If ``warn_when_unused`` is set and fsmonitor isn't enabled, a warning will +be printed during working directory updates if this many files will be +created. ''' # Platforms Supported diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -491,6 +491,12 @@ coreconfigitem('format', 'usestore', default=True, ) +coreconfigitem('fsmonitor', 'warn_when_unused', + default=True, +) +coreconfigitem('fsmonitor', 'warn_update_file_count', + default=50000, +) coreconfigitem('hooks', '.*', default=dynamicdefault, generic=True, diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -25,6 +25,7 @@ from . import ( copies, error, + extensions, filemerge, match as matchmod, obsutil, @@ -1943,6 +1944,38 @@ # note that we're in the middle of an update repo.vfs.write('updatestate', p2.hex()) + # 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('fsmonitor', 'warn_when_unused') + fsmonitorthreshold = repo.ui.configint('fsmonitor', + 'warn_update_file_count') + try: + extensions.find('fsmonitor') + fsmonitorenabled = repo.ui.config('fsmonitor', 'mode') != '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['g']) >= fsmonitorthreshold + and pycompat.sysplatform.startswith(('linux', 'darwin'))): + repo.ui.warn( + _('(warning: large working directory being used without ' + 'fsmonitor enabled; enable fsmonitor to improve performance; ' + 'see "hg help -e fsmonitor")\n')) + stats = applyupdates(repo, actions, wc, p2, overwrite, labels=labels) wc.flushall() diff --git a/tests/hghave.py b/tests/hghave.py --- a/tests/hghave.py +++ b/tests/hghave.py @@ -559,6 +559,11 @@ except ImportError: return False +@check('linuxormacos', 'Linux or MacOS') +def has_linuxormacos(): + # This isn't a perfect test for MacOS. But it is sufficient for our needs. + return sys.platform.startswith(('linux', 'darwin')) + @check("docker", "docker support") def has_docker(): pat = br'A self-sufficient runtime for' diff --git a/tests/test-clone.t b/tests/test-clone.t --- a/tests/test-clone.t +++ b/tests/test-clone.t @@ -1177,3 +1177,80 @@ We should not have created a file named owned - if it exists, the attack succeeded. $ if test -f owned; then echo 'you got owned'; fi + +Cloning without fsmonitor enabled does not print a warning for small repos + + $ hg clone a fsmonitor-default + updating to bookmark @ on branch stable + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Lower the warning threshold to simulate a large repo + + $ cat >> $HGRCPATH << EOF + > [fsmonitor] + > warn_update_file_count = 2 + > EOF + +We should see a warning about no fsmonitor on supported platforms + +#if linuxormacos no-fsmonitor + $ hg clone a nofsmonitor + updating to bookmark @ on branch stable + (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved +#else + $ hg clone a nofsmonitor + updating to bookmark @ on branch stable + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved +#endif + +We should not see warning about fsmonitor when it is enabled + +#if fsmonitor + $ hg clone a fsmonitor-enabled + updating to bookmark @ on branch stable + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved +#endif + +We can disable the fsmonitor warning + + $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning + updating to bookmark @ on branch stable + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Loaded fsmonitor but disabled in config should still print warning + +#if linuxormacos fsmonitor + $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off + updating to bookmark @ on branch stable + (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !) + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved +#endif + +Warning not printed if working directory isn't empty + + $ hg -q clone a fsmonitor-update + (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?) + $ cd fsmonitor-update + $ hg up acb14030fe0a + 1 files updated, 0 files merged, 2 files removed, 0 files unresolved + (leaving bookmark @) + $ hg up cf0fe1914066 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +`hg update` from null revision also prints + + $ hg up null + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + +#if linuxormacos no-fsmonitor + $ hg up cf0fe1914066 + (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved +#else + $ hg up cf0fe1914066 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved +#endif + + $ cd .. +