Alex
Alex

Reputation: 191

File name pattern for ignore files in Mercurial

I use TortoiseHg and I have folders structure, as below:

testSet1
     test1
          filesystem
                    input_1.obj
                    output_1.obj
          etalon_1.obj
          result_1.obj
     test2
          filesystem
                    input_1.obj
                    output_1.obj
          etalon_1.obj
          result_1.obj
     ......
     errors.txt
......
result.xml

I need to ignore only .obj files located in directories "testSetN/testN", but not in directories "testSetN/testN/filesystem". I use glob pattern "*/*/*.obj" in .hgignore, but it doesn't work. Mercurial just ignores all .obj files in all directories (including "filesystem" directory). But if I use, for example, "testSet1/*/*.obj", then everything works fine. How can I do what I need? It's not necessary for me to use only glob syntax. I would be grateful for any way.

Upvotes: 0

Views: 918

Answers (1)

Sigve Kolbeinson
Sigve Kolbeinson

Reputation: 1161

Looking at https://www.selenic.com/mercurial/hgignore.5.html#syntax

Neither glob nor regexp patterns are rooted. A glob-syntax pattern of the form *.c will match a file ending in .c in any directory, and a regexp pattern of the form .c$ will do the same. To root a regexp pattern, start it with ^.

According to this, the glob */*/*.obj will match .obj files inside the filesystem directory, because the glob is not rooted. So it matches those files by rooting the glob at testSetN/

If you have the prefix of testSet on all folders, you can use the glob testSet*/*/*.obj. This way, it will ignore .obj files in a subdirectory of a directory that begins with testSet. - it would also ignore a/testSetX/testY/Z.obj as well as testSetN/testN/N.obj

Mercurial will also let you manually add files that would otherwise be ignored according to .hgignore, so you could simply ignore all .obj files, or use your original glob of */*/*.obj and hg add the files you want to track.

Edit: adding regex as discussed in the comments.

If you prefer regex, or don't have a pattern to root the glob at, you need to use a regex. The regex ^[^/]*/[^/]*/[^/]*\.obj$ to match any .obj file at exactly two levels from the repository root. That is:

  • ^ to anchor the match at the root of the repository
  • [^/]*/ to match any first-level directory. That is any sequence of characters that does not contain the directory separator /
  • [^/]*/ again, to match any second-level directory.
  • [^/]*\.obj$ to match any filenames that end with .obj

Upvotes: 4

Related Questions