diff --git a/hgext3rd/sparse.py b/hgext3rd/sparse.py --- a/hgext3rd/sparse.py +++ b/hgext3rd/sparse.py @@ -664,6 +664,8 @@ ('', 'clear-rules', False, _('clears local include/exclude rules')), ('', 'refresh', False, _('updates the working after sparseness changes')), ('', 'reset', False, _('makes the repo full again')), + ('', 'cwd-list', False, _('list the full contents of the current ' + 'directory')), ] + commands.templateopts, _('[--OPTION] PATTERN...')) def sparse(ui, repo, *pats, **opts): @@ -705,6 +707,10 @@ --clear-rules removes all local include and exclude rules, while leaving any enabled profiles in place. + --cwd-list list all the contents of the current directory. The files that + are excluded by the current sparse checkout are annotated with a hyphen + ('-') before the name. + The following config option defines whether sparse treats supplied paths as relative to repo root or to the current working dir for include and exclude options: @@ -731,8 +737,9 @@ delete = opts.get('delete') refresh = opts.get('refresh') reset = opts.get('reset') + cwdlist = opts.get('cwd_list') count = sum([include, exclude, enableprofile, disableprofile, delete, - importrules, refresh, clearrules, reset]) + importrules, refresh, clearrules, reset, cwdlist]) if count > 1: raise error.Abort(_("too many flags specified")) @@ -768,6 +775,9 @@ finally: wlock.release() + if cwdlist: + _cwdlist(repo) + def _config(ui, repo, pats, opts, include=False, exclude=False, reset=False, delete=False, enableprofile=False, disableprofile=False, force=False): @@ -1041,6 +1051,42 @@ fm.condwrite(ui.verbose, 'files_conflicting', 'Files conflicting: %d\n', lookup) +def _cwdlist(repo): + """ List the contents in the current directory. Annotate + the files in the sparse profile. + """ + ctx = repo['.'] + mf = ctx.manifest() + cwd = util.normpath(os.getcwd()) + + # Get the root of the repo so that we remove the content of + # the root from the current working directory + root = repo.root + if cwd.startswith(root): + cwd = cwd[len(root):] + else: + raise error.Abort(_("the current working directory should begin " + + "with the root %s"% root)) + + cwd = cwd.strip("/") + sparsematch = repo.sparsematch(ctx.rev()) + checkedoutentries = set() + allentries = set() + cwdlength = len(cwd) + 1 + for filepath in mf: + if filepath.startswith(cwd): + tail = filepath[cwdlength:] if cwdlength > 1 else filepath + entryname = tail.split('/', 1)[0] + + allentries.add(entryname) + if sparsematch(filepath): + checkedoutentries.add(entryname) + + ui = repo.ui + for entry in sorted(allentries): + marker = ' ' if entry in checkedoutentries else '-' + ui.status("%s %s\n" % (marker, entry)) + class forceincludematcher(object): """A matcher that returns true for any of the forced includes before testing against the actual matcher.""" diff --git a/tests/test-sparse.t b/tests/test-sparse.t --- a/tests/test-sparse.t +++ b/tests/test-sparse.t @@ -338,6 +338,23 @@ [exclude] +Test --cwd-list + $ hg commit -m 'commit' + $ hg sparse --cwd-list + add + - hide + - show + - show2 + $ cd add + $ hg sparse --cwd-list + bar + foo + $ hg sparse -I foo + $ hg sparse --delete . + $ hg sparse --cwd-list + - bar + foo + $ cd .. $ cd ..