Selective revert in mercurial, like record but in reverse - mercurial

I was debugging a crash by adding some printfs. Once I had some changes that avoided the crash, it was time to complete the fix by adding some more changes.
At that point I wanted to remove the printfs and continue with the changes that weren't yet ready for a commit.
Is there a mercurial extension that lets me revert temporary changes like hg record lets me select just the useful bits ? One way would be to qrecord, then delete the patch. But maybe there's something simpler.

You can use hg revert -i (which is still experimental and thus shows up only in hg help revert -v).

Related

How to re-commit last changeset with a different comment?

As I understand it, you can't really fix a comment in Hg. So what I would like to do instead is re-push the exact same changes (or at least "touch" the same files and commit & push again).
The reason this is necessary is because we have a bug tracking and build system that relies on specific comment patterns, and we need to make sure the right files get included in the build, but if I forget to update the bug # in my comment from my last commit, and I accidentally commit and push it under the wrong # because i'm overzealous, how can I re-push those same files again without manually going into each one and adding a space or line break just to create a diff?
To clarify, I can't "rollback" or something; it's already been pushed with the wrong message.
As far as I know, current Mercurial features provide no support for this. After the changeset has been pushed, there's little you can do to un-push it, besides stripping it from the server repo and any other developer's repo.
I guess you you should ask those who set up this workflow in your shop; they should've come up with some exception handlers for it.
We usually just ignore issues like this, and close the bug by hand, making sure the bug links to the correct changeset. If the changeset is really messed up (usually this means bad changes, not a malformed commit message), we resort to stripping.
Since your change has already been pushed you can't use a simple fix, like "hg commit --amend", but you can do something similar. Basically, the following commands re-do the commit with Mercurial's help:
CSET=...the changeset to re-do...
hg up -r "p1($CSET)" # Update the working directory to the parent revision
hg log -r "$CSET" -p > changes.patch
hg import --no-commit changes.patch
hg commit # And use the appropriate commit message.
Then, merge and push.
The only way that I could think of doing this is to commit two more changes, one would be an hg backout of the incorrect revision and the other would be an hg backout of that revision with the corrected comment.
I don't like that idea though and wouldn't recommend it if there was any way to fix the problem in your bug tracking system.

How to retrieve an accidentally deleted patch in Mercurial with MQ

I had two patches in series, neither one applied, and I accidentally called qdelete on the wrong one. Is there any way to reverse this operation and get my patch back? I had a huge amount of work in this one!!!
The way to avoid this (and I know it's not helpful now, sorry) is to not just use Mercurial Queues, mq, but to use it with a patch repository. Mercurial/mq has great support for this.
When initially creating the queue you do:
hg qinit --create-repo
(instead of just hg qinit), which creates a new Mercurial repository in your .hg/patches directory. Then you can use:
hg commit --mq
to commit all your patch files, and bringing this back would be just a matter of:
hg revert --mq
The bottom line, and again I know it's not helping you now, but maybe it'll help the next guy or you later, is: if you're writing code and it isn't committed somewhere it doesn't exist -- commit and push early and often
Unfortunately, if you did not use the -k option when calling the qdelete command, the patch file also got deleted. Thus your only hope is either a backup or an tool that could perform some "undelete" operation.

Mercurial: back out last change so codebase is clean?

I've just messed something up in Mercurial.
How do I back out the last change so that the codebase is clean - specifically so that if someone else does 'hg pull', they'll have a working codebase?
Two ways:
hg rollback as mentioned by Fred; if you've already pushed, too late. hg rollback is only suitable for local use. hg strip (also as mentioned by Fred) works the same way and is (excepting its support for backing up) equivalent to doing hg rollback a number of times, till you get back to that revision.
hg backout for when you have already pushed and just want to revert the effects of the commit (if you've accidentally pushed out sensitive data, you'll need to take more drastic measures, but if you just want it to work, use this).
If the commit is not the last-committed revision, say so and we can get into deeper stuff (or search - it's been answered before).
Another way is to clone from a specific revision. Say checkin 6 was the mistake. You can clone your repository up to revision 5:
hg clone -r 5 myrepobad myrepoclean
now in myrepoclean you are back to where you were before the bad checkin. Obviously you need to be aware that anyone who has pulled the bad checkin is now liable to push it back in.
$ hg rollback --help
hg rollback
roll back the last transaction (dangerous)
This command should be used with care. There is only one level of rollback,
and there is no way to undo a rollback. It will also restore the dirstate at
the time of the last transaction, losing any dirstate changes since that
time. This command does not alter the working directory.
...
You should also look at the strip command.

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.

Mercurial: Revert a single hunk

How do I revert a single hunk in Mercurial, similar to the way it's done in darcs, i.e. it asks me for each hunk and file whether I want to revert it? Is it possible using TortoiseHg?
Thanks
Actually mercurial refers to "chunks", at least in the Shelve tool. Which brings me to favorite way to revert them (and favorite features of TortoiseHg).
Just move the chunks you want to revert onto a shelf you create solely with the intention to delete. This works really well as long as the chunks are identified as you need them to be. If not, you've got no choice but to do something manually.
If you use TortoiseHg Workbench or VisualHg, it is very easy to get to the Shelve tool: there is a button next to the diff mode toggle buttons. If you are not familiar with shelves, do yourself a favor and start using it. It has saved me much aggravation when I've forgotton to commit early, or decided to leave out experimental code from a commit.
The record extension is inspired by darcs record. It will allow you to add only specific hunks to the next commit, i.e., the opposite of what you want. But you could add all hunks except the one you want to revert and then do a hg revert to revert it. A little backwards, I know... :-)
You could also do hg diff > patch; hg revert, edit patch to delete the hunk and do hg import --no-commit to reappy the patch. That is likely faster, but requires you to manually edit the patch. I've had great success with the Emacs diff-mode, but since you ask about TortoiseHg you might not want to use Emacs.
For reversing a changeset on a single file try:
hg diff -c | patch -R
That will reverse the changeset introduced by that revision on that filename. Now if the same darcs/git style cherry-picking behavior could be included in that somehow I would be very happy.