changeset 2003:62647394e368

Implementation of per-user .hgignore. Reference: http://www.selenic.com/mercurial/bts/issue166 If the [ui] section of .hgrc contains keys like "ignore" or "ignore.something", the values corresponding to these keys are treated as per-user hgignore files. These hgignore files apply to all repositories used by that user.
author mcmillen@cs.cmu.edu
date Fri, 24 Mar 2006 20:18:02 +0100
parents 4aab906517c6
children 7dd6317ab4fd
files doc/hgrc.5.txt mercurial/dirstate.py mercurial/ui.py
diffstat 3 files changed, 49 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/doc/hgrc.5.txt	Fri Mar 24 19:51:05 2006 +0100
+++ b/doc/hgrc.5.txt	Fri Mar 24 20:18:02 2006 +0100
@@ -236,6 +236,12 @@
     Print debugging information.  True or False.  Default is False.
   editor;;
     The editor to use during a commit.  Default is $EDITOR or "vi".
+  ignore;;
+    A file to read per-user ignore patterns from. This file should be in
+    the same format as a repository-wide .hgignore file. This option
+    supports hook syntax, so if you want to specify multiple ignore
+    files, you can do so by setting something like
+    "ignore.other = ~/.hgignore2".
   interactive;;
     Allow to prompt the user.  True or False.  Default is True.
   logtemplate;;
--- a/mercurial/dirstate.py	Fri Mar 24 19:51:05 2006 +0100
+++ b/mercurial/dirstate.py	Fri Mar 24 20:18:02 2006 +0100
@@ -34,7 +34,11 @@
         return cwd[len(self.root) + 1:]
 
     def hgignore(self):
-        '''return the contents of .hgignore as a list of patterns.
+        '''return the contents of .hgignore files as a list of patterns.
+
+        the files parsed for patterns include:
+        .hgignore in the repository root
+        any additional files specified in the [ui] section of ~/.hgrc
 
         trailing white space is dropped.
         the escape character is backslash.
@@ -58,36 +62,44 @@
                     elif line[i] == '#': break
                 line = line[:i].rstrip()
                 if line: yield line
+        files = [self.wjoin('.hgignore')]
+        files.extend(self.ui.hgignorefiles())
         pats = []
-        try:
-            fp = open(self.wjoin('.hgignore'))
-            syntax = 'relre:'
-            for line in parselines(fp):
-                if line.startswith('syntax:'):
-                    s = line[7:].strip()
-                    try:
-                        syntax = syntaxes[s]
-                    except KeyError:
-                        self.ui.warn(_(".hgignore: ignoring invalid "
-                                       "syntax '%s'\n") % s)
-                    continue
-                pat = syntax + line
-                for s in syntaxes.values():
-                    if line.startswith(s):
-                        pat = line
-                        break
-                pats.append(pat)
-        except IOError: pass
+        for f in files:
+            try:
+                fp = open(f)
+                syntax = 'relre:'
+                for line in parselines(fp):
+                    if line.startswith('syntax:'):
+                        s = line[7:].strip()
+                        try:
+                            syntax = syntaxes[s]
+                        except KeyError:
+                            self.ui.warn(_("%s: ignoring invalid "
+                                           "syntax '%s'\n") % (f, s))
+                        continue
+                    pat = syntax + line
+                    for s in syntaxes.values():
+                        if line.startswith(s):
+                            pat = line
+                            break
+                    pats.append(pat)
+            except IOError: pass
         return pats
 
     def ignore(self, fn):
-        '''default match function used by dirstate and localrepository.
-        this honours the .hgignore file, and nothing more.'''
+        '''default match function used by dirstate and
+        localrepository.  this honours the repository .hgignore file
+        and any other files specified in the [ui] section of .hgrc.'''
         if self.blockignore:
             return False
         if not self.ignorefunc:
             ignore = self.hgignore()
             if ignore:
+                # FIXME: if there are errors in patterns, matcher will
+                # print out an error containing src ('.hgignore');
+                # really, we want the original source file to be
+                # printed instead.
                 files, self.ignorefunc, anypats = util.matcher(self.root,
                                                                inc=ignore,
                                                                src='.hgignore')
--- a/mercurial/ui.py	Fri Mar 24 19:51:05 2006 +0100
+++ b/mercurial/ui.py	Fri Mar 24 20:18:02 2006 +0100
@@ -123,6 +123,15 @@
     def extensions(self):
         return self.configitems("extensions")
 
+    def hgignorefiles(self):
+        result = []
+        cfgitems = self.configitems("ui")
+        for key, value in cfgitems:
+            if key == 'ignore' or key.startswith('ignore.'):
+                path = os.path.expanduser(value)
+                result.append(path)
+        return result
+
     def diffopts(self):
         if self.diffcache:
             return self.diffcache