[PATCH V2] status: add terse option flag (issue4119)
Ryan McElroy
rm at fb.com
Wed Oct 14 17:40:35 CDT 2015
On 10/14/2015 7:20 AM, Pierre-Yves David wrote:
>
>
> On 10/13/2015 02:46 PM, 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 93173ffbe421307efe9cae4404587a541a826ee7
>> # Parent a38924f7680c6b7d95e14ade999c35748c9dcafd
>> status: add terse option flag (issue4119)
>
> I really like the idea and think we should move forward on this topic.
> However there is likely some testing and discussion required. Can we
> flag the command switch as EXPERIMENTAL so that we have option to
> adjust this in the next cycle?
>
>>
>> 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. By
>> default, we do this for all status types but control this through the
>> experimental.terse 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
Why do we get ugh/x and not just ugh/ ?
If not all files in mercurial/adddir/a was not added (ie, only some
files were added, what does the output look like?)
>>
>> and with some config knobs, we get:
>>
>> $ hg st -t --config experimental.terse='?'
This config option is poorly named -- I have no idea what to expect it
to do (I had to read the code).
Perhaps better: 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
What about for the '' filematcher? (eg, hg status ''). Does that also
fail to be tersified?
What would it take to make this work?
>>
>> 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')),
>> ] + 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', 'terse', '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-help.t b/tests/test-help.t
>> --- a/tests/test-help.t
>> +++ b/tests/test-help.t
>> @@ -575,10 +575,11 @@ Test command without options
>> -n --no-status hide status prefix
>> -C --copies show source of copied files
>> -0 --print0 end filenames with NUL, for use with xargs
>> --rev REV [+] show difference from revision
>> --change REV list the changed files of a revision
>> + -t --terse show only directory of unknown files
>> -I --include PATTERN [+] include names matching the given patterns
>> -X --exclude PATTERN [+] exclude names matching the given patterns
>> -S --subrepos recurse into subrepositories
>>
>> (some details hidden, use --verbose to show complete help)
>> 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,32 @@ 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 --config experimental.terse='MAR!?IC'
>> + A 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