hgignore multi line regex - mercurial

I googled a bit, but didn't find any suggestions on that topic. Is multi line regex possible in .hgignore?
I'm writing a magento module, and wan't to include only my module code in repository, so I came up with this regex, but it would a be mess, if I had to write it in one line.
syntax: regexp
^(?!(
app/code/local/Mage/Myreviews/|
app/design/frontend/default/default/layout/myreviews\.xml|
app/design/frontend/default/default/template/myreviews/|
app/etc/modules/Mage_Myreviews\.xml|
skin/frontend/default/default/css/myreviews/|
skin/frontend/default/default/myreviews/|
js/myreviews/
)).*

As for the canonical answer to your question, are multi-line regular expressions supported? No. For confirmation, take a look at the ignorepats function in ignore.py in the mercurial Python package—it iterates over the lines in the file one by one.
As for what you should do instead, #jk.'s answer is good (and the glob: * that you've come up with).

You can add files to a repository and have mercurial track them even if they match an ignore rule, so usually the best way to do this sort of thing is to ignore a bit too much e.g. (don't know anything about magneto modules so this may be wrong)
syntax: glob
app/*
skin/*
js/myreviews/*
and then explicitly hg add the files you do want.
As Joel points out hg adds --include and --exclude options are also useful in these scenarios
pre-emptive additional info: hg forget will undo tracking a file without deleting it

Related

Mercurial : "diff" of a changeset in template

I am trying to display the diff of each changed file in a changeset, using a template.
What I need is something very similar to "hg diff" command. I cannot find anything which might serve my purpose in the help here
To add context, I am trying to use this template in Bugzilla extension. I need to add the diff of the changes which went in to bugzilla ticket.
You can use diff() pattern
(extract from hg help templates - better than URL referenced by you)
- diff([includepattern [, excludepattern]])
You if you don't specify any patterns, it will simply give you the equivalent of hg log -p. If you want to print diff per file, you will need to pass explicit filenames as includepattern parameter, like
hg log -r tip --template "{diff('mercurial/bundlerepo.py')}"
Looping through the list of files (like "{files % '{file}'}" in templates help) seems broken in this case (well, I didn't manage to make it work). Probably it's a bug, so you can write to mercurial discussion list to get confirmation.
Anyways, to get more luxury support, better to write to mercurial discussion list, or join #mercurial IRC and ask :)
Also they will guide you on how to achieve what you are trying to do in better way - seems you are trying to reinvent something

How to embed version information in source code with Mercurial

I would like to embed some version information on top of my source code file with information such as version number, author, and date of edit.
Is there a simple way to do this with Mercurial?
This has been asked a lot here on Stackoverflow and the short answer is: you shouldn't do it.
You don't want a file that changes with every commit it makes merging a nightmare.
Better options are:
write the version string to a file on update
have you build/deploy script run $(hg id) and put that into the build at that time
Trust me, revision strings in files is CVS/SVN thinking. It has no place in a git / Mercurial world.
As comments and other answers mention, it is not a good idea to rely on CVS-like, automatically expanded, tags. Specially since you can extract whatever meta-information you need at any time and almost any granularity afterwards.
However, if you really need it (because your boss says so, for instance), the closest you can get is by making use of the keyword extension that comes bundled with mercurial.
My favorite way is to use the hgversioninfo plugin.
It generates a version.py file on the fly on "hg commit", "hg update", etc.
Yes it is possible, but you need to enable it. What you are asking for is basically the keyword extension. Be careful when enabling this the first time (read the section about kwshrink, kwexpand), because you wouldn't want the actual expanded keywords to become part of the revision history.

Search for "TODO" only in files which changed in specific mercurial changeset(s)?

I'm working in a code base that already has a lot of "TODO" comments, and before I push my changeset(s) I want to make sure I haven't left any of my TODO comments in there (rather than actually doing it, or adding it to the new-feature database and removing the comment).
At the moment I'm just using "TODO: Wilka" in each of the comments, so it's easy to search for. But is there a way with Mercurial I can search for "TODO" only in the files that have changed in a collection of changesets? Ideally, it would only search the lines that have actually changed - but even just the files would be good.
to search a specific set of revisions you could do:
hg grep -r 0:3 "\bTODO:"
Diff between wanted revisions piped to the grep, only modified files file be searched with the grep
hg diff -r 100:105 | grep TODO
EDIT:
As mentioned in the comments, this is presumes that grep is installed (so non Windows enviroment)
#thanks Tim, if using Windoes, use findstr instead of the grep
The automated way is via Mercurial commit hooks. The examples may be helpful as might the checkfiles extension referred to by mercurial developers.
In my experience, commit hooks are a mixed bag and often do what you want but are irksome when you really want to commit a TODO. The Shelve extension attempts to work around this, but the cure can be worse than the problem.
I haven't explored the possibility of something like hg com --but-ignore-my-TODO-hook which could be nifty.

How can I ignore all directories except one using .hgignore?

I'm managing $HOME using Mercurial, to keep my dotfiles nice and tracked, or at least the ones that matter to me.
However, there's a profusion of files and directories in ~ that do not need to be tracked, and that set is ever-changing and ever-growing.
Historically, I've dealt with this by having this .hgignore:
syntax: glob
*
This keeps my status clean, as far as it goes, making only previously tracked files visible. However, I have some directories (in my case, scripts, .emacs.d) that I would like to see untracked files in; I almost always want to track new additions to those directories.
I know that I can run hg st -u scripts to identify untracked files, but I want a means whereby I can achieve the same function using plain ole hg status.
Is there a way to do this?
Try this in .hgignore instead:
syntax: regexp
^(?!(scripts|foo|bar)/)[^/]+/
^ matches start of path
(?!(scripts|foo|bar) uses negative lookahead to ignore all files except those in directories scripts, foo or bar
/) ensures that directories which have a tracked directory as a prefix are ignored
[^/]+/ then actually matches any directory (excluding those ruled out by the lookahead), so that files in ~ aren't ignored
Credit for the central idea in this solution (the negative lookahead) goes to Michael La Voie's answer to this question
This question has been asked here on SO quite a few times, and you'll get a lot of convoluted answers using zero-width negative look ahead assertions, an oft abused regex trick, but the better solutions are to either (a) just make the repo in that directory alone or (b) just add the files in that directory. For option (b) you'd just put .* in your .hgignore file to ignore everything, and then manually hg add the files you want tracked. In mercurial, unlike svn and cvs, you can override an ignore with an add.

How good is my method of embedding version numbers into my application using Mercurial hooks?

This is not quite a specifc question, and more me like for a criticism of my current approach.
I would like to include the program version number in the program I am developing. This is not a commercial product, but a research application so it is important to know which version generated the results.
My method works as follows:
There is a "pre-commit" hook in my .hg/hgrc file link to version_gen.sh
version_gen.sh consists solely of:
hg parent --template "r{rev}_{date|shortdate}" > version.num
In the makefile, the line version="%__VERSION__% in the main script is replaced with the content of the version.num file.
Are there better ways of doing this? The only real short coming I can see is that if you only commit a specfic file, version.num will be updated, but it won't be commited, and if I tried to add always committing that file, that would result in an infite loop (unless I created some temp file to indicate I was already in a commit, but that seems ugly...).
The problem
As you've identified, you've really created a Catch-22 situation here.
You can't really put meaningful information in the version.num file until the changes are committed and because you are storing version.num in the repository, you can't commit changes to the repository until you have populated the version.num file.
My solution
What I would suggest is:
Get rid of the "pre-commit" hook and hg forget the version.num file.
Add version.num to your .hgignore file.
Adjust version_gen.sh to consist of:
hg parent --template "r{node|short}_{date|shortdate}" > version.num
In the makefile, make sure version_gen.sh is run before version.num is used to set the version parameter.
My reasons
As #Ry4an suggests, getting the build system to insert revision information into the software at build time, using information from the Version Control System is a much better option. The only problem with this is if you try to compile the code from an hg archive of the repository, where the build system cannot extract the relevant information.
I would be inclined to discourage this however - in my own build system, the build failed if revision information couldn't be extracted.
Also, as #Kai Inkinen suggests, using the revision number is not portable. Rev 21 on one machine might be rev 22 on another. While this may not be a problem right now, it could be in the future, if you start colaborating with other people.
Finally, I explain my reasons for not liking the Keyword extension in a question of mine, which touches on similar issues to your own question:
I looked at Mercurials Keyword extension, since it seemed like the obvious solution. However the more I looked at it and read peoples opinions, the more that I came to the conclusion that it wasn't the right thing to do.
I also remember the problems that keyword substitution has caused me in projects at previous companies. ...
Also, I don't particularly want to have to enable Mercurial extensions to get the build to complete. I want the solution to be self contained, so that it isn't easy for the application to be accidentally compiled without the embedded version information just because an extension isn't enabled or the right helper software hasn't been installed.
Then in comments to an answer which suggested using the keyword extension anyway:
... I rejected using the keyword extension as it would be too easy to end up with the string "$Id$" being compiled into the executable. If keyword expansion was built into mercurial rather than an extension, and on by default, I might consider it, but as it stands it just wouldn't be reliable. – Mark Booth
A don't think that there can be a more reliable solution. What if someone accidentally damages .hg or builds not from a clone but from an archive? – Mr.Cat
#Mr.Cat - I don't think there can be a less reliable solution than the keywords extension. Anywhere you haven't explicitly enabled the extension (or someone has disabled it) then you get the literal string "$ID$" compiled into the object file without complaint. If mercurial or the repo is damaged (not sure which you meant) you need to fix that first anyway. As for hg archive, my original solution fails to compile if you try to build it from an archive! That is precisely what I want. I don't want any source to be compiled into our apps without it source being under revision control! – Mark Booth
What you are trying to do is called Keyword Expansion, which is not supported in Mercurial core.
You can integrate that expansion in make file, or (simpler) with the Keyword extension.
This extension allows the expansion of RCS/CVS-like and user defined keys in text files tracked by Mercurial.
Expansion takes place in the working directory or/and when creating a distribution using "hg archive"
That you use a pre-commit hook is what's concerning. You shouldn't be putting the rest of version_gen.sh into the source files thesemves, just into the build/release artifacts which you can do more accurately with an 'update' hook.
You don't want the Makefile to actually change in the repo with each commit, that just makes merges hell. You want to insert the version after checking out the files in advance of a build, which is is what an update hook does.
In distributed systems like Mercurial, the actual "version number" does not necessarily mean the same thing in every environment. Even if this is a single person project, and you are really careful with having only your central repo, you would still probably want to use the sha1-sum instead, since that is truly unique for the given repository state. The sha1 can be fetched through the template {node}
As a suggestion, I think that a better workflow would be to use tags instead, which btw are also local to your repository until you push them upstream. Don't write your number into a file, but instead tag your release code with a meaningful tag like
RELEASE_2
or
RELEASE_2010-04-01
or maybe script this and use the template to create the tag?
You can then add the tag to your non-versioned (in .hgignore) version.num file to be added into the build. This way you can give meaningful names to the releases and you tie the release to the unique identifier.