diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -1567,7 +1567,7 @@ # Calling purge with --all will cause the largefiles to be deleted. # Override repo.status to prevent this from happening. -@eh.wrapcommand(b'purge', extension=b'purge') +@eh.wrapcommand(b'purge') def overridepurge(orig, ui, repo, *dirs, **opts): # XXX Monkey patching a repoview will not work. The assigned attribute will # be set on the unfiltered repo, but we will only lookup attributes in the diff --git a/hgext/purge.py b/hgext/purge.py --- a/hgext/purge.py +++ b/hgext/purge.py @@ -22,118 +22,11 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, see . -'''command to delete untracked files from the working directory''' -from __future__ import absolute_import - -from mercurial.i18n import _ -from mercurial import ( - cmdutil, - merge as mergemod, - pycompat, - registrar, - scmutil, -) - -cmdtable = {} -command = registrar.command(cmdtable) -# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for -# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should -# be specifying the version(s) of Mercurial they are tested with, or -# leave the attribute unspecified. -testedwith = b'ships-with-hg-core' - - -@command( - b'purge|clean', - [ - (b'a', b'abort-on-err', None, _(b'abort if an error occurs')), - (b'', b'all', None, _(b'purge ignored files too')), - (b'i', b'ignored', None, _(b'purge only ignored files')), - (b'', b'dirs', None, _(b'purge empty directories')), - (b'', b'files', None, _(b'purge files')), - (b'p', b'print', None, _(b'print filenames instead of deleting them')), - ( - b'0', - b'print0', - None, - _( - b'end filenames with NUL, for use with xargs' - b' (implies -p/--print)' - ), - ), - (b'', b'confirm', None, _(b'ask before permanently deleting files')), - ] - + cmdutil.walkopts, - _(b'hg purge [OPTION]... [DIR]...'), - helpcategory=command.CATEGORY_WORKING_DIRECTORY, -) -def purge(ui, repo, *dirs, **opts): - """removes files not tracked by Mercurial - - Delete files not known to Mercurial. This is useful to test local - and uncommitted changes in an otherwise-clean source tree. - - This means that purge will delete the following by default: - - - Unknown files: files marked with "?" by :hg:`status` - - Empty directories: in fact Mercurial ignores directories unless - they contain files under source control management +'''command to delete untracked files from the working directory (DEPRECATED) - But it will leave untouched: - - - Modified and unmodified tracked files - - Ignored files (unless -i or --all is specified) - - New files added to the repository (with :hg:`add`) - - The --files and --dirs options can be used to direct purge to delete - only files, only directories, or both. If neither option is given, - both will be deleted. - - If directories are given on the command line, only files in these - directories are considered. - - Be careful with purge, as you could irreversibly delete some files - you forgot to add to the repository. If you only want to print the - list of files that this program would delete, use the --print - option. - """ - opts = pycompat.byteskwargs(opts) - cmdutil.check_at_most_one_arg(opts, b'all', b'ignored') +The functionality of this extension has been included in core Mercurial since +version 5.7. Please use :hg:`purge ...` instead. :hg:`purge --confirm` is now the default, unless the extension is enabled for backward compatibility. +''' - act = not opts.get(b'print') - eol = b'\n' - if opts.get(b'print0'): - eol = b'\0' - act = False # --print0 implies --print - if opts.get(b'all', False): - ignored = True - unknown = True - else: - ignored = opts.get(b'ignored', False) - unknown = not ignored - - removefiles = opts.get(b'files') - removedirs = opts.get(b'dirs') - confirm = opts.get(b'confirm') - - if not removefiles and not removedirs: - removefiles = True - removedirs = True - - match = scmutil.match(repo[None], dirs, opts) - - paths = mergemod.purge( - repo, - match, - unknown=unknown, - ignored=ignored, - removeemptydirs=removedirs, - removefiles=removefiles, - abortonerror=opts.get(b'abort_on_err'), - noop=not act, - confirm=confirm, - ) - - for path in paths: - if not act: - ui.write(b'%s%s' % (path, eol)) +# This empty extension looks pointless, but core mercurial checks if it's loaded +# to implement the slightly different behavior documented above. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -5447,6 +5447,108 @@ @command( + b'purge|clean', + [ + (b'a', b'abort-on-err', None, _(b'abort if an error occurs')), + (b'', b'all', None, _(b'purge ignored files too')), + (b'i', b'ignored', None, _(b'purge only ignored files')), + (b'', b'dirs', None, _(b'purge empty directories')), + (b'', b'files', None, _(b'purge files')), + (b'p', b'print', None, _(b'print filenames instead of deleting them')), + ( + b'0', + b'print0', + None, + _( + b'end filenames with NUL, for use with xargs' + b' (implies -p/--print)' + ), + ), + (b'', b'confirm', None, _(b'ask before permanently deleting files')), + ] + + cmdutil.walkopts, + _(b'hg purge [OPTION]... [DIR]...'), + helpcategory=command.CATEGORY_WORKING_DIRECTORY, +) +def purge(ui, repo, *dirs, **opts): + """removes files not tracked by Mercurial + + Delete files not known to Mercurial. This is useful to test local + and uncommitted changes in an otherwise-clean source tree. + + This means that purge will delete the following by default: + + - Unknown files: files marked with "?" by :hg:`status` + - Empty directories: in fact Mercurial ignores directories unless + they contain files under source control management + + But it will leave untouched: + + - Modified and unmodified tracked files + - Ignored files (unless -i or --all is specified) + - New files added to the repository (with :hg:`add`) + + The --files and --dirs options can be used to direct purge to delete + only files, only directories, or both. If neither option is given, + both will be deleted. + + If directories are given on the command line, only files in these + directories are considered. + + Be careful with purge, as you could irreversibly delete some files + you forgot to add to the repository. If you only want to print the + list of files that this program would delete, use the --print + option. + """ + opts = pycompat.byteskwargs(opts) + cmdutil.check_at_most_one_arg(opts, b'all', b'ignored') + + act = not opts.get(b'print') + eol = b'\n' + if opts.get(b'print0'): + eol = b'\0' + act = False # --print0 implies --print + if opts.get(b'all', False): + ignored = True + unknown = True + else: + ignored = opts.get(b'ignored', False) + unknown = not ignored + + removefiles = opts.get(b'files') + removedirs = opts.get(b'dirs') + confirm = opts.get(b'confirm') + if confirm is None: + try: + extensions.find(b'purge') + confirm = False + except KeyError: + confirm = True + + if not removefiles and not removedirs: + removefiles = True + removedirs = True + + match = scmutil.match(repo[None], dirs, opts) + + paths = mergemod.purge( + repo, + match, + unknown=unknown, + ignored=ignored, + removeemptydirs=removedirs, + removefiles=removefiles, + abortonerror=opts.get(b'abort_on_err'), + noop=not act, + confirm=confirm, + ) + + for path in paths: + if not act: + ui.write(b'%s%s' % (path, eol)) + + +@command( b'push', [ (b'f', b'force', None, _(b'force push')), diff --git a/relnotes/next b/relnotes/next --- a/relnotes/next +++ b/relnotes/next @@ -17,6 +17,8 @@ can be e.g. `rebase`. As part of this effort, the default format from `hg rebase` was reorganized a bit. + * `hg purge` is now a core command using `--confirm` by default. + * `hg strip`, from the strip extension, is now a core command, `hg debugstrip`. The extension remains for compatibility. diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -38,6 +38,7 @@ paths phase pull + purge push recover remove @@ -354,6 +355,7 @@ paths: template phase: public, draft, secret, force, rev pull: update, force, confirm, rev, bookmark, branch, ssh, remotecmd, insecure + purge: abort-on-err, all, ignored, dirs, files, print, print0, confirm, include, exclude push: force, rev, bookmark, all-bookmarks, branch, new-branch, pushvars, publish, ssh, remotecmd, insecure recover: verify remove: after, force, subrepos, include, exclude, dry-run diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t --- a/tests/test-globalopts.t +++ b/tests/test-globalopts.t @@ -351,6 +351,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files @@ -483,6 +484,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files diff --git a/tests/test-help-hide.t b/tests/test-help-hide.t --- a/tests/test-help-hide.t +++ b/tests/test-help-hide.t @@ -55,6 +55,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files @@ -191,6 +192,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -107,6 +107,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files @@ -235,6 +236,7 @@ addremove add all new files, delete all missing files files list tracked files forget forget the specified files on the next commit + purge removes files not tracked by Mercurial remove remove the specified files on the next commit rename rename files; equivalent of copy + remove resolve redo merges or set/view the merge status of files @@ -375,8 +377,6 @@ mq manage a stack of patches notify hooks for sending email push notifications patchbomb command to send changesets as (a series of) patch emails - purge command to delete untracked files from the working - directory relink recreates hardlinks between repository clones schemes extend schemes with shortcuts to repository swarms share share a common history between several working directories @@ -2718,6 +2718,13 @@ set or show the current phase name + + purge + + + removes files not tracked by Mercurial + + recover diff --git a/tests/test-hgweb-json.t b/tests/test-hgweb-json.t --- a/tests/test-hgweb-json.t +++ b/tests/test-hgweb-json.t @@ -2190,6 +2190,10 @@ "topic": "phase" }, { + "summary": "removes files not tracked by Mercurial", + "topic": "purge" + }, + { "summary": "roll back an interrupted transaction", "topic": "recover" }, diff --git a/tests/test-purge.t b/tests/test-purge.t --- a/tests/test-purge.t +++ b/tests/test-purge.t @@ -1,8 +1,3 @@ - $ cat <> $HGRCPATH - > [extensions] - > purge = - > EOF - init $ hg init t @@ -18,6 +13,26 @@ $ echo 'ignored' > .hgignore $ hg ci -qAmr3 -d'2 0' +purge without the extension + + $ hg st + $ touch foo + $ hg purge + permanently delete 1 unkown files? (yN) n + abort: removal cancelled + [250] + $ hg st + ? foo + $ hg purge --no-confirm + $ hg st + +now enabling the extension + + $ cat <> $HGRCPATH + > [extensions] + > purge = + > EOF + delete an empty directory $ mkdir empty_dir