Continuously Fixing Same Mercurial Merge Issues - mercurial

My co-worker and I are working on a project and we are using mercurial + bitbucket.
We are experiencing problems when one of us pulls from bitbucket and merge. For instance, after I pull from bitbucket with hg pull --rebase, I have to
remove files that were removed in previous commits
modify files that were modified in previous commits
move files/folders that were moved in previous commits
He does hg pull followed with hg merge and gets the same results as me.
What are we doing wrong?
Besides rebase/merge, we work the same
work, work, work
pull rebase/merge
fix merge issues
push

The most likely cause is that you're rebasing changesets that have already been pushed. Rebase modifies history, and unless you really know what you're doing you should only rebase changesets that have never been shared to another repository.
If you are using Mercurial 2.1 or later it has support for phases. When phases are working rebase will only allow rebasing of draft and secret changesets, not public ones.
In general, I'd advise you to use merging rather than rebasing.

Related

Mercurial : how to deal with rejected pull request?

At least : how to deal with it cleanly?
Currently, the only worklow I know is : suppress your clone + re-fork from main repository.
That's really underoptimal...
The other option is merging with main repo's tip, or backing out your changeset.
But if you do that, will the backout appear in subsequent pull requests?
If so, it's embarrassing polluting main repo with rejected changesets and their backout...
What's the correct workflow?
It depends.
If your fork is public or you want to keep the rejects, something like this workflow is probably ideal:
Update to the tip and do hg ci --close-branch.
Pull from the main repository if necessary.
Update to the most recent changeset which belongs to the main repository, and do all work there.
If your repo is using the # bookmark, move it to the new head.
If your fork is not public, you can simply strip the changesets you no longer want. Look in your repository settings for the "strip changesets" option. You will also need to execute hg strip locally on each clone of the repo; the activity feed will provide the precise command to use.
If you happen to be using the experimental Evolve extension, you can hg prune unwanted changesets instead of the procedures described above. This will leave them around, but hide them from history and prevent them from being pushed or pulled (in most circumstances). This is (intended to be) a "safe" operation that you can do to shared changesets. If anyone pulls from your repository, the changesets will be automatically pruned in their repository as well. To undo, see the hg touch command.
NB: Bitbucket will not back up changesets when you strip them. Please be careful.

Mercurial: How can I create an unplanned branch

My use case is this:
I am working on a new feature and I have several commits on that feature.
Since it was a minor feature, I didn't even consider doing the feature in a feature branch.
However. Now my boss comes along and tells me to fix a bug on the same branch that I am working on (default).
To fix that I'd like to create a feature branch for my feature, push all my existing (unpushed) commits into that branch.
So I'd like to create a branch just before my first commit and then somehow move all my commits to that branch.
How can I do this?
There’s two ways to approach this, depending on your preference:
In a new repository.
Make a new clone of your repository, and do the bug fix you need to make there. Then push it to the main repository when you’re done, and continue where you left off in the original repository. Pull and merge to get the new changes as usual.
In the existing repository.
Update to the changeset before your local changes, and just start fixing and committing there. This creates a new anonymous branch. When you’re done, push using push -r ., this will only push the changes that are included in the working copy. After this, merge with your original branch (hg merge) and continue where you left off.
Note that you can bookmark the feature branch with hg bookmark if you do not feel comfortable with leaving your changes unlabeled. Also you can easily find back any heads you left behind using hg heads.
Personally I prefer to work in a new clean clone, as you don’t need to worry about branching and where to leave uncommitted changes. However if your project setup is complicated it may be more convenient to reuse the existing repo.
For this situation you can fix it by rebasing (which may need enabling in your configuration).
On your branch, update to the revision before the change-sets you want to move:
hg up -r<revison>
This assumes contiguous revisions need moving.
Create a new branch:
hg branch "TempWork"
Put a dummy commit onto it in order to get a new revision:
hg commit -m"New Branch"
Then perform the rebase from the first of the change-sets you want to move (it moves descendants automatically) and specify the new branch revision as the destination:
hg rebase -s<base revision> -d<new branch revision>
Then update back onto your main-line branch.
Fourth method: Using mq-patches
You have to have mq extension enabled and initiated for repo
On hotfix moment you
convert feature-commits into set of mq-patches (hg qimport)
Unapply all patches in set (hg qpop -a)
Code hotfix, commit
...
Finish and test hotfix on clean codebase
Apply all patches in set (hg qpush -a), fix possible conflicts
Convert patches back to changeset (hg qfinish)

how to undo a commit pull

I faced today my first mercurial problem. I was in my repo, I modified a file and I did a
hg commit
hg pull
followed by
hg update
hg rollback
to repair what I've done, (but actually I didn't push anything)
The problem is that when I did the pull (that I should do before the commit, the head changed and so hg heads looks like :
- Modif from yesterday
- My modif
- Modif from last week
and now I see that someone also did another modification (via the http interface). What should I do to repair my local repo, (if possible modifying my summary) and push it after the 2 others modifications.
Thanks a lot. Quiet confusing, was easier on my "one-man" repo..
Your local repo doesn't need "repairing". This is a very standard case that you will see often if you use Mercurial a lot.
The issue is multiple heads.
You can either merge your heads, assuming your working directory is your version and there is only the other head:
hg merge
This will result in a merge changeset (same as if you were merging across branches).
Or you can enable the rebase extension to re-base your version onto the tip of the branch (the other head):
hg rebase --source<YourVersionNumber> --dest<TipVersionNumber>
This will not result in a merge changeset, and will simply transplant your changes on top of the changeset you specify as if they were born of that changeset all along (hence rebase or "new"basing).
Multiple heads is a funny sort of inner-branch branching... you can continue checking stuff in against your own head and change between heads using hg update. We block multiple heads per branch on our server, so our push would fail. I'd advise keeping multiple heads local as they are less clear-cut than branches.
I tend to work with Mercurial in one of two ways:
If the work is large in scale I will branch it off and follow Continuous Integration practices (constantly merging the main branch into my own etc). I then re-merge back into main when I am happy with the end result.
If the work is small in scale I will simply work against main branch and "merge" heads every so often. I say "merge" as I usually use rebase. Re-basing works great if the changes are simple and conflicts are unlikely.
My hard and fast rule: if I can't use rebase I put it on a branch born of main.

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.

Mercurial - how to fetch latest changes from parent of fork?

I've been dabbling with Mercurial for a short while now, and I've now set up several projects on BitBucket, one forking off of the other.
I've been able to make changes to each repo with no problem, but one thing I can't figure out, is how to keep the fork up-to-date with changes from the parent repo?
After I've forked a repo, I only see the commits from that repo up to X revision, after which point I only see the fork's own commits, no new parent commits.
I'm pretty certain that during my dabbling with git, I was able to rebase to the latest parent revision, but that was awhile back and I'd rather not guess my way into bad habits :-)
Just perform the pull with the source repository as an argument. It will pull all the changes done after your previous pull (or from the time you forked the project, if no pulls were performed).
After that you will have some additional heads, which you have to merge with your ones.
Here are 3 essential steps:
hg pull -u path_to_parent
hg merge
hg commit -m"updates from parent"
Or you could install fetch extension that combines all these steps:
hg fetch path_to_parent