I need to ignore all files in whole project tree, versioned by Mercurial, that starts with specific character. Let's say underscore (or it may be some other).
I searched on google a lot, but I cannot find right glob syntax. I found glob expression test environment, where I could try patterns, but nothing works for me.
Consider following project structure:
/function/_backup/file1.php
/function/_backup/file2.php
/function/Class/A.php
/function/Class/_B.php
/_graph/1.jpg
/.hgignore
/.htaccess
/_index.php
/index.php
The only files that I need to propagate to repository are A.php, .htaccess and index.php.
The question is: how should my .hgignore look like?
You should add the following line to .hgignore:
glob:_*
I'm working on a commit hook for Mercurial and running into problems with relative paths.
Say my hook wants to look at the contents of the files being committed and warn if any contain the phrase "xyzzy". However, the user has decided to call commit from a subfolder and pass in the name of the file as a pattern...
C:\clone\subdir> hg commit file.txt -m 'test'
My hook is called with C:\clone as the working directory, but HG_PATS contains simply file.txt with no subdir\ prefix. How can I get the working directory of the hg command itself? I can't find a way to do this in docs.
The only way I can figure out how to get it is look up the process tree to find the first hg.exe and get its working directory. But that's not exactly portable to other OS's. (And I know I could write an extension, but would really like to avoid that.)
If you use the pretxncommit hook then you are given $HG_NODE which is the commit id, but the commit hasn't been finalized at that point so you can still return 1 to cancel it.
Then you could use
hg log -r $HG_NODE --template '{files}'
to get the list of files in the commit, and it gives you the full path relative to the repo root.
It's not exactly what you were after but it might get you close enough to let you do the content examination you want.
Thanks for the answers and comments, but after some more research I determined there's no clean way to do what I want from an external hook. I did implement the CWD hack I mentioned in my question. Not a ton of code, but quite nasty, and on Windows it requires undocumented access to external process CWD via tlist.exe. It works, but..yuck.
The right way to do this appears to be to write an in-process hook (example library at hghooklib). Usual versioning caveats apply as with writing any extension, though I think for our hooks the interface to hg is simple enough that we'll be ok.
(In my question I mentioned I didn't want to write an extension, but I was thinking of a full extension like hgeol. A hook-only extension with a single function entry point feels more constrained and simple, which is what I want at this point.)
When I create a new repository, I can ask TortoiseHG to give me a .hgignore file. Is there a way that I can customise what that file will look like, rather than having to go and get one manually from somewhere every time?
It's an old question, put still popped up as the first result on google, so here is an update:
In the TortoiseHg settings under the tab TortoiseHg users can specify the path of a Repo Skeleton. You can put your predefined .hgignore there, and it will be automatically copied during hg init.
See also:
#3569 Allow user-defined default .hgignore file when creating a new repository
TortoiseHG Docs
Like Tim already said in his comment, apparently it's not possible to do this.
Take a look at the following issue from TortoiseHG's bug tracker:
#966 Include some reasonable defaults in .hgignore on repo creation
Quotes from this link, both by Steve Borho (THG project lead):
This topic comes up on the Mercurial mailing list once a year or so and Matt always shoots it down. There is already support for user level ignore files; one could add these globs to a global file and be done with it.
and:
If a user has files or directories that they always want to ignore, they can add those to a global ignore file without having to introduce any new behaviors in THG.
So putting the things you always want ignored in a user-global ignore file seems to be the only option (even though it's not exactly what you're asking for):
Would like to create some defaults for my .hgignore files in TortoiseHG/Mercurial
(the question that I posted in my comment above)
Global hgignore usage
I've read several posts here about ignoring files in Mercurial but I'm stumped on this one.
I have a couple of .svn files in my repository (I'm using hg for local commits, then pushing to svn). The files are:
Apps\.svn\dir-prop-base
Apps\.svn\entries
I've got several ignore entries in my .hgignore but none of them seem to be covering these two files.
syntax: glob
.svn/*
**/.svn/**.*
syntax: regexp
\.svn\\*
I'm trying a couple of things to see which sticks there. To me, it looks like those files should be ignored twice. The strange thing is that Apps\.svn\all-wcprops is being ignored. Clearly I'm missing something. I'm checking whether the files are ignored by opening a new status window using TortoiseHg. I can't detect any difference between that and hg status.
Oben pointed me in the right direction. He declined making an answer, so here it is:
The files that you want to ignore can't be in an Add state when you are editing the ignore file (since Add takes precedence over Ignore apparently). So my solution was to do hg revert, edit the ignore file, then use hg status [directory] -i to see which files in the target directory would be ignored. Repeat until all the correct files are ignored, then use hg add.
syntax: regexp
^.*\.svn/dir-prop-base$
works for me.
The following simple .hgignore works fine for me to ignore all .svn folders (on Windows, hg 1.7):
syntax: glob
.svn
I have a personal Mercurial repository tracking some changes I am working on. I'd like to share these changes with a collaborator, however they don't have/can't get Mercurial, so I need to send the entire file set and the collaborator will merge on their end. I am looking for a way to extract the "tip" version of the subset of files that were modified between two revision numbers. Is there a way to easily do this in Mercurial?
Adding a bounty - This is still a pain for us. We often work with internal "customers" who take our source code releases as a .zip, and testing a small fix is easier to distribute as a .zip overlay than as a patch (since we often don't know the state of their files).
The best case scenario is to put the proper pressure on these folks to get Mercurial, but barring that, a patch is probably better than a zipped set of files, since the patch will track deletes and renames. If you still want a zip file, I've written a short script that makes a zip file:
import os, subprocess, sys
from zipfile import ZipFile, ZIP_DEFLATED
def main(revfrom, revto, destination, *args):
root, err = getoutput("hg root")
if "no Merurial repository" in err:
print "This script must be run from within an Hg repository"
return
root = root.strip()
filelist, _ = getoutput("hg status --rev %s:%s" % (revfrom, revto))
paths = []
for line in filelist.split('\n'):
try:
(status, path) = line.split(' ', 1)
except ValueError:
continue
if status != 'D':
paths.append(path)
if len(paths) < 1:
print "No changed files could be found."
return
z = ZipFile(destination, "w", ZIP_DEFLATED)
os.chdir(root)
for path in paths:
z.write(path)
z.close()
print "Done."
def getoutput(cmd):
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p.communicate()
if __name__ == '__main__':
main(*sys.argv[1:])
The usage would be nameofscript.py fromrevision torevision destination. E.g., nameofscript.py 45 51 c:\updates.zip
Sorry about the poor command line interface, but hey the script only took 25 minutes to write.
Note: this should be run from a working directory within a repository.
Well. hg export $base:tip > patch.diff will produce a standard patch file, readable by most tools around.
In particular, the GNU patch command can apply the whole patch against the previous files. Isn't it enough? I dont see why you would need the set of files: to me, applying a patch seems easier than extracting files from a zip and copying them to the right place. Plus, if your collaborator has local changes, you will overwrite them. You're not using a Version Control tool to bluntly force the other person to merge manually the changes, right? Let patch deal with that, honestly :)
In UNIX this can be done with:
hg status --rev 1 --rev 2 -m -a -n | xargs zip changes.zip
I also contributed an extension, see the hgexportfiles extension on bitbucket for more info. The export files extension works on a given revision or revision range and creates the set of changed files in a specified directory. It's easy to zip the directory as part of a script.
To my knowledge, there's not a handy tool for this (though a mercurial plugin might be doable). You can export a patch for the fileset, using hg export from:to (where from and to identify revisions.) If you really need the entire files as seen on tip, you could probably hack something together based on the output of hg diff --stat -r from:to , which outputs a list of files with annotations about how many lines were changed, like:
...
src/test/scala/RegressionTest.scala | 25 +++++++++++++----------
src/test/scala/SLDTest.scala | 2 +-
15 files changed, 111 insertions(+), 143 deletions(-)
If none of your files have spaces or special characters in their names, you could use something like:
hg diff -r156:159 --stat | head - --lines=-1 | sed 's!|.*$!!' | xargs zip ../diffed.zip
I'll leave dealing with special characters as an exercise for the reader ;)
Here is a small and ugly bash script that will do the job, at least if you work in an Linux environment. This has absolutely no checks what so ever and will most likely break when you have moved a file but it is a start.
Command:
zipChanges.sh REVISION REPOSITORY DESTINATION
zipChanges.sh 3 /home/hg/repo /home/hg/files.tgz
Code:
#!/bin/sh
REV=$1
SRC_REPO=$2
DST_ZIP=$3
cd $SRC_REPO
FILES=$(hg status --rev $1 $SRC_REPO | cut -c3-)
IFS=$'\n'
FILENAMES=""
for line in ${FILES}
do
FILENAMES=$FILENAMES" \""$SRC_REPO"/"$line"\""
done
CMD="tar czf \"$DST_ZIP\" $FILENAMES"
eval $CMD
I know you already have a few answers to this one but a friend of mine had a similar issue and I created a simple program in VB.Net to do this for him perhaps it could help for you too, the prog and a copy of the source is at the bottom of the article linked below.
http://www.simianenterprises.co.uk/blog/mercurial-export-changed-files-80.html
Although this does not let you pick an end revision at the moment, it would be very easy to add that in using the source, however you would have to update to the target revision manually before extracting the files.
If needed you could even mod it to create the zip instead of a folder of files (which is also nice and easy to manually zip)
hope this helps either you or anyone else who wants this functionality.
i just contributed an extension here https://sites.google.com/site/alessandronegrin/pack-mercurial-extension
I ran into this problem recently. My solution:
hg update null
hg debugsetparents (starting revision)
hg update (ending revision)
This will have the effect of deleting all tracked files that were not changed between those two revisions. You will have to remove any untracked files yourself, though. After doing this, the local branch will be in an inconsistent state; you can fix this by running hg debugrebuildstate (or simply deleting the local branch, if you no longer need it).