[PATCH V3] status: add terse option flag (issue4119)
Augie Fackler
raf at durin42.com
Thu Oct 15 08:50:36 CDT 2015
On Wed, Oct 14, 2015 at 11:24:37PM -0700, Sean Farley wrote:
> # HG changeset patch
> # User Sean Farley <sean at farley.io>
> # Date 1427261050 25200
> # Tue Mar 24 22:24:10 2015 -0700
> # Node ID 3dd7ff9879636256252dd87ddda204383fb5863e
> # Parent a38924f7680c6b7d95e14ade999c35748c9dcafd
> status: add terse option flag (issue4119)
I'm +1 on this for this cycle, but would like others to chime in as I
know this has been contentious in the past.
(One thing I know this will need eventually is a way to disable it,
probably along the lines of --terse=never or something.)
>
> Based on an idea by Martin Geisler, this patch adds the ability to abbreviate
> the ouput of status by only listing the parent directory for multiple files.
> Directories that only contain one file are not collapsed, though. By default,
> we do this for all status types but control this through the
> experimental.tersestatuses option.
>
> Future work could speed up status operations even further by skipping disk
> operations based on this config.
>
> For example, imagine we have the following output of status:
>
> $ hg st
> A mercurial/adddir/a
> A mercurial/adddir/b
> A mercurial/adddir/c
> ? bar
> ? baz
> ? foo/subdir/a
> ? foo/subdir/b
> ? foo/subdir/c
> ? foo/x
> ? foo/y
> ? mercurial/subdir/a
> ? mercurial/subdir/b
> ? mercurial/subdir/c
> ? ugh/x
>
> without any configuration, we get:
>
> $ hg st -t
> A mercurial/adddir/
> ? bar
> ? baz
> ? foo/
> ? mercurial/subdir/
> ? ugh/x
>
> and with some config knobs, we get:
>
> $ hg st -t --config experimental.tersestatuses='?'
> A mercurial/adddir/a
> A mercurial/adddir/b
> A mercurial/adddir/c
> ? bar
> ? baz
> ? foo/
> ? mercurial/subdir/
> ? ugh/x
>
> And we can still see the files in 'foo' by:
>
> $ hg st -t foo
> ? foo/subdir/
> ? foo/x
> ? foo/y
>
> But, this has a downside of not working as desired with relative paths:
>
> $ hg st -t re:
> A mercurial/adddir/a
> A mercurial/adddir/b
> A mercurial/adddir/c
> ? bar
> ? baz
> ? foo/subdir/a
> ? foo/subdir/b
> ? foo/subdir/c
> ? foo/x
> ? foo/y
> ? mercurial/subdir/a
> ? mercurial/subdir/b
> ? mercurial/subdir/c
> ? ugh/x
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -21,10 +21,11 @@ import minirst, revset, fileset
> import dagparser, context, simplemerge, graphmod, copies
> import random, operator
> import setdiscovery, treediscovery, dagutil, pvec, localrepo
> import phases, obsolete, exchange, bundle2, repair, lock as lockmod
> import ui as uimod
> +import match as matchmod
>
> table = {}
>
> command = cmdutil.command(table)
>
> @@ -5898,10 +5899,11 @@ class httpservice(object):
> ('n', 'no-status', None, _('hide status prefix')),
> ('C', 'copies', None, _('show source of copied files')),
> ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
> ('', 'rev', [], _('show difference from revision'), _('REV')),
> ('', 'change', '', _('list the changed files of a revision'), _('REV')),
> + ('t', 'terse', None, _('show only directory of unknown files (EXPERIMENTAL)')),
> ] + walkopts + subrepoopts + formatteropts,
> _('[OPTION]... [FILE]...'),
> inferrepo=True)
> def status(ui, repo, *pats, **opts):
> """show changed files in the working directory
> @@ -5998,10 +6000,65 @@ def status(ui, repo, *pats, **opts):
>
> m = scmutil.match(repo[node2], pats, opts)
> stat = repo.status(node1, node2, m,
> 'ignored' in show, 'clean' in show, 'unknown' in show,
> opts.get('subrepos'))
> +
> + if opts.get('terse'):
> + stat = list(stat)
> + statmap = dict(zip('MAR!?IC', range(len('MAR!?IC'))))
> + knowndirs = set([''])
> +
> + # can we avoid walking everything?
> + for path in repo.unfiltered()['.']:
> + d = os.path.dirname(path)
> + while d not in knowndirs:
> + knowndirs.add(d)
> + d = os.path.dirname(d)
> +
> + match = None
> + if pats:
> + match = matchmod.match(repo.root, cwd, pats, opts.get('include'),
> + opts.get('exclude'))
> +
> + # this method exists to override hiding a subdirectory if it matches
> + # one of the *pats, e.g.:
> + # hg st -t foo
> + # foo/a
> + # foo/b
> + def _match(path):
> + ret = path not in knowndirs
> + if match is not None:
> + ret = ret and not match(path)
> + return ret
> +
> + for s in ui.config('experimental', 'tersestatuses', 'MAR!?IC').upper():
> + results = {}
> + for path in stat[statmap[s]]:
> + prev = path
> + d = os.path.dirname(prev)
> + while _match(d):
> + prev = d
> + d = os.path.dirname(prev)
> +
> + # to get the behavior of displaying the full path if there is
> + # only one file, we add the resulting path to a dictionary and
> + # overwrite that value if it already existed.
> + if prev != path:
> + prev += '/'
> + res = results.get(prev)
> + if res is None:
> + results[prev] = path
> + else:
> + results[prev] = prev
> + else:
> + results[prev] = path
> +
> + # replace the previous list
> + stat[statmap[s]] = sorted(results.values())
> + stat = scmutil.status(*stat)
> +
> changestates = zip(states, 'MAR!?IC', stat)
>
> if (opts.get('all') or opts.get('copies')
> or ui.configbool('ui', 'statuscopies')) and not opts.get('no_status'):
> copy = copies.pathcopies(repo[node1], repo[node2], m)
> diff --git a/tests/test-completion.t b/tests/test-completion.t
> --- a/tests/test-completion.t
> +++ b/tests/test-completion.t
> @@ -214,11 +214,11 @@ Show all commands + options
> merge: force, rev, preview, tool
> pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
> push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
> remove: after, force, subrepos, include, exclude
> serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
> - status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos, template
> + status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, terse, include, exclude, subrepos, template
> summary: remote
> update: clean, check, date, rev, tool
> addremove: similarity, subrepos, include, exclude, dry-run
> archive: no-decode, prefix, rev, type, subrepos, include, exclude
> backout: merge, commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user
> diff --git a/tests/test-status.t b/tests/test-status.t
> --- a/tests/test-status.t
> +++ b/tests/test-status.t
> @@ -99,10 +99,40 @@ hg status . in repo root:
> $ hg status --cwd b/2 ..
> ? ../1/in_b_1
> ? in_b_2
> ? ../in_b
>
> +test status with terse
> +
> + $ hg status --terse
> + ? a/
> + ? b/
> + ? in_root
> +
> +make sure we can still list the individual files by specifying the directory
> +
> + $ hg status --terse a
> + ? a/1/in_a_1
> + ? a/in_a
> +
> +test all status modes, not just unknown files, with terse
> +
> + $ hg add -q a
> + $ hg status --terse
> + A a/
> + ? b/
> + ? in_root
> +
> +test config option to terse-ify just unknown files
> +
> + $ hg status --terse --config experimental.tersestatuses='?'
> + A a/1/in_a_1
> + A a/in_a
> + ? b/
> + ? in_root
> + $ hg forget -q a
> +
> combining patterns with root and patterns without a root works
>
> $ hg st a/in_a re:.*b$
> ? a/in_a
> ? b/in_b
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list