How to use a relative pathname to a Mercurial hook - mercurial

I have a script that is in the top level of my working copy and would like to use it as a Mercurial hook. If I use an absolute pathname to the hook then everything is fine, but I want a relative pathname so the whole thing can be easily moved around, used in other working copies and other developers can copy the hgrc as is.
/space/project/.hg/hgrc contains
[hooks]
update = genid
The genid script is at /space/project/genid
The hook is invoked just fine if I am in /space/project but if my current directory is /space/project/src/tools then 'hg update' will give an error as the hook cannot be found.

Python hooks cannot use a relative path. Script hooks can like this:
[hooks]
update = ./genid

In certain cases, environment variables are expanded in mercurial configuration. So you can check out if you can use a environment variable.
[hooks]
update = $MercurialHooks/genid
See Faq (12) in https://www.mercurial-scm.org/wiki/TipsAndTricks

I had the same problem and couldnt resolve it. The workaround was easy though! I versioned the file in the repo and just copied it to my .hg folder! Not ideal but it isnt that likely to change and other repo users can still get a copy of the file

Related

How to get the working directory of the command from an hg hook?

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.)

How to add specific subfolder of subrepo

I'm comming from SVN background and I'm having a problem of adding to my main repo a subfolder of subrepo. That means that I don't want to add the whole subrepo to my main project - only a part of it. In my situation I want to include only source files of my library excluding all unit tests.
I have created .hgsub file and wrote there:
libs/my_std_lib = https://myreposhost.com/my_std_lib_repo/src/main/java/
But when I'm trying to synchronize libs/my_std_lib folder I get such error: HTTP Error: 404 (Not Found)
When I try to synchronize without subpath (https://myreposhost.com/my_std_lib_repo/) - it works well.
So what do I do wrong or this is not posible in hg?
The answer is pretty simple : it's impossible to clone only a part of a repository with Mercurial.
By extension, you can't add only a part of a repository as a subrepo.
Sorry.

Mercurial workflow with subrepositories and offline clones?

I'm offline a lot.
So normally, I use one local clone as a "hub" for features, bugs, etc.
hg clone local-hub bug-123
Works offline. Cool.
Can I use a similar workflow if that project contains remote subrepositories?
Because, if .hgsub says
sub/shared = http://server/hg/shared
hg clone says
abort: error: getaddrinfo failed
Note that once the clone is created (while connected), push and pull will use the path in the subrepo's hgrc (instead of the location in .hgsub). So I can point this to a local clone and everything is cool.
But clone looks at .hgsub (as it's supposed to). So if the "blessed" subrepo is on a server, I can't create new clones offline, even though the files I need are right there.
This is a problem, right?
Ideally whomever set up the project uses relative URLs in their .hgsub file like this:
sub/shared = ../shared
and then, of course, actually makes shared a sibling of the main repo. Then as long as you have cloned down the main repo and the subs (as siblings) then everything will work out.
If they've used absolute URLs in their .hgsub file you can work around it using the subpaths section in your .hgrc like this:
[subpaths]
http://server/hg/shared = ../shared
which provides a translation layer in your client.
The canonical way to use subrepositories is to have X = X paths in the .hgsub file:
sub/shared = sub/shared
That way a clone will structurally look just like the original -- and so you can use the clone to make further (local!) clones.
However, this is not always possible, for example, Bitbucket wont let you create the nested repositories on their server. In that case, the ../X style paths in the .hgsub file is better, and you can use the subpaths configuration section to translate these paths into paths you can use locally.

Mercurial subrepo and relative path

I have a project, which I have a bitbucket repository for, and it is dependent on another project that I incorporate as a subrepo. Now, I don't have push access to the subrepository, nor do I want or need to--it's a pull-only relationship.
I realize that when you push the main repository, it will try to push the subrepositories, as well. Since I cannot do that, I pulled a local copy of the dependent project, at the same level as the main repository's directory. In essence, I have the following layout:
Main/ ; pushes to https://mine.org/Main
.hg/
.hgsub
Lib/
SubRepo/ ; clone of Main/../SubRepo/
.hg/
SubRepo/ ; local copy of https://forbidden.org/SubRepo
.hg/
The content of .hgsub is something like,
Lib/SubRepo = ../SubRepo
Then I cloned,
~/path/to/Main $ hg clone ../SubRepo/ Lib/SubRepo
So far, so good. The problem is, after I set this all up and committed the changes, when I try to push Main Mercurial will try to push SubRepo to https://mine.org/SubRepo, which does not exist, thereby failing the whole push operation.
Is there something I'm missing?
Why not just create a https://mine.org/SubRepo -- if you don't want to advertise it you can always turn on hide for it in the [web] section in its .hg/hgrc file. This is the pattern I'm used to, where you clone down the main repo and all the subrepos in the same layout at each place you'll use them: both your development box and your web-facing hgweb install.
Alternately, you could use a [subpaths] section in Main/.hg/hgrc with something like this in it:
[subpaths]
https://mine.org/SubRepo = https://forbidden.org/SubRepo
which should let you intercept the derrived target for the push and point it at a place that which it won't let you push, will let you see nothing has changed so push can continue.
It seems like what Mercurial is doing is legitimate: using the paths listed in your .hgsub it's attempting to push to a directory called 'SubRepo' that exists one level up from Main. This is obviously not what you want, so you'll probably have to work some magic here. I can think of two options:
If you can support this, place the local copy of forbidden.org's repository at C:/Forbidden/Subrepo or something like that, and use this absolute path in your .hgsub. Mercurial will be able to push to this and it should work.
There's no problem including the actual forbidden.org url as your subrepo address if you don't make any modifications to this repo. If there are no changes to the subrepo, your push should succeed. Of course, this is a fairly manual option and on a larger team it would be impossible to enforce. If you did accidentally commit some modification to the subrepo, you'd have to go through and use histedit or MQueues to pull it out, and that can be tricky with subrepos.

Mercurial replacing values in a file that been cloned?

Say I'm cloning a repository that I always clone to C:\working_copies\<customer-name>\<customer-project>\ and that the project has variables in it's build.properties that get filled in with <customer-name> <customer-project> (by me) everytime I clone the repo.
Is there a way that I can fill in these values in the file automatically by placing some special value in the file (in ant it's something like ${base-dir} or something like that) that would fill in these build.property values for me?
option 1: make sure build process only relies on relative paths, and dont change name/project variable
option2: write a hook, specifically a post-clone hook, try the book for a hook tutorial
No, Mercurial is completely unaware of what is outside of it's repository folder.
You should be able to rig this up using the Keyword Extension. Just set up a HGRC that populates the working directory with the values you want upon update.