Pulling changes from other's shared repository - mercurial

I have a repository called "abc" and my team member has forked this repository as "fork_abc". He commited some changes to "fork_abc". Now I have a cloned repository called "clone_abc" in my local system.
How can I pull the changes from "fork_abc" to "clone_abc" . I want to verify the changes and then push it to "abc" later.
I tried using $ hg pull "fork_abc" ,
but it seems its not the correct way. I am using mercurial for this and not git.Can some suggest what is correct command for this operation.

You could always export as patches the changes in fork_abc, review them as patches and then import them to abc.

Related

How to view changes in a recent push to the repository

I have a group of three friends working on programming a game engine, so we have a ton of code to look over. Sometimes one of us might accidentally modify a piece of code and forget to tell the other about, leading to some confusion later on in the code.
How can i look at the changes that were made specifically to the code when a new push is made to the repository? I enjoyed working with SVN's patch for an open source project that would show you what you directly modified and send over to the mod who would implement it into the application. How would i do something like this along hg's lines?
How can i look at the changes that were made specifically to the code when a new push is made to the repository?
The --patch switch for the hg log command is a quick way to review patches from the command line.
If you want to export a patch to a file, use the hg export command. For example, with:
hg export -r-2 -o file.patch
you are saving the second to last commit into the file named: file.patch. You can now share the file and anybody can import the patch with:
hg import file.patch
This command will also create a commit with the same message as the original exported commit, unless the --no-commit switch is used.

"Side-Pull" a mercurial repo into main project

I have a repo in my VCS called CodingStandards. In it is a checkstyle.xml file along with findbugs.xml and it will no doubt grow in the future.
What I want to do is in my project FunkyApp is pull CodingStandards into the project and maintain the link to CodingStandards so that if I change it, I can pull & update in my FunkyApp.
Subrepositories are what you are looking for.
However they forces you to have these files in a subdirectory of your project. There's no way to add juste one file to a repository from another.
First of all setup the CodingStandards repo in .hg/hgrc to make life easier
[paths]
default = https://url/FunkyApp
standards = https://url/CodingStandards
Then you can force pull into your repository
hg pull -f standards
This will create two heads in your repo that need to be merged with hg merge and then committed into your main repo.
To be clear CodingStandards will be unchanged. FunkyApp will have all the files from CodingStandards imported in it. Anyone else who clones FunkyApp will get the files without knowing about CodingStandards.

Push to two repositories that can't reach each other

The setup:
a laptop L
an office server hosting various repositories SOffice
a customer's database server SCustomer
I'm writing code on L for a customer, and regularly want to push it both to SOffice as well as SCustomer.
I know I could use a changegroup hook to push to a third repository from the second (as described in this answer), but this requires that the second can reach the third network-wise.
In my case, each is behind a firewall, and only my laptop typically accesses both through a VPN (or by being physically there). I could set up the VPN on SOffice to get to SCustomer, but I'd rather not.
Is there a way I can, say, set default to two repositories?
You can't default to two repositories, but you can define more than one repository in your hgrc file :
[paths]
default= /path/to/first/repo
scustomer = /path/to/second/repo
You can then push to the scustomer repository explicitly :
hg push scustomer
If you want to automate the process of pushing to both repository at once, I'm not aware of a Mercurial method to do it, but it is really easy to create a shell script, alias or something else to run both commands one after the other.
You can even use a hook on the repository to automatically push to the other one, but you will have to discriminate between a "manual" push and the automatic push in the hook, and I'm supposing this will be really messy.
Could you create a second clone of the repository with a hook that automatically pushes to both of the external repositories? Then push from your working clone to the second clone.
There's a MultirepoExtension that adds commands for doing any operation on multiple repositories.
Or you could create an alias to push to both like:
[aliases]
pushboth = !$HG push http://first ; $HG push http://second
or you could create a pre-push hook that pushes to the other one. Something like:
[hooks]
pre-push = hg push http://second
But I like (and upvoted) krtek's answer the most. Just give each a path alias and run push twice with the short names instead of the URLs.

How do I set up a hook in HG / Mercurial that gets dictated by the repository?

I have a need for a hook to run after update (this will build the solution they have updated) and I don't want to have to add that hook manually for each person that clones my central repository.
When someone first clones my central repository, is it possible to include hooks into that clone? It seems that the .hgrc file doesn't get cloned automatically.
I did read about site-wide hooks, but as far as I understand it, they work on each created repository, where I only want to have the hooks on some repos.
As Rudi already said, this is (thankfully) not possible for security reasons.
However, you can reduce the per-clone workload to set up hooks manually: Ship the hook scripts as part of your repository, e.g. in a directory .hghooks, and additionally include a script in your repo which sets up these hooks in a clone's hgrc. Each coworker now only needs to call the setup script once per clone.
This is not possible, since that hooks do not propagate to clones is a security measure. If this were possible, one could set up a rouge repository, which runs arbitrary commands on any machine where the repo is cloned.
See http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html#id402330 for more details.
This will allow for centralised per-repo hooks, with a single setup step per user. It will however cause problems for users who are disconnected from the network. An alternative if you tend to have disconnected developers (or ones over high-latency/low bandwidth links) would be to have a repo containing the hooks, and set up each user's global hgrc to point into that repo (and require regular pulls from a central hook repo).
Note that I treat the ID of the first commit as the "repo ID" - this assumes that the first commit in each repository is unique in some way - contents or commit message. If this is not the case you could do the same thing but applying it over the first N commits - but you would then have to account for repos that have fewer than N commits - can't just take repo[:5] for example as newer commits would then change the repo ID. I'd personally suggest that the first commit should probably be a standard .ignore file with a commit message unique to that repo.
Have a central shared_hgrc file, accessible from a network share (or in a hook repo).
Each user's global hgrc has:
%include /path/to/shared_hgrc
Create a shared repository of python hook modules. The hooks must be written in python.
Create your hook functions. In each function, check which repo the hook has been called on by checking the ID of the first commit:
# hooktest.py
import mercurial.util
FOOBAR_REPO = 'b88c69276866d73310be679b6a4b40d875e26d84'
ALLOW_PRECOMMIT_REPOS = set((
FOOBAR_REPO,
))
def precommit_deny_if_wrong_repo(ui, repo, **kwargs):
"""Aborts if the repo is not allowed to do this.
The repo ID is the ID of the first commit to the repo."""
repo_id = repo[0].hex().lower()
if repo_id not in ALLOW_PRECOMMIT_REPOS:
raise mercurial.util.Abort('Repository denied: %s' % (repo_id,))
ui.status('Repository allowed: %s\n' % (repo_id,))
def precommit_skip_if_wrong_repo(ui, repo, **kwargs):
"""Skips the hook if the repo is not allowed to do this.
The repo ID is the ID of the first commit to the repo."""
repo_id = repo[0].hex().lower()
if repo_id not in ALLOW_PRECOMMIT_REPOS:
ui.debug('Repository hook skipped: %s\n' % (repo_id,))
return
ui.status('Repository hook allowed: %s\n' % (repo_id,))
In the shared_hgrc file, set up the hooks you need (make sure you qualify the hook names to prevent conflicts):
[hooks]
pre-commit.00_skip = python:/path/to/hooktest.py:precommit_skip_if_wrong_repo
pre-commit.01_deny = python:/path/to/hooktest.py:precommit_deny_if_wrong_repo
As #Rudi said first, it can't be done for security reasons.
With some prior setup you can make it so that hooks are run on clone, but putting a hook with a repo-relative path in /etc/mercurial or in each user's ~/.hgrc, which in a corporate setting can be done via your system management tools or by building a custom Mercurial installer. In a non-corporate setting follow #Oben's advice and provide the scripts and a readme.

how to ignore files in kiln/mercurial using tortoise hg "that are part of the repository"

We use tortoise hg with Kiln. In my vs 2010 c# project there are some files that are part of the repository but I would like tortoise hg to ignore them when I make a commit.
For eg., say in a login screen I may hard code the userid, password for testing. I dont really want this file considered during a commit. I understand .hgignore file but this really works for files that are not part of the repo. Any trick in tortoise hg to ignore files that are part of the repo ? (so they do not show up as modified (M) during a commit.) thanks
I always use a combination of .hgignore and BeforeBuild (in the .csproj file) for things like this.
In one of my pet projects, I have the following setup:
App.config contains my real hardcoded user id and password for testing.
App.config.example is identical, but with fake data like "dummy_user" and "dummy_pw".
App.config is not part of the repository, and it's ignored (in .hgignore).
App.config.example is part of the repository.
Then, I have the following in the BeforeBuild target in the .csproj file of my solution:
<Target Name="BeforeBuild">
<Copy
Condition="!Exists('App.config')"
SourceFiles="App.config.example"
DestinationFiles="App.config"/>
</Target>
All this together has the following effect:
the config file with the real data can never be accidentally committed to the repository, because it's ignored
the repository only contains the config file with the example data
if someone else clones the repository to his machine, he won't have the "real" config file...but if it's missing, it will be automatically created before the first build by Visual Studio / MSBuild by simply copying the .example file (and then he can just put his real login data into the newly created App.config file).
if an App.config with real hardcoded user data already exists, it won't be overwritten when building because the BeforeBuild event will only happen if App.config does not already exist
The answer by Christian is the right one, but I want to mention that TortoiseHg supports what you want with their Auto Exclude List.
One problem with an exclude list is that it cannot work with merges: you must commit all files when you merge and so you'll have to do a little dance with shelve, merge, commit, and unshelve.
When you do a TortoiseHG commit, there is a list of files with checkboxes by them. Deselect the files you do not want comitted.
Or, on the command line, do a commit of the form hg commit --exclude "pattern", where pattern is defined in the hg man page.
You could always use hg forget.