D6848: narrow: add option for automatically removing unused includes

martinvonz (Martin von Zweigbergk) phabricator at mercurial-scm.org
Fri Sep 13 01:42:14 EDT 2019


martinvonz created this revision.
Herald added a reviewer: durin42.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  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've marked it experimental
  because 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?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6848

AFFECTED FILES
  hgext/narrow/narrowcommands.py
  tests/test-narrow.t

CHANGE DETAILS

diff --git a/tests/test-narrow.t b/tests/test-narrow.t
--- a/tests/test-narrow.t
+++ b/tests/test-narrow.t
@@ -447,3 +447,37 @@
   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
+  $ hg tracked --auto-remove-includes
+  comparing with ssh://user@dummy/master
+  searching for changes
+  looking for unused includes to remove
+  removing these unused includes:
+  path:d0
+  path:d2
+  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 --auto-remove-includes
+  comparing with ssh://user@dummy/master
+  searching for changes
+  looking for unused includes to remove
+  found no unused includes
diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py
--- a/hgext/narrow/narrowcommands.py
+++ b/hgext/narrow/narrowcommands.py
@@ -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 (EXPERIMENTAL)')),
      ('', 'addexclude', [], _('new paths to exclude')),
      ('', 'import-rules', '', _('import narrowspecs from a file')),
      ('', 'removeexclude', [], _('old paths to no longer exclude')),
@@ -398,10 +400,12 @@
     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
-                     removedexcludes or newrules or update_working_copy)
+                     removedexcludes or newrules or autoremoveincludes or
+                     update_working_copy)
 
     oldincludes, oldexcludes = repo.narrowpats
 
@@ -436,7 +440,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 +463,27 @@
 
         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:
+                ui.status(_('removing these unused includes:\n'))
+                for s in suggestedremovals:
+                    ui.status('%s\n' % s)
+                removedincludes.update(suggestedremovals)
+                narrowing = True
+            else:
+                ui.status(_('found no unused includes\n'))
+
         if narrowing:
             newincludes = oldincludes - removedincludes
             newexcludes = oldexcludes | addedexcludes



To: martinvonz, durin42, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list