How do I make mercurial ignore any file with .xxx extension - mercurial

I want Mercurial to ignore any file with a certain extension.
For example, I wanted to ignore files with a .SUO extension. (There's no need to version-control Visual Studio user settings.)
So I changed my .hgignore file to this:
syntax: glob
*.suo
However, this has no effect, and Mercurial still sees my .suo file.
What am I doing wrong here?

If, when running hg status before altering your .hgignore file, the .suo file had a ? in front of it, then it should be ignored now. If anything else (M or A for example) it is already tracked by the repository and will not magically stop being tracked. In such a case you'll need to do hg remove on the file to delete it and have hg stop tracking it, or just do hg forget on it to have hg stop tracking it but keep the file. Either should be followed by a commit.
The only files that will be omitted from the status listing if their path matches a pattern in the .hgignore file are files that are not tracked. It would make no sense to omit a file that is tracked, because you would never see whether it had been modified, added, or removed.
Edit: Mercurial does only track files (you can't make it track empty directories), but the patterns in .hgignore are simply run against strings of the file paths relative to the root of the repository. The very same relative paths that it shows you when you run hg status. So it does work how you say you want it to work because the following lines are a standard part of my own .hgignore files:
syntax: glob
*\obj\*
*\bin\*
*.csproj.user
*.suo
Again, when you run hg status and it shows a .suo file, what single character is at the beginning of that line? Is it a M, A, R, ! or ? character? What is the path after it?

Mercurial uses entries in a file called .hgignore to determine what files it completely ignores. It is normally located in the root file for your repository (and not in the .hg directory, which you might think).
You can find out more here:
http://www.selenic.com/mercurial/hgignore.5.html
Normally, we use regular expression syntax to ensure that case is not a factor in extensions:
# use regexp syntax.
syntax: regexp
(?i)\.dcu
(?i)\.identcache
(?i)\.dof
(?i)\.dsk
(?i)\.bak
(?i)\.old
That way, it ensures that even if for some reason the case of the extension changes, it is still ignored.

Example for ignoring/excluding files with .o extension:
.*\.o$
should translate to .*\.suo$ for .suo extensions.
I have used this method successfully

Check where .hgignore file is located and ensure it is either in $HOME or project root folder. Check the CASE (vs case) of the extension. I doubt if pattern matching is case insensitive.
edit: tested, the pattern matching is NOT case sensitive. Hence, add "*.SUO" if you want to ignore files with ".SUO" extension.

Related

How can i make mercurial to add wildcard for file name

we are working on a project, where the angularjs web project is compiled and binaries are stored in hg repo. The problem is angularjs js files are usually compiled with hashing for all binary files. Ex: binary files are suffixed with unique extensions for each file
main.1cc794c25c00388d81bb.js,
polyfills.eda7b2736c9951cdce19.js,
runtime.a2aefc53e5f0bce023ee.js,
common.7d1522841bf85b01f2e6.js,
1.620807da7415abaeeb47.js,
2.93e8bd3b179a0199a6a3.....etc.
The problem is every time a new binary in checkin in hg repo, it is being detected as new file and retained along with old file of same name. So, i need a way to fool the hg repo, to retain the file name but still consider them as old file replacing the previous one.
main.1cc794c25c00388d81bb.js ==> overwrite old main.js
polyfills.eda7b2736c9951cdce19.js ==> overwrite old polyfill.js
runtime.a2aefc53e5f0bce023ee.js ==> overwrite old polyfill.js
common.7d1522841bf85b01f2e6.js ==> overwrite old commom.js
1.620807da7415abaeeb47.js ==> overwrite old 1.js
2.93e8bd3b179a0199a6a3 ==> overwrite old 2.js
Could any one point out a way, to fool the hg to consider these files are just modification of previous files and not as new files ?
Can hgignore or some other extension be used...
A VCS shall track the state of files. And those are indeed new files. One can argue that those are the old files renamed - which can be recorded by the VCS.
So there are two solutions I see:
Record moving the old filenames to the new filenames. hg addremove --similarity XX might be of big help here. It will result in all the files having the new names each time - but if the similarity is good enough it will work nicely. You might need to adjust the XX to get a similarity measure (0 ... 100) which works for you best. Adding --dry-run for testing purposes might make testing easy. You WILL need to delete the old files before you run hg addremove though.
Have a pre-commit hook which iterates over *.js files and moves via an appropriate regex ..js to *.js omitting the hashing code, effectively overwriting the generic filenames with the newly generated hashed filenames.

how to remove a folder from tracking in mercurial

To ignore ./node_modules/ folder and .idea folder into .hgignore file so that I don't want to track them.
Currently I have the following rules on my .hgignore file.
*.orig
*./node_module/
*.idea/
*.rej
*~
*.o
tests/*.err
But abort error on hg status.
Well, hg help hgignore points to have a look at hg help patterns. I can't quite explain it better:
Mercurial accepts several notations for identifying one or more files at a
time.
By default, Mercurial treats filenames as shell-style extended glob
patterns.
Alternate pattern notations must be specified explicitly.
Note:
Patterns specified in ".hgignore" are not rooted. Please see 'hg help
hgignore' for details.
To use a plain path name without any pattern matching, start it with
"path:". These path names must completely match starting at the current
repository root.
To use an extended glob, start a name with "glob:". Globs are rooted at
the current directory; a glob such as "*.c" will only match files in the
current directory ending with ".c".
The supported glob syntax extensions are "**" to match any string across
path separators and "{a,b}" to mean "a or b".
(...)
Plain examples:
path:foo/bar a name bar in a directory named foo in the root
of the repository
path:path:name a file or directory named "path:name"
There are alternate ways to specify paths using regex as well as also explained in the available command line help.
So, use something like
node_module/**
.idea/**
or
path:node_module
path:.idea
provided you quoted your entire .hgignore and thus use the default glob pattern matching.
finally i found tip . here is how to .
Foradding node_modules/ and .idea/ folder you need to specify the following.N.B > is refers terminal.
touch .hgignore
nano .hgignore
add the following
^node_modules/
^.idea/
Done !

hg pull/update only if local repository is "clean"

I want to write a script that recursively descends a directory tree, and does an hg pull -u on all repositories that are "clean" - i.e. have no local diffs, outgoing changesets, or anything else that might make them different to remote. (The script would also do a rebuild, etc.)
Is there a good way to check whether a repository is "clean"? Keep in mind that I would probably be doing this from a bash or python script.
hg status is your friend. However, you should be careful about what "clean" means. If all files in your directory structure are under version control, and none of them have changed, hg status should return no console output, and (probably) a 0 return code.
If that does not match your definition of clean, you have to be more careful. For example, I commonly do not add generated files (binaries, PDFs from Latex, etc) to version control, but they are inside my directory structure. In that case these files are listed as 'unknown', and I'm sure the return code of hg will differ.

funny that when .hgignore is added for Mercurial, this file itself shows up as "?" in hg status?

Is it normal? So you just need to add \.hgignore to the list to ignore itself?
Yes, but you don't want to ignore the .hgignore file. When a new person checks out your repository, don't you want them to get your ignored-files list? Instead, do hg add .hgignore; hg commit.
Bottom line: .hgignore is tracked like any other file in the repository.
Just to supplement Borealid's answer: ? in hg status means that the file is in the working directory, but not tracked. You usually see it in one of two situations:
A file got generated that you don't need to check in, like a compiled binary or something.
You added a new file to your project, but haven't hg added it yet.
In #1, you'll want to add the file or file type to .hgignore. In #2, you want to hg add the file. In the case of .hgignore, it's #2.

Folders not being added in Mercurial

I looked at this question: ignoring folders in mercurial that mentions how to ignore a folder, but that's not what I need.
I'm using TortoiseHG and after I "add" all my folders, they show still as "?" instead of "+". The files within them show "+", but the folders themselves just show "?". Is this a problem with Mercurial on Windows XP? Or, is it a problem between my keyboard and my chair?
Mercurial adds only files in, and infers the folders from the actual file names. If you drop down to a command line and do hg status, you will see that folders are not listed at all. The files within the folder you added will be listed with the A tag, but the actual folders don't list in a hg status command.
You don't need to add the folders separately (in fact, Mercurial doesn't handle plain folders/directories at all). As long as your files are there, you're fine.