Skip to content
Snippets Groups Projects
Commit 40f78072fda9 authored by Martin von Zweigbergk's avatar Martin von Zweigbergk
Browse files

narrow: add option for automatically removing unused includes

It's been a somewhat common request among our users to have Mercurial
automatically pick includes to remove. This patch adds an option for
that: `hg tracked --auto-remove-includes`. I'm not sure if this is the
right name and semantics for it. Perhaps the feature should also add
excludes of large subdirectories even if other files in the include
are needed? Narrow clones are experimental, so we can change the name
and/or semantics later if necessary.

Differential Revision: https://phab.mercurial-scm.org/D6848
parent c2676b5a9f59
No related branches found
No related tags found
No related merge requests found
......@@ -328,6 +328,8 @@
@command('tracked',
[('', 'addinclude', [], _('new paths to include')),
('', 'removeinclude', [], _('old paths to no longer include')),
('', 'auto-remove-includes', False,
_('automatically choose unused includes to remove')),
('', 'addexclude', [], _('new paths to exclude')),
('', 'import-rules', '', _('import narrowspecs from a file')),
('', 'removeexclude', [], _('old paths to no longer exclude')),
......@@ -363,6 +365,11 @@
If --clear is specified without any further options, the narrowspec will be
empty and will not match any files.
If --auto-remove-includes is specified, then those includes that don't match
any files modified by currently visible local commits (those not shared by
the remote) will be added to the set of explicitly specified includes to
remove.
--import-rules accepts a path to a file containing rules, allowing you to
add --addinclude, --addexclude rules in bulk. Like the other include and
exclude switches, the changes are applied immediately.
......@@ -398,6 +405,7 @@
removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
autoremoveincludes = opts['auto_remove_includes']
update_working_copy = opts['update_working_copy']
only_show = not (addedincludes or removedincludes or addedexcludes or
......@@ -401,7 +409,8 @@
update_working_copy = opts['update_working_copy']
only_show = not (addedincludes or removedincludes or addedexcludes or
removedexcludes or newrules or update_working_copy)
removedexcludes or newrules or autoremoveincludes or
update_working_copy)
oldincludes, oldexcludes = repo.narrowpats
......@@ -436,7 +445,7 @@
narrowspec.copytoworkingcopy(repo)
return 0
if not widening and not narrowing:
if not (widening or narrowing or autoremoveincludes):
ui.status(_("nothing to widen or narrow\n"))
return 0
......@@ -459,6 +468,28 @@
commoninc = discovery.findcommonincoming(repo, remote)
if autoremoveincludes:
outgoing = discovery.findcommonoutgoing(repo, remote,
commoninc=commoninc)
ui.status(_('looking for unused includes to remove\n'))
localfiles = set()
for n in itertools.chain(outgoing.missing, outgoing.excluded):
localfiles.update(repo[n].files())
suggestedremovals = []
for include in sorted(oldincludes):
match = narrowspec.match(repo.root, [include], oldexcludes)
if not any(match(f) for f in localfiles):
suggestedremovals.append(include)
if suggestedremovals:
for s in suggestedremovals:
ui.status('%s\n' % s)
if (ui.promptchoice(_('remove these unused includes (yn)?'
'$$ &Yes $$ &No')) == 0):
removedincludes.update(suggestedremovals)
narrowing = True
else:
ui.status(_('found no unused includes\n'))
if narrowing:
newincludes = oldincludes - removedincludes
newexcludes = oldexcludes | addedexcludes
......
......@@ -101,6 +101,8 @@
--addinclude VALUE [+] new paths to include
--removeinclude VALUE [+] old paths to no longer include
--auto-remove-includes automatically choose unused includes to
remove
--addexclude VALUE [+] new paths to exclude
--import-rules VALUE import narrowspecs from a file
--removeexclude VALUE [+] old paths to no longer exclude
......
......@@ -447,3 +447,48 @@
abort: local changes found
(use --force-delete-local-changes to ignore)
[255]
$ cd ..
Test --auto-remove-includes
$ hg clone --narrow ssh://user@dummy/master narrow-auto-remove -q \
> --include d0 --include d1 --include d2
$ cd narrow-auto-remove
$ echo a >> d0/f
$ hg ci -m 'local change to d0'
$ hg co '.^'
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo a >> d1/f
$ hg ci -m 'local change to d1'
created new head
$ hg debugobsolete $(hg log -T '{node}' -r 'desc("local change to d0")')
1 new obsolescence markers
obsoleted 1 changesets
$ echo n | hg tracked --auto-remove-includes --config ui.interactive=yes
comparing with ssh://user@dummy/master
searching for changes
looking for unused includes to remove
path:d0
path:d2
remove these unused includes (yn)? n
$ hg tracked --auto-remove-includes
comparing with ssh://user@dummy/master
searching for changes
looking for unused includes to remove
path:d0
path:d2
remove these unused includes (yn)? y
looking for local changes to affected paths
saved backup bundle to $TESTTMP/narrow-auto-remove/.hg/strip-backup/*-narrow.hg (glob)
deleting data/d0/f.i
deleting data/d2/f.i
deleting meta/d0/00manifest.i (tree !)
deleting meta/d2/00manifest.i (tree !)
$ hg tracked
I path:d1
$ hg files
d1/f
$ hg tracked --auto-remove-includes
comparing with ssh://user@dummy/master
searching for changes
looking for unused includes to remove
found no unused includes
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment