How to force a merge with an ancestor? - mercurial

I branched off changeset "A". Later, "A" was merged into default. Then it was decided that "A" was not ready to go live, so someone hg revert -a'd it to an older revision and pushed that. Now I'm trying to merge default into my branch, but because those changes were reverted, they're all being ripped out of my branch.
I want to force a re-merge with "A" so that I can get all those changes back. How can I do that?
Update: I just tried backing out the changeset that undoing "A" was made on. It looks like this gave me all my code changes back.

It looks like you solved your problem already. I was going to point you to http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html and then mention that you try to "hg revert" the commit that previously reverted the changes you want back.

Instead of trying to re-merge "A" you can backout the changeset where "A" was undone on default. e.g.,
hg backout -r <changeset>

Related

mercurial hg up -C created a branch with the same name as current, how to remove it or merge it

I had a change in my branch and after unseccessfull merge, I tried to revert that unsuccessefull merge with hg up -c but it created a new branch instead. I can merge it into current or discard it or what to do with it?
EDIT:
actually I did the following, I had a branch and committed changes there there. then I wanted to push my changes to server, so I pulled changes, and tried to merge with them, but there were a conflict I couldn't resolve myself and I thought: I'll revert all changes back and merge again - so used hg up -C which I thought, will revert everything I changed during my unfinished merge. But what actually happened, another branch with the same name was created, containing only that changes I committed previously and with the same name as a branch I was working in and I was switched to the branch where I was working, which didn't have my changes. So two questions here: what actually happened and why another branch with the same name was created?
Having multiple heads on the same branch, which I think is what you're saying with "a branch with the same name as current" is a normal situation and, yes, you can use hg merge to consolidate them into one head. Use the hg heads command to find the hashes of the two heads of branch X. Then:
hg update REVISION_ID_OF_ONE_HEAD # changes your working directory to match one of the heads
hg merge REVISION_ID_OF_THE_OTHER_HEAD # merges that head's changes in
hg commit # create a new changeset that is the child of both those heads thus reducing the head count by one
Also #ringding is correct that hg update never creates branches. You either already had them and didn't know or received another head when you pulled.

Merging/Removing a commit

I have a commit i pushed earlier today that i learned i had messed up on by not adding the correct files before pushing. I fixed the revision and re-pushed it, so now i have a revision containing literally nothing new and my real revision. This could really confuse my other team members working, so i would like to either merge both together or remove my 'blank' revision.
Here is a picture of my problem:
http://img525.imageshack.us/img525/3929/revisionproblem.png
Note that i cannot undo/rollback, it tells me the transaction is not available.
If you've pushed it there's very little you can do. You could hg strip it from your local repo, but you'll get it back the next time you pull. You could edit history with hg histedit or merge two changesets with hg collapse, but none of that will get rid of the changeset you've pushed.
That said, the comment in your screenshot, "I just rolled back my latest push...", has me thinking you might have hg push and hg commit confused. They're entirely different and hg push can't be rolled back (locally). A hg push sends your local changesets out to the world -- no takebacks. A hg commit creates a new local changeset.
If you've misstated your problem and you've merely hg commited a changeset you regret you have all the extension-based options I listed above available to you. If you've really pushed it -- welcome to DVCS usage: once it's out there it's out there, and the best you can do it correct it in a subsequent commit.

Mercurial undo three hg push

I'm using mercurial VCS, I've mistakenly pushed three commits and I want them to be undone, can this be achieved?
I'm pretty sure no changes were propagated to anyone from the repository I pushed to, so I'm confident that this won't break anyones code...
I've tried hg rollback but since I have pushed I cannot undo anything in the right way. Also I know about hg backout, but I'm not sure if I should use this one for what I need...
Thanks!
EDIT
This is the graph log, I forgot to mention that some commits were part of a merge, but they too need to be undone...
tip
|
a
| \
| b
| /
c
|
d
I need to return the tip to c, or d if there is no other way to prevent that because of the merge...
If it's already pushed, there are only two things that you can do now:
1) If you are able to delete the central repository and replace it by another one:
You can clone the central repository, but tell Mercurial to clone only up to changeset "c".
Then you can take this repository (which doesn't have the wrong changes) and replace the "old" central repository (the one which does have the wrong changes) with it.
Disadvantage: if someone already pulled the unwanted commits and later pushes again, they are in the repository again.
So you need to make sure that either no one pulled the mistakes, or everybody who did deletes his clone.
2) If option 1 is not possible, you can use hg backout to undo the effects of the wrong changes - not the changesets themselves.
Quote from the link:
Backout works by applying a changeset that's the opposite of the changeset to be backed out. That new changeset is committed to the repository, and eventually merged.
So the three wrong changesets will remain in the repository, plus another three will be added, each of them reverting the effects of one of the three wrong changesets.
If you do it like this, it doesn't matter if someone else already pulled the wrong changes...as soon as he pulls the three "backout" changesets as well, everything is okay again.
If you're positive the push is the last thing that happened to that remote repository, meaning neither you nor anyone else has pushed to it, you can login to that system and run hg rollback.
If it's a repository on a machine to which you can ssh you can run this command on your local system:
ssh you#there hg -R /path/to/the/repo rollback
As always please do be really careful with rollback. It undoes the last action on the repository without altering the working directory at all, and it's not always clear what the last action was. For example, this is datalosss:
...hack...
hg commit -m 'important work'
hg update somewhere else
hg rollback
Yikes!

Mercurial - Multiple heads - how do I "abandon" one head and take the other as tip/default?

I forked someone elses repository on Bitbucket and made some changes (and pushed them to my forked repo). In the meantime, the original author made substantial changes (pretty much a rewrite).
I want to update my repo to be exactly the same as his (but with my changes still present on that tag) in a way that he can easily pull my new changes without the previous changes I made affecting anything.
I pulled his changes into my local version, which left me with 2 heads. I want to just take his head as the tip/default. I tried to resolve this (based on some SO answers) by doing:
hg update -r [myrev]
hg commit --close-branch
hg update -r [hisrev]
This seemed to put me in a state I wanted. My working directory looks like his. However, when I tryed to hg push I'm told this will create multiple remote heads, and I'm not sure if this is what I want (the message makes it sound scary!)
So, have I done this correctly? Should I force the push? Will this do what I want (eg. keep a copy of my changes so I can get to them, but in a way that generally won't interfere?). If so, was this the best way to achieve this?
Heads on a closed branch are still heads, so if you want to push those changes you'll need --force.
The other option, is to merge that head into what you want to be your default branch, but select none of its changes. This can be done non-interactively using:
hg update [hisrev]
hg --config ui.merge=internal:local merge [myrev]
hg commit
You'll be down to one head, and it will have only his content, but yours is still available in the history.

How do I unadd a not yet committed file I have added?

I typed in hg add and I am brand new to mercurial and the result of this was a bunch of dll's exe's pdb's etc all got added
Nothing's been committed yet and I basically want to undo the add.
the documentation for hg forget is not very clear not sure if that is want I want
How do I undo the add before the next commit
I do have some real files that need adding so after I can undo the add I will use add with the exclude flag
Thanks
Check out this mercurial tip. To cite the link - if you have accidentally added a file, the way to undo that (changing its status from A back to ?, or unknown) is hg revert. For example, if you just ran hg add and realized that you do not want files foo or bar to be tracked by Mercurial:
hg revert foo bar
Either revert or remove can be used to un-add not yet commited stuff. However, they both have other uses too, so for clarity hg forget was (re-)added in 1.3, and despite its name it might be easier to remember.
If you are using a Unix like system i believe the best option is to run
hg status -an0 | xargs -0 hg revert
Two tips for these sorts of situations:
If nothing has been commited at all, just delete .hg and start over with hg init.
If you do something terrible to your repository and can't seem to figure out how to undo it, (and hg update -C or revert all won't fix), consider cloning the repository at the last good spot.