Tutorial :Mercurial .hgignore regular expression



Question:

Using Mercurial, I need to ignore all files and directories except directories "tests" and "languages" and files in those directories. That all must be done with regex and .hgignoere

Files:

  • tests\junk.txt
  • cms\tests\some_file.txt
  • cms\languages\users\lang.txt
  • languages\lang2.txt
  • tests.txt
  • proba/tests.txt

I tried with this:

^(?!test|test/|test$|languages|languages/|languages$)  

but this only matches the files that starts with test and language:

  • tests\junk.txt
  • languages\lang2.txt

What I want is to matches also

  • cms\tests\some_file.txt
  • cms\languages\users\lang.txt

Any advice would be appreciated.


Solution:1

Use globs, they're simpler:

C:> dir  tests  languages pr0n espionage more_pr0n    C:> type .hgignore  syntax: glob  pr0n/*  espionage/*  more_pr0n/*  

added: If you are concerned that there will be new directories that won't be ignored then you should:

hg add .hgignore  hg commit   echo "new_directory/*" >> .hgignore  hg commit  

If you have too many directories and files popping up in your source directory for this method to work, make a source-only directory.


Solution:2

It's not the answer you're looking for but almost no one uses the negative-width-look-ahead ?: syntax in their .hgignore files. In cases where they want just a small subset of all files to be unignored they usually just ignore everything and then hg add the exceptions -- remember that in mercurial (unlike in cvs/svn) adding a file overrides ignore.

So if your .hgignore you'd have:

.*  

and then you'd hg add the files in your tests and languages directories explicitly with 'hg add'. You do then, of course have to remember to add any new files as you go as everything will be ignored, but if most files are supposed to be ignored it still the easier way to go.


Solution:3

Key to solving this is this section from the hgignore man page:

For example, say we have an untracked file, file.c, at a/b/file.c inside our repository. Mercurial will ignore file.c if any pattern in .hgignore matches a/b/file.c, a/b or a.

In order to ignore everything but a certain set of directories, we must carefully ignore everything at each level of the file hierarchy. Let's say you want to ignore everything except one/two/three/, one/two/four/, and foo/. First, ignore everything but one/ and foo/:

^(?!(one|foo)(/|$))

The ^ and (/|$) anchor one|foo in the path. Next, ignore everything inside one/ that isn't two/:

^one/(?!(two)(/|$))

The parentheses around two are there for consistency and aren't necessary. And finally ignore everything in two/ that isn't three/ or four/:

^one/two/(?!(three|four)(/|$))

This easily generalizes to any such set of directories.


Solution:4

It's not possible.

See the manpage.

For example, say we have an untracked file, file.c, at a/b/file.c inside our repository. Mercurial will ignore file.c if any pattern in .hgignore matches a/b/file.c, a/b or a.

So let's say you make a regex that will not match any path containing test and the file proba/tests.txt is in your working directory. That regex will first be applied to proba and will match which will result in the file being ignored.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »