File name pattern for ignore files in Mercurial - regex

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.

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

Related

Regex for all folders under one folder with a specific name

I have a EFS will thousands of folders, I need a regex that can find a folder called "NewFile" and select all the xml files in it which is in any of directory listed from the root directory.
i.e.
selects:
C:\dir1\something\something2\NewFile\some.xml
C:\dir1\something\NewFile\some2.xml
C:\dir1\NewFile\some3.xml
ignores:
C:\dir1\something\something.xml
I did some research and found this question
Regex match folder and all subfolders
But it was matching the folder name at the same level
So you want to match pathnames that contain NewFile followed by an XML file:
/NewFile\\.*\.xml$/

explain gitignore pattern matching

I have the following directory tree:
> #pwd is the repo
> tree -a
.
├── .git
│   |.....
├── .gitignore
├── README.md
├── f1.html
├── f2.html ... and some more html
├── images
│   └── river.jpg
>
I also have the following in my .gitignore:
> cat .gitignore
*
!*.html
!images/*.*
>
I would like all files in the images directory to be included in the repo. But that is not happening. I got it to work using the following in gitignore:
*
!*.html
!images*
!*.jp*g
What is happening here? Is there a foolproof way to test gitignore. I checked the documentation. Here is the point it don't understand (this is under pattern format heading):
Otherwise, Git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the
pattern will not match a / in the pathname. For example,
"Documentation/*.html" matches "Documentation/git.html" but not
"Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".
Firstly the tricky part in your question is the first line in the .gitignore file:
* // Says exclude each and every file in the repository,
// unless I specify with ! pattern explicitly to consider it
First we will consider the first version of your .gitignore.
* exclude every file in the repository.
!*.html allow all html files.
!images/*.* consider all types of file in images folder.
To include all JPG/JPEG you could have simply added !*.jp*g at 3rd line, which would have made git to consider all jpg and jpeg irrespective of any folder where that file is. But you specifically wanted only from images folder and not only jpg, any type of file in the images folder. Let's read some documentation related to it and in 3rd section we will go to solution part.
Git ignore pattern regarding the folder consideration:
Pattern ending only with slash: If a pattern ends with <dir-name>/ then git will ignore the files contained in that directory and all other sub-directories. As example given in the docs
foo/ will match a directory foo and paths underneath it, but will not
match a regular file or a symbolic link foo
but also note, if any pattern matches a file in the excluded directory, git doesn’t consider it.
Pattern does not have slash: If you are specifying the dir name in the ignore list which does not end with a slash, git will consider it as just a pattern, which can match any file having that pathname.
If the pattern does not contain a slash /, Git treats it as a shell
glob pattern and checks for a match against the pathname relative to
the location
Pattern with slash and special character (*/?) : If the pattern ends like the 1st example you gave, images/*.* It works as specified in the documentation
Example: "Documentation/*.html" matches "Documentation/git.html" but not
"Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html".
Solution
Considering 3rd point git should consider all the files in the images directory for !images/*.* pattern. But it is not doing that because the documentation says one more important point
Git doesn’t list excluded directories
Because of the first line * the "images" directory itself is ignored. So first we should tell the git to consider images directory and later additional lines explicitly to say consider the other types (if needed).
*
!*.html
!images/ // <- consider images folder
!images/*.*
Note : the last line considers all types of files only from images directory not from any of its sub-directories. (3rd point in section 2)

gitignore to allow obj models but not compiled obj files

So I'm trying to figure out a suitable gitignore for an OpenGL project. I have the standard C++ gitignore.
Now it ignores .objs, for compiled object file, rightfully so.
However, it also ignores models that are of the .obj format and I do want tracked by version control.
How can I have setup the gitignore to ignore .objs, except from the Assets directory?
If the models are .obj, you should be able to just use
*.objs
in your gitignore to ignore compiled object files, while not ignoring .obj files because they will not match that.
If you want to not ignore .objs that are inside of the Assets folder, you can do
# Ignore compiled files
*.objs
# Don't want to ignore .objs files in Assets
!Assets/*.objs
From gitignore documentation:
An optional prefix "!" which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. Put a backslash ("\") in front of the first "!" for patterns that begin with a literal "!", for example, "!important!.txt".

How to hgignore all files of a particular extension except in one directory and its subdirectories?

I would like to use the .hgignore file of Mercurial to ignore all files with file extension .tex, except those .tex files in one particular directory and whatever subdirectory of this directory.
I presume syntax: regexp will be required for this.
A brief explanation of the particular regular expression used, would also be very welcome, so that we can all learn a bit here.
Let's say you want to exclude the directory named exclude. The following regex would then match all files that end in .tex unless exclude/ comes somewhere before that:
^(?!.*\bexclude/).*\.tex$

.hgignore syntax for ignoring only files, not directories?

I have a problem which I can't seem to understand. I'm using TortoiseHg (version 0.7.5) on Windows but on Linux I have the same problem. Here it is:
My .hgignore file:
syntax: regexp
^[^\\/]+$
What I'm trying to achieve is to add to the ignore list the files which are in the root of the hg repository.
For example if I have like this:
.hg
+mydir1
+mydir2
-myfile1
-myfile2
-anotherfile1
-anotherfile2
.hgignore
I want myfile1(2) and anotherfile1(2) to be ignored (names are only for the purpose of this example - they don't have a simple rule that can be put in the hgignore file easily)
Is there something I'm missing because I'm pretty sure that regexp is good (I even tested it)? Ideas?
Is there a simpler way to achieve this? [to add to the ignore list files that are in the root of the mercurial repository]
I relayed this question in #mercurial on irc.freenode.net and the response was that you cannot distinguish between files and directories — the directory is matched without the slash that you're searching for in your regexp.
However, if you can assume that your directories will never contain a full-stop ., but your files will, then something like this seems to work:
^[^/]*\..*$
I tested it in a repository like this:
% hg status -ui
? a.txt
? bbb
? foo/x.txt
? foo/yyy
Adding the .hgignore file gives:
% hg status -ui
? bbb
? foo/x.txt
? foo/yyy
I .hgignore
I a.txt
which indicates that the a.txt file is correctly ignored in your root directory, but x.txt in the foo subdirectory is not. You can also see that a file named just bbb in the root directory is not ignored. But maybe you can add such files yourself to the .hgignore file.
If you happen to have a directory like bar.baz in your root directory, then this directory and all files within will be ignored. I hope this helps a bit.
Here is a dirty trick:
Create an empty file ".hidden" in your directory, than add to .hgignore:
^mydir/(?!\.hidden).+$
This will ignore all files in the directory except ".hidden".