[PATCH] new command debugignore

Jason Harris jason at jasonfharris.com
Sun Jul 4 03:31:28 CDT 2010


Here is the patch for adding the command debugignore.  This is my second patch and my
Mercurial coding foo is weak, and I am sure I have named something wrong, or put
something in the wrong place, etc.  Thus go easy on me with this patch :)

(I raised this with a few people on IRC#mercurial and they thought it was a good idea...)

Example syntax:

[Bolt:MacHgDev/MacHg/LocalMercurial/mercurial] MacHg 372(372) $ hg debugignore
(?:^\.hg|^\.mq|.*.DS_Store|.*.Trash|.*\.xcodeproj/.*\.pbxuser|.*\.xcodeproj/.*\.mode1v3|(?:|.*/)status(?:/|$)|(?:|.*/)guards(?:/|$)|(?:|.*/)[^/]*\.mode1v3(?:/|$))

[Bolt:~] $ hg debugignore /Development/MacHgDev/MacHg/.hgignore
(?:(?:|.*/)\.DS\_Store(?:/|$)|(?:|.*/)build(?:/|$))


# HG changeset patch
# User jfh <jason at jasonfharris.com>
# Date 2010-07-03 15:25:52 +0200
# Node ID 7ca04442899e3a8e745db00ee502450de7f22589
# Parent  359483f43ffb2e0bd311f80531efe0aebb8f6293
- Add command debugignore.
- This will return the regular expression which mercurial uses to determine if a file or
  folder should be ignored.  Mercurial internally generates this string from the .hgignore
  files and this just exposes the generated regular expression.

diff --git a/contrib/tcsh_completion b/contrib/tcsh_completion
--- a/contrib/tcsh_completion
+++ b/contrib/tcsh_completion
@@ -33,7 +33,7 @@
     backout bisect branch branches bundle \
     cat clone commit ci copy \
     cp debugancestor debugbuilddag debugcheckstate debugcommands \
-    debugcomplete debugdag debugdata debugdate debugfsinfo \
+    debugcomplete debugdag debugdata debugdate debugfsinfo debugignore \
     debugindex debugindexdot debuginstall debugpushkey debugrebuildstate \
     debugrename debugrevspec debugsetparents debugstate debugsub \
     debugwalk diff export forget grep \
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -9,7 +9,7 @@
 from lock import release
 from i18n import _, gettext
 import os, re, sys, difflib, time, tempfile
-import hg, util, revlog, bundlerepo, extensions, copies, error
+import hg, util, ignore, revlog, bundlerepo, extensions, copies, error
 import patch, help, mdiff, url, encoding, templatekw, discovery
 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
 import merge as mergemod
@@ -997,6 +997,33 @@
         cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
     ui.write("%s\n" % "\n".join(sorted(cmdlist)))
 
+def debugignore(ui, repo, *args):
+    """return the regular expression corresponding to the .hgignore files
+
+    With no .hgignore file arguments, return the regular expression which
+    represents all the .hgignore files which effect the repositories files.
+
+    With one or more .hgignore file arguments return the regular expression
+    which represents the specified .hgignore files."""
+    if len(args) == 0:
+        if not repo:
+            raise util.Abort(_("There is no Mercurial repository here "
+                               "(.hg not found)"))
+        files = [repo.join('.hgignore')]
+        for name, path in ui.configitems("ui"):
+            if name == 'ignore' or name.startswith('ignore.'):
+                files.append(util.expandpath(path))
+        root, cwd = repo.root, repo.getcwd()
+    else:
+        files = args
+        root = cmdutil.findrepo(files[0])
+        if not root:
+            root = files[0]
+        cwd = files[0]
+
+    regex = ignore.ignoreregex(files, root, cwd)
+    ui.write(regex)
+
 def debugfsinfo(ui, path = "."):
     """show information detected about current filesystem"""
     open('.debugfsinfo', 'w').write('')
@@ -4102,6 +4129,7 @@
          _('[-e] DATE [RANGE]')),
     "debugdata": (debugdata, [], _('FILE REV')),
     "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
+    "debugignore": (debugignore, [], _('[FILE]...')),
     "debugindex": (debugindex, [], _('FILE')),
     "debugindexdot": (debugindexdot, [], _('FILE')),
     "debuginstall": (debuginstall, [], ''),
@@ -4456,4 +4484,4 @@
 norepo = ("clone init version help debugcommands debugcomplete debugdata"
           " debugindex debugindexdot debugdate debuginstall debugfsinfo"
           " debugpushkey")
-optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
+optionalrepo = ("identify paths serve showconfig debugancestor debugdag debugignore")
diff --git a/mercurial/ignore.py b/mercurial/ignore.py
--- a/mercurial/ignore.py
+++ b/mercurial/ignore.py
@@ -101,3 +101,24 @@
                 raise util.Abort('%s: %s' % (f, inst[0]))
 
     return ignorefunc
+
+def ignoreregex(files, root, cwd):
+    pats = {}
+    for f in files:
+        try:
+            pats[f] = []
+            fp = open(f)
+            pats[f], warnings = ignorepats(fp)
+            for warning in warnings:
+                warn("%s: %s\n" % (f, warning))
+        except IOError, inst:
+            if f != files[0]:
+                warn(_("skipping unreadable ignore file '%s': %s\n") %
+                     (f, inst.strerror))
+
+    allpats = []
+    [allpats.extend(patlist) for patlist in pats.values()]
+    if not allpats:
+        return util.never
+    
+    return match.patregex(allpats, root, cwd)
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -175,6 +175,13 @@
             res += escape(c)
     return res
 
+def patregex(pats, root, cwd):
+    """Create a combined regular expression for the given patterns."""
+
+    normalizedpats = _normalize(pats, 'glob', root, cwd)
+    tail = '(?:/|$)'
+    return '(?:%s)' % '|'.join([_regex(k, p, tail) for (k, p) in normalizedpats])
+
 def _regex(kind, name, tail):
     '''convert a pattern into a regular expression'''
     if not name:



More information about the Mercurial-devel mailing list