My project's .hg directory is 40MB. If I hg push --verbose --debug to an empty remote repository I see it sending hundreds of MBs. Where is the extra overhead coming from?
UPDATE: hg bundle -a generates a 35MB file. Here is a stripped-down version of the output I'm seeing:
pushing to https://jace.googlecode.com/hg/
using https://jace.googlecode.com/hg/
sending between command
using auth.default.* for authentication
jace.googlecode.com certificate successfully verified
sending capabilities command
using auth.default.* for authentication
capabilities: branchmap lookup unbundle=HG10UN,HG10UGZ,HG10BZ changegroupsubset
sending heads command
using auth.default.* for authentication
searching for changes
common changesets up to 71818a195bf5
sending branchmap command
[...]
bundling: <filenames>
sending unbundle command
sending xxx bytes
[...]
sending: xxx/xxx kb
This is a known python bug. Because of the way the python http library work, it first sends the data, the server replies that it needs an auth, and it resends the data.
With a recent mercurial (starting at 1.9) you can use an alternative http library. Just add the following in hgrc:
[ui]
usehttp2 = true
It could be that the repository you're pushing to doesn't support compressed transfer. What protocol are you using? If it's http, I recommend you watch the first requests to the remote repository (one of them is about determining the capabilities the remote repo offers).
If you're using a file URL for pushing, there's probably not much you can do about it.
Related
I want to push a repository from my computer to a repository on a remote site for the purpose of synchronizing the files. TortoiseHg seems to correctly identify outgoing changesets, but when I try to push the changes, TortoiseHg responds with "abort: destination does not support push" with "Push to https://myid:ps#mydomain.com aborted, ret 255" in the status bar at the bottom. The log file includes "(falling back to static-http)"
I've googled but I'm getting nowhere. What does "abort: destination does not support push" mean in English? What doesn't support push? What is the "destination"? Is it the settings in the config files in the repo that make it so the destination doesn't support push? Is it the way the server is set up?
One of the responses to 27967022 "Your destination does not support push, or push is disabled" So how does one enable push?
If you use hgweb on the server side, to allow pushing to a repository, add
[web]
allow_push = *
to its .hg/hgrc on the server or in your hgweb.config. You can also allow pushing only for specific users by listing them instead of *. This is documented here.
If that is not the case and you just use the https server to serve the repo as files, you'll not be able to push via https. In that case, your most likely option is to push via ssh, as in
hg push ssh://myid#mydomain.com/path/to/repo
This requires that you have ssh access to the server and that the repository lies in $HOME/path/to/repo. For an absolute path (if the repository lies in /path/to/repo and not below $HOME), push to ssh://myid#mydomain.com//path/to/repo (note the double slash).
If you always push to the same destination, you can add this path to your local .hg/hgrc:
[paths]
default-push = ssh://myid#mydomain.com/path/to/repo
so that you can then just use hg push.
What are you running for your mercurial server on mydomain.com? If it's hgweb, then #wintermute has your answer. If you're serving static HTTP (using Apache, nginx, etc.) then your server is setup for clone or pull, but not push. More likely you just need to enable push like #wintermute is saying.
I need to control the version of a few files accessible via an SMB share. These files will be modified by several people. The files themselves are directly used by a web server.
Since these are production files I wanted to force the users to pull a local copy, edit them, commit and push them back. Unfortunately there is no Mercurial server on that machine.
What would be the appropriate way to configure Mercurial on my side so that:
the versioning (.hg directory) is kept on the share
and that the files on the share are at the latest version?
I do not have access to this server (other than via the share). If I could have a mercurial server on that machine I would have used a hook to update the files in the production directory (I am saying this just to highlight what I want to achieve - this approach is not possible as I do not control that server)
Thanks!
UPDATE: I ended up using an intermediate server (which I have control over). A hook on changegroup triggers a script which i) hg update to have fresh local files ii) copies them to the SMB share
EDIT 1 Following discussions in comments with alex I have looked at the verbose version of the command line output. The \\srv\hg\test1 repo has a [hooks] section with changegroup = hg update. The output from a hg push -v gives some insights:
pushing to \\srv\hg\test1
query 1; heads
(...)
updating the branch cache
running hook changegroup: hg update
'\\srv\hg\test1'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported. Defaulting to Windows directory.
abort: no repository found in 'C:\Windows' (.hg not found)!
warning: changegroup hook exited with status 255
checking for updated bookmarks
listing keys for "bookmarks"
If I understand correctly the output above:
a cmd.exe was triggered on the client, even though the [hook] was on the receiving server
it tried to update the remote repo
... but failed because UNC are not supported
So alex's answer was correct - it just does not work (yet?) on MS Windows. (Alex please correct me in the comments if I am wrong)
If I understood correctly, you are looking for two things:
A repository hook that will automatically update the production repo to the latest version whenever someone pushes to it. This is simple: You're looking for the answer to this question.
If you can rely on your co-workers to always go through the pull-commit-push process, you're done. If that's not the case, you need a way to prevent people from modifying the production files in place and never committing them.
Unfortunately, I don't think you can selectively withhold write permissions to the checked-out files (but not to the repo) on an SMB share. But you could discourage direct modification by making the location of the files less obvious. Perhaps you could direct people to a second repository, configured so that everything pushed to it is immediately pushed on to the production repository. This repo need not have a checked-out version of the files at all (create it with hg clone -U, or do an hg update -r 0 afterwards), eliminating the temptation to bypass mercurial.
What prevents you from mount your Samba share and run hg init there? You don't need mercurial server (hg serve or more sophisticated things) to perform push/pull operations.
I'm using hgweb to publish my local repositories.
/project_path/project_name/.hg/.hgrc have:
[hooks]
changegroup.bitbucket = hg push ssh://hg#bitbucket.org/user/repo
When i'm use hg serve, all changegroup hooks working fine, but when i'm using hgweb through nginx with fcgi it's not working at all. I need those functionality to have some kind of backups.
It's mostly like Trust.
Mercurial needs to trust a hgrc file before it will parse/run it. If your /project_path/project_name/.hg/.hgrc file is owned by you then when you run hg serve with Mercurial running as you it's parsed/used. However, nginx runs as its own user, probably nginx which doesn't trust files owned by you, so when it invokes Mercurial those files are ignored (see Note).
That Mercurial trust link gives a better explanation and talks about how to say "nginx trusts X", but if it's a single-user system or you want everyone to trust you you can just throw a trust block in the system-global /etc/mercurial/hgrc file saying everyone trusts X.
Note: It doesn't actually just ignore those files it puts a warning on STDERR which in apache-land you'd find in your error.log, but in nginx land no one ever seems to find those warnings so I've no idea where nginx puts them.
I assume you have some kind of authentication issue here. When running hg serve from the command line, your ssh credentials are provided by an ssh-agent running in the background.
However, this does not work when running hgweb as a service, because there is no ssh-agent running in the background. If you would start an ssh-agent, there would be no possibility to enter the password for your ssh key.
Bitbucket uses ssh keys to authenticate you, so you can't just add your password to the above hg push command.
One possible solution would be to not use bitbucket as your backup, but a different mercurial server that let's you provide a simple password on the command line.
I'm afraid I can't help you further with this.
I am having a problem to trigger a repository clone of googlecode project.
I keep receiving the following error:
Started by user anonymous $ hg clone
--rev default "https://username#demo.projectname.googlecode.com/hg/ " "F:\Hudson\jobs\project Demostration project\workspace" abort: demo.projectname.googlecode.com certificate error: certificate is for
*.googlecode.com, googlecode.com, *.codespot.com, *.googlesource.com, googlesource.com (use --insecure to connect insecurely) ERROR: Failed to clone.
--template {node}
Anyone know on how to tell jenkins it is safe to use that certificate? In what textbox do you place --insecure option
That's a relatively new command line option (1.8.3 I think) to get around a relatively new practice of actually checking certificates (1.8.2 I think). It's likely not exposed in the Jenkins UI. Some things you could do to work around it:
put the server's cert's fingerprint in a whitelist in your (Jenkin's user's) hgrc
wrap Mercurial in a quick shell script that passes --insecure
clone from the non-https version of the google URL (I think they still allow that)
configure the CACerts for Mercurial either globally (/etc/mercurial/hgrc) or in the Jenkins user's ~/.hgrc
Any of those should work and most of them are explained here: https://www.mercurial-scm.org/wiki/CACertificates
I've setup a simple changegroup hook for my Mercurial repositories to email the set of changes to interested users. I'd like to use a single script for every repository I manage, and I would also like to identify the repository the changegroup came from. According to the Mercurial Hooks documentation, the environment variable HG_URL is available for this purpose. However, I am not getting what I'm expecting from this variable:
expected:
https://repo01/hg/project
actual:
remote:https::rnideffer
Why is this the URL, and how do I get what I expected into the changegroup hook?
The changegroup hook can't always tell the remote URL being used. From the Hooks chapter of the Mercurial Book:
When possible, Mercurial will tell a
hook the location of the “far side” of
an activity that transfers changeset
data between repositories. This is
provided by Mercurial in a Python
parameter named url, or an environment
variable named HG_URL. No comments
This information is not always known.
If a hook is invoked in a repository
that is being served via http or ssh,
Mercurial cannot tell where the remote
repository is, but it may know where
the client is connecting from. In such
cases, the URL will take one of the
following forms: No comments
remote:ssh:1.2.3.4—remote ssh client,
at the IP address 1.2.3.4. No comments
remote:http:1.2.3.4—remote http
client, at the IP address 1.2.3.4. If
the client is using SSL, this will be
of the form remote:https:1.2.3.4. No
comments
So you're being told they're pushing via https from a machine named rnideffer.
Have you considered using the notify extension? It ships with mercurial, does pretty much exactly what you're describing, and can be provided with the URL prefix necessary to turn repo names into the URLs you want.