Pushing Mercurial changesets from my local clone to "the real" clone? - mercurial

I created a project at Google code, and am using Mercurial for it.
I made a clone of the project: farm-myclone up on Google code.
I pull out a copy of farm-myclone, and start adding files, modifying files, etc.
I use hg commit, then hg push to get changes back into my clone's repository.
Now I want to move these changes into the real repository, just named farm.
Do I just do something like:
hg push [farm-myclone] to [farm]
so that whatever the state of my clone is gets pushed to the real clone?
Is that right? I'm an SVN user so this is a bit confusing to me.
Thanks

I think you've got one more clone than you actually need: You probably don't need "farm-myclone" to exist at all on Google Code.
If that main project is just called "farm", then when you run hg clone to make a clone of it, you get a clone on your local machine. This clone is a full Mercurial repository in all respects. When you're ready to publish your changes for the rest of the world to see, use hg push to push them up to the "farm" repository.
I think the presence of the additional "farm-myclone" repository is confusing the issue.

There is no syntax like the one you suggest -- may I ask where you got it from? I would love to improve the documentation, so please let us know (preferably on the Mercurial mailinglist) how we can improve the output of hg help push.
As for your question, then I agree with Greg -- you seem to have an unneeded clone. Often, you'll only have a single other clone to push/pull from. When you do
hg clone http://example.org/foo foo-clone
then foo-clone will have http://example.org/foo as its default push/pull path. This means that a simple
hg pull
inside of foo-clone is enough to pull the latest changes from http://example.org/foo.
The default path is stored in foo-clone/.hg/hgrc and you are welcome to add other paths and/or change the default. So the hgrc file may look like this:
[paths]
default = http://example.org/foo
alice = http://other-domain.org/foo
experiement = /home/me/foo-experiment
You can then use hg pull alice to get her changes or hg push experiment to push to your own local experimental clone.
These are just shortcuts, you can always push/pull using an explicit URL:
hg pull http://bobs-world.org/foo
works as well, if Bob has configured his webserver to serve a clone of the foo repository.
I hope this helps a bit :-)

Related

Mercurial : How to revert to a prev version after performing push

I have two branches let's say A and B. I have done few changes in A and committed my code into A then i have merged A into B and did a push.
Now the problem is i have added some unnecessary files into B.
I want o revert to a prev version of B. I have see few solutions to perform hg update -r and then forcefully push it to the repo which might lead to new heads which i don't want to do.
Bare me for the explanation, doing this for the first time. Thanks.
I want to revert back to 3313 revision
you can go on your head, remove the unnecessary files, commit and push.
Go to your branch B
hg update -r 3316
Remove the files, commit and push
hg forget yourfilethere
hg commit -m "Remove unecessary files"
hg push
let me know if it helps!
If what you want is to remove or modify a pushed revision, then I am afraid Mercurial (by design) does not support this. (You can change the phase of a revision to 'draft' and strip or amend it, but when you pull again the old revision will re-appear.)
If you really need to remove the revision (e.g. it contains some huge files), then there is nothing you can do about it on your local repository; the only way this can be done is on the remote repository (e.g. having the administrator run hg strip directly on the remote repository, or some equivalent thereof; the BitBucket interface does support stripping a revision).
We have had a similar problem at work, where some user committed very large files to the repository, and a lot of work was done on the repository afterwards. The only way we were to solve it was using the 'convert' extension to remove the files, and then pushing into a brand new repository. (If we had just pushed the converted repository to the existing one, this would just have created duplicate revisions starting from the point where the bad files were committed.)

Mercurial Workflow: Need to track file in my local working copy, but not push to "trunk"

This is my setup:
I have a main Mercurial repository (call it trunk). When I want to work on a feature, I do a clone and start working on it (usually add a bookmark as well).
I use various tools to do my work, which tend to generate convenient text files in the directory. It would be very helpful for me to track those files as well. However, I need to ensure those files do not get pushed to trunk.
In a sense, I'd like a "parallel" Mercurial repository in that directory where I can track these files.
How do people manage this? I'm open to using (stable) Mercurial extensions. Ideally, I do not want to "remember" to remove stuff before pushing to trunk.
There are two possibilities: patch queues and phases. Probably for what you want to do, phases are the less-friction approach. But there is no really "parallel" solution to my knowledge.
Have a look at hg help phases for an overview and hg phase for the command to manipulate the phase of a changeset.
To be sure you never push to trunk inadvertently, you have to make your commits "secret" by default (in your HOME/.hgrc):
[phases]
new-commit = secret
Then hg push will never allow to push anything by default, you would have to selectively change the phase of the changesets you want to push.
You could also not use the above configuration and use the --secret option of hg commit when committing something you want to keep for you, but it is too risky to forget.
Note that, both with patch queues and phases, you have to be proficient with history rewriting with hg histedit, to reshuffle around the commits.

Teaching a mercurial repository about a bad rename after it is pushed

We have moves and renames of files in our published mercurial history that were not properly recorded, so that they appear in the history as unrelated deletions and adds.
Is there any way to tell the repository about the connections so that --follow commands can work again?
(For non-pushed changes, here is a question discussing how to get mercurial to properly record moves/renames before you commit, as well as a useful tip here.)
One solution that works but is a bit brutal: You can login remotely on your central Mercurial server, fix the renames there as a local change and then ask everyone to clone the repo again.
This works since all Mercurial repos are equal. You just think of one as "central" but in fact it's a repo like any other. So if you have access to that, you can rewrite history there. The drawback is of course that every developer will notice, so they'll have to export any non-pushed changes they made, clone the repo again and then import the patch.
[EDIT] A possible workaround would be to create a new branch just before you did the bad rename, rename the files properly and then cherry pick all the changes after that into the new branch.
I'm not sure if it's a good idea to merge this branch into your original branch. If you did, then Mercurial would see two kinds of file renames in the past and I'm not sure which one it would follow.
So before you merge, I suggest that you create a small test/demo repo where you reproduce the situation and then try it out.
You can start a new head from before the rename, do the rename properly, then merge it into the head from the upstream server. It will give you a conflict. When this happens, revert the offending files to the revision from your new head (with the good renames; hg revert -r <rev> <files...>).

Force pushing to new head when already pulled all changes

Is it possible to forcibly create new remote head when pushing ?
Suppose I have done some local commits on branch "default" then pulled and merged from remote.
Now, I would like to push my commits to remote creating new head and a bookmark but preserve existing remote head and tip - ie. my coworkers should not get my changes yet when doing hg fetch.
Basically this should be a short lived branch (thus not a named branch) for purpose of backup and code review by other before being fully merged into "main" head of default branch.
I've tried --new-branch but it didn't help - no new head was created and remote tip moved to my head.
You can use the --force option to force the creation of a new head.
The --new-branch option is used for named branch, in your case, we are talking of anonymous branching.
The reason why the "tip is moved" is because you merged the changeset recently pulled. Doing that, there's no way to do what you want.
You should just pull the new changes from the remote, and force push everything without merging, this will create a new head (called an anonymous branch), which can later be merged to the default branch by you or someone else after the code review.
You can also use a second repository to push your changes, but this is a totally different workflow.
You cannot preserve tip when you push: it is a pseudo-tag that always points to the newest changeset in a repository. The concept of tip is deprecated in Mercurial because tip can change meaning more or less randomly depending on the order of pushes — as you've seen.
The only way to create a new head is to, well, create it :-) By this I mean that you need two heads — one with your changes and one with the main code you want the colleges to pull and merge with. With only a single head (the one you got after running hg merge) there's no way to signal to the colleges that they shouldn't use it.
A much better approach is to use a separate repository on the server. Go to your repository management software and create a fork for your changes. Then push into that and tell your colleges to review it. They'll pull from your clone and look the changes over. If they like them, then they can merge with the main code and push to the normal repo. If they don't like the changes, then they can throw away their local clone, strip the changesets, or maybe just rollback the pull.
My solution to this issue is to use a previous revision for the start of the bookmark, if there is none or you just do not want to, you can make a dummy commit (like a small change to a README file, etc.) and bookmark the revision before that.
I think hg bookmarks need a lot of fine tuning before they become like git branches, but the process I describe is pretty much what is explained in the mercurial bookmarks kick starter.
For example, if your currently at revision 250.
echo >>README
hg ci -m "enabling bookmark branch_xyz"
hg book my-tip # optional but nice to have
hg book -r 250 branch_xyz
hg up branch_xyz
# hack ... hack hack
hg ci -m "awesome feature xyz (in progress)"
hg push -fB branch_xyz
now this bookmark lives on the server for others to work with ... but can be easily pruned later

Mercurial clone cleanup to match upstream

I have a hg clone of a repository into which I have done numerous changes locally over a few months and pushed them to my clone at google code. Unfortunately as a noob I committed a whole bunch of changes on the default branch.
Now I would like to make sure my current default is EXACTLY as upstream and then I can do proper branching off default and only working on the branches..
However how do I do that cleanup though?
For reference my clone is http://code.google.com/r/mosabua-roboguice/source/browse
PS: I got my self into the same problem with git and got that cleaned up: Cleanup git master branch and move some commit to new branch?
First, there's nothing wrong with committing on the default branch. You generally don't want to create a separate named branch for every task in Mercurial, because named branches are forever. You might want to look at the bookmark feature for something closer to git branches ("hg help bookmarks"). So if the only thing wrong with your existing changesets is that they are on the default branch, then there really is nothing wrong with them. Don't worry about it.
However, if you really want to start afresh, the obvious, straightforward thing to do is reclone from upstream. You can keep your messy changesets by moving the existing repo and recloning. Then transplant the changesets from the old repo into the new one on a branch of your choosing.
If you don't want to spend the time/bandwidth for a new clone, you can use the (advanced, dangerous, not for beginners) strip command. First, you have to enable the mq extension (google it or see the manual -- I'm deliberately not explaining it here because it's dangerous). Then run
hg strip 'outgoing("http://upstream/path/to/repo")'
Note that I'm using the revsets feature added in Mercurial 1.7 here. If you're using an older version, there's no easy way to do this.
The best way to do this is with two clones. When working with a remote repo I don't control I always keep a local clone called 'virgin' to which I make no changes. For example:
hg clone -U https://code.google.com/r/mosabua-roboguice-clean/ mosabua-roboguice-clean-virgin
hg clone mosabua-roboguice-clean-virgin mosabua-roboguice-clean-working
Note that because Mercurial uses hard links for local clones and because that first clone was a clone with -U (no working directory (bare repo in git terms)) this takes up no additional disk space.
Work all you want in robo-guice working and pull in robo-guice virgin to see what's going on upstream, and pull again in roboguice-working to get upstream changes.
You can do something like this after the fact by creating a new clone of the remote repo and if diskspace is precious use the relink extension to associate them.
Preface - all history changes have sense only for non-published repos. You'll have to push to GoogleCode's repo from scratch after editing local history (delete repo on GC, create empty, push) - otherwise you'll gust get one more HEAD in default branch
Manfred
Easy (but not short) way - default only+MQ
as Greg mentioned, install MQ
move all your commits into MQ-patches on top of upstream code
leave your changes as pathes forever
check, edit if nesessary and re-integrate patches after each upstream pull (this way your own CG-repo without MQ-patches will become identical to upstream)
More complex - MQ in the middle + separate branches
above
above
create named branch, switch to it
"Finish" patches
Pull upstream, merge with your branch changes (from defaut to yourbranch)
Commit your changes only into yourbranch
Rebasing
Enable rebase extension
Create named branch (with changeset in it? TBT)
Rebase your changesets to the new ancestor, test results
See 5-6 from "More complex" chapter
Perhaps you could try the Convert extension. It can bring a repository in a better shape, while preserving history. Of course, after the modifications have been done, you will have to delete the old repo and upload the converted one.