how to rollback a branch merge in mercurial - mercurial

I have merged my development branch with production by mistake. I haven't made it public, please let me know how can I revert back this merge ?
I am using TortoiseHG workbench.

You can just strip the commit that did the merge, assuming it's the last one. Right-click, Modify History -> Strip.
If it's more complex that that, post more detail (e.g. screenshot of the graph) and I'll try to help.

Related

How to revert a file to an earlier version in Mercurial?

I made some changes to a file and committed it. (In fact there were several commits).
Then I wanted to revert to the earlier version and lose all those changes.
I did something like:
hg update -r nnn where nnn was the reversion number of the changeset I wanted to go back to.
That worked. I was happy.
Then, later, I had to push my local repository to the remote. But when I did hg push I got a message about there being two heads on this branch and one of them not being known to the remote repositiory. It suggested I merge before pushing. (I think).
I googled this and found a page that suggested I do "hg merge". I did that. Now the resultant file is back to where I started. I.e. it contains all the changes I wanted to throw away.
Where did i go wrong?
EDIT:
I have found this post Mercurial — revert back to old version and continue from there
where it says:
If later you commit, you will effectively create a new branch. Then
you might continue working only on this branch or eventually merge the
existing one into it.
That sounds like my case. Something went wrong at the merging stage it seems. Was I on the wrong branch when I did "hg merge"?
You're past this point now but if it happens again, and it's just a single file you want to revert then consider:
hg revert --rev REVISION_YOU_LIKED path/to/just/one/file.txt
That doesn't update you whole repository to a different revision, and it doesn't create any commits. It just takes a single file in your working directory and makes it look like it used to. After doing that you can just commit and you're set.
That's not the way to go if you want to undo all the changes you've made to all files, but for reverting a single file use revert and avoid multiple heads and merging entirely.
No, nothing went wrong at the merge stage – Mercurial did exactly what you asked it to...
What merge means is that you take the changes on your current branch, and the changes on the 'other' branch, and you merge them. Since your original changes were in the 'other' branch, Mercurial carefully merged them back into your current branch.
What you needed to do was to discard the 'other' branch. There are various ways of doing that. The Mercurial help pages discuss the various techniques, but there are pointers in other SO questions: see for example Discard a local branch in Mercurial before it is pushed and Remove experimental branch.
(Edit) Afterthought: the reason you got a warning about there being two heads on the branch is because having two heads is often a temporary situation, so pushing them to a remote repository is something you don't want to do accidentally. Resolutions are (i) you did mean to push them, so use --force to create two heads in the remote repository; (ii) ooops!, you meant to merge them before pushing, so do that; or (iii) ooops!, you'd abandoned the 'other' one, so get rid of it. Your case was (iii).

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...>).

Mercurial: abandoning multiple, contiguous commits, on the `default` branch

Requirement
I'd like to abandon a line of development on the default branch, winding back to a revision from about 15 change sets back, and have default proceed from there.
My setup
This is a solo development project with one other guy testing infrequently. I push (frequently) to bitbucket for backups and sharing with the tester. Several of the changes I want to abandon are pushed to BitBucket.
Options
Any of these would be fine…
The abandoned change sets to continue to exist in the repo. It would be nice if they could live on their own branch abandoned-experiment-1, say, that I can close and ignore, but this would need them to move on to a retrospectively created branch (which seems like it would be an awesome feature?).
Some kind of merge to happen where I add a new revision to default that is the rollback to the revision I want to continue from.
The change sets to be destroyed, but I suspect there's no way to achieve that without replacing the BitBucket repo and my tester's repo, which I'm not keen on.
I'm not too sure how to evaluate which options are possible, which is best, or whether there are other, better options. I'm also not sure how to actually proceed with the repo update!
Thank you.
You do have several options (Note that I'm assuming that you are dispensing with all changes in the 15 or so revisions and not trying to keep small bits of them):
Easiest is kinda #2: You can close anonymous branches just like named branches; Tag the tip first with abandoned-development if you wish; hg update to the point you wish to continue from; and continue to code as normal. (You may need to create the new head for new development before you can close the old one. I haven't tested it yet.)
Regarding #3: Based on my cursory read, it does appear that bitbucket has a strip command. If you (both locally and on bitbucket) and your tester strip the offending changesets, you can carry on your merry way and pretend like they never existed.
Achieving #1: If you are definitely set on getting them to a named branch, you could strip them at the remote repos and then hg rebase them onto a new branch locally and then close that branch.
Personally, I try not to mess with history when I can avoid it, so I'd go with the easiest.
Mercurial now has (yet experimental) support for changeset evolution. That is you are able to abandon or rebase already pushed changesets. Internally this works by hiding obsolete changesets (i.e. practically nothing is stripped, only new replacement revisions are added to the history, that is why it works across multiple clones).
To extend #Edward's suggestions, you could also update to the last good revision, continue to commit from there and then merge in the head of the bad changesets using a null-merge:
hg up <good-revision>
... work ... commit ...
hg merge <head-of-bad-revisions>
hg revert --all -r .
hg commit -m 'null-merge of abandoned changesets'
This may be what you thought of as option 2.

Mercurial - why can't I find deleted files?

I recently let the IDE replace a trivial text in the entire project, and recognized that mistake only after committing other changes to Mercurial. I panicked and (knowing very little about Mercurial, now after having read the definitive guide starting to get to know it better) tried every command that seemed to make my mistake "go away". It goes without saying that this was a move I am not proud of.
Of the things I remember to have tried was hg update tip and hg rollback. Since I'm using Mercurial on my local machine only and do not pull or push from any other repository, I think these commands did not cause my main problem: There are a lot of files missing now -exactly the files I let the IDE make the wrong replacements in.
What bothers me is that I have done hg status --change REV to find all files changed in a revision, and the deleted files do not show up there.
PHPStorm has a local history, which shows which files are now missing. That (only that?) enables me to hunt down the individual files and revert to their last known revision:
hg log -l 1 path/to/foo.txt
hg revert -r <my revision> path/to/foo.txt
... but that is way too time-consuming for the hundreds of files that got changed. Please tell me there's a better way. The PHPStorm history is nice and can restore the files as well, but it will restore them to the point where they had already been erroneously changed.
Your help is greatly appreciated, and I vow to learn & appreciate Mercurial as more than just a context menu item starting today.
If you are willing to lose the changes that were committed with or since the error, you may be able to go back to the revision just before the error, and start working from there. Use hg log to find out which revision you need, and hg update --rev XX to go to that revision. If you're not sure which revision you want, update to various revisions and take a look.
Once you have updated to the correct revision, you can just continue working from there. The next time you commit, you will automatically create a new branch on which you'll be working, which will not have the error in it. If you want, you can go back to the original branch and close it.
You might even be able to get back any correct commits that happened after you committed the error up to the revision you rolled back to. On the old branch, identify the revision after the error, and do a diff between that revision and the tip of that branch. Then, see if you can apply the diff as a patch on your new branch. You will still lose any changes that were in the same commit as the error, though.

Mercurial: Pulling in others merges + branching

I'm still very new to Mercurial so please let me know what I'm doing wrong.
We have an hg repo for each of our developers. I'm working on a new feature in branch x. Since then, others have made critical changes to the project, which I have pulled into my repo. However, when I'm working on branch x my working copy still has the old stuff, which causes it to not play well w/ our shared MySQL database.
Q: How do I update my branch to have the other developers new stuff while keeping my own code in the x branch; I'm not ready for them to have it yet and I definitely don't want to merge x into default... I'm not sure what to do here...
Or am I going about this the entirely wrong way? If so, what should I be doing instead?
[edit]
Also, I'm using TortoiseHG, so if you have any instructions specific for that it would be appreciated.
[/edit]
You are doing everything right. In order to "keep up" with the work of the other developers, you have to merge the default branch into your x branch. Not the other way around.
When you are in your x branch, it is as easy as doing hg merge default.
Edit : I deleted my statement about hg merge being equivalent to hg merge default, which is false. I misread the documentation.