# HG changeset patch # User mcmillen@cs.cmu.edu # Date 1143227882 -3600 # Node ID 62647394e36822a2fd42ccc5b3492188cce5d107 # Parent 4aab906517c6ef8c78b8a2d9eeb681220cb24750 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. diff --git a/doc/hgrc.5.txt b/doc/hgrc.5.txt --- a/doc/hgrc.5.txt +++ b/doc/hgrc.5.txt @@ -236,6 +236,12 @@ ui:: 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;; diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -34,7 +34,11 @@ class dirstate(object): 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 @@ class dirstate(object): 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') diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -123,6 +123,15 @@ class ui(object): 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