Ignore Linux executables with hgignore - mercurial

I'm trying to set up .hgignore correctly, but I'm having some problems. I don't want to see executables in my list of unadded files.
On Windows, this is very easy: *.exe. On Linux, executables typically do not have an extension. So how do you set up a filter that will ignore files that have no extension?

There's no way to do it. You could, relatively easily, build a list of the executable files that exist now and automatically add them to your .hgignore but new ones will still show up as un-tracked.

I have occasionally tweaked my project build files (Makefiles, .sconstructs, etc.) to build UNIX executables as foo.x rather than foo, just to make automatically ignoring them easier.

Related

Mercurial -- Ignore certain files based on the existence of other files

I use mercurial to keep track of a repository which contains both PDF files (generated by others, which I need to keep track of), and latex files, written by me.
For instance, assume a directory structure like this:
root
- Requirements.pdf
- MyReport.tex
- MyReport.pdf
In this case, MyReport.pdf changes every time MyReport.tex does, and can be wholly determined by the contents of the tex file, so it should not be under version control.
I am looking for a way to tell mercurial to ignore such files. Obviously I can add a rule to .hgignore like this (http://www.selenic.com/mercurial/hgignore.5.html)
syntax: glob
*.pdf
But that will ignore the PDFs that I do need to keep version controlled.
There's also this link: https://www.mercurial-scm.org/wiki/TipsAndTricks#Avoid_merging_autogenerated_.28binary.29_files_.28PDF.29 but that doesn't really solve my problem either, because while it handles building the PDFs, it does not handle telling hg which files are important.
Or I could just do this manually, but I would like a way to script it, to make it more general, since these repositories can have several dozen tex and pdf files and manually managing this has become cumbersome.
It seems like quite a simple rule: If there is a file by the name of "blah.pdf", check to see if there is also a file name "blah.tex" and if so, ignore it, otherwise, pay attention to it. But I can't find anything about that.
There is no such feature in Mercurial, nor in Git, nor will there likely ever be such a feature because it's extremely niche. However, you might consider simply putting your "generated" files into a separate output subdirectory, and then ignoring all such directories. For example, if you have an input like foo/bar.tex, the output could be foo/gen/bar.tex, and you could ignore gen/.
Obviously I can add a rule to .hgignore like this
(http://www.selenic.com/mercurial/hgignore.5.html) ... But that will
ignore the PDFs that I do need to keep version controlled.
.hgignore ignore all newly added or existing not versioned files, matching pattern, but bolded texts give you at least two usable solutions:
Write regexp, which means "all pdf, except some filename(s)" (with manually added filenames, most probably)
use wide pattern, but add needed files into repository explicitly (hg add FILENAME)

Sharing files between Mercurial repositories

There are one or two files, like .hgignore, which I generally want to be the same in each of a bunch of projects.
However, the nature of these files means that I can't simply move them to a common shared project and just make the other projects depend on that project. They have to be inside each project. Symbolic links are not an option either because some of our developers use Windows.
How can I share these files between repositories and have changes propagated across (on my local machine, at least)? I'm using Eclipse.
For your specific case of hgignore you can put an entry like this in each project's .hg/hgrc file:
[ui]
ignore.common = ~/hgignore-common
If you you know your common library will always the in the parent directory, as is often the case with a subrepo setup you could do:
[ui]
ignore.common = ../hgignore-common
or if you know it will always be in a sibling directory of project checkouts you could do:
[ui]
ignore.common = ../company-wide-defaults/hgignore-common
Unforunately there's no absolute way to reference a file that's valid everywhere, but you can at least to to a point where on your machine all your checkouts are referencing a common ignore.
Hardlinking instead of copying the relevant files sort of works with Eclipse - although you have to refresh each of the other projects to get it to pick up the change. However, you can configure Eclipse to watch the filesystem and automatically refresh whenever it needs to - I recommend this.
It does not work by default with Emacs, because Emacs breaks hard links (which is normally the right thing to do, but is not what you want in this case). However, you can disable this behaviour for multiply-linked files with (setq backup-by-copying-when-linked t).

Cross-platform hgrc solution?

I'm looking for a solution to have one .hgrc for mercurial to work in all my working environments(win/lin/mac), just like one vimrc to rule all.
It comes to a problem when I have to specify the path for some extensions, for example, hg-git:
on windows:
[extensions]
hggit = E:\hg-git\hggit
on linux/mac:
[extensions]
hggit = ~/hg-git/hggit
For vimrc, we have solution to distinguish different platform, like
if has('win32')
...
endif
Knowing that mercurial's hgrc is barely a normal ini file, I wonder if there is similar solution for hgrc file.
Or maybe some other solution?
Update
Thanks for mentioning using "custom environment variable instead of hard coding", that works for extensions' path.
However, to make extensions work is just one goal. I believe there are other configurations' behavior that depends on platform, like in http://www.ogre3d.org/docs/OGREDeveloperGuide/index.html, specific options are needed for Windows and Mac. How to solve this kind of problem?
How about using the .hgrc include mechanism and three separate files:
~/.hgrc
~/.hgrc-windows
~/.hgrc-linux
where the main ~/.hgrc has:
%include .hgrc-$OS
and then set $OS in your windows profile and your linux profile's. Alternately you could probably find an env variable that already exists on both systems ($USERNAME is usally already set in both windows and unix and may differ for you).
This is just in case you don't find a way to have only one .hgrc (or one set of .hgrc* files, per Oben Sonne's comment).
I only face Windows environments, so my mercurial.ini files are the same except for 1 path. I keep a copy in version control along with my Powershell profile script.
However, if I were faced with environments more varied, I would abstract the configuration to a script in a cross-platform language (e.g., Python) that overwrites the target .hgrc or mercurial.ini. I'd be able to have the pieces that have to be different for each OS/machine right next each other with easy ways of distinguishing which environment is current. Then I would keep that script in version-control to help keep the same version on each machine.
Since I don't change it often, I would probably execute it manually on each machine when I visited it next. For a larger number of machines or more frequent changes, I would have another script executed on login that pulls changes to the generating script from a central repo, and if there were indeed new changes pulled, update to tip and run the script.
(Heck, I'm now tempted to rig this kind of setup anyway.)
Why don't you just use a custom environment variable instead of hard coding the paths?

Perforce like client specs mappings with Mercurial

We recently moved from Perforce to Mercurial and love it!
One little problem: after much research we can't figure out how to map a special directory in the repository to some special place on the client. Here is an example of our hg repo:
/foo/source files
/bar/source files
/build
/macosx/mac make files
/win/windows make files
With Perforce, we were using client spec mappings to map //depot/build/macosx/... to just /build/... on the Mac client, and //depot/build/win/... to /build/... on the Windows dev box. Directories foo and bar are synced as is. Makefiles in /foo and /bar assume that our build makefiles are located in /build and we would like to keep them as is. The final client set of files should look like this:
/foo/source files
/bar/source files
/build/client specific make files
I've read about subrepos, but this solution does not seem to be client specific.
Any idea how to solve this problem will be very much appreciated!
You can't check out only portions of a repository with Mercurial.
You always get a clone containing everything, and the working directory will also contain everything.
With Mercurial you should strive to have 1 repository for 1 project, so that everything you get logically belongs together, and then you shouldn't have much need for just a portion of it.
This also means that whatever directory structure you have in your Mercurial repository will always match exactly the structure you have on disk.
You can't do this with Mercurial as it doesn't have the concept of a client separate from a depot.
However, you can use a symlink on Mac OS X (ln -s) and a junction on windows (mklink on Vista and up using the junction tool on XP http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx) to solve this problem on the file system level.
Alternatively you can use a variable in the Makefiles to refer to the build directory (eg $(BUILD)/something.ext instead of build/something.ext).
This sort of mapping cannot be done in Mercurial. There is an outstanding TODO item for 'narrow' clones so you can check out just a subdirectory. And I could see an implementation of that supporting that sort of functionality. But then again, I know that something like this would be considered a little too 'clever' (read complex) and there would be a lot of push-back on the idea.
In the meantime, I would suggest one of these two solutions.
Symbolic links. Put the symbolic link to your build directory in your .hgignore file. Then each person can make their own symbolic link to the appropriate directory of build files. This has the disadvantage of not working on a platform without symbolic links.
An environment variable that's used in a top level makefile to construct the path to the platform specific makefile it should be calling.

Mercurial (Hg) and Binary Files

I am writing a set of django apps and would like to use Hg for version control. I would like each app to be independent of the others so in each app there may be a directory for static media that contains images that I would not want under version control. In other words, the binary files would not all be in one central location
I would like to find a way to clone the repository that would include copies of the image files. It also would be great if when I did a merge, if there were an image file in one repo and not another, that there would be some sort of warning.
Currently I use a python script to find images and other binary files that are in one repo, but not the other. But a lot of people must face this problem, so there must be a more robust and elegant solution.
One one other thing...for reasons I do not want to go into, usually one of my repos is on a windows machine, and the other is on Linux. So a crossplatform solution would be nice.
Since Mercurial 2.0 the extension largefiles is now included in the main distribution. That extension keeps and manages large files outside of the "normal" repository in a way that you get the benefit of DCVS but without the benefit of exponential size and processing time growth.
Other extension that work along similar lines are SnapExtension and BigFilesExtension. However, those two are not distributed with Mercurial (you have to get them manually).
Mercurial can track any kind of file, for binary files if something changes then the whole file gets replaced not just the changes.
On the getting a warning if one repo doesn't contain a file, that's kind of the point of a DVCS is that the repos are related but are autonomous. You could always check and see what files were added during a synch or merge operation.
The current Mercurial book (by Bryan O'Sullivan) says, that Mercurial stores diffs also for binary files. How efficient this is, obviously depends on the nature of changes to binary files.